loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve "must-change-password" logic and document (#30472)

Unify the behaviors of "user create" and "user change-password".

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
(cherry picked from commit 4c6e2da088cf092a9790df5c84b7b338508fede7)

Conflicts:
- cmd/admin_user_create.go
Resolved by favoring Gitea's version of the conflicting areas.
- docs/content/administration/command-line.en-us.md
Removed, Gitea specific.

authored by

wxiaoguang
KN4CK3R
and committed by
Gergely Nagy
b122c6ef d8258482

+31 -24
+5 -9
cmd/admin_user_change_password.go
··· 36 36 &cli.BoolFlag{ 37 37 Name: "must-change-password", 38 38 Usage: "User must change password", 39 + Value: true, 39 40 }, 40 41 }, 41 42 } ··· 57 58 return err 58 59 } 59 60 60 - var mustChangePassword optional.Option[bool] 61 - if c.IsSet("must-change-password") { 62 - mustChangePassword = optional.Some(c.Bool("must-change-password")) 63 - } 64 - 65 61 opts := &user_service.UpdateAuthOptions{ 66 62 Password: optional.Some(c.String("password")), 67 - MustChangePassword: mustChangePassword, 63 + MustChangePassword: optional.Some(c.Bool("must-change-password")), 68 64 } 69 65 if err := user_service.UpdateAuth(ctx, user, opts); err != nil { 70 66 switch { 71 67 case errors.Is(err, password.ErrMinLength): 72 - return fmt.Errorf("Password is not long enough. Needs to be at least %d", setting.MinPasswordLength) 68 + return fmt.Errorf("password is not long enough, needs to be at least %d characters", setting.MinPasswordLength) 73 69 case errors.Is(err, password.ErrComplexity): 74 - return errors.New("Password does not meet complexity requirements") 70 + return errors.New("password does not meet complexity requirements") 75 71 case errors.Is(err, password.ErrIsPwned): 76 - return errors.New("The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password.\nFor more details, see https://haveibeenpwned.com/Passwords") 72 + return errors.New("the password is in a list of stolen passwords previously exposed in public data breaches, please try again with a different password, to see more details: https://haveibeenpwned.com/Passwords") 77 73 default: 78 74 return err 79 75 }
+24 -13
cmd/admin_user_create.go
··· 8 8 "fmt" 9 9 10 10 auth_model "code.gitea.io/gitea/models/auth" 11 + "code.gitea.io/gitea/models/db" 11 12 user_model "code.gitea.io/gitea/models/user" 12 13 pwd "code.gitea.io/gitea/modules/auth/password" 13 14 "code.gitea.io/gitea/modules/optional" ··· 46 47 Usage: "Generate a random password for the user", 47 48 }, 48 49 &cli.BoolFlag{ 49 - Name: "must-change-password", 50 - Usage: "Set this option to false to prevent forcing the user to change their password after initial login", 51 - Value: true, 50 + Name: "must-change-password", 51 + Usage: "Set this option to false to prevent forcing the user to change their password after initial login", 52 + Value: true, 53 + DisableDefaultText: true, 52 54 }, 53 55 &cli.IntFlag{ 54 56 Name: "random-password-length", ··· 72 74 } 73 75 74 76 if c.IsSet("name") && c.IsSet("username") { 75 - return errors.New("Cannot set both --name and --username flags") 77 + return errors.New("cannot set both --name and --username flags") 76 78 } 77 79 if !c.IsSet("name") && !c.IsSet("username") { 78 - return errors.New("One of --name or --username flags must be set") 80 + return errors.New("one of --name or --username flags must be set") 79 81 } 80 82 81 83 if c.IsSet("password") && c.IsSet("random-password") { ··· 111 113 return errors.New("must set either password or random-password flag") 112 114 } 113 115 114 - changePassword := c.Bool("must-change-password") 115 - 116 - // If this is the first user being created. 117 - // Take it as the admin and don't force a password update. 118 - if n := user_model.CountUsers(ctx, nil); n == 0 { 119 - changePassword = false 116 + isAdmin := c.Bool("admin") 117 + mustChangePassword := true // always default to true 118 + if c.IsSet("must-change-password") { 119 + // if the flag is set, use the value provided by the user 120 + mustChangePassword = c.Bool("must-change-password") 121 + } else { 122 + // check whether there are users in the database 123 + hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{}) 124 + if err != nil { 125 + return fmt.Errorf("IsTableNotEmpty: %w", err) 126 + } 127 + if !hasUserRecord && isAdmin { 128 + // if this is the first admin being created, don't force to change password (keep the old behavior) 129 + mustChangePassword = false 130 + } 120 131 } 121 132 122 133 restricted := optional.None[bool]() ··· 132 143 Name: username, 133 144 Email: c.String("email"), 134 145 Passwd: password, 135 - IsAdmin: c.Bool("admin"), 136 - MustChangePassword: changePassword, 146 + IsAdmin: isAdmin, 147 + MustChangePassword: mustChangePassword, 137 148 Visibility: visibility, 138 149 } 139 150
+2 -2
models/db/engine.go
··· 293 293 } 294 294 295 295 // IsTableNotEmpty returns true if table has at least one record 296 - func IsTableNotEmpty(tableName string) (bool, error) { 297 - return x.Table(tableName).Exist() 296 + func IsTableNotEmpty(beanOrTableName any) (bool, error) { 297 + return x.Table(beanOrTableName).Exist() 298 298 } 299 299 300 300 // DeleteAllRecords will delete all the records of this table