Files
team-api/internal/cmd/cmd_reset_pwd.go
T
22ee0aa112 修复安全问题 (#9)
* fix:修复权限问题

* fix:修复项目key类型错误问题

* fix:修复rbac权限问题

* fix:修复api密钥未及时失效的问题

* improve:优化渠道调度稳定性

* improve:优化路由

* fix:修复项目预算控制缺陷

* fix:加强限流等安全措施

* feat:添加限流相关字段的前端展示及接口字段

* improve:优化注册时密码要求,只需要字母和数字即可

* feat(setting):添加注册限流设置

* improve:优化前端数字类型转换

* chore:rbac权限放行

---------

Co-authored-by: chengqian <wuchengqian@kkidc.com>
Co-authored-by: qian <wuchengqian5@163.com>
2026-06-23 22:47:54 +08:00

105 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package cmd
import (
"context"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/qianfree/team-api/internal/dao"
"github.com/qianfree/team-api/internal/logic/common"
do "github.com/qianfree/team-api/internal/model/do"
"github.com/qianfree/team-api/internal/utility/crypto"
)
var resetPwdCmd = gcmd.Command{
Name: "reset-pwd",
Usage: "reset-pwd -u <username> -p <password>",
Brief: "重置管理员账号密码",
Func: func(ctx context.Context, parser *gcmd.Parser) error {
username := parser.GetOpt("u", "admin").String()
password := parser.GetOpt("p").String()
if password == "" {
fmt.Println("用法: team-api reset-pwd -u <用户名> -p <新密码>")
fmt.Println(" -u 管理员用户名(默认 admin)")
fmt.Println(" -p 新密码(必填,至少8位,需含字母和数字)")
return nil
}
// Validate password policy
if err := common.ValidatePassword(password); err != nil {
fmt.Println(err.Error())
return nil
}
// Hash password using the same crypto.HashPassword used by Login/InitSuperAdmin
passwordHash, err := crypto.HashPassword(password)
if err != nil {
return fmt.Errorf("密码加密失败: %w", err)
}
// Check user exists, get id and status
var user struct {
Id int64 `orm:"id"`
Status string `orm:"status"`
}
err = dao.SysAdminUsers.Ctx(ctx).
Where("username", username).
Fields("id,status").
Scan(&user)
if err != nil {
return fmt.Errorf("查询用户失败: %w", err)
}
if user.Id == 0 {
fmt.Printf("用户 '%s' 不存在\n", username)
return nil
}
// Update password and reactivate account in case it was disabled
_, err = dao.SysAdminUsers.Ctx(ctx).
Where("id", user.Id).
Data(do.SysAdminUsers{
PasswordHash: passwordHash,
Status: "active",
}).
Update()
if err != nil {
return fmt.Errorf("更新密码失败: %w", err)
}
// 回读数据库验证哈希是否正确落盘(诊断 ORM 写入问题)
storedHash, err := dao.SysAdminUsers.Ctx(ctx).
Where("id", user.Id).
Fields("password_hash").
Value()
if err != nil {
return fmt.Errorf("回读密码哈希失败: %w", err)
}
storedHashStr := storedHash.String()
if !crypto.VerifyPassword(password, storedHashStr) {
return fmt.Errorf("密码已写入但回读校验失败,哈希长度=%d,预期=60(bcrypt)。请检查数据库连接与 password_hash 字段是否被截断",
len(storedHashStr))
}
// 清理该用户的所有会话(避免老会话残留导致登录状态异常)
_, _ = g.DB().Model("sys_sessions").Ctx(ctx).
Where("user_type", "admin").
Where("user_id", user.Id).
Delete()
fmt.Printf("已重置用户 '%s' 的密码,回读校验通过,旧会话已清理\n", username)
fmt.Printf(" - 用户ID: %d\n", user.Id)
fmt.Printf(" - 原状态: %s → active\n", user.Status)
return nil
},
}
func init() {
err := Main.AddCommand(&resetPwdCmd)
if err != nil {
panic(fmt.Sprintf("注册 reset-pwd 命令失败: %v", err))
}
}