UX: Improve error handling for common OmniAuth exceptions (#7991)

This displays more useful messages for the most common issues we see:
- CSRF (when the user switches browser)
- Invalid IAT (when the server clock is wrong)
- OAuth::Unauthorized for OAuth1 providers, when the credentials are incorrect

This commit also stops earlier for disabled authenticators. Now we stop at the request phase, rather than the callback phase.
This commit is contained in:
David Taylor
2019-08-12 10:55:02 +01:00
committed by GitHub
parent 731f61a818
commit 750802bf56
6 changed files with 65 additions and 8 deletions

View File

@ -87,7 +87,7 @@ RSpec.describe Users::OmniauthCallbacksController do
it "should display the failure message if needed" do
get "/auth/failure"
expect(response.status).to eq(200)
expect(response.body).to include(I18n.t("login.omniauth_error"))
expect(response.body).to include(I18n.t("login.omniauth_error.generic"))
end
describe "request" do
@ -98,6 +98,28 @@ RSpec.describe Users::OmniauthCallbacksController do
expect(response.status).to eq(403)
end
it "should error for disabled authenticators" do
SiteSetting.enable_google_oauth2_logins = false
post "/auth/google_oauth2"
expect(response.status).to eq(404)
get "/auth/google_oauth2"
expect(response.status).to eq(403)
end
it "should handle common errors" do
OmniAuth::Strategies::GoogleOauth2.any_instance.stubs(:mock_request_call).raises(
OAuth::Unauthorized.new(mock().tap { |m| m.stubs(:code).returns(403); m.stubs(:message).returns("Message") })
)
post "/auth/google_oauth2"
expect(response.status).to eq(302)
expect(response.location).to include("/auth/failure?message=request_error")
OmniAuth::Strategies::GoogleOauth2.any_instance.stubs(:mock_request_call).raises(JWT::InvalidIatError.new)
post "/auth/google_oauth2"
expect(response.status).to eq(302)
expect(response.location).to include("/auth/failure?message=invalid_iat")
end
it "should only start auth with a POST request" do
post "/auth/google_oauth2"
expect(response.status).to eq(302)
@ -111,10 +133,12 @@ RSpec.describe Users::OmniauthCallbacksController do
it "should be CSRF protected" do
post "/auth/google_oauth2"
expect(response.status).to eq(422)
expect(response.status).to eq(302)
expect(response.location).to include("/auth/failure?message=csrf_detected")
post "/auth/google_oauth2", params: { authenticity_token: "faketoken" }
expect(response.status).to eq(422)
expect(response.status).to eq(302)
expect(response.location).to include("/auth/failure?message=csrf_detected")
get "/session/csrf.json"
token = JSON.parse(response.body)["csrf"]