package cmd import ( "fmt" "github.com/spf13/cobra" "hy2xs-admin/dao" "hy2xs-admin/model/entity" "hy2xs-admin/util" "os" "time" ) var resetCmd = &cobra.Command{ Use: "reset-admin", Short: "Reset admin username and password", Long: "Reset admin username and password.", Run: runReset, } func init() { rootCmd.AddCommand(resetCmd) } // Длины восстановительных учётных данных. // // Было по 6 символов на оба поля. Шесть символов алфавита из 62 — это около 36 // бит, то есть ровно нижняя граница, которую пропускает HashPassword, и // единственной защитой оставался force_password_change. Пароль восстановления // живёт до первого входа администратора, но до этого входа он полноценно // пускает в панель, поэтому его стойкость должна соответствовать остальным // секретам продукта, а не минимально допустимой. const ( resetUsernameLength = 12 resetPasswordLength = 24 ) func runReset(cmd *cobra.Command, args []string) { username, err := util.RandomString(resetUsernameLength) if err != nil { fmt.Println(err.Error()) os.Exit(1) } password, err := util.RandomString(resetPasswordLength) if err != nil { fmt.Println(err.Error()) os.Exit(1) } if err = dao.InitSql(); err != nil { fmt.Println(err.Error()) os.Exit(1) } admin, err := dao.GetAdminUser("1 = 1") nowMs := time.Now().UnixMilli() if err != nil { tokenVersion := int64(1) status := int64(1) forcePasswordChange := int64(1) passwordChangedAt := nowMs hash, hashErr := util.HashPassword(password) if hashErr != nil { fmt.Println(hashErr.Error()) os.Exit(1) } adminUser := entity.AdminUser{ Username: &username, PasswordHash: &hash, Status: &status, ForcePasswordChange: &forcePasswordChange, PasswordChangedAt: &passwordChangedAt, TokenVersion: &tokenVersion, } if _, saveErr := dao.SaveAdminUser(adminUser); saveErr != nil { fmt.Println(saveErr.Error()) os.Exit(1) } } else { tokenVersion := int64(1) if admin.TokenVersion != nil && *admin.TokenVersion > 0 { tokenVersion = *admin.TokenVersion + 1 } if err = dao.UpdateAdminUser([]int64{*admin.Id}, map[string]interface{}{ "username": username, "password_hash": func() string { hash, _ := util.HashPassword(password) return hash }(), "force_password_change": 1, "password_changed_at": nowMs, "token_version": tokenVersion, "status": 1, }); err != nil { fmt.Println(err.Error()) os.Exit(1) } } if err = dao.CloseSqliteDB(); err != nil { fmt.Println(err.Error()) os.Exit(1) } fmt.Println(fmt.Sprintf("HY2XS admin Login Username: %s", username)) fmt.Println(fmt.Sprintf("HY2XS admin Login Password: %s", password)) }