summaryrefslogtreecommitdiffstats
path: root/cmd/admin_user_change_password.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cmd/admin_user_change_password.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/cmd/admin_user_change_password.go b/cmd/admin_user_change_password.go
new file mode 100644
index 0000000..bd9063a
--- /dev/null
+++ b/cmd/admin_user_change_password.go
@@ -0,0 +1,80 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package cmd
+
+import (
+ "errors"
+ "fmt"
+
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/auth/password"
+ "code.gitea.io/gitea/modules/optional"
+ "code.gitea.io/gitea/modules/setting"
+ user_service "code.gitea.io/gitea/services/user"
+
+ "github.com/urfave/cli/v2"
+)
+
+var microcmdUserChangePassword = &cli.Command{
+ Name: "change-password",
+ Usage: "Change a user's password",
+ Action: runChangePassword,
+ Flags: []cli.Flag{
+ &cli.StringFlag{
+ Name: "username",
+ Aliases: []string{"u"},
+ Value: "",
+ Usage: "The user to change password for",
+ },
+ &cli.StringFlag{
+ Name: "password",
+ Aliases: []string{"p"},
+ Value: "",
+ Usage: "New password to set for user",
+ },
+ &cli.BoolFlag{
+ Name: "must-change-password",
+ Usage: "User must change password",
+ Value: true,
+ },
+ },
+}
+
+func runChangePassword(c *cli.Context) error {
+ if err := argsSet(c, "username", "password"); err != nil {
+ return err
+ }
+
+ ctx, cancel := installSignals()
+ defer cancel()
+
+ if err := initDB(ctx); err != nil {
+ return err
+ }
+
+ user, err := user_model.GetUserByName(ctx, c.String("username"))
+ if err != nil {
+ return err
+ }
+
+ opts := &user_service.UpdateAuthOptions{
+ Password: optional.Some(c.String("password")),
+ MustChangePassword: optional.Some(c.Bool("must-change-password")),
+ }
+ if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
+ switch {
+ case errors.Is(err, password.ErrMinLength):
+ return fmt.Errorf("password is not long enough, needs to be at least %d characters", setting.MinPasswordLength)
+ case errors.Is(err, password.ErrComplexity):
+ return errors.New("password does not meet complexity requirements")
+ case errors.Is(err, password.ErrIsPwned):
+ 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")
+ default:
+ return err
+ }
+ }
+
+ fmt.Printf("%s's password has been successfully updated!\n", user.Name)
+ return nil
+}