Files
X-Agents/server/internal/handler/auth_handler.go
DESKTOP-72TV0V4\caoxiaozhu ecb885ee5e feat: 后端认证和工具模块更新
- main.go: 添加 Swagger 文档、初始化默认管理员
- 认证模块: 完善用户角色管理
- 新增工具模块: tool_handler, tool_repo, tool_service, tool model
- 更新 go.mod 依赖

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:25:55 +08:00

242 lines
5.9 KiB
Go
Raw Permalink 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 handler
import (
"net/http"
"strings"
"x-agents/server/internal/service"
"github.com/gin-gonic/gin"
)
// maskEmail 邮箱脱敏只显示前后各1个字符
func maskEmail(email string) string {
if email == "" {
return ""
}
parts := strings.Split(email, "@")
if len(parts) != 2 {
return "***"
}
local := parts[0]
domain := parts[1]
if len(local) <= 2 {
local = "**"
} else {
local = string(local[0]) + "***" + string(local[len(local)-1])
}
if len(domain) <= 2 {
domain = "***"
} else {
domain = string(domain[0]) + "***" + string(domain[len(domain)-1])
}
return local + "@" + domain
}
// @title X-Agents API
// @version 1.0
// @description X-Agents 后端 API 文档
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.example.com/support
// @contact.email support@example.com
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /
// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description Type "Bearer" followed by a space and JWT token.
type AuthHandler struct {
authService *service.AuthService
}
func NewAuthHandler(authService *service.AuthService) *AuthHandler {
return &AuthHandler{authService: authService}
}
type LoginRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
}
type LoginResponse struct {
Token string `json:"token"`
User interface{} `json:"user"`
}
// RegisterRequest 注册请求
type RegisterRequest struct {
Username string `json:"username" binding:"required"`
Password string `json:"password" binding:"required"`
Email string `json:"email"`
}
// @Summary 用户登录
// @Description 用户登录并获取 JWT Token
// @Tags 认证
// @Accept json
// @Produce json
// @Param request body LoginRequest true "登录请求"
// @Success 200 {object} LoginResponse
// @Failure 400 {object} map[string]string
// @Failure 401 {object} map[string]string
// @Router /auth/login [post]
func (h *AuthHandler) Login(c *gin.Context) {
var req LoginRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
resp, err := h.authService.Login(service.LoginRequest{
Username: req.Username,
Password: req.Password,
})
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, LoginResponse{
Token: resp.Token,
User: gin.H{
"id": resp.User.ID,
"username": resp.User.Username,
"email": resp.User.Email,
"role": resp.User.RoleID,
},
})
}
// @Summary 用户注册
// @Description 新用户注册账号
// @Tags 认证
// @Accept json
// @Produce json
// @Param RegisterRequest body handler.RegisterRequest true "注册请求"
// @Success 201 {object} map[string]interface{}
// @Failure 400 {object} map[string]string
// @Router /auth/register [post]
func (h *AuthHandler) Register(c *gin.Context) {
var req RegisterRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := h.authService.Register(req.Username, req.Password, req.Email)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, gin.H{
"id": user.ID,
"username": user.Username,
"email": maskEmail(user.Email),
})
}
// @Summary 获取当前用户信息
// @Description 获取已登录用户的详细信息
// @Tags 认证
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} map[string]interface{}
// @Failure 401 {object} map[string]string
// @Router /auth/me [get]
func (h *AuthHandler) GetCurrentUser(c *gin.Context) {
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found in context"})
return
}
user, err := h.authService.GetUserByID(userID.(string))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
return
}
c.JSON(http.StatusOK, gin.H{
"id": user.ID,
"username": user.Username,
"email": maskEmail(user.Email),
"role_id": user.RoleID,
"is_active": user.IsActive,
"created_at": user.CreatedAt,
})
}
// @Summary 获取所有用户
// @Description 获取所有用户列表(需要管理员权限)
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} map[string]interface{}
// @Failure 401 {object} map[string]string
// @Router /user/list [get]
func (h *AuthHandler) ListUsers(c *gin.Context) {
users, err := h.authService.GetAllUsers()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
var userList []gin.H
for _, user := range users {
userList = append(userList, gin.H{
"id": user.ID,
"username": user.Username,
"email": maskEmail(user.Email),
"role_id": user.RoleID,
"is_active": user.IsActive,
"created_at": user.CreatedAt,
})
}
c.JSON(http.StatusOK, gin.H{"list": userList})
}
// @Summary 获取用户详情
// @Description 根据ID获取用户详情
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "用户ID"
// @Success 200 {object} map[string]interface{}
// @Failure 404 {object} map[string]string
// @Router /user/{id} [get]
func (h *AuthHandler) GetUserByID(c *gin.Context) {
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "user id is required"})
return
}
user, err := h.authService.GetUserByID(id)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
return
}
c.JSON(http.StatusOK, gin.H{
"id": user.ID,
"username": user.Username,
"email": maskEmail(user.Email),
"role_id": user.RoleID,
"is_active": user.IsActive,
"created_at": user.CreatedAt,
})
}