123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- package handlers
- import (
- // Added for context.Context
- "errors"
- "fmt"
- "net/http"
- "git.linuxforward.com/byop/byop-engine/auth"
- "git.linuxforward.com/byop/byop-engine/dbstore" // Keep for NewAuthHandler, but userStore is not directly used in handlers
- "git.linuxforward.com/byop/byop-engine/models"
- "github.com/gin-gonic/gin"
- "github.com/go-playground/validator/v10" // Added for validation
- )
- // AuthHandler handles authentication-related operations
- type AuthHandler struct {
- authService auth.Service
- validate *validator.Validate // Added for validation
- }
- // NewAuthHandler creates a new AuthHandler
- func NewAuthHandler(authService auth.Service, userStore *dbstore.SQLiteStore) *AuthHandler {
- return &AuthHandler{
- authService: authService,
- validate: validator.New(), // Initialize validator
- }
- }
- // LoginRequest defines the structure for login requests.
- type LoginRequest struct {
- Email string `json:"email" validate:"required,email"`
- Password string `json:"password" validate:"required"`
- }
- // Login handles user authentication
- func (h *AuthHandler) Login(c *gin.Context) {
- ctx := c.Request.Context() // Propagate context
- var req LoginRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- models.RespondWithError(c, models.NewErrValidation("invalid_request_body", map[string]string{"body": "Invalid request body"}, err))
- return
- }
- fmt.Println("Login request received:", req.Email) // Debugging line to check input
- // Validate input
- if err := h.validate.Struct(req); err != nil {
- validationErrors := models.ExtractValidationErrors(err)
- models.RespondWithError(c, models.NewErrValidation("input_validation_failed", validationErrors, err))
- return
- }
- tokenResp, err := h.authService.Login(ctx, req.Email, req.Password)
- if err != nil {
- if errors.Is(err, auth.ErrInvalidCredentials) || errors.Is(err, auth.ErrUserNotFound) {
- models.RespondWithError(c, models.NewErrUnauthorized("login_failed", err))
- } else {
- models.RespondWithError(c, models.NewErrInternalServer("login_token_generation_failed", err))
- }
- return
- }
- c.JSON(http.StatusOK, tokenResp) // auth.TokenResponse is now the direct response
- }
- // RefreshTokenRequest defines the structure for refresh token requests.
- type RefreshTokenRequest struct {
- RefreshToken string `json:"refresh_token" validate:"required"`
- }
- // RefreshToken handles token refresh
- func (h *AuthHandler) RefreshToken(c *gin.Context) {
- ctx := c.Request.Context() // Propagate context
- var req RefreshTokenRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- models.RespondWithError(c, models.NewErrValidation("invalid_request_body_refresh", map[string]string{"body": "Invalid request body"}, err))
- return
- }
- if err := h.validate.Struct(req); err != nil {
- validationErrors := models.ExtractValidationErrors(err)
- models.RespondWithError(c, models.NewErrValidation("input_validation_failed_refresh", validationErrors, err))
- return
- }
- resp, err := h.authService.RefreshToken(ctx, req.RefreshToken)
- if err != nil {
- if errors.Is(err, auth.ErrInvalidToken) || errors.Is(err, auth.ErrRefreshTokenNotFound) || errors.Is(err, auth.ErrTokenExpired) {
- models.RespondWithError(c, models.NewErrUnauthorized("invalid_refresh_token", err))
- } else {
- models.RespondWithError(c, models.NewErrInternalServer("refresh_token_failed", err))
- }
- return
- }
- c.JSON(http.StatusOK, resp)
- }
- // LogoutRequest defines the structure for logout requests.
- type LogoutRequest struct {
- Token string `json:"token" validate:"required"` // Assuming the client sends the token to be invalidated
- }
- // Logout handles user logout
- func (h *AuthHandler) Logout(c *gin.Context) {
- ctx := c.Request.Context() // Propagate context
- var req LogoutRequest
- if err := c.ShouldBindJSON(&req); err != nil {
- models.RespondWithError(c, models.NewErrValidation("invalid_request_body_logout", map[string]string{"body": "Invalid request body"}, err))
- return
- }
- if err := h.validate.Struct(req); err != nil {
- validationErrors := models.ExtractValidationErrors(err)
- models.RespondWithError(c, models.NewErrValidation("input_validation_failed_logout", validationErrors, err))
- return
- }
- err := h.authService.Logout(ctx, req.Token)
- if err != nil {
- if errors.Is(err, auth.ErrInvalidToken) {
- models.RespondWithError(c, models.NewErrBadRequest("logout_failed_invalid_token", err))
- } else {
- models.RespondWithError(c, models.NewErrInternalServer("logout_failed", err))
- }
- return
- }
- c.Status(http.StatusNoContent)
- }
|