veza/veza-backend-api/internal/handlers/csrf.go

99 lines
2.5 KiB
Go
Raw Normal View History

package handlers
import (
"context"
"net/http"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"go.uber.org/zap"
"veza-backend-api/internal/middleware"
)
// CSRFHandler gère les handlers pour la protection CSRF
type CSRFHandler struct {
csrfMiddleware CSRFMiddlewareInterface
logger *zap.Logger
}
// CSRFMiddlewareInterface defines methods needed for CSRF handler
type CSRFMiddlewareInterface interface {
GetToken(ctx context.Context, userID uuid.UUID) (string, error)
}
// NewCSRFHandler crée un nouveau handler CSRF
func NewCSRFHandler(csrfMiddleware *middleware.CSRFMiddleware, logger *zap.Logger) *CSRFHandler {
return &CSRFHandler{
csrfMiddleware: csrfMiddleware,
logger: logger,
}
}
// NewCSRFHandlerWithInterface creates a new CSRF handler with interface (for testing)
func NewCSRFHandlerWithInterface(csrfMiddleware CSRFMiddlewareInterface, logger *zap.Logger) *CSRFHandler {
return &CSRFHandler{
csrfMiddleware: csrfMiddleware,
logger: logger,
}
}
// GetCSRFToken retourne un token CSRF pour l'utilisateur authentifié
// GET /api/v1/csrf-token
func (h *CSRFHandler) GetCSRFToken() gin.HandlerFunc {
return func(c *gin.Context) {
// Récupérer le userID depuis le contexte (défini par AuthMiddleware.OptionalAuth)
userIDInterface, exists := c.Get("user_id")
if !exists {
// Si pas d'utilisateur authentifié, on retourne un token public/anonyme
// Le middleware CSRF côté serveur ignore la validation si user_id est absent du contexte
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"csrf_token": "public-anonymous-token",
},
})
return
}
userID, ok := userIDInterface.(uuid.UUID)
if !ok {
h.logger.Error("Invalid user_id type in context")
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"error": gin.H{
"code": 500,
"message": "Internal server error",
},
})
return
}
// Générer ou récupérer le token CSRF
ctx := c.Request.Context()
token, err := h.csrfMiddleware.GetToken(ctx, userID)
if err != nil {
h.logger.Error("Failed to get CSRF token",
zap.Error(err),
zap.String("user_id", userID.String()),
)
c.JSON(http.StatusInternalServerError, gin.H{
"success": false,
"error": gin.H{
"code": 500,
"message": "Failed to generate CSRF token",
},
})
return
}
// Retourner le token
c.JSON(http.StatusOK, gin.H{
"success": true,
"data": gin.H{
"csrf_token": token,
},
})
}
}