The Webfinger spec now mandates a standard URL. Check that URL first, instead of

checking host-meta first (which may actually not be present). Bump to 1.2.0
This commit is contained in:
Eugen Rochko 2017-04-27 16:25:20 +02:00
parent 73a44507c6
commit eddf330c22
6 changed files with 70 additions and 35 deletions

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
goldfinger (1.1.0)
goldfinger (1.2.0)
addressable (~> 2.4)
http (~> 2.0)
nokogiri (~> 1.6)
@ -9,18 +9,19 @@ PATH
GEM
remote: https://rubygems.org/
specs:
addressable (2.4.0)
addressable (2.5.1)
public_suffix (~> 2.0, >= 2.0.2)
coderay (1.1.1)
crack (0.4.3)
safe_yaml (~> 1.0.0)
diff-lcs (1.2.5)
domain_name (0.5.20160826)
diff-lcs (1.3)
domain_name (0.5.20170404)
unf (>= 0.0.5, < 1.0.0)
fuubar (2.2.0)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
hashdiff (0.3.0)
http (2.0.3)
hashdiff (0.3.2)
http (2.2.1)
addressable (~> 2.3)
http-cookie (~> 1.0)
http-form_data (~> 1.0.1)
@ -31,18 +32,19 @@ GEM
http_parser.rb (0.6.0)
method_source (0.8.2)
mini_portile2 (2.1.0)
nokogiri (1.6.8.1)
nokogiri (1.7.1)
mini_portile2 (~> 2.1.0)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
rake (11.2.2)
public_suffix (2.0.5)
rake (12.0.0)
rspec (3.5.0)
rspec-core (~> 3.5.0)
rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.5.0)
rspec-core (3.5.3)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
diff-lcs (>= 1.2.0, < 2.0)
@ -56,8 +58,8 @@ GEM
slop (3.6.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.2)
webmock (2.1.0)
unf_ext (0.0.7.4)
webmock (3.0.1)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff

View File

@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = 'goldfinger'
s.version = '1.1.0'
s.version = '1.2.0'
s.platform = Gem::Platform::RUBY
s.required_ruby_version = '>= 2.0.0'
s.date = '2016-02-17'

View File

@ -13,35 +13,56 @@ module Goldfinger
ssl = true
begin
template = perform_get(url(ssl))
response = perform_get(standard_url(ssl))
return finger_from_template if response.code != 200
Goldfinger::Result.new(response)
rescue HTTP::Error
if ssl
ssl = false
retry
else
raise Goldfinger::NotFoundError
end
raise Goldfinger::NotFoundError unless ssl
ssl = false
retry
end
raise Goldfinger::NotFoundError, "No host-meta on the server" if template.code != 200
response = perform_get(url_from_template(template.body))
raise Goldfinger::NotFoundError, "No such user on the server" if response.code != 200
Goldfinger::Result.new(response)
rescue HTTP::Error
raise Goldfinger::NotFoundError
rescue OpenSSL::SSL::SSLError
raise Goldfinger::SSLError
rescue Addressable::URI::InvalidURIError
raise Goldfinger::NotFoundError, 'Invalid URI'
end
private
def finger_from_template
ssl = true
begin
template = perform_get(url(ssl))
rescue HTTP::Error
raise Goldfinger::NotFoundError unless ssl
ssl = false
retry
end
raise Goldfinger::NotFoundError, 'No host-meta on the server' if template.code != 200
response = perform_get(url_from_template(template.body))
raise Goldfinger::NotFoundError, 'No such user on the server' if response.code != 200
Goldfinger::Result.new(response)
end
def url(ssl = true)
"http#{'s' if ssl}://#{domain}/.well-known/host-meta"
end
def standard_url(ssl = true)
"http#{'s' if ssl}://#{domain}/.well-known/webfinger?resource=#{@uri}"
end
def url_from_template(template)
xml = Nokogiri::XML(template)
links = xml.xpath('//xmlns:Link[@rel="lrdd"]')

View File

@ -1,15 +1,18 @@
module Goldfinger
# @!attribute [r] href
# @return [String] The href the link points to
# @!attribute [r] template
# @return [String] The template the link contains
# @!attribute [r] type
# @return [String] The mime type of the link
# @!attribute [r] rel
# @return [String] The relation descriptor of the link
class Link
attr_reader :href, :type, :rel
attr_reader :href, :template, :type, :rel
def initialize(a)
@href = a[:href]
@template = a[:template]
@type = a[:type]
@rel = a[:rel]
@titles = a[:titles]

View File

@ -2,7 +2,6 @@ describe Goldfinger::Client do
context 'with HTTPS available' do
describe '#finger' do
before do
stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_return(body: fixture('quitter.no_.well-known_host-meta'), headers: { content_type: 'application/xrd+xml' })
stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(body: fixture('quitter.no_.well-known_webfinger.json'), headers: { content_type: 'application/jrd+json' })
end
@ -11,15 +10,19 @@ describe Goldfinger::Client do
it 'returns a result' do
expect(subject.finger).to be_instance_of Goldfinger::Result
end
it 'performs a single HTTP request' do
subject.finger
expect(a_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no')).to have_been_made.once
end
end
end
context 'with only HTTP available' do
describe '#finger' do
before do
stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_raise(HTTP::Error)
stub_request(:get, 'http://quitter.no/.well-known/host-meta').to_return(body: fixture('quitter.no_.well-known_host-meta'), headers: { content_type: 'application/xrd+xml' })
stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(body: fixture('quitter.no_.well-known_webfinger.json'), headers: { content_type: 'application/jrd+json' })
stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_raise(HTTP::Error)
stub_request(:get, 'http://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_return(body: fixture('quitter.no_.well-known_webfinger.json'), headers: { content_type: 'application/jrd+json' })
end
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
@ -27,12 +30,20 @@ describe Goldfinger::Client do
it 'returns a result' do
expect(subject.finger).to be_instance_of Goldfinger::Result
end
it 'performs two HTTP requests' do
subject.finger
expect(a_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no')).to have_been_made.once
expect(a_request(:get, 'http://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no')).to have_been_made.once
end
end
end
context 'with XRD missing' do
describe '#finger' do
before do
stub_request(:get, 'https://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_raise(HTTP::Error)
stub_request(:get, 'http://quitter.no/.well-known/webfinger?resource=acct:gargron@quitter.no').to_raise(HTTP::Error)
stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_raise(HTTP::Error)
stub_request(:get, 'http://quitter.no/.well-known/host-meta').to_raise(HTTP::Error)
end
@ -40,7 +51,7 @@ describe Goldfinger::Client do
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
it 'raises an error' do
expect {subject.finger }.to raise_error(Goldfinger::NotFoundError)
expect { subject.finger }.to raise_error(Goldfinger::NotFoundError)
end
end
end

View File

@ -5,7 +5,6 @@ require 'pry'
WebMock.disable_net_connect!
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
@ -13,7 +12,6 @@ RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
def fixture_path(path)