Skip to content
Merged
25 changes: 25 additions & 0 deletions routers/web/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,19 @@ func performAutoLogin(ctx *context.Context) bool {
return false
}

func performAutoLoginOAuth2(ctx *context.Context) bool {
providers, ok := ctx.Data["OAuth2Providers"].([]oauth2.Provider)
if ok && len(providers) == 1 {
skipToOAuthURL := setting.AppSubURL + "/user/oauth2/" + url.PathEscape(providers[0].DisplayName())
if redirectTo := ctx.FormString("redirect_to"); redirectTo != "" {
skipToOAuthURL += "?" + url.Values{"redirect_to": []string{redirectTo}}.Encode()
}
ctx.Redirect(skipToOAuthURL)
return true
}
return false
}

func prepareSignInPageData(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
ctx.Data["OAuth2Providers"], _ = oauth2.GetOAuth2Providers(ctx, optional.Some(true))
Expand All @@ -242,6 +255,18 @@ func SignIn(ctx *context.Context) {
return
}
prepareSignInPageData(ctx)

// If only 1 OAuth provider is present and other login methods are disabled, redirect to the OAuth provider.
if !ctx.FormBool("skipAutoLogin") &&
!setting.Service.EnablePasswordSignInForm &&
!setting.Service.EnableOpenIDSignIn &&
!setting.Service.EnablePasskeyAuth &&
!auth.IsSSPIEnabled(ctx) {
Comment thread
navneet102 marked this conversation as resolved.
Outdated
if performAutoLoginOAuth2(ctx) {
return
}
}

ctx.HTML(http.StatusOK, tplSignIn)
}

Expand Down
19 changes: 19 additions & 0 deletions routers/web/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"testing"

auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -134,4 +135,22 @@ func TestWebAuthOAuth2(t *testing.T) {
u.RawQuery = ""
assert.Equal(t, "https://example.com/oidc-logout", u.String())
})

t.Run("SignInAutoRedirectSingleProvider", func(t *testing.T) {
unittest.PrepareTestEnv(t)
addOAuth2Source(t, "dummy-auth-source", oauth2.Source{})
defer test.MockVariableValue(&setting.Service.EnablePasswordSignInForm, false)()
defer test.MockVariableValue(&setting.Service.EnableOpenIDSignIn, false)()
defer test.MockVariableValue(&setting.Service.EnablePasskeyAuth, false)()

ctx, resp := contexttest.MockContext(t, "/user/login?redirect_to=/other")
SignIn(ctx)
assert.Equal(t, http.StatusSeeOther, resp.Code)
expectedURL := "/user/oauth2/dummy-auth-source?redirect_to=" + url.QueryEscape("/other")
assert.Equal(t, expectedURL, test.RedirectURL(resp))

ctx, resp = contexttest.MockContext(t, "/user/login?redirect_to=/other&skipAutoLogin=true")
SignIn(ctx)
assert.Equal(t, http.StatusOK, resp.Code)
})
Comment thread
navneet102 marked this conversation as resolved.
Outdated
}
Loading