code.gitea.io/gitea@v1.22.3/cmd/admin_user_change_password.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package cmd
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  
    10  	user_model "code.gitea.io/gitea/models/user"
    11  	"code.gitea.io/gitea/modules/auth/password"
    12  	"code.gitea.io/gitea/modules/optional"
    13  	"code.gitea.io/gitea/modules/setting"
    14  	user_service "code.gitea.io/gitea/services/user"
    15  
    16  	"github.com/urfave/cli/v2"
    17  )
    18  
    19  var microcmdUserChangePassword = &cli.Command{
    20  	Name:   "change-password",
    21  	Usage:  "Change a user's password",
    22  	Action: runChangePassword,
    23  	Flags: []cli.Flag{
    24  		&cli.StringFlag{
    25  			Name:    "username",
    26  			Aliases: []string{"u"},
    27  			Value:   "",
    28  			Usage:   "The user to change password for",
    29  		},
    30  		&cli.StringFlag{
    31  			Name:    "password",
    32  			Aliases: []string{"p"},
    33  			Value:   "",
    34  			Usage:   "New password to set for user",
    35  		},
    36  		&cli.BoolFlag{
    37  			Name:  "must-change-password",
    38  			Usage: "User must change password (can be disabled by --must-change-password=false)",
    39  			Value: true,
    40  		},
    41  	},
    42  }
    43  
    44  func runChangePassword(c *cli.Context) error {
    45  	if err := argsSet(c, "username", "password"); err != nil {
    46  		return err
    47  	}
    48  
    49  	ctx, cancel := installSignals()
    50  	defer cancel()
    51  
    52  	if err := initDB(ctx); err != nil {
    53  		return err
    54  	}
    55  
    56  	user, err := user_model.GetUserByName(ctx, c.String("username"))
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	opts := &user_service.UpdateAuthOptions{
    62  		Password:           optional.Some(c.String("password")),
    63  		MustChangePassword: optional.Some(c.Bool("must-change-password")),
    64  	}
    65  	if err := user_service.UpdateAuth(ctx, user, opts); err != nil {
    66  		switch {
    67  		case errors.Is(err, password.ErrMinLength):
    68  			return fmt.Errorf("password is not long enough, needs to be at least %d characters", setting.MinPasswordLength)
    69  		case errors.Is(err, password.ErrComplexity):
    70  			return errors.New("password does not meet complexity requirements")
    71  		case errors.Is(err, password.ErrIsPwned):
    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")
    73  		default:
    74  			return err
    75  		}
    76  	}
    77  
    78  	fmt.Printf("%s's password has been successfully updated!\n", user.Name)
    79  	return nil
    80  }