2023-02-14 15:12:19 -07:00
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package cmd
import (
"context"
"errors"
"fmt"
user_model "code.gitea.io/gitea/models/user"
2023-02-19 00:35:20 -07:00
pwd "code.gitea.io/gitea/modules/auth/password"
2023-02-14 15:12:19 -07:00
"code.gitea.io/gitea/modules/setting"
2023-07-21 02:28:19 -07:00
"github.com/urfave/cli/v2"
2023-02-14 15:12:19 -07:00
)
2023-07-21 02:28:19 -07:00
var microcmdUserChangePassword = & cli . Command {
2023-02-14 15:12:19 -07:00
Name : "change-password" ,
Usage : "Change a user's password" ,
Action : runChangePassword ,
Flags : [ ] cli . Flag {
2023-07-21 02:28:19 -07:00
& cli . StringFlag {
Name : "username" ,
Aliases : [ ] string { "u" } ,
Value : "" ,
Usage : "The user to change password for" ,
2023-02-14 15:12:19 -07:00
} ,
2023-07-21 02:28:19 -07:00
& cli . StringFlag {
Name : "password" ,
Aliases : [ ] string { "p" } ,
Value : "" ,
Usage : "New password to set for user" ,
2023-02-14 15:12:19 -07:00
} ,
2024-02-03 10:53:27 -07:00
& cli . BoolFlag {
Name : "must-change-password" ,
Usage : "User must change password" ,
} ,
2023-02-14 15:12:19 -07:00
} ,
}
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
}
if len ( c . String ( "password" ) ) < setting . MinPasswordLength {
return fmt . Errorf ( "Password is not long enough. Needs to be at least %d" , setting . MinPasswordLength )
}
if ! pwd . IsComplexEnough ( c . String ( "password" ) ) {
return errors . New ( "Password does not meet complexity requirements" )
}
pwned , err := pwd . IsPwned ( context . Background ( ) , c . String ( "password" ) )
if err != nil {
return err
}
if pwned {
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" )
}
uname := c . String ( "username" )
user , err := user_model . GetUserByName ( ctx , uname )
if err != nil {
return err
}
if err = user . SetPassword ( c . String ( "password" ) ) ; err != nil {
return err
}
2024-02-03 10:53:27 -07:00
if c . IsSet ( "must-change-password" ) {
user . MustChangePassword = c . Bool ( "must-change-password" )
}
if err = user_model . UpdateUserCols ( ctx , user , "must_change_password" , "passwd" , "passwd_hash_algo" , "salt" ) ; err != nil {
2023-02-14 15:12:19 -07:00
return err
}
fmt . Printf ( "%s's password has been successfully updated!\n" , user . Name )
return nil
}