mirror of https://github.com/mastodon/goldfinger
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:
parent
73a44507c6
commit
eddf330c22
24
Gemfile.lock
24
Gemfile.lock
|
@ -1,7 +1,7 @@
|
||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
goldfinger (1.1.0)
|
goldfinger (1.2.0)
|
||||||
addressable (~> 2.4)
|
addressable (~> 2.4)
|
||||||
http (~> 2.0)
|
http (~> 2.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
|
@ -9,18 +9,19 @@ PATH
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
addressable (2.4.0)
|
addressable (2.5.1)
|
||||||
|
public_suffix (~> 2.0, >= 2.0.2)
|
||||||
coderay (1.1.1)
|
coderay (1.1.1)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.3)
|
||||||
domain_name (0.5.20160826)
|
domain_name (0.5.20170404)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
fuubar (2.2.0)
|
fuubar (2.2.0)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
hashdiff (0.3.0)
|
hashdiff (0.3.2)
|
||||||
http (2.0.3)
|
http (2.2.1)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
http-cookie (~> 1.0)
|
http-cookie (~> 1.0)
|
||||||
http-form_data (~> 1.0.1)
|
http-form_data (~> 1.0.1)
|
||||||
|
@ -31,18 +32,19 @@ GEM
|
||||||
http_parser.rb (0.6.0)
|
http_parser.rb (0.6.0)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.1.0)
|
||||||
nokogiri (1.6.8.1)
|
nokogiri (1.7.1)
|
||||||
mini_portile2 (~> 2.1.0)
|
mini_portile2 (~> 2.1.0)
|
||||||
pry (0.10.4)
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
rake (11.2.2)
|
public_suffix (2.0.5)
|
||||||
|
rake (12.0.0)
|
||||||
rspec (3.5.0)
|
rspec (3.5.0)
|
||||||
rspec-core (~> 3.5.0)
|
rspec-core (~> 3.5.0)
|
||||||
rspec-expectations (~> 3.5.0)
|
rspec-expectations (~> 3.5.0)
|
||||||
rspec-mocks (~> 3.5.0)
|
rspec-mocks (~> 3.5.0)
|
||||||
rspec-core (3.5.3)
|
rspec-core (3.5.4)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.5.0)
|
||||||
rspec-expectations (3.5.0)
|
rspec-expectations (3.5.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
|
@ -56,8 +58,8 @@ GEM
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.2)
|
unf_ext (0.0.7.4)
|
||||||
webmock (2.1.0)
|
webmock (3.0.1)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff
|
hashdiff
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = 'goldfinger'
|
s.name = 'goldfinger'
|
||||||
s.version = '1.1.0'
|
s.version = '1.2.0'
|
||||||
s.platform = Gem::Platform::RUBY
|
s.platform = Gem::Platform::RUBY
|
||||||
s.required_ruby_version = '>= 2.0.0'
|
s.required_ruby_version = '>= 2.0.0'
|
||||||
s.date = '2016-02-17'
|
s.date = '2016-02-17'
|
||||||
|
|
|
@ -13,35 +13,56 @@ module Goldfinger
|
||||||
ssl = true
|
ssl = true
|
||||||
|
|
||||||
begin
|
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
|
rescue HTTP::Error
|
||||||
if ssl
|
raise Goldfinger::NotFoundError unless ssl
|
||||||
ssl = false
|
|
||||||
retry
|
ssl = false
|
||||||
else
|
retry
|
||||||
raise Goldfinger::NotFoundError
|
|
||||||
end
|
|
||||||
end
|
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
|
rescue HTTP::Error
|
||||||
raise Goldfinger::NotFoundError
|
raise Goldfinger::NotFoundError
|
||||||
rescue OpenSSL::SSL::SSLError
|
rescue OpenSSL::SSL::SSLError
|
||||||
raise Goldfinger::SSLError
|
raise Goldfinger::SSLError
|
||||||
|
rescue Addressable::URI::InvalidURIError
|
||||||
|
raise Goldfinger::NotFoundError, 'Invalid URI'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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)
|
def url(ssl = true)
|
||||||
"http#{'s' if ssl}://#{domain}/.well-known/host-meta"
|
"http#{'s' if ssl}://#{domain}/.well-known/host-meta"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def standard_url(ssl = true)
|
||||||
|
"http#{'s' if ssl}://#{domain}/.well-known/webfinger?resource=#{@uri}"
|
||||||
|
end
|
||||||
|
|
||||||
def url_from_template(template)
|
def url_from_template(template)
|
||||||
xml = Nokogiri::XML(template)
|
xml = Nokogiri::XML(template)
|
||||||
links = xml.xpath('//xmlns:Link[@rel="lrdd"]')
|
links = xml.xpath('//xmlns:Link[@rel="lrdd"]')
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
module Goldfinger
|
module Goldfinger
|
||||||
# @!attribute [r] href
|
# @!attribute [r] href
|
||||||
# @return [String] The href the link points to
|
# @return [String] The href the link points to
|
||||||
|
# @!attribute [r] template
|
||||||
|
# @return [String] The template the link contains
|
||||||
# @!attribute [r] type
|
# @!attribute [r] type
|
||||||
# @return [String] The mime type of the link
|
# @return [String] The mime type of the link
|
||||||
# @!attribute [r] rel
|
# @!attribute [r] rel
|
||||||
# @return [String] The relation descriptor of the link
|
# @return [String] The relation descriptor of the link
|
||||||
class Link
|
class Link
|
||||||
attr_reader :href, :type, :rel
|
attr_reader :href, :template, :type, :rel
|
||||||
|
|
||||||
def initialize(a)
|
def initialize(a)
|
||||||
@href = a[:href]
|
@href = a[:href]
|
||||||
|
@template = a[:template]
|
||||||
@type = a[:type]
|
@type = a[:type]
|
||||||
@rel = a[:rel]
|
@rel = a[:rel]
|
||||||
@titles = a[:titles]
|
@titles = a[:titles]
|
||||||
|
|
|
@ -2,7 +2,6 @@ describe Goldfinger::Client do
|
||||||
context 'with HTTPS available' do
|
context 'with HTTPS available' do
|
||||||
describe '#finger' do
|
describe '#finger' do
|
||||||
before 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' })
|
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
|
end
|
||||||
|
|
||||||
|
@ -11,15 +10,19 @@ describe Goldfinger::Client do
|
||||||
it 'returns a result' do
|
it 'returns a result' do
|
||||||
expect(subject.finger).to be_instance_of Goldfinger::Result
|
expect(subject.finger).to be_instance_of Goldfinger::Result
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with only HTTP available' do
|
context 'with only HTTP available' do
|
||||||
describe '#finger' do
|
describe '#finger' do
|
||||||
before do
|
before do
|
||||||
stub_request(:get, 'https://quitter.no/.well-known/host-meta').to_raise(HTTP::Error)
|
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/host-meta').to_return(body: fixture('quitter.no_.well-known_host-meta'), headers: { content_type: 'application/xrd+xml' })
|
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' })
|
||||||
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
|
end
|
||||||
|
|
||||||
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
|
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
|
||||||
|
@ -27,12 +30,20 @@ describe Goldfinger::Client do
|
||||||
it 'returns a result' do
|
it 'returns a result' do
|
||||||
expect(subject.finger).to be_instance_of Goldfinger::Result
|
expect(subject.finger).to be_instance_of Goldfinger::Result
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with XRD missing' do
|
context 'with XRD missing' do
|
||||||
describe '#finger' do
|
describe '#finger' do
|
||||||
before 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, '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)
|
stub_request(:get, 'http://quitter.no/.well-known/host-meta').to_raise(HTTP::Error)
|
||||||
end
|
end
|
||||||
|
@ -40,7 +51,7 @@ describe Goldfinger::Client do
|
||||||
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
|
subject { Goldfinger::Client.new('acct:gargron@quitter.no') }
|
||||||
|
|
||||||
it 'raises an error' do
|
it 'raises an error' do
|
||||||
expect {subject.finger }.to raise_error(Goldfinger::NotFoundError)
|
expect { subject.finger }.to raise_error(Goldfinger::NotFoundError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,6 @@ require 'pry'
|
||||||
WebMock.disable_net_connect!
|
WebMock.disable_net_connect!
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
||||||
config.expect_with :rspec do |expectations|
|
config.expect_with :rspec do |expectations|
|
||||||
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
||||||
end
|
end
|
||||||
|
@ -13,7 +12,6 @@ RSpec.configure do |config|
|
||||||
config.mock_with :rspec do |mocks|
|
config.mock_with :rspec do |mocks|
|
||||||
mocks.verify_partial_doubles = true
|
mocks.verify_partial_doubles = true
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fixture_path(path)
|
def fixture_path(path)
|
||||||
|
|
Loading…
Reference in New Issue