You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.6 KiB
167 lines
4.6 KiB
2 weeks ago
|
package controller
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"strconv"
|
||
|
|
||
|
"gofaster/internal/auth/model"
|
||
|
"gofaster/internal/auth/service"
|
||
|
"gofaster/internal/shared/response"
|
||
|
|
||
|
"github.com/gin-gonic/gin"
|
||
|
)
|
||
|
|
||
|
type PasswordController struct {
|
||
|
passwordService *service.PasswordService
|
||
|
userService *service.UserService
|
||
|
}
|
||
|
|
||
|
func NewPasswordController(
|
||
|
passwordService *service.PasswordService,
|
||
|
userService *service.UserService,
|
||
|
) *PasswordController {
|
||
|
return &PasswordController{
|
||
|
passwordService: passwordService,
|
||
|
userService: userService,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ChangePassword 修改密码
|
||
|
func (c *PasswordController) ChangePassword(ctx *gin.Context) {
|
||
|
var req model.PasswordChangeRequest
|
||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
|
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 从JWT获取用户ID
|
||
|
userID, exists := ctx.Get("user_id")
|
||
|
if !exists {
|
||
|
response.Error(ctx, http.StatusUnauthorized, "未授权", "用户ID不存在")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
req.UserID = userID.(uint)
|
||
|
|
||
|
// 验证新密码确认
|
||
|
if req.NewPassword != req.ConfirmPassword {
|
||
|
response.Error(ctx, http.StatusBadRequest, "密码确认失败", "新密码与确认密码不匹配")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 修改密码
|
||
|
err := c.passwordService.ChangePassword(req.UserID, req.CurrentPassword, req.NewPassword)
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusBadRequest, "修改密码失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
response.Success(ctx, "密码修改成功", nil)
|
||
|
}
|
||
|
|
||
|
// ResetPassword 重置用户密码(管理员功能)
|
||
|
func (c *PasswordController) ResetPassword(ctx *gin.Context) {
|
||
|
userIDStr := ctx.Param("id")
|
||
|
userID, err := strconv.ParseUint(userIDStr, 10, 32)
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusBadRequest, "用户ID格式错误", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 从JWT获取操作人ID
|
||
|
operatorID, exists := ctx.Get("user_id")
|
||
|
if !exists {
|
||
|
response.Error(ctx, http.StatusUnauthorized, "未授权", "操作人ID不存在")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 重置密码
|
||
|
tempPassword, err := c.passwordService.ResetPassword(uint(userID), operatorID.(uint))
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusInternalServerError, "重置密码失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
response.Success(ctx, "密码重置成功", gin.H{
|
||
|
"temp_password": tempPassword,
|
||
|
"message": "用户首次登录后需要立即修改密码",
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// GetPasswordPolicy 获取密码策略
|
||
|
func (c *PasswordController) GetPasswordPolicy(ctx *gin.Context) {
|
||
|
policy, err := c.passwordService.GetPasswordPolicy()
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusInternalServerError, "获取密码策略失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
response.Success(ctx, "获取密码策略成功", policy)
|
||
|
}
|
||
|
|
||
|
// ValidatePassword 验证密码强度
|
||
|
func (c *PasswordController) ValidatePassword(ctx *gin.Context) {
|
||
|
var req struct {
|
||
|
Password string `json:"password" binding:"required"`
|
||
|
}
|
||
|
|
||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||
|
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 验证密码
|
||
|
result, err := c.passwordService.ValidatePassword(req.Password)
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusInternalServerError, "密码验证失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
response.Success(ctx, "密码验证完成", result)
|
||
|
}
|
||
|
|
||
|
// CheckPasswordStatus 检查用户密码状态
|
||
|
func (c *PasswordController) CheckPasswordStatus(ctx *gin.Context) {
|
||
|
userID, exists := ctx.Get("user_id")
|
||
|
if !exists {
|
||
|
response.Error(ctx, http.StatusUnauthorized, "未授权", "用户ID不存在")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 获取用户信息
|
||
|
user, err := c.userService.GetByID(userID.(uint))
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusInternalServerError, "获取用户信息失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 检查密码过期
|
||
|
isExpired, err := c.passwordService.CheckPasswordExpiration(user)
|
||
|
if err != nil {
|
||
|
response.Error(ctx, http.StatusInternalServerError, "检查密码过期失败", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 检查是否需要强制修改密码
|
||
|
forceChange := c.passwordService.CheckForceChangePassword(user)
|
||
|
|
||
|
response.Success(ctx, "获取密码状态成功", gin.H{
|
||
|
"force_change_password": forceChange,
|
||
|
"password_expired": isExpired,
|
||
|
"password_changed_at": user.PasswordChangedAt,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// UpdatePasswordPolicy 更新密码策略(管理员功能)
|
||
|
func (c *PasswordController) UpdatePasswordPolicy(ctx *gin.Context) {
|
||
|
var policy model.PasswordPolicy
|
||
|
if err := ctx.ShouldBindJSON(&policy); err != nil {
|
||
|
response.Error(ctx, http.StatusBadRequest, "请求参数错误", err.Error())
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 这里需要调用密码策略服务来更新策略
|
||
|
// 暂时返回成功,具体实现需要完善
|
||
|
response.Success(ctx, "密码策略更新成功", policy)
|
||
|
}
|