package handlers import ( models "api-service/internal/models/auth" services "api-service/internal/services/auth" "net/http" "github.com/gin-gonic/gin" ) // AuthHandler handles authentication endpoints type AuthHandler struct { authService *services.AuthService } // NewAuthHandler creates a new authentication handler func NewAuthHandler(authService *services.AuthService) *AuthHandler { return &AuthHandler{ authService: authService, } } // Login godoc // @Summary Login user and get JWT token // @Description Authenticate user with username and password to receive JWT token // @Tags Authentication // @Accept json // @Produce json // @Param login body models.LoginRequest true "Login credentials" // @Success 200 {object} models.TokenResponse // @Failure 400 {object} map[string]string "Bad request" // @Failure 401 {object} map[string]string "Unauthorized" // @Router /api/v1/auth/login [post] func (h *AuthHandler) Login(c *gin.Context) { var loginReq models.LoginRequest // Bind JSON request if err := c.ShouldBindJSON(&loginReq); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Authenticate user tokenResponse, err := h.authService.Login(loginReq.Username, loginReq.Password) if err != nil { c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, tokenResponse) } // RefreshToken godoc // @Summary Refresh JWT token // @Description Refresh the JWT token using a valid refresh token // @Tags Authentication // @Accept json // @Produce json // @Param refresh body map[string]string true "Refresh token" // @Success 200 {object} models.TokenResponse // @Failure 400 {object} map[string]string "Bad request" // @Failure 401 {object} map[string]string "Unauthorized" // @Router /api/v1/auth/refresh [post] func (h *AuthHandler) RefreshToken(c *gin.Context) { // For now, this is a placeholder for refresh token functionality // In a real implementation, you would handle refresh tokens here c.JSON(http.StatusNotImplemented, gin.H{"error": "refresh token not implemented"}) } // Register godoc // @Summary Register new user // @Description Register a new user account // @Tags Authentication // @Accept json // @Produce json // @Param register body map[string]string true "Registration data" // @Success 201 {object} map[string]string // @Failure 400 {object} map[string]string "Bad request" // @Router /api/v1/auth/register [post] func (h *AuthHandler) Register(c *gin.Context) { var registerReq struct { Username string `json:"username" binding:"required"` Email string `json:"email" binding:"required,email"` Password string `json:"password" binding:"required,min=6"` Role string `json:"role" binding:"required"` } if err := c.ShouldBindJSON(®isterReq); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } err := h.authService.RegisterUser( registerReq.Username, registerReq.Email, registerReq.Password, registerReq.Role, ) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusCreated, gin.H{"message": "user registered successfully"}) } // Me godoc // @Summary Get current user info // @Description Get information about the currently authenticated user // @Tags Authentication // @Produce json // @Security Bearer // @Success 200 {object} models.User // @Failure 401 {object} map[string]string "Unauthorized" // @Router /api/v1/auth/me [get] func (h *AuthHandler) Me(c *gin.Context) { // Get user info from context (set by middleware) userID, exists := c.Get("user_id") if !exists { c.JSON(http.StatusUnauthorized, gin.H{"error": "user not authenticated"}) return } // In a real implementation, you would fetch user details from database c.JSON(http.StatusOK, gin.H{ "id": userID, "username": c.GetString("username"), "email": c.GetString("email"), "role": c.GetString("role"), }) }