UX: Improve error handling for DiscourseConnect (#26140)

Previously, if the sso= payload was invalid Base64, but signed correctly, there would be no useful log or error. This commit improves things by:

- moving the base64 check before the signature checking so that it's properly surfaced
- split the ParseError exception into PayloadParseError and SignatureError
- add user-facing errors for both of those
- add/improve spec for both
This commit is contained in:
David Taylor
2024-03-12 16:16:04 +00:00
committed by GitHub
parent ec3d29a1fa
commit 127214c613
4 changed files with 53 additions and 13 deletions

View File

@ -1268,6 +1268,23 @@ RSpec.describe SessionController do
end
end
it "returns the correct error code for invalid payload" do
sso = get_sso("/hello/world")
sso.external_id = "997"
sso.sso_url = "http://somewhere.over.com/sso_login"
params = Rack::Utils.parse_query(sso.payload)
params["sso"] = "#{params["sso"]}%3C"
params["sig"] = sso.sign(params["sso"])
get "/session/sso_login", params: params, headers: headers
expect(response.status).to eq(422)
expect(response.body).to include(I18n.t("discourse_connect.payload_parse_error"))
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).to eq(nil)
end
it "returns the correct error code for invalid signature" do
sso = get_sso("/hello/world")
sso.external_id = "997"
@ -1278,6 +1295,7 @@ RSpec.describe SessionController do
params: correct_params.merge(sig: "thisisnotthesigyouarelookingfor"),
headers: headers
expect(response.status).to eq(422)
expect(response.body).to include(I18n.t("discourse_connect.signature_error"))
expect(response.body).not_to include(correct_params["sig"]) # Check we didn't send the real sig back to the client
logged_on_user = Discourse.current_user_provider.new(request.env).current_user
expect(logged_on_user).to eq(nil)