package handlers import ( "net/http" "github.com/gin-gonic/gin" "github.com/yourusername/victorialogs-manager/internal/services" ) // AuthHandler handles authentication endpoints type AuthHandler struct { authService *services.AuthService } // NewAuthHandler creates a new auth handler func NewAuthHandler(authService *services.AuthService) *AuthHandler { return &AuthHandler{ authService: authService, } } // Login handles user login // @Summary User login // @Description Authenticate user and return JWT tokens // @Tags auth // @Accept json // @Produce json // @Param request body services.LoginRequest true "Login credentials" // @Success 200 {object} services.LoginResponse // @Failure 400 {object} ErrorResponse // @Failure 401 {object} ErrorResponse // @Router /api/v1/auth/login [post] func (h *AuthHandler) Login(c *gin.Context) { var req services.LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Error: "invalid request", Message: err.Error(), }) return } // Validate input if req.Username == "" || req.Password == "" { c.JSON(http.StatusBadRequest, ErrorResponse{ Error: "validation error", Message: "username and password are required", }) return } resp, err := h.authService.Login(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusUnauthorized, ErrorResponse{ Error: "authentication failed", Message: err.Error(), }) return } c.JSON(http.StatusOK, resp) } // RefreshToken handles token refresh // @Summary Refresh access token // @Description Get new access and refresh tokens using refresh token // @Tags auth // @Accept json // @Produce json // @Param request body services.RefreshTokenRequest true "Refresh token" // @Success 200 {object} services.RefreshTokenResponse // @Failure 400 {object} ErrorResponse // @Failure 401 {object} ErrorResponse // @Router /api/v1/auth/refresh [post] func (h *AuthHandler) RefreshToken(c *gin.Context) { var req services.RefreshTokenRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Error: "invalid request", Message: err.Error(), }) return } resp, err := h.authService.RefreshToken(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusUnauthorized, ErrorResponse{ Error: "refresh failed", Message: err.Error(), }) return } c.JSON(http.StatusOK, resp) } // GetMe returns the current user // @Summary Get current user // @Description Get current authenticated user information // @Tags auth // @Produce json // @Success 200 {object} models.User // @Failure 401 {object} ErrorResponse // @Security BearerAuth // @Router /api/v1/auth/me [get] func (h *AuthHandler) GetMe(c *gin.Context) { // Get user ID from context (set by auth middleware) userID, exists := c.Get("user_id") if !exists { c.JSON(http.StatusUnauthorized, ErrorResponse{ Error: "unauthorized", Message: "user not authenticated", }) return } user, err := h.authService.GetCurrentUser(c.Request.Context(), userID.(string)) if err != nil { c.JSON(http.StatusNotFound, ErrorResponse{ Error: "user not found", Message: err.Error(), }) return } c.JSON(http.StatusOK, user) } // ChangePassword handles password change // @Summary Change password // @Description Change current user's password // @Tags auth // @Accept json // @Produce json // @Param request body services.ChangePasswordRequest true "Password change request" // @Success 200 {object} SuccessResponse // @Failure 400 {object} ErrorResponse // @Failure 401 {object} ErrorResponse // @Security BearerAuth // @Router /api/v1/auth/change-password [post] func (h *AuthHandler) ChangePassword(c *gin.Context) { // Get user ID from context userID, exists := c.Get("user_id") if !exists { c.JSON(http.StatusUnauthorized, ErrorResponse{ Error: "unauthorized", Message: "user not authenticated", }) return } var req services.ChangePasswordRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Error: "invalid request", Message: err.Error(), }) return } err := h.authService.ChangePassword(c.Request.Context(), userID.(string), &req) if err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Error: "password change failed", Message: err.Error(), }) return } c.JSON(http.StatusOK, SuccessResponse{ Message: "password changed successfully", }) } // ErrorResponse represents an error response type ErrorResponse struct { Error string `json:"error"` Message string `json:"message"` } // SuccessResponse represents a success response type SuccessResponse struct { Message string `json:"message"` }