Skip to content

Commit b266c78

Browse files
GiteaBotwxiaoguangKN4CK3R
authored
Improve "must-change-password" logic and document (#30472) (#30478)
Backport #30472 by wxiaoguang Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: KN4CK3R <[email protected]>
1 parent e64926c commit b266c78

File tree

4 files changed

+31
-30
lines changed

4 files changed

+31
-30
lines changed

cmd/admin_user_change_password.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var microcmdUserChangePassword = &cli.Command{
3636
&cli.BoolFlag{
3737
Name: "must-change-password",
3838
Usage: "User must change password",
39+
Value: true,
3940
},
4041
},
4142
}
@@ -57,23 +58,18 @@ func runChangePassword(c *cli.Context) error {
5758
return err
5859
}
5960

60-
var mustChangePassword optional.Option[bool]
61-
if c.IsSet("must-change-password") {
62-
mustChangePassword = optional.Some(c.Bool("must-change-password"))
63-
}
64-
6561
opts := &user_service.UpdateAuthOptions{
6662
Password: optional.Some(c.String("password")),
67-
MustChangePassword: mustChangePassword,
63+
MustChangePassword: optional.Some(c.Bool("must-change-password")),
6864
}
6965
if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
7066
switch {
7167
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)
7369
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")
7571
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")
7773
default:
7874
return err
7975
}

cmd/admin_user_create.go

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99

1010
auth_model "code.gitea.io/gitea/models/auth"
11+
"code.gitea.io/gitea/models/db"
1112
user_model "code.gitea.io/gitea/models/user"
1213
pwd "code.gitea.io/gitea/modules/auth/password"
1314
"code.gitea.io/gitea/modules/optional"
@@ -46,8 +47,9 @@ var microcmdUserCreate = &cli.Command{
4647
Usage: "Generate a random password for the user",
4748
},
4849
&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, (Default: true)",
50+
Name: "must-change-password",
51+
Usage: "Set to false to prevent forcing the user to change their password after initial login",
52+
DisableDefaultText: true,
5153
},
5254
&cli.IntFlag{
5355
Name: "random-password-length",
@@ -71,10 +73,10 @@ func runCreateUser(c *cli.Context) error {
7173
}
7274

7375
if c.IsSet("name") && c.IsSet("username") {
74-
return errors.New("Cannot set both --name and --username flags")
76+
return errors.New("cannot set both --name and --username flags")
7577
}
7678
if !c.IsSet("name") && !c.IsSet("username") {
77-
return errors.New("One of --name or --username flags must be set")
79+
return errors.New("one of --name or --username flags must be set")
7880
}
7981

8082
if c.IsSet("password") && c.IsSet("random-password") {
@@ -110,17 +112,21 @@ func runCreateUser(c *cli.Context) error {
110112
return errors.New("must set either password or random-password flag")
111113
}
112114

113-
// always default to true
114-
changePassword := true
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
120-
}
121-
115+
isAdmin := c.Bool("admin")
116+
mustChangePassword := true // always default to true
122117
if c.IsSet("must-change-password") {
123-
changePassword = c.Bool("must-change-password")
118+
// if the flag is set, use the value provided by the user
119+
mustChangePassword = c.Bool("must-change-password")
120+
} else {
121+
// check whether there are users in the database
122+
hasUserRecord, err := db.IsTableNotEmpty(&user_model.User{})
123+
if err != nil {
124+
return fmt.Errorf("IsTableNotEmpty: %w", err)
125+
}
126+
if !hasUserRecord && isAdmin {
127+
// if this is the first admin being created, don't force to change password (keep the old behavior)
128+
mustChangePassword = false
129+
}
124130
}
125131

126132
restricted := optional.None[bool]()
@@ -136,8 +142,8 @@ func runCreateUser(c *cli.Context) error {
136142
Name: username,
137143
Email: c.String("email"),
138144
Passwd: password,
139-
IsAdmin: c.Bool("admin"),
140-
MustChangePassword: changePassword,
145+
IsAdmin: isAdmin,
146+
MustChangePassword: mustChangePassword,
141147
Visibility: visibility,
142148
}
143149

docs/content/administration/command-line.en-us.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ Admin operations:
8383
- `--email value`: Email. Required.
8484
- `--admin`: If provided, this makes the user an admin. Optional.
8585
- `--access-token`: If provided, an access token will be created for the user. Optional. (default: false).
86-
- `--must-change-password`: If provided, the created user will be required to choose a newer password after the
87-
initial login. Optional. (default: true).
86+
- `--must-change-password`: The created user will be required to set a new password after the initial login, default: true. It could be disabled by `--must-change-password=false`.
8887
- `--random-password`: If provided, a randomly generated password will be used as the password of the created
8988
user. The value of `--password` will be discarded. Optional.
9089
- `--random-password-length`: If provided, it will be used to configure the length of the randomly generated
@@ -95,7 +94,7 @@ Admin operations:
9594
- Options:
9695
- `--username value`, `-u value`: Username. Required.
9796
- `--password value`, `-p value`: New password. Required.
98-
- `--must-change-password`: If provided, the user is required to choose a new password after the login. Optional.
97+
- `--must-change-password`: The user is required to set a new password after the login, default: true. It could be disabled by `--must-change-password=false`.
9998
- Examples:
10099
- `gitea admin user change-password --username myname --password asecurepassword`
101100
- `must-change-password`:

models/db/engine.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ func MaxBatchInsertSize(bean any) int {
284284
}
285285

286286
// IsTableNotEmpty returns true if table has at least one record
287-
func IsTableNotEmpty(tableName string) (bool, error) {
288-
return x.Table(tableName).Exist()
287+
func IsTableNotEmpty(beanOrTableName any) (bool, error) {
288+
return x.Table(beanOrTableName).Exist()
289289
}
290290

291291
// DeleteAllRecords will delete all the records of this table

0 commit comments

Comments
 (0)