From aa4ae81fe0f2dc6850470b7a7f88129aab90d2ec Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 29 Apr 2025 13:31:20 +0200 Subject: [PATCH] fix(sec): add tests for OAuth2 signup Test two scenarios: 1. Account linking is set to `auto` and tries to link against a user who is enrolled into Webauthn should show 2FA screen. 2. User is already linked and logins via OAuth2 and is enrolled into WebAuthn should show 2FA screen. --- tests/integration/oauth_test.go | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/integration/oauth_test.go b/tests/integration/oauth_test.go index e9b17634c9..a89bb2c510 100644 --- a/tests/integration/oauth_test.go +++ b/tests/integration/oauth_test.go @@ -1456,3 +1456,69 @@ func TestSignUpViaOAuthDefaultRestricted(t *testing.T) { unittest.AssertExistsIf(t, true, &user_model.User{Name: "gitlab-user"}, "is_restricted = true") } + +func TestSignUpViaOAuthLinking2FA(t *testing.T) { + defer tests.PrepareTestEnv(t)() + defer test.MockVariableValue(&setting.OAuth2Client.EnableAutoRegistration, true)() + defer test.MockVariableValue(&setting.OAuth2Client.AccountLinking, setting.OAuth2AccountLinkingAuto)() + + // Fake that user 2 is enrolled into WebAuthn. + t.Cleanup(func() { + unittest.AssertSuccessfulDelete(t, &auth_model.WebAuthnCredential{UserID: 2}) + }) + unittest.AssertSuccessfulInsert(t, &auth_model.WebAuthnCredential{UserID: 2}) + + gitlabName := "gitlab" + addAuthSource(t, authSourcePayloadGitLabCustom(gitlabName)) + userGitLabUserID := "BB(4)=107" + + defer mockCompleteUserAuth(func(res http.ResponseWriter, req *http.Request) (goth.User, error) { + return goth.User{ + Provider: gitlabName, + UserID: userGitLabUserID, + NickName: "user2", + Email: "user2@example.com", + }, nil + })() + req := NewRequest(t, "GET", fmt.Sprintf("/user/oauth2/%s/callback?code=XYZ&state=XYZ", gitlabName)) + resp := MakeRequest(t, req, http.StatusSeeOther) + + // Make sure the user has to go through 2FA after linking. + assert.Equal(t, "/user/webauthn", test.RedirectURL(resp)) +} + +func TestSignUpViaOAuth2FA(t *testing.T) { + defer tests.PrepareTestEnv(t)() + defer test.MockVariableValue(&setting.OAuth2Client.EnableAutoRegistration, true)() + defer test.MockVariableValue(&setting.OAuth2Client.AccountLinking, setting.OAuth2AccountLinkingAuto)() + + gitlabName := "gitlab" + addAuthSource(t, authSourcePayloadGitLabCustom(gitlabName)) + userGitLabUserID := "BB(3)=21" + + defer mockCompleteUserAuth(func(res http.ResponseWriter, req *http.Request) (goth.User, error) { + return goth.User{ + Provider: gitlabName, + UserID: userGitLabUserID, + NickName: "user2", + Email: "user2@example.com", + }, nil + })() + req := NewRequest(t, "GET", fmt.Sprintf("/user/oauth2/%s/callback?code=XYZ&state=XYZ", gitlabName)) + resp := MakeRequest(t, req, http.StatusSeeOther) + + // Make sure the user can login normally and is linked. + assert.Equal(t, "/", test.RedirectURL(resp)) + + // Fake that user 2 is enrolled into WebAuthn. + t.Cleanup(func() { + unittest.AssertSuccessfulDelete(t, &auth_model.WebAuthnCredential{UserID: 2}) + }) + unittest.AssertSuccessfulInsert(t, &auth_model.WebAuthnCredential{UserID: 2}) + + req = NewRequest(t, "GET", fmt.Sprintf("/user/oauth2/%s/callback?code=XYZ&state=XYZ", gitlabName)) + resp = MakeRequest(t, req, http.StatusSeeOther) + + // Make sure user has to go through 2FA. + assert.Equal(t, "/user/webauthn", test.RedirectURL(resp)) +}