From 724f0c6a8035f95bfe49200ab36ecb47da44829f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 17 Feb 2016 15:13:19 +0100 Subject: [PATCH] Initial commit --- .rspec | 3 ++ .ruby-version | 2 ++ Gemfile | 9 +++++ Gemfile.lock | 63 +++++++++++++++++++++++++++++++++ LICENSE | 0 README.md | 0 goldfinger.gemspec | 20 +++++++++++ lib/goldfinger.rb | 15 ++++++++ lib/goldfinger/client.rb | 38 ++++++++++++++++++++ lib/goldfinger/request.rb | 23 ++++++++++++ lib/goldfinger/result.rb | 40 +++++++++++++++++++++ lib/goldfinger/utils.rb | 11 ++++++ spec/goldfinger/client_spec.rb | 5 +++ spec/goldfinger/request_spec.rb | 5 +++ spec/goldfinger/result_spec.rb | 17 +++++++++ spec/goldfinger/utils_spec.rb | 3 ++ spec/spec_helper.rb | 16 +++++++++ 17 files changed, 270 insertions(+) create mode 100644 .rspec create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 LICENSE create mode 100644 README.md create mode 100644 goldfinger.gemspec create mode 100644 lib/goldfinger.rb create mode 100644 lib/goldfinger/client.rb create mode 100644 lib/goldfinger/request.rb create mode 100644 lib/goldfinger/result.rb create mode 100644 lib/goldfinger/utils.rb create mode 100644 spec/goldfinger/client_spec.rb create mode 100644 spec/goldfinger/request_spec.rb create mode 100644 spec/goldfinger/result_spec.rb create mode 100644 spec/goldfinger/utils_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..954c6fb --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--color +--require spec_helper +--format NyanCatFormatter diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..edbec98 --- /dev/null +++ b/.ruby-version @@ -0,0 +1,2 @@ +2.2.0 + diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..89f0b91 --- /dev/null +++ b/Gemfile @@ -0,0 +1,9 @@ +source "https://rubygems.org" + +group :test do + gem 'rspec', '>= 3.0' + gem 'nyan-cat-formatter' + gem 'webmock' +end + +gemspec diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..2ef2144 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,63 @@ +PATH + remote: . + specs: + goldfinger (0.0.0) + addressable (~> 2.4) + http (~> 1.0) + nokogiri (~> 1.6) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.4.0) + crack (0.4.3) + safe_yaml (~> 1.0.0) + diff-lcs (1.2.5) + domain_name (0.5.20160128) + unf (>= 0.0.5, < 1.0.0) + hashdiff (0.3.0) + http (1.0.2) + addressable (~> 2.3) + http-cookie (~> 1.0) + http-form_data (~> 1.0.1) + http_parser.rb (~> 0.6.0) + http-cookie (1.0.2) + domain_name (~> 0.5) + http-form_data (1.0.1) + http_parser.rb (0.6.0) + mini_portile2 (2.0.0) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) + nyan-cat-formatter (0.11) + rspec (>= 2.99, >= 2.14.2, < 4) + rspec (3.4.0) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-core (3.4.2) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-mocks (3.4.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) + safe_yaml (1.0.4) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) + webmock (1.22.6) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 1.3) + goldfinger! + nyan-cat-formatter + rspec (>= 3.0) + webmock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/goldfinger.gemspec b/goldfinger.gemspec new file mode 100644 index 0000000..0a82810 --- /dev/null +++ b/goldfinger.gemspec @@ -0,0 +1,20 @@ +Gem::Specification.new do |s| + s.name = 'goldfinger' + s.version = '0.0.0' + s.platform = Gem::Platform::RUBY + s.required_ruby_version = '>= 2.0.0' + s.date = '2016-02-17' + s.summary = "A Webfinger utility for Ruby" + s.description = "A Webfinger utility for Ruby" + s.authors = ["Eugen Rochko"] + s.email = 'eugen@zeonfederated.com' + s.files = `git ls-files lib LICENSE README.md`.split($RS) + s.homepage = 'https://github.com/Gargron/goldfinger' + s.license = 'MIT' + + s.add_dependency('http', '~> 1.0') + s.add_dependency('addressable', '~> 2.4') + s.add_dependency('nokogiri', '~> 1.6') + + s.add_development_dependency('bundler', '~> 1.3') +end diff --git a/lib/goldfinger.rb b/lib/goldfinger.rb new file mode 100644 index 0000000..069f9d7 --- /dev/null +++ b/lib/goldfinger.rb @@ -0,0 +1,15 @@ +require 'goldfinger/request' +require 'goldfinger/result' +require 'goldfinger/utils' +require 'goldfinger/client' + +module Goldfinger + module Error + class NotFound < StandardError + end + end + + def self.finger(uri) + Goldfinger::Client.new(uri).finger + end +end diff --git a/lib/goldfinger/client.rb b/lib/goldfinger/client.rb new file mode 100644 index 0000000..20e0247 --- /dev/null +++ b/lib/goldfinger/client.rb @@ -0,0 +1,38 @@ +require 'addressable' +require 'nokogiri' + +module Goldfinger + class Client + include Goldfinger::Utils + + def initialize(uri) + @uri = uri + end + + def finger + _, template = perform_get(url) + headers, body = perform_get(url_from_template(template)) + Goldfinger::Result.new(headers, body) + end + + private + + def url(ssl = true) + "http#{'s' if ssl}://#{domain}/.well-known/host-meta" + end + + def url_from_template(template) + xml = Nokogiri::XML(template) + links = xml.xpath('//xmlns:Link[@rel="lrdd"]', xmlns: 'http://docs.oasis-open.org/ns/xri/xrd-1.0') + + raise Goldfinger::Error::NotFound if links.empty? + + url = Addressable::Template.new(links.first.attribute('template').value) + url.expand({ uri: @uri }).to_s + end + + def domain + @uri.split('@').last + end + end +end diff --git a/lib/goldfinger/request.rb b/lib/goldfinger/request.rb new file mode 100644 index 0000000..bc06052 --- /dev/null +++ b/lib/goldfinger/request.rb @@ -0,0 +1,23 @@ +require 'http' +require 'addressable' + +module Goldfinger + class Request + def initialize(request_method, path, options = {}) + @request_method = request_method + @uri = Addressable::URI.parse(path) + @options = options + end + + def perform + response = http_client.request(@request_method, @uri.to_s, @options) + [response.headers, response.body] + end + + private + + def http_client + HTTP + end + end +end diff --git a/lib/goldfinger/result.rb b/lib/goldfinger/result.rb new file mode 100644 index 0000000..610bc40 --- /dev/null +++ b/lib/goldfinger/result.rb @@ -0,0 +1,40 @@ +module Goldfinger + class Result + def initialize(headers, body) + @mime_type = headers.get(HTTP::Headers::CONTENT_TYPE).first + @body = body + @links = {} + + parse + end + + def links + @links.to_a + end + + def link(rel) + @links[rel] + end + + private + + def parse + case @mime_type + when 'application/jrd+json' + parse_json + when 'application/xrd+xml' + parse_xml + end + end + + def parse_json + json = JSON.parse(@body) + json['links'].each { |link| @links[link['rel']] = link['href'] } + end + + def parse_xml + xml = Nokogiri::XML(@body) + xml.xpath('//xmlns:Link', xmlns: 'http://docs.oasis-open.org/ns/xri/xrd-1.0').each { |link| @links[link.attribute('rel').value] = link.attribute('href').value } + end + end +end diff --git a/lib/goldfinger/utils.rb b/lib/goldfinger/utils.rb new file mode 100644 index 0000000..5e60b25 --- /dev/null +++ b/lib/goldfinger/utils.rb @@ -0,0 +1,11 @@ +module Goldfinger + module Utils + def perform_get(path, options = {}) + perform_request(:get, path, options) + end + + def perform_request(request_method, path, options = {}) + Goldfinger::Request.new(request_method, path, options).perform + end + end +end diff --git a/spec/goldfinger/client_spec.rb b/spec/goldfinger/client_spec.rb new file mode 100644 index 0000000..73b5883 --- /dev/null +++ b/spec/goldfinger/client_spec.rb @@ -0,0 +1,5 @@ +describe Goldfinger::Client do + describe '#finger' do + pending + end +end diff --git a/spec/goldfinger/request_spec.rb b/spec/goldfinger/request_spec.rb new file mode 100644 index 0000000..82245e7 --- /dev/null +++ b/spec/goldfinger/request_spec.rb @@ -0,0 +1,5 @@ +describe Goldfinger::Request do + describe '#perform' do + pending + end +end diff --git a/spec/goldfinger/result_spec.rb b/spec/goldfinger/result_spec.rb new file mode 100644 index 0000000..baa1b19 --- /dev/null +++ b/spec/goldfinger/result_spec.rb @@ -0,0 +1,17 @@ +describe Goldfinger::Result do + describe '#links' do + pending + end + + describe '#link' do + pending + end + + describe '#parse_xml' do + pending + end + + describe '#parse_json' do + pending + end +end diff --git a/spec/goldfinger/utils_spec.rb b/spec/goldfinger/utils_spec.rb new file mode 100644 index 0000000..ad6b398 --- /dev/null +++ b/spec/goldfinger/utils_spec.rb @@ -0,0 +1,3 @@ +describe Goldfinger::Utils do + pending +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..a06f2bf --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,16 @@ +require 'goldfinger' +require 'webmock/rspec' + +WebMock.disable_net_connect! + +RSpec.configure do |config| + + config.expect_with :rspec do |expectations| + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + config.mock_with :rspec do |mocks| + mocks.verify_partial_doubles = true + end + +end