aboutsummaryrefslogtreecommitdiffstats
path: root/routers/web/auth/oauth.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/web/auth/oauth.go')
-rw-r--r--routers/web/auth/oauth.go75
1 files changed, 49 insertions, 26 deletions
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index 94a8bec565..3df2734bb6 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -18,8 +18,8 @@ import (
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web/middleware"
source_service "code.gitea.io/gitea/services/auth/source"
"code.gitea.io/gitea/services/auth/source/oauth2"
@@ -34,9 +34,8 @@ import (
// SignInOAuth handles the OAuth2 login buttons
func SignInOAuth(ctx *context.Context) {
- provider := ctx.PathParam("provider")
-
- authSource, err := auth.GetActiveOAuth2SourceByName(ctx, provider)
+ authName := ctx.PathParam("provider")
+ authSource, err := auth.GetActiveOAuth2SourceByAuthName(ctx, authName)
if err != nil {
ctx.ServerError("SignIn", err)
return
@@ -73,8 +72,6 @@ func SignInOAuth(ctx *context.Context) {
// SignInOAuthCallback handles the callback from the given provider
func SignInOAuthCallback(ctx *context.Context) {
- provider := ctx.PathParam("provider")
-
if ctx.Req.FormValue("error") != "" {
var errorKeyValues []string
for k, vv := range ctx.Req.Form {
@@ -87,7 +84,8 @@ func SignInOAuthCallback(ctx *context.Context) {
}
// first look if the provider is still active
- authSource, err := auth.GetActiveOAuth2SourceByName(ctx, provider)
+ authName := ctx.PathParam("provider")
+ authSource, err := auth.GetActiveOAuth2SourceByAuthName(ctx, authName)
if err != nil {
ctx.ServerError("SignIn", err)
return
@@ -132,7 +130,7 @@ func SignInOAuthCallback(ctx *context.Context) {
if u == nil {
if ctx.Doer != nil {
// attach user to the current signed-in user
- err = externalaccount.LinkAccountToUser(ctx, ctx.Doer, gothUser)
+ err = externalaccount.LinkAccountToUser(ctx, authSource.ID, ctx.Doer, gothUser)
if err != nil {
ctx.ServerError("UserLinkAccount", err)
return
@@ -173,12 +171,11 @@ func SignInOAuthCallback(ctx *context.Context) {
gothUser.RawData = make(map[string]any)
}
gothUser.RawData["__giteaAutoRegMissingFields"] = missingFields
- showLinkingLogin(ctx, gothUser)
+ showLinkingLogin(ctx, authSource, gothUser)
return
}
u = &user_model.User{
Name: uname,
- FullName: gothUser.Name,
Email: gothUser.Email,
LoginType: auth.OAuth2,
LoginSource: authSource.ID,
@@ -192,10 +189,14 @@ func SignInOAuthCallback(ctx *context.Context) {
source := authSource.Cfg.(*oauth2.Source)
isAdmin, isRestricted := getUserAdminAndRestrictedFromGroupClaims(source, &gothUser)
- u.IsAdmin = isAdmin.ValueOrDefault(false)
- u.IsRestricted = isRestricted.ValueOrDefault(false)
+ u.IsAdmin = isAdmin.ValueOrDefault(user_service.UpdateOptionField[bool]{FieldValue: false}).FieldValue
+ u.IsRestricted = isRestricted.ValueOrDefault(setting.Service.DefaultUserIsRestricted)
- if !createAndHandleCreatedUser(ctx, templates.TplName(""), nil, u, overwriteDefault, &gothUser, setting.OAuth2Client.AccountLinking != setting.OAuth2AccountLinkingDisabled) {
+ linkAccountData := &LinkAccountData{*authSource, gothUser}
+ if setting.OAuth2Client.AccountLinking == setting.OAuth2AccountLinkingDisabled {
+ linkAccountData = nil
+ }
+ if !createAndHandleCreatedUser(ctx, "", nil, u, overwriteDefault, linkAccountData) {
// error already handled
return
}
@@ -206,7 +207,7 @@ func SignInOAuthCallback(ctx *context.Context) {
}
} else {
// no existing user is found, request attach or new account
- showLinkingLogin(ctx, gothUser)
+ showLinkingLogin(ctx, authSource, gothUser)
return
}
}
@@ -257,11 +258,11 @@ func getClaimedGroups(source *oauth2.Source, gothUser *goth.User) container.Set[
return claimValueToStringSet(groupClaims)
}
-func getUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, gothUser *goth.User) (isAdmin, isRestricted optional.Option[bool]) {
+func getUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, gothUser *goth.User) (isAdmin optional.Option[user_service.UpdateOptionField[bool]], isRestricted optional.Option[bool]) {
groups := getClaimedGroups(source, gothUser)
if source.AdminGroup != "" {
- isAdmin = optional.Some(groups.Contains(source.AdminGroup))
+ isAdmin = user_service.UpdateOptionFieldFromSync(groups.Contains(source.AdminGroup))
}
if source.RestrictedGroup != "" {
isRestricted = optional.Some(groups.Contains(source.RestrictedGroup))
@@ -270,9 +271,22 @@ func getUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, gothUser *g
return isAdmin, isRestricted
}
-func showLinkingLogin(ctx *context.Context, gothUser goth.User) {
+type LinkAccountData struct {
+ AuthSource auth.Source
+ GothUser goth.User
+}
+
+func oauth2GetLinkAccountData(ctx *context.Context) *LinkAccountData {
+ v, ok := ctx.Session.Get("linkAccountData").(LinkAccountData)
+ if !ok {
+ return nil
+ }
+ return &v
+}
+
+func showLinkingLogin(ctx *context.Context, authSource *auth.Source, gothUser goth.User) {
if err := updateSession(ctx, nil, map[string]any{
- "linkAccountGothUser": gothUser,
+ "linkAccountData": LinkAccountData{*authSource, gothUser},
}); err != nil {
ctx.ServerError("updateSession", err)
return
@@ -280,7 +294,7 @@ func showLinkingLogin(ctx *context.Context, gothUser goth.User) {
ctx.Redirect(setting.AppSubURL + "/user/link_account")
}
-func updateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
+func oauth2UpdateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
if setting.OAuth2Client.UpdateAvatar && len(url) > 0 {
resp, err := http.Get(url)
if err == nil {
@@ -298,11 +312,14 @@ func updateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
}
}
-func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model.User, gothUser goth.User) {
- updateAvatarIfNeed(ctx, gothUser.AvatarURL, u)
+func handleOAuth2SignIn(ctx *context.Context, authSource *auth.Source, u *user_model.User, gothUser goth.User) {
+ oauth2SignInSync(ctx, authSource, u, gothUser)
+ if ctx.Written() {
+ return
+ }
needs2FA := false
- if !source.Cfg.(*oauth2.Source).SkipLocalTwoFA {
+ if !authSource.TwoFactorShouldSkip() {
_, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
ctx.ServerError("UserSignIn", err)
@@ -311,7 +328,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
needs2FA = err == nil
}
- oauth2Source := source.Cfg.(*oauth2.Source)
+ oauth2Source := authSource.Cfg.(*oauth2.Source)
groupTeamMapping, err := auth_module.UnmarshalGroupTeamMapping(oauth2Source.GroupTeamMap)
if err != nil {
ctx.ServerError("UnmarshalGroupTeamMapping", err)
@@ -337,7 +354,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
}
}
- if err := externalaccount.EnsureLinkExternalToUser(ctx, u, gothUser); err != nil {
+ if err := externalaccount.EnsureLinkExternalToUser(ctx, authSource.ID, u, gothUser); err != nil {
ctx.ServerError("EnsureLinkExternalToUser", err)
return
}
@@ -352,10 +369,16 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
ctx.ServerError("UpdateUser", err)
return
}
+ userHasTwoFactorAuth, err := auth.HasTwoFactorOrWebAuthn(ctx, u.ID)
+ if err != nil {
+ ctx.ServerError("UpdateUser", err)
+ return
+ }
if err := updateSession(ctx, nil, map[string]any{
- "uid": u.ID,
- "uname": u.Name,
+ session.KeyUID: u.ID,
+ session.KeyUname: u.Name,
+ session.KeyUserHasTwoFactorAuth: userHasTwoFactorAuth,
}); err != nil {
ctx.ServerError("updateSession", err)
return