Add option for RFC 7033 WebFinger http fallback
This commit is contained in:
parent
80e4844654
commit
f24dd528ee
4 changed files with 98 additions and 38 deletions
|
|
@ -14,8 +14,6 @@ GET /.well-known/webfinger
|
|||
|
||||
Let's assume we are searching for `alice@example.org`, then we need to make a request to `example.org`.
|
||||
|
||||
The request should first be tried with https, if this doesn't work, the requesting server should fallback to http.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description |
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ module DiasporaFederation
|
|||
]
|
||||
|
||||
# defaults
|
||||
@webfinger_http_fallback = false
|
||||
@http_concurrency = 20
|
||||
@http_timeout = 30
|
||||
@http_verbose = false
|
||||
|
|
@ -74,6 +75,21 @@ module DiasporaFederation
|
|||
# @param [String] value path to certificate authorities
|
||||
attr_accessor :certificate_authorities
|
||||
|
||||
# Configure if WebFinger discovery should fallback to http if https fails (default: +false+)
|
||||
#
|
||||
# This is useful for example for development environments where https isn't available.
|
||||
#
|
||||
# This setting only applies to the WebFinger route from RFC 7033 +/.well-known/webfinger+.
|
||||
# Legacy WebFinger flow unconditionally falls back to http.
|
||||
#
|
||||
# @overload webfinger_http_fallback
|
||||
# @return [Boolean] webfinger http fallback enabled
|
||||
# @overload webfinger_http_fallback=
|
||||
# @example
|
||||
# config.webfinger_http_fallback = AppConfig.server.rails_environment == "development"
|
||||
# @param [Boolean] value webfinger http fallback enabled
|
||||
attr_accessor :webfinger_http_fallback
|
||||
|
||||
# Maximum number of parallel HTTP requests made to other pods (default: +20+)
|
||||
#
|
||||
# @overload http_concurrency
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ module DiasporaFederation
|
|||
return @webfinger if @webfinger
|
||||
webfinger_url = "https://#{domain}/.well-known/webfinger?resource=#{acct_parameter}"
|
||||
|
||||
# This tries the WebFinger URL with https first, then falls back to http.
|
||||
@webfinger = WebFinger.from_json(get(webfinger_url, true))
|
||||
# This tries the WebFinger URL with https first, then falls back to http if webfinger_http_fallback is enabled.
|
||||
@webfinger = WebFinger.from_json(get(webfinger_url, DiasporaFederation.webfinger_http_fallback))
|
||||
rescue => e
|
||||
logger.warn "WebFinger failed, retrying with legacy WebFinger for #{diaspora_id}: #{e.class}: #{e.message}"
|
||||
@webfinger = WebFinger.from_xml(get(legacy_webfinger_url_from_host_meta))
|
||||
|
|
|
|||
|
|
@ -94,36 +94,6 @@ module DiasporaFederation
|
|||
expect(subject.fetch_and_save).to be(callback_person)
|
||||
end
|
||||
|
||||
it "falls back to http if https fails with 404" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_jrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
|
||||
it "falls back to http if https fails with ssl error" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_jrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
|
||||
it "fails if the diaspora* ID does not match" do
|
||||
modified_webfinger = webfinger_jrd.gsub(account, "anonther_user@example.com")
|
||||
|
||||
|
|
@ -146,6 +116,86 @@ module DiasporaFederation
|
|||
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||
end
|
||||
|
||||
context "http fallback" do
|
||||
context "http fallback disabled (default)" do
|
||||
it "falls back to legacy WebFinger if https fails with 404" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||
.to_return(status: 200, body: host_meta_xrd)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_xrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
|
||||
it "falls back to legacy WebFinger if https fails with ssl error" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||
.to_return(status: 200, body: host_meta_xrd)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger.xml?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_xrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
end
|
||||
|
||||
context "http fallback enabled" do
|
||||
before :all do
|
||||
DiasporaFederation.webfinger_http_fallback = true
|
||||
end
|
||||
|
||||
after :all do
|
||||
DiasporaFederation.webfinger_http_fallback = false
|
||||
end
|
||||
|
||||
it "falls back to http if https fails with 404" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_jrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
|
||||
it "falls back to http if https fails with ssl error" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: webfinger_jrd)
|
||||
stub_request(:get, "http://localhost:3000/hcard/users/#{alice.guid}")
|
||||
.to_return(status: 200, body: hcard_html)
|
||||
|
||||
expect_callback(:save_person_after_webfinger, kind_of(Entities::Person))
|
||||
person = subject.fetch_and_save
|
||||
|
||||
expect(person.guid).to eq(alice.guid)
|
||||
expect(person.diaspora_id).to eq(account)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "legacy WebFinger" do
|
||||
it "falls back to legacy WebFinger" do
|
||||
incomplete_webfinger_json = "{\"links\":[{\"rel\":\"http://openid.net/specs/connect/1.0/issuer\"," \
|
||||
|
|
@ -181,8 +231,6 @@ module DiasporaFederation
|
|||
it "falls back to http if https fails with 404" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||
.to_return(status: 404)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||
|
|
@ -202,8 +250,6 @@ module DiasporaFederation
|
|||
it "falls back to http if https fails with ssl error" do
|
||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||
.to_return(status: 200, body: "foobar")
|
||||
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||
.to_raise(OpenSSL::SSL::SSLError)
|
||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||
|
|
|
|||
Loading…
Reference in a new issue