2023-02-14 15:12:19 -07:00
// 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"
2024-02-04 06:29:09 -07:00
"code.gitea.io/gitea/modules/auth/password"
"code.gitea.io/gitea/modules/optional"
2023-02-14 15:12:19 -07:00
"code.gitea.io/gitea/modules/setting"
2024-02-04 06:29:09 -07:00
user_service "code.gitea.io/gitea/services/user"
2023-02-14 15:12:19 -07:00
2023-07-21 03:28:19 -06:00
"github.com/urfave/cli/v2"
2023-02-14 15:12:19 -07:00
)
2023-07-21 03:28:19 -06: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 03:28:19 -06: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 03:28:19 -06: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
}
2024-02-04 06:29:09 -07:00
user , err := user_model . GetUserByName ( ctx , c . String ( "username" ) )
2023-02-14 15:12:19 -07:00
if err != nil {
return err
}
2024-02-04 06:29:09 -07:00
var mustChangePassword optional . Option [ bool ]
2024-02-03 10:53:27 -07:00
if c . IsSet ( "must-change-password" ) {
2024-02-04 06:29:09 -07:00
mustChangePassword = optional . Some ( c . Bool ( "must-change-password" ) )
2024-02-03 10:53:27 -07:00
}
2024-02-04 06:29:09 -07:00
opts := & user_service . UpdateAuthOptions {
Password : optional . Some ( c . String ( "password" ) ) ,
MustChangePassword : mustChangePassword ,
}
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" , 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 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" )
default :
return err
}
2023-02-14 15:12:19 -07:00
}
fmt . Printf ( "%s's password has been successfully updated!\n" , user . Name )
return nil
}