78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"veza-backend-api/internal/services"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// WebhookAPIKeyMiddleware crée un middleware pour valider les clés API de webhook (BE-SEC-012)
|
|
func WebhookAPIKeyMiddleware(webhookService *services.WebhookService, logger *zap.Logger) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Extraire la clé API depuis les headers
|
|
apiKey := extractAPIKey(c)
|
|
if apiKey == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"error": "API key required",
|
|
})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// Valider la clé API
|
|
webhook, err := webhookService.ValidateAPIKey(c.Request.Context(), apiKey)
|
|
if err != nil {
|
|
logger.Warn("Invalid webhook API key",
|
|
zap.String("api_key_prefix", apiKey[:min(8, len(apiKey))]+"..."),
|
|
zap.Error(err))
|
|
c.JSON(http.StatusUnauthorized, gin.H{
|
|
"error": "Invalid API key",
|
|
})
|
|
c.Abort()
|
|
return
|
|
}
|
|
|
|
// Stocker le webhook dans le contexte pour utilisation ultérieure
|
|
c.Set("webhook", webhook)
|
|
c.Set("webhook_id", webhook.ID)
|
|
c.Set("user_id", webhook.UserID)
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// extractAPIKey extrait la clé API depuis les headers
|
|
// Supporte X-API-Key et Authorization: Bearer <api_key>
|
|
func extractAPIKey(c *gin.Context) string {
|
|
// Essayer X-API-Key header
|
|
if apiKey := c.GetHeader("X-API-Key"); apiKey != "" {
|
|
return apiKey
|
|
}
|
|
|
|
// Essayer Authorization header avec Bearer
|
|
authHeader := c.GetHeader("Authorization")
|
|
if authHeader != "" {
|
|
parts := strings.SplitN(authHeader, " ", 2)
|
|
if len(parts) == 2 && strings.ToLower(parts[0]) == "bearer" {
|
|
return parts[1]
|
|
}
|
|
// Si pas de "Bearer", essayer directement la valeur
|
|
if len(parts) == 1 {
|
|
return parts[0]
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// min retourne le minimum de deux entiers
|
|
func min(a, b int) int {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|