自动更新管控端
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.
 
 
 
 
 
 

272 lines
7.2 KiB

package core
import (
"encoding/json"
"errors"
"net/http"
"time"
"aufs/crypto"
"aufs/db"
)
// LoginRequest 登录请求结构
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
// LoginResponse 登录响应结构
type LoginResponse struct {
Token string `json:"token"`
User User `json:"user"`
ExpiresAt time.Time `json:"expires_at"`
}
// User 用户数据结构
type User struct {
ID int `json:"id" db:"id"`
Username string `json:"username" db:"username"`
Email string `json:"email" db:"email"`
Role string `json:"role" db:"role"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
LastLogin time.Time `json:"last_login" db:"last_login"`
Status string `json:"status" db:"status"` // active, locked, deleted
}
// 处理登录传入的数据
func LoginHandler(w http.ResponseWriter, r *http.Request) {
// 解析请求体中的JSON数据
var loginReq LoginRequest
err := json.NewDecoder(r.Body).Decode(&loginReq)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
// 验证用户名和密码
user, err := authenticateUser(loginReq.Username, loginReq.Password)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
// 生成访问令牌(这里简化处理,实际项目中可能需要使用JWT等)
token := "temp_token_" + time.Now().Format("20060102150405")
expiresAt := time.Now().Add(24 * time.Hour) // 令牌有效期24小时
// 更新用户最后登录时间
err = db.UpdateUserLastLogin(user.ID)
if err != nil {
// 记录错误但不影响登录流程
// 实际项目中应该有日志记录
}
// 构建响应
response := LoginResponse{
Token: token,
User: *user,
ExpiresAt: expiresAt,
}
// 返回JSON响应
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
// 用户状态常量
const (
UserStatusActive = "active"
UserStatusLocked = "locked"
UserStatusDeleted = "deleted"
)
// RegisterRequest 注册请求结构
type RegisterRequest struct {
Username string `json:"username" binding:"required"`
Email string `json:"email" binding:"required"`
Password string `json:"password" binding:"required"`
}
// RegisterResponse 注册响应结构
type RegisterResponse struct {
User User `json:"user"`
Message string `json:"message"`
CreatedAt time.Time `json:"created_at"`
}
// RegisterHandler 处理用户注册
func RegisterHandler(w http.ResponseWriter, r *http.Request) {
// 解析请求体中的JSON数据
var registerReq RegisterRequest
err := json.NewDecoder(r.Body).Decode(&registerReq)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
// 检查用户名是否已存在
usernameExists, err := db.CheckUsernameExists(registerReq.Username)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
if usernameExists {
http.Error(w, "Username already exists", http.StatusConflict)
return
}
// 检查邮箱是否已存在
emailExists, err := db.CheckEmailExists(registerReq.Email)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
if emailExists {
http.Error(w, "Email already exists", http.StatusConflict)
return
}
// 对密码进行哈希处理
hashedPassword, err := crypto.HashPassword(registerReq.Password)
if err != nil {
http.Error(w, "Failed to process password", http.StatusInternalServerError)
return
}
// 创建用户对象
userDB := db.User{
Username: registerReq.Username,
Email: registerReq.Email,
PasswordHash: hashedPassword,
Role: "user", // 默认角色
Status: UserStatusActive,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
LastLogin: time.Time{}, // 初始为零值
}
// 保存用户到数据库
createdUser, err := db.AddUser(userDB)
if err != nil {
http.Error(w, "Failed to create user", http.StatusInternalServerError)
return
}
// 转换为core包的User对象
user := User{
ID: createdUser.ID,
Username: createdUser.Username,
Email: createdUser.Email,
Role: createdUser.Role,
CreatedAt: createdUser.CreatedAt,
UpdatedAt: createdUser.UpdatedAt,
LastLogin: createdUser.LastLogin,
Status: createdUser.Status,
}
// 构建响应
response := RegisterResponse{
User: user,
Message: "User registered successfully",
CreatedAt: user.CreatedAt,
}
// 返回JSON响应
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(response)
}
// ResetPasswordRequest 重置密码请求结构
type ResetPasswordRequest struct {
Username string `json:"username" binding:"required"`
NewPassword string `json:"new_password" binding:"required"`
}
// ResetPasswordResponse 重置密码响应结构
type ResetPasswordResponse struct {
Message string `json:"message"`
UpdatedAt time.Time `json:"updated_at"`
}
// ResetPasswordHandler 处理密码重置
func ResetPasswordHandler(w http.ResponseWriter, r *http.Request) {
// 解析请求体中的JSON数据
var resetReq ResetPasswordRequest
err := json.NewDecoder(r.Body).Decode(&resetReq)
if err != nil {
http.Error(w, "Invalid request payload", http.StatusBadRequest)
return
}
// 检查用户是否存在
userDB, err := db.GetUserByUsername(resetReq.Username)
if err != nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}
// 检查用户状态
if userDB.Status != UserStatusActive {
http.Error(w, "User account is locked or disabled", http.StatusForbidden)
return
}
// 对新密码进行哈希处理
hashedPassword, err := crypto.HashPassword(resetReq.NewPassword)
if err != nil {
http.Error(w, "Failed to process new password", http.StatusInternalServerError)
return
}
// 更新用户密码
updatedAt := time.Now()
err = db.UpdateUserPassword(userDB.ID, hashedPassword, updatedAt)
if err != nil {
http.Error(w, "Failed to update password", http.StatusInternalServerError)
return
}
// 构建响应
response := ResetPasswordResponse{
Message: "Password reset successful",
UpdatedAt: updatedAt,
}
// 返回JSON响应
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
// authenticateUser 验证用户身份
func authenticateUser(username, password string) (*User, error) {
// 根据用户名查询用户信息
userDB, err := db.GetUserByUsername(username)
if err != nil {
return nil, errors.New("用户名或密码错误")
}
// 检查用户状态
if userDB.Status != UserStatusActive {
return nil, errors.New("用户账号已被锁定或禁用")
}
// 验证密码
isValid, err := crypto.VerifyPassword(userDB.PasswordHash, password)
if err != nil || !isValid {
return nil, errors.New("用户名或密码错误")
}
// 转换为core包的User对象
return &User{
ID: userDB.ID,
Username: userDB.Username,
Email: userDB.Email,
Role: userDB.Role,
CreatedAt: userDB.CreatedAt,
UpdatedAt: userDB.UpdatedAt,
LastLogin: userDB.LastLogin,
Status: userDB.Status,
}, nil
}