Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 新增 RedisSystemOperationPasswordKey 常量函数(pkg/constants/redis.go) - 新增 operation_password Service(Set/IsSet/Verify,bcrypt 哈希存 Redis) - 新增 SuperAdminHandler 及两个接口: - POST /api/admin/super-admin/operation-password(设置/重置,仅超级管理员) - GET /api/admin/super-admin/operation-password/status(查询是否已设置) - AgentRecharge.OfflinePay 操作密码验证从"查当前用户登录密码"改为"全局操作密码 Verify" - Bootstrap/路由/文档生成器同步注册
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
// Package operation_password 提供全局操作密码的设置、查询与验证服务
|
||
// 操作密码以 bcrypt 哈希存储于 Redis,仅超级管理员可维护
|
||
package operation_password
|
||
|
||
import (
|
||
"context"
|
||
|
||
"github.com/redis/go-redis/v9"
|
||
"golang.org/x/crypto/bcrypt"
|
||
|
||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||
)
|
||
|
||
// Service 全局操作密码服务
|
||
type Service struct {
|
||
redis *redis.Client
|
||
}
|
||
|
||
// New 创建操作密码服务实例
|
||
func New(rdb *redis.Client) *Service {
|
||
return &Service{redis: rdb}
|
||
}
|
||
|
||
// Set 设置/修改全局操作密码
|
||
// 对明文密码做 bcrypt 哈希后永久存储到 Redis(无 TTL)
|
||
func (s *Service) Set(ctx context.Context, password string) error {
|
||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||
if err != nil {
|
||
return errors.Wrap(errors.CodeInternalError, err, "操作密码加密失败")
|
||
}
|
||
|
||
key := constants.RedisSystemOperationPasswordKey()
|
||
if err := s.redis.Set(ctx, key, string(hash), 0).Err(); err != nil {
|
||
return errors.Wrap(errors.CodeInternalError, err, "操作密码存储失败")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// IsSet 查询操作密码是否已设置
|
||
func (s *Service) IsSet(ctx context.Context) bool {
|
||
key := constants.RedisSystemOperationPasswordKey()
|
||
n, err := s.redis.Exists(ctx, key).Result()
|
||
if err != nil {
|
||
return false
|
||
}
|
||
return n > 0
|
||
}
|
||
|
||
// Verify 验证操作密码是否正确
|
||
// key 不存在时返回"操作密码未设置"错误,密码错误时返回"操作密码错误"
|
||
func (s *Service) Verify(ctx context.Context, inputPassword string) error {
|
||
key := constants.RedisSystemOperationPasswordKey()
|
||
hash, err := s.redis.Get(ctx, key).Result()
|
||
if err == redis.Nil {
|
||
return errors.New(errors.CodeInvalidParam, "操作密码未设置,请联系超级管理员")
|
||
}
|
||
if err != nil {
|
||
return errors.Wrap(errors.CodeInternalError, err, "查询操作密码失败")
|
||
}
|
||
|
||
if err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(inputPassword)); err != nil {
|
||
return errors.New(errors.CodeInvalidParam, "操作密码错误")
|
||
}
|
||
|
||
return nil
|
||
}
|