[bugfix/backend] /users/me handling
This commit is contained in:
parent
823bedd1fa
commit
d8d8e4b0d7
3 changed files with 228 additions and 156 deletions
|
@ -1,183 +1,183 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Password string `json:"password" binding:"required,min=8"`
|
||||
Role string `json:"role" binding:"required,oneof=admin editor contributor"`
|
||||
Username string `json:"username" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
Password string `json:"password" binding:"required,min=8"`
|
||||
Role string `json:"role" binding:"required,oneof=admin editor contributor"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" binding:"required,min=3,max=32"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
Username string `json:"username" binding:"required,min=3,max=32"`
|
||||
Password string `json:"password" binding:"required"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
Token string `json:"token"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
func (h *Handler) Register(c *gin.Context) {
|
||||
// 检查是否启用注册功能
|
||||
if !h.config.Auth.Registration.Enabled {
|
||||
message := h.config.Auth.Registration.Message
|
||||
if message == "" {
|
||||
message = "Registration is currently disabled"
|
||||
}
|
||||
c.JSON(http.StatusForbidden, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "REGISTRATION_DISABLED",
|
||||
"message": message,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
// 检查是否启用注册功能
|
||||
if !h.config.Auth.Registration.Enabled {
|
||||
message := h.config.Auth.Registration.Message
|
||||
if message == "" {
|
||||
message = "Registration is currently disabled"
|
||||
}
|
||||
c.JSON(http.StatusForbidden, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "REGISTRATION_DISABLED",
|
||||
"message": message,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var req RegisterRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": err.Error(),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
var req RegisterRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": err.Error(),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.service.CreateUser(c.Request.Context(), req.Username, req.Email, req.Password, req.Role)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to create user")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "CREATE_USER_FAILED",
|
||||
"message": "Failed to create user",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
user, err := h.service.CreateUser(c.Request.Context(), req.Username, req.Email, req.Password, req.Role)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to create user")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "CREATE_USER_FAILED",
|
||||
"message": "Failed to create user",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user roles
|
||||
roles, err := h.service.GetUserRoles(c.Request.Context(), user.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get user roles")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GET_ROLES_FAILED",
|
||||
"message": "Failed to get user roles",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
// Get user roles
|
||||
roles, err := h.service.GetUserRoles(c.Request.Context(), user.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get user roles")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GET_ROLES_FAILED",
|
||||
"message": "Failed to get user roles",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Extract role names for JWT
|
||||
roleNames := make([]string, len(roles))
|
||||
for i, r := range roles {
|
||||
roleNames[i] = r.Name
|
||||
}
|
||||
// Extract role names for JWT
|
||||
roleNames := make([]string, len(roles))
|
||||
for i, r := range roles {
|
||||
roleNames[i] = r.Name
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"sub": user.ID,
|
||||
"roles": roleNames,
|
||||
"exp": time.Now().Add(24 * time.Hour).Unix(),
|
||||
})
|
||||
// Generate JWT token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"sub": int64(user.ID), // 将用户 ID 转换为 int64
|
||||
"roles": roleNames,
|
||||
"exp": time.Now().Add(24 * time.Hour).Unix(),
|
||||
})
|
||||
|
||||
tokenString, err := token.SignedString([]byte(h.cfg.JWT.Secret))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to generate token")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GENERATE_TOKEN_FAILED",
|
||||
"message": "Failed to generate token",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
tokenString, err := token.SignedString([]byte(h.cfg.JWT.Secret))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to generate token")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GENERATE_TOKEN_FAILED",
|
||||
"message": "Failed to generate token",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, AuthResponse{Token: tokenString})
|
||||
c.JSON(http.StatusCreated, AuthResponse{Token: tokenString})
|
||||
}
|
||||
|
||||
func (h *Handler) Login(c *gin.Context) {
|
||||
var req LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": err.Error(),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
var req LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_REQUEST",
|
||||
"message": err.Error(),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.service.GetUserByUsername(c.Request.Context(), req.Username)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_CREDENTIALS",
|
||||
"message": "Invalid username or password",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
user, err := h.service.GetUserByUsername(c.Request.Context(), req.Username)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_CREDENTIALS",
|
||||
"message": "Invalid username or password",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 验证密码
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_CREDENTIALS",
|
||||
"message": "Invalid username or password",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
// 验证密码
|
||||
err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(req.Password))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "INVALID_CREDENTIALS",
|
||||
"message": "Invalid username or password",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user roles
|
||||
roles, err := h.service.GetUserRoles(c.Request.Context(), user.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get user roles")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GET_ROLES_FAILED",
|
||||
"message": "Failed to get user roles",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
// Get user roles
|
||||
roles, err := h.service.GetUserRoles(c.Request.Context(), user.ID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to get user roles")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GET_ROLES_FAILED",
|
||||
"message": "Failed to get user roles",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Extract role names for JWT
|
||||
roleNames := make([]string, len(roles))
|
||||
for i, r := range roles {
|
||||
roleNames[i] = r.Name
|
||||
}
|
||||
// Extract role names for JWT
|
||||
roleNames := make([]string, len(roles))
|
||||
for i, r := range roles {
|
||||
roleNames[i] = r.Name
|
||||
}
|
||||
|
||||
// Generate JWT token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"sub": user.ID,
|
||||
"roles": roleNames,
|
||||
"exp": time.Now().Add(24 * time.Hour).Unix(),
|
||||
})
|
||||
// Generate JWT token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
"sub": int64(user.ID), // 将用户 ID 转换为 int64
|
||||
"roles": roleNames,
|
||||
"exp": time.Now().Add(24 * time.Hour).Unix(),
|
||||
})
|
||||
|
||||
tokenString, err := token.SignedString([]byte(h.cfg.JWT.Secret))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to generate token")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GENERATE_TOKEN_FAILED",
|
||||
"message": "Failed to generate token",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
tokenString, err := token.SignedString([]byte(h.cfg.JWT.Secret))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to generate token")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": gin.H{
|
||||
"code": "GENERATE_TOKEN_FAILED",
|
||||
"message": "Failed to generate token",
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, AuthResponse{Token: tokenString})
|
||||
c.JSON(http.StatusOK, AuthResponse{Token: tokenString})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue