Merge branch 'next-minor' into develop

This commit is contained in:
Benjamin Neff 2022-07-23 00:54:06 +02:00
commit 37a00173f5
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
3 changed files with 22 additions and 33 deletions

View file

@ -57,6 +57,7 @@ We use yarn to install the frontend dependencies now, so you need to have that i
* Upgrade to rails 6.1 [#8366](https://github.com/diaspora/diaspora/pull/8366) * Upgrade to rails 6.1 [#8366](https://github.com/diaspora/diaspora/pull/8366)
* Update the suggested Ruby version to 2.7. If you run into trouble during the update and you followed our installation guides, run `rvm install 2.7`. [#8366](https://github.com/diaspora/diaspora/pull/8366) * Update the suggested Ruby version to 2.7. If you run into trouble during the update and you followed our installation guides, run `rvm install 2.7`. [#8366](https://github.com/diaspora/diaspora/pull/8366)
* Upgrade to bundler 2 [#8366](https://github.com/diaspora/diaspora/pull/8366) * Upgrade to bundler 2 [#8366](https://github.com/diaspora/diaspora/pull/8366)
* Stop checking `/.well-known/host-meta`, check for `/.well-known/nodeinfo` instead [#8377](https://github.com/diaspora/diaspora/pull/8377)
## Bug fixes ## Bug fixes
* Fix that no mails were sent after photo export [#8365](https://github.com/diaspora/diaspora/pull/8365) * Fix that no mails were sent after photo export [#8365](https://github.com/diaspora/diaspora/pull/8365)

View file

@ -1,4 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
class ConnectionTester class ConnectionTester
@ -97,16 +96,13 @@ class ConnectionTester
# * is the SSL certificate valid (only on HTTPS) # * is the SSL certificate valid (only on HTTPS)
# * does the server return a successful HTTP status code # * does the server return a successful HTTP status code
# * is there a reasonable amount of redirects (3 by default) # * is there a reasonable amount of redirects (3 by default)
# * is there a /.well-known/host-meta (this is needed to work, this can be replaced with a mandatory NodeInfo later)
# (can't do a HEAD request, since that's not a defined route in the app) # (can't do a HEAD request, since that's not a defined route in the app)
# #
# @raise [NetFailure, SSLFailure, HTTPFailure] if any of the checks fail # @raise [NetFailure, SSLFailure, HTTPFailure] if any of the checks fail
# @return [Integer] HTTP status code # @return [Integer] HTTP status code
def request def request
with_http_connection do |http| with_http_connection do |http|
capture_response_time { http.get("/") } capture_response_time { handle_http_response(http.get("/")) }
response = http.get("/.well-known/host-meta")
handle_http_response(response)
end end
rescue HTTPFailure => e rescue HTTPFailure => e
raise e raise e
@ -114,8 +110,8 @@ class ConnectionTester
raise NetFailure, e.message raise NetFailure, e.message
rescue Faraday::SSLError => e rescue Faraday::SSLError => e
raise SSLFailure, e.message raise SSLFailure, e.message
rescue ArgumentError, Faraday::FollowRedirects::RedirectLimitReached, Faraday::ClientError => e rescue ArgumentError, Faraday::ClientError => e
raise HTTPFailure, e.message raise HTTPFailure, "#{e.class}: #{e.message}"
rescue StandardError => e rescue StandardError => e
unexpected_error(e) unexpected_error(e)
end end
@ -123,19 +119,21 @@ class ConnectionTester
# Try to find out the version of the other servers software. # Try to find out the version of the other servers software.
# Assuming the server speaks nodeinfo # Assuming the server speaks nodeinfo
# #
# @raise [NodeInfoFailure] if the document can't be fetched # @raise [HTTPFailure] if the document can't be fetched
# or the attempt to parse it failed # @raise [NodeInfoFailure] if the document can't be parsed or is invalid
def nodeinfo def nodeinfo
with_http_connection do |http| with_http_connection do |http|
ni_resp = http.get(NODEINFO_FRAGMENT) ni_resp = http.get(NODEINFO_FRAGMENT)
nd_resp = http.get(find_nodeinfo_url(ni_resp.body)) nd_resp = http.get(find_nodeinfo_url(ni_resp.body))
find_software_version(nd_resp.body) find_software_version(nd_resp.body)
end end
rescue Faraday::ClientError => e
raise HTTPFailure, "#{e.class}: #{e.message}"
rescue NodeInfoFailure => e rescue NodeInfoFailure => e
raise e raise e
rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError => e rescue JSON::Schema::ValidationError, JSON::Schema::SchemaError => e
raise NodeInfoFailure, "#{e.class}: #{e.message}" raise NodeInfoFailure, "#{e.class}: #{e.message}"
rescue Faraday::ResourceNotFound, JSON::JSONError => e rescue JSON::JSONError => e
raise NodeInfoFailure, e.message[0..255].encode(Encoding.default_external, undef: :replace) raise NodeInfoFailure, e.message[0..255].encode(Encoding.default_external, undef: :replace)
rescue StandardError => e rescue StandardError => e
unexpected_error(e) unexpected_error(e)
@ -175,14 +173,11 @@ class ConnectionTester
def handle_http_response(response) def handle_http_response(response)
@result.status_code = Integer(response.status) @result.status_code = Integer(response.status)
if response.success? raise HTTPFailure, "unsuccessful response code: #{response.status}" unless response.success?
raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host raise HTTPFailure, "redirected to other hostname: #{response.env.url}" unless @uri.host == response.env.url.host
@result.reachable = true @result.reachable = true
@result.ssl = (response.env.url.scheme == "https") @result.ssl = (response.env.url.scheme == "https")
else
raise HTTPFailure, "unsuccessful response code: #{response.status}"
end
end end
# walk the JSON document, get the actual document location # walk the JSON document, get the actual document location

View file

@ -47,9 +47,8 @@ describe ConnectionTester do
end end
describe "#request" do describe "#request" do
it "performs a successful GET request on '/' and '/.well-known/host-meta'" do it "performs a successful GET request on '/'" do
stub_request(:get, url).to_return(status: 200, body: "Hello World!") stub_request(:get, url).to_return(status: 200, body: "Hello World!")
stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta")
tester.request tester.request
expect(result.rt).to be > -1 expect(result.rt).to be > -1
@ -60,27 +59,22 @@ describe ConnectionTester do
it "receives a 'normal' 301 redirect" do it "receives a 'normal' 301 redirect" do
stub_request(:get, url).to_return(status: 301, headers: {"Location" => "#{url}/redirect"}) stub_request(:get, url).to_return(status: 301, headers: {"Location" => "#{url}/redirect"})
stub_request(:get, "#{url}/redirect").to_return(status: 200, body: "Hello World!") stub_request(:get, "#{url}/redirect").to_return(status: 200, body: "Hello World!")
stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta")
tester.request tester.request
end end
it "updates ssl after https redirect" do it "updates ssl after https redirect" do
tester = ConnectionTester.new("http://pod.example.com/", result) tester = ConnectionTester.new("http://pod.example.com/", result)
stub_request(:get, "http://pod.example.com/").to_return(status: 200, body: "Hello World!") stub_request(:get, "http://pod.example.com/").to_return(status: 301, headers: {"Location" => url})
stub_request(:get, "http://pod.example.com/.well-known/host-meta") stub_request(:get, url).to_return(status: 200, body: "Hello World!")
.to_return(status: 301, headers: {"Location" => "#{url}/.well-known/host-meta"})
stub_request(:get, "#{url}/.well-known/host-meta").to_return(status: 200, body: "host-meta")
tester.request tester.request
expect(result.ssl).to be_truthy expect(result.ssl).to be_truthy
end end
it "rejects other hostname after redirect redirect" do it "rejects other hostname after redirect" do
stub_request(:get, url).to_return(status: 200, body: "Hello World!") stub_request(:get, url).to_return(status: 301, headers: {"Location" => "https://example.com/"})
stub_request(:get, "#{url}/.well-known/host-meta") stub_request(:get, "https://example.com/").to_return(status: 200, body: "Hello World!")
.to_return(status: 301, headers: {"Location" => "https://example.com/.well-known/host-meta"})
stub_request(:get, "https://example.com/.well-known/host-meta").to_return(status: 200, body: "host-meta")
expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure) expect { tester.request }.to raise_error(ConnectionTester::HTTPFailure)
end end
@ -131,10 +125,9 @@ describe ConnectionTester do
expect(result.software_version).to eq("diaspora a.b.c.d") expect(result.software_version).to eq("diaspora a.b.c.d")
end end
it "handles a missing nodeinfo document gracefully" do it "fails the nodeinfo document is missing" do
stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}") stub_request(:get, "#{url}#{ConnectionTester::NODEINFO_FRAGMENT}").to_return(status: 404, body: "Not Found")
.to_return(status: 404, body: "Not Found") expect { tester.nodeinfo }.to raise_error(ConnectionTester::HTTPFailure)
expect { tester.nodeinfo }.to raise_error(ConnectionTester::NodeInfoFailure)
end end
it "handles a malformed document gracefully" do it "handles a malformed document gracefully" do