-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
fix:添加命令行模式,支持修改 password。需要输入用户名 #2188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,106 @@ | ||||||||
| package core | ||||||||
|
|
||||||||
| import ( | ||||||||
| "errors" | ||||||||
| "fmt" | ||||||||
| "os" | ||||||||
| "path/filepath" | ||||||||
| "strings" | ||||||||
|
|
||||||||
| "github.com/flipped-aurora/gin-vue-admin/server/global" | ||||||||
| "github.com/flipped-aurora/gin-vue-admin/server/service/system" | ||||||||
| "github.com/flipped-aurora/gin-vue-admin/server/utils" | ||||||||
| "github.com/spf13/cobra" | ||||||||
| ) | ||||||||
|
|
||||||||
| const ( | ||||||||
| configFlagShort = "-c" | ||||||||
| configFlagLong = "--config" | ||||||||
| ) | ||||||||
|
|
||||||||
| func runCli() error { | ||||||||
| var configPath string | ||||||||
| var resetPasswordUsername string | ||||||||
|
|
||||||||
| rootCmd := &cobra.Command{ | ||||||||
| Use: filepath.Base(os.Args[0]), | ||||||||
| Short: "gva", | ||||||||
| Example: fmt.Sprintf("%s -c config.yaml --reset-password admin", filepath.Base(os.Args[0])), | ||||||||
| SilenceUsage: true, | ||||||||
| SilenceErrors: true, | ||||||||
| Args: cobra.NoArgs, | ||||||||
| RunE: func(cmd *cobra.Command, args []string) error { | ||||||||
| if resetPasswordUsername != "" { | ||||||||
| return resetPasswordByUsername(resetPasswordUsername) | ||||||||
| } | ||||||||
| return cmd.Help() | ||||||||
| }, | ||||||||
| } | ||||||||
|
|
||||||||
| rootCmd.Flags().StringVarP(&configPath, "config", "c", "", "choose config file.") | ||||||||
| rootCmd.Flags().StringVar(&resetPasswordUsername, "reset-password", "", "reset the specified user's password and print the new password") | ||||||||
|
|
||||||||
| return rootCmd.Execute() | ||||||||
| } | ||||||||
|
|
||||||||
| func resetPasswordByUsername(username string) error { | ||||||||
| username = strings.TrimSpace(username) | ||||||||
| if username == "" { | ||||||||
| return errors.New("用户名不能为空") | ||||||||
| } | ||||||||
| if global.GVA_DB == nil { | ||||||||
| return errors.New("db not init") | ||||||||
| } | ||||||||
|
|
||||||||
| password, err := utils.RandomPassword(16) | ||||||||
| if err != nil { | ||||||||
| return err | ||||||||
| } | ||||||||
| if err = system.UserServiceApp.ResetPasswordByUsername(username, password); err != nil { | ||||||||
| return err | ||||||||
| } | ||||||||
| fmt.Printf("++++++++++++++++++++++++++++++++++\n") | ||||||||
| fmt.Printf("the new password is: %s\n", password) | ||||||||
| fmt.Printf("++++++++++++++++++++++++++++++++++\n") | ||||||||
| return nil | ||||||||
| } | ||||||||
|
|
||||||||
| func hasCommandArgs(args []string) bool { | ||||||||
| return len(filterCommonArgs(args)) > 0 | ||||||||
| } | ||||||||
|
|
||||||||
| func filterCommonArgs(args []string) []string { | ||||||||
| filtered := make([]string, 0, len(args)) | ||||||||
| for i := 0; i < len(args); i++ { | ||||||||
| arg := args[i] | ||||||||
| switch { | ||||||||
| case arg == configFlagShort || arg == configFlagLong: | ||||||||
| if i+1 < len(args) { | ||||||||
| i++ | ||||||||
| } | ||||||||
| case strings.HasPrefix(arg, configFlagShort+"="), strings.HasPrefix(arg, configFlagLong+"="): | ||||||||
| continue | ||||||||
| default: | ||||||||
| filtered = append(filtered, arg) | ||||||||
| } | ||||||||
| } | ||||||||
| return filtered | ||||||||
| } | ||||||||
|
|
||||||||
| func lookupConfigPathArg(args []string) (string, bool) { | ||||||||
| for i := 0; i < len(args); i++ { | ||||||||
| arg := args[i] | ||||||||
| switch { | ||||||||
| case arg == configFlagShort || arg == configFlagLong: | ||||||||
| if i+1 < len(args) { | ||||||||
| return args[i+1], true | ||||||||
| } | ||||||||
| return "", false | ||||||||
|
||||||||
| return "", false | |
| // Flag present but missing its value: signal presence (true) with empty path | |
| return "", true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,6 @@ | ||
| package core | ||
|
|
||
| import ( | ||
| "flag" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
|
|
@@ -43,10 +42,8 @@ func Viper() *viper.Viper { | |
|
|
||
| // getConfigPath 获取配置文件路径, 优先级: 命令行 > 环境变量 > 默认值 | ||
| func getConfigPath() (config string) { | ||
| // `-c` flag parse | ||
| flag.StringVar(&config, "c", "", "choose config file.") | ||
| flag.Parse() | ||
| if config != "" { // 命令行参数不为空 将值赋值于config | ||
| if cliConfig, ok := lookupConfigPathArg(os.Args[1:]); ok && cliConfig != "" { | ||
| config = cliConfig | ||
| fmt.Printf("您正在使用命令行的 '-c' 参数传递的值, config 的路径为 %s\n", config) | ||
| return | ||
|
Comment on lines
+45
to
48
|
||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -121,6 +121,7 @@ require ( | |||||
| github.com/hashicorp/go-multierror v1.1.1 // indirect | ||||||
| github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect | ||||||
| github.com/hashicorp/hcl v1.0.0 // indirect | ||||||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||||
| github.com/invopop/jsonschema v0.13.0 // indirect | ||||||
| github.com/jackc/pgpassfile v1.0.0 // indirect | ||||||
| github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect | ||||||
|
|
@@ -166,7 +167,8 @@ require ( | |||||
| github.com/sourcegraph/conc v0.3.0 // indirect | ||||||
| github.com/spf13/afero v1.12.0 // indirect | ||||||
| github.com/spf13/cast v1.7.1 // indirect | ||||||
| github.com/spf13/pflag v1.0.5 // indirect | ||||||
| github.com/spf13/cobra v1.10.2 // indirect | ||||||
|
||||||
| github.com/spf13/cobra v1.10.2 // indirect | |
| github.com/spf13/cobra v1.10.2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -324,6 +324,23 @@ func (userService *UserService) FindUserByUuid(uuid string) (user *system.SysUse | |
| return &u, nil | ||
| } | ||
|
|
||
| func (userService *UserService) ResetPasswordByUsername(username, password string) (err error) { | ||
| if global.GVA_DB == nil { | ||
| return fmt.Errorf("db not init") | ||
| } | ||
|
|
||
| var user system.SysUser | ||
|
Comment on lines
+327
to
+332
|
||
| err = global.GVA_DB.Select("id").Where("username = ?", username).First(&user).Error | ||
| if errors.Is(err, gorm.ErrRecordNotFound) { | ||
| return errors.New("用户不存在") | ||
| } | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return userService.ResetPassword(user.ID, password) | ||
| } | ||
|
|
||
| //@author: [piexlmax](https://github.com/piexlmax) | ||
| //@function: ResetPassword | ||
| //@description: 修改用户密码 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package utils | ||
|
|
||
| import ( | ||
| "crypto/rand" | ||
| "errors" | ||
| ) | ||
|
|
||
| const passwordAlphabet = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789+-@!" | ||
|
|
||
| func RandomPassword(length int) (string, error) { | ||
| if length <= 0 { | ||
| return "", errors.New("password length must be greater than 0") | ||
| } | ||
|
Comment on lines
+10
to
+13
|
||
|
|
||
| buf := make([]byte, length) | ||
| if _, err := rand.Read(buf); err != nil { | ||
| return "", err | ||
| } | ||
|
|
||
| password := make([]byte, length) | ||
| for i, b := range buf { | ||
| password[i] = passwordAlphabet[int(b)%len(passwordAlphabet)] | ||
| } | ||
|
Comment on lines
+20
to
+23
|
||
|
|
||
| return string(password), nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filterCommonArgs silently drops "-c/--config" even when it is provided without a value (e.g.,
server -c), which can make RunServer incorrectly treat the invocation as “no command args” and start the HTTP server instead of surfacing an error. Consider detecting the missing value case here (or earlier) and returning an explicit error/exit so mis-specified config flags don’t get ignored.