1
0
Fork 0
forked from forgejo/forgejo

Unify user update methods (#28733)

Fixes #28660
Fixes an admin api bug related to `user.LoginSource`
Fixed `/user/emails` response not identical to GitHub api

This PR unifies the user update methods. The goal is to keep the logic
only at one place (having audit logs in mind). For example, do the
password checks only in one method not everywhere a password is updated.

After that PR is merged, the user creation should be next.
This commit is contained in:
KN4CK3R 2024-02-04 14:29:09 +01:00 committed by GitHub
parent b4513f48ce
commit f8b471ace1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 1383 additions and 1068 deletions

View file

@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
@ -990,7 +991,9 @@ func SignInOAuthCallback(ctx *context.Context) {
source := authSource.Cfg.(*oauth2.Source)
setUserAdminAndRestrictedFromGroupClaims(source, u, &gothUser)
isAdmin, isRestricted := getUserAdminAndRestrictedFromGroupClaims(source, &gothUser)
u.IsAdmin = isAdmin.ValueOrDefault(false)
u.IsRestricted = isRestricted.ValueOrDefault(false)
if !createAndHandleCreatedUser(ctx, base.TplName(""), nil, u, overwriteDefault, &gothUser, setting.OAuth2Client.AccountLinking != setting.OAuth2AccountLinkingDisabled) {
// error already handled
@ -1054,19 +1057,17 @@ func getClaimedGroups(source *oauth2.Source, gothUser *goth.User) container.Set[
return claimValueToStringSet(groupClaims)
}
func setUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, u *user_model.User, gothUser *goth.User) bool {
func getUserAdminAndRestrictedFromGroupClaims(source *oauth2.Source, gothUser *goth.User) (isAdmin, isRestricted optional.Option[bool]) {
groups := getClaimedGroups(source, gothUser)
wasAdmin, wasRestricted := u.IsAdmin, u.IsRestricted
if source.AdminGroup != "" {
u.IsAdmin = groups.Contains(source.AdminGroup)
isAdmin = optional.Some(groups.Contains(source.AdminGroup))
}
if source.RestrictedGroup != "" {
u.IsRestricted = groups.Contains(source.RestrictedGroup)
isRestricted = optional.Some(groups.Contains(source.RestrictedGroup))
}
return wasAdmin != u.IsAdmin || wasRestricted != u.IsRestricted
return isAdmin, isRestricted
}
func showLinkingLogin(ctx *context.Context, gothUser goth.User) {
@ -1133,18 +1134,12 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
// Clear whatever CSRF cookie has right now, force to generate a new one
ctx.Csrf.DeleteCookie(ctx)
// Register last login
u.SetLastLogin()
// Update GroupClaims
changed := setUserAdminAndRestrictedFromGroupClaims(oauth2Source, u, &gothUser)
cols := []string{"last_login_unix"}
if changed {
cols = append(cols, "is_admin", "is_restricted")
opts := &user_service.UpdateOptions{
SetLastLogin: true,
}
if err := user_model.UpdateUserCols(ctx, u, cols...); err != nil {
ctx.ServerError("UpdateUserCols", err)
opts.IsAdmin, opts.IsRestricted = getUserAdminAndRestrictedFromGroupClaims(oauth2Source, &gothUser)
if err := user_service.UpdateUser(ctx, u, opts); err != nil {
ctx.ServerError("UpdateUser", err)
return
}
@ -1177,10 +1172,11 @@ func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model
return
}
changed := setUserAdminAndRestrictedFromGroupClaims(oauth2Source, u, &gothUser)
if changed {
if err := user_model.UpdateUserCols(ctx, u, "is_admin", "is_restricted"); err != nil {
ctx.ServerError("UpdateUserCols", err)
opts := &user_service.UpdateOptions{}
opts.IsAdmin, opts.IsRestricted = getUserAdminAndRestrictedFromGroupClaims(oauth2Source, &gothUser)
if opts.IsAdmin.Has() || opts.IsRestricted.Has() {
if err := user_service.UpdateUser(ctx, u, opts); err != nil {
ctx.ServerError("UpdateUser", err)
return
}
}