package handler import ( "net/http" "github.com/gin-gonic/gin" "note-manager/middleware" "note-manager/service" ) // AuthHandler 认证处理器(多租户账号:注册/登录/登出/当前用户) type AuthHandler struct { userSvc *service.UserService } // NewAuthHandler 创建认证处理器 func NewAuthHandler(userSvc *service.UserService) *AuthHandler { return &AuthHandler{userSvc: userSvc} } // REGISTER 注册请求 type registerReq struct { Username string `json:"username"` Password string `json:"password"` DisplayName string `json:"display_name"` } // Register 注册新用户 // 首个注册用户自动成为 admin,并接管历史遗留笔记。 func (h *AuthHandler) Register(c *gin.Context) { var req registerReq if err := c.ShouldBindJSON(&req); err != nil { fail(c, http.StatusBadRequest, "请求参数错误") return } u, err := h.userSvc.Register(req.Username, req.Password, req.DisplayName) if err != nil { fail(c, http.StatusBadRequest, err.Error()) return } // 注册成功即自动登录 token, _ := middleware.NewSession(u.ID) secure := c.Request.TLS != nil middleware.SetAuthCookie(c, token, secure) success(c, gin.H{"id": u.ID, "username": u.Username, "display_name": u.DisplayName, "role": u.Role}) } // Login 登录(用户名 + 密码) func (h *AuthHandler) Login(c *gin.Context) { var req struct { Username string `json:"username"` Password string `json:"password"` } // 兼容 form 提交(后台登录页) if err := c.ShouldBindJSON(&req); err != nil { req.Username = c.PostForm("username") req.Password = c.PostForm("password") } if req.Password == "" || req.Username == "" { fail(c, http.StatusBadRequest, "请输入用户名和密码") return } u, err := h.userSvc.Login(req.Username, req.Password) if err != nil { fail(c, http.StatusUnauthorized, err.Error()) return } token, _ := middleware.NewSession(u.ID) secure := c.Request.TLS != nil middleware.SetAuthCookie(c, token, secure) success(c, gin.H{"id": u.ID, "username": u.Username, "display_name": u.DisplayName, "role": u.Role}) } // Logout 登出 func (h *AuthHandler) Logout(c *gin.Context) { middleware.RevokeSession(middleware.GetAuthToken(c)) middleware.ClearAuthCookie(c) success(c, nil) } // Me 返回当前登录用户信息(未登录返回 null) func (h *AuthHandler) Me(c *gin.Context) { uid := middleware.GetUserID(c) if uid == 0 { success(c, gin.H{ "registration_enabled": h.userSvc.RegistrationEnabled(), }) return } u, err := h.userSvc.GetByID(uid) if err != nil { success(c, nil) return } success(c, gin.H{ "id": u.ID, "username": u.Username, "display_name": u.DisplayName, "role": u.Role, "registration_enabled": h.userSvc.RegistrationEnabled(), }) } // GetRegistrationStatus 获取注册开关状态(管理员) func (h *AuthHandler) GetRegistrationStatus(c *gin.Context) { if !h.userSvc.IsAdmin(middleware.GetUserID(c)) { fail(c, http.StatusForbidden, "仅管理员可操作") return } success(c, gin.H{"registration_enabled": h.userSvc.RegistrationEnabled()}) } // SetRegistration 切换注册开关(管理员) func (h *AuthHandler) SetRegistration(c *gin.Context) { if !h.userSvc.IsAdmin(middleware.GetUserID(c)) { fail(c, http.StatusForbidden, "仅管理员可操作") return } var req struct { Enabled bool `json:"enabled"` } if err := c.ShouldBindJSON(&req); err != nil { fail(c, http.StatusBadRequest, "请求参数错误") return } if err := h.userSvc.SetRegistrationEnabled(req.Enabled); err != nil { fail(c, http.StatusInternalServerError, err.Error()) return } success(c, gin.H{"registration_enabled": req.Enabled}) }