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`.
|
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
|
#### Parameters
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ module DiasporaFederation
|
||||||
]
|
]
|
||||||
|
|
||||||
# defaults
|
# defaults
|
||||||
|
@webfinger_http_fallback = false
|
||||||
@http_concurrency = 20
|
@http_concurrency = 20
|
||||||
@http_timeout = 30
|
@http_timeout = 30
|
||||||
@http_verbose = false
|
@http_verbose = false
|
||||||
|
|
@ -74,6 +75,21 @@ module DiasporaFederation
|
||||||
# @param [String] value path to certificate authorities
|
# @param [String] value path to certificate authorities
|
||||||
attr_accessor :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+)
|
# Maximum number of parallel HTTP requests made to other pods (default: +20+)
|
||||||
#
|
#
|
||||||
# @overload http_concurrency
|
# @overload http_concurrency
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,8 @@ module DiasporaFederation
|
||||||
return @webfinger if @webfinger
|
return @webfinger if @webfinger
|
||||||
webfinger_url = "https://#{domain}/.well-known/webfinger?resource=#{acct_parameter}"
|
webfinger_url = "https://#{domain}/.well-known/webfinger?resource=#{acct_parameter}"
|
||||||
|
|
||||||
# This tries the WebFinger URL with https first, then falls back to http.
|
# 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, true))
|
@webfinger = WebFinger.from_json(get(webfinger_url, DiasporaFederation.webfinger_http_fallback))
|
||||||
rescue => e
|
rescue => e
|
||||||
logger.warn "WebFinger failed, retrying with legacy WebFinger for #{diaspora_id}: #{e.class}: #{e.message}"
|
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))
|
@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)
|
expect(subject.fetch_and_save).to be(callback_person)
|
||||||
end
|
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
|
it "fails if the diaspora* ID does not match" do
|
||||||
modified_webfinger = webfinger_jrd.gsub(account, "anonther_user@example.com")
|
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
|
expect { subject.fetch_and_save }.to raise_error Discovery::DiscoveryError
|
||||||
end
|
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
|
context "legacy WebFinger" do
|
||||||
it "falls back to legacy WebFinger" do
|
it "falls back to legacy WebFinger" do
|
||||||
incomplete_webfinger_json = "{\"links\":[{\"rel\":\"http://openid.net/specs/connect/1.0/issuer\"," \
|
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
|
it "falls back to http if https fails with 404" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||||
.to_return(status: 404)
|
.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")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_return(status: 404)
|
.to_return(status: 404)
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
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
|
it "falls back to http if https fails with ssl error" do
|
||||||
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
stub_request(:get, "https://localhost:3000/.well-known/webfinger?resource=acct:#{account}")
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
.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")
|
stub_request(:get, "https://localhost:3000/.well-known/host-meta")
|
||||||
.to_raise(OpenSSL::SSL::SSLError)
|
.to_raise(OpenSSL::SSL::SSLError)
|
||||||
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
stub_request(:get, "http://localhost:3000/.well-known/host-meta")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue