Only validate changed columns when update user (#24867) (#24903)

Backport #24867 by @lunny

Fix #23211
Replace #23496

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
(cherry picked from commit 275abd65935216c05aa2d1238d8d8a7cfc739a35)
This commit is contained in:
Giteabot 2023-05-24 04:24:02 -04:00 committed by Earl Warren
parent 936eb64ebf
commit 75122edc97
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
2 changed files with 35 additions and 9 deletions

View file

@ -614,7 +614,7 @@ func CreateUser(u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err e
} }
// validate data // validate data
if err := validateUser(u); err != nil { if err := ValidateUser(u); err != nil {
return err return err
} }
@ -804,19 +804,26 @@ func checkDupEmail(ctx context.Context, u *User) error {
return nil return nil
} }
// validateUser check if user is valid to insert / update into database // ValidateUser check if user is valid to insert / update into database
func validateUser(u *User) error { func ValidateUser(u *User, cols ...string) error {
if !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(u.Visibility) && !u.IsOrganization() { if len(cols) == 0 || util.SliceContainsString(cols, "visibility", true) {
return fmt.Errorf("visibility Mode not allowed: %s", u.Visibility.String()) if !setting.Service.AllowedUserVisibilityModesSlice.IsAllowedVisibility(u.Visibility) && !u.IsOrganization() {
return fmt.Errorf("visibility Mode not allowed: %s", u.Visibility.String())
}
} }
u.Email = strings.ToLower(u.Email) if len(cols) == 0 || util.SliceContainsString(cols, "email", true) {
return ValidateEmail(u.Email) u.Email = strings.ToLower(u.Email)
if err := ValidateEmail(u.Email); err != nil {
return err
}
}
return nil
} }
// UpdateUser updates user's information. // UpdateUser updates user's information.
func UpdateUser(ctx context.Context, u *User, changePrimaryEmail bool, cols ...string) error { func UpdateUser(ctx context.Context, u *User, changePrimaryEmail bool, cols ...string) error {
err := validateUser(u) err := ValidateUser(u, cols...)
if err != nil { if err != nil {
return err return err
} }
@ -882,7 +889,7 @@ func UpdateUser(ctx context.Context, u *User, changePrimaryEmail bool, cols ...s
// UpdateUserCols update user according special columns // UpdateUserCols update user according special columns
func UpdateUserCols(ctx context.Context, u *User, cols ...string) error { func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
if err := validateUser(u); err != nil { if err := ValidateUser(u, cols...); err != nil {
return err return err
} }

View file

@ -5,6 +5,7 @@ package user_test
import ( import (
"context" "context"
"fmt"
"math/rand" "math/rand"
"strings" "strings"
"testing" "testing"
@ -524,3 +525,21 @@ func TestIsUserVisibleToViewer(t *testing.T) {
test(user31, user33, true) test(user31, user33, true)
test(user31, nil, false) test(user31, nil, false)
} }
func Test_ValidateUser(t *testing.T) {
oldSetting := setting.Service.AllowedUserVisibilityModesSlice
defer func() {
setting.Service.AllowedUserVisibilityModesSlice = oldSetting
}()
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, true}
kases := map[*user_model.User]bool{
{ID: 1, Visibility: structs.VisibleTypePublic}: true,
{ID: 2, Visibility: structs.VisibleTypeLimited}: false,
{ID: 2, Visibility: structs.VisibleTypeLimited, Email: "invalid"}: false,
{ID: 2, Visibility: structs.VisibleTypePrivate, Email: "valid@valid.com"}: true,
}
for kase, expected := range kases {
err := user_model.ValidateUser(kase)
assert.EqualValues(t, expected, err == nil, fmt.Sprintf("case: %+v", kase))
}
}