package handler import ( "net/http" "github.com/gin-gonic/gin" "github.com/user-management-system/internal/service" ) // AuthHandler handles authentication requests type AuthHandler struct { authService *service.AuthService } // NewAuthHandler creates a new AuthHandler func NewAuthHandler(authService *service.AuthService) *AuthHandler { return &AuthHandler{authService: authService} } func (h *AuthHandler) Register(c *gin.Context) { var req struct { Username string `json:"username" binding:"required"` Email string `json:"email"` Phone string `json:"phone"` Password string `json:"password" binding:"required"` Nickname string `json:"nickname"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } registerReq := &service.RegisterRequest{ Username: req.Username, Email: req.Email, Phone: req.Phone, Password: req.Password, Nickname: req.Nickname, } userInfo, err := h.authService.Register(c.Request.Context(), registerReq) if err != nil { handleError(c, err) return } c.JSON(http.StatusCreated, userInfo) } func (h *AuthHandler) Login(c *gin.Context) { var req struct { Account string `json:"account"` Username string `json:"username"` Email string `json:"email"` Phone string `json:"phone"` Password string `json:"password"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } loginReq := &service.LoginRequest{ Account: req.Account, Username: req.Username, Email: req.Email, Phone: req.Phone, Password: req.Password, } clientIP := c.ClientIP() resp, err := h.authService.Login(c.Request.Context(), loginReq, clientIP) if err != nil { handleError(c, err) return } c.JSON(http.StatusOK, resp) } func (h *AuthHandler) Logout(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "logged out"}) } func (h *AuthHandler) RefreshToken(c *gin.Context) { var req struct { RefreshToken string `json:"refresh_token" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } resp, err := h.authService.RefreshToken(c.Request.Context(), req.RefreshToken) if err != nil { handleError(c, err) return } c.JSON(http.StatusOK, resp) } func (h *AuthHandler) GetUserInfo(c *gin.Context) { userID, ok := getUserIDFromContext(c) if !ok { c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) return } userInfo, err := h.authService.GetUserInfo(c.Request.Context(), userID) if err != nil { handleError(c, err) return } c.JSON(http.StatusOK, userInfo) } func (h *AuthHandler) GetCSRFToken(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"csrf_token": "not_implemented"}) } func (h *AuthHandler) GetAuthCapabilities(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "register": true, "login": true, "oauth_login": false, "totp": true, }) } func (h *AuthHandler) OAuthLogin(c *gin.Context) { provider := c.Param("provider") c.JSON(http.StatusOK, gin.H{"provider": provider, "message": "OAuth not configured"}) } func (h *AuthHandler) OAuthCallback(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"error": "OAuth not configured"}) } func (h *AuthHandler) OAuthExchange(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"error": "OAuth not configured"}) } func (h *AuthHandler) GetEnabledOAuthProviders(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"providers": []string{}}) } func (h *AuthHandler) ActivateEmail(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email activation not configured"}) } func (h *AuthHandler) ResendActivationEmail(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email activation not configured"}) } func (h *AuthHandler) SendEmailCode(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email code login not configured"}) } func (h *AuthHandler) LoginByEmailCode(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"error": "email code login not configured"}) } func (h *AuthHandler) ForgotPassword(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "password reset not configured"}) } func (h *AuthHandler) ResetPassword(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "password reset not configured"}) } func (h *AuthHandler) ValidateResetToken(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"valid": false}) } func (h *AuthHandler) BootstrapAdmin(c *gin.Context) { var req struct { Username string `json:"username" binding:"required"` Email string `json:"email" binding:"required"` Password string `json:"password" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } bootstrapReq := &service.BootstrapAdminRequest{ Username: req.Username, Email: req.Email, Password: req.Password, } clientIP := c.ClientIP() resp, err := h.authService.BootstrapAdmin(c.Request.Context(), bootstrapReq, clientIP) if err != nil { handleError(c, err) return } c.JSON(http.StatusCreated, resp) } func (h *AuthHandler) SendEmailBindCode(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email bind not configured"}) } func (h *AuthHandler) BindEmail(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email bind not configured"}) } func (h *AuthHandler) UnbindEmail(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "email unbind not configured"}) } func (h *AuthHandler) SendPhoneBindCode(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "phone bind not configured"}) } func (h *AuthHandler) BindPhone(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "phone bind not configured"}) } func (h *AuthHandler) UnbindPhone(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "phone unbind not configured"}) } func (h *AuthHandler) GetSocialAccounts(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"accounts": []interface{}{}}) } func (h *AuthHandler) BindSocialAccount(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "social binding not configured"}) } func (h *AuthHandler) UnbindSocialAccount(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "social unbinding not configured"}) } func (h *AuthHandler) SupportsEmailCodeLogin() bool { return false } func getUserIDFromContext(c *gin.Context) (int64, bool) { userID, exists := c.Get("user_id") if !exists { return 0, false } id, ok := userID.(int64) return id, ok } func handleError(c *gin.Context, err error) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) }