refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
aovantsev
2025-10-10 19:56:06 +03:00
parent f081c9d947
commit 73ed514a34
30 changed files with 1728 additions and 1020 deletions

View File

@@ -0,0 +1,57 @@
package middleware
import (
"net/http"
"strings"
"counter/internal/infrastructure/security"
"github.com/gin-gonic/gin"
)
// AuthMiddleware validates JWT token and sets user context
func AuthMiddleware(jwtService security.JWTService) gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
c.Abort()
return
}
// Extract token from "Bearer <token>"
tokenParts := strings.Split(authHeader, " ")
if len(tokenParts) != 2 || tokenParts[0] != "Bearer" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid authorization header format"})
c.Abort()
return
}
tokenString := tokenParts[1]
claims, err := jwtService.ValidateToken(tokenString)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
c.Abort()
return
}
// Set user information in context
userID, ok := claims["user_id"].(float64)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"})
c.Abort()
return
}
username, ok := claims["username"].(string)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token claims"})
c.Abort()
return
}
c.Set("user_id", int(userID))
c.Set("username", username)
c.Next()
}
}

View File

@@ -0,0 +1,43 @@
package middleware
import (
"time"
"counter/internal/infrastructure/config"
"counter/internal/infrastructure/logging"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
// LoggingMiddleware creates a Gin middleware for HTTP request logging
func LoggingMiddleware(logger logging.Logger, cfg *config.Config) gin.HandlerFunc {
return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
// Create structured log entry with default fields
entry := logger.WithFields(logrus.Fields{
"service": "counter-app",
"environment": string(cfg.Environment),
"version": "1.0.0",
"method": param.Method,
"path": param.Path,
"status": param.StatusCode,
"latency": param.Latency.String(),
"client_ip": param.ClientIP,
"user_agent": param.Request.UserAgent(),
"timestamp": param.TimeStamp.Format(time.RFC3339),
})
// Set log level based on status code
switch {
case param.StatusCode >= 500:
entry.Error("HTTP Request")
case param.StatusCode >= 400:
entry.Warn("HTTP Request")
default:
entry.Info("HTTP Request")
}
// Return empty string since we're handling logging ourselves
return ""
})
}

View File

@@ -0,0 +1,21 @@
package middleware
import (
"time"
"counter/internal/infrastructure/metrics"
"github.com/gin-gonic/gin"
)
// MetricsMiddleware creates a Gin middleware for HTTP metrics
func MetricsMiddleware(metricsService metrics.MetricsService) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
duration := time.Since(start)
metricsService.RecordHTTPRequest(c.Request.Method, c.FullPath(), c.Writer.Status(), duration)
}
}