241e3b5f2d
- Introduced a new `auditlog` package to handle audit logging for user actions, including creation, updates, deletions, and authentication events. - Enhanced existing services (customer, user) to log relevant actions using the new audit logger, capturing details such as actor ID, action type, target type, and success status. - Added middleware to enrich request context with metadata for audit logging, ensuring comprehensive tracking of user interactions. - Integrated Elasticsearch for persistent storage of audit logs, with fallback to file-only logging if Elasticsearch is unavailable. - Updated API documentation to include new audit log endpoints for administrative access. This update significantly improves the system's ability to track and audit user actions, enhancing security and accountability within the application.
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package customer
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"tm/pkg/audit"
|
|
"tm/pkg/response"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// AuthMiddleware validates JWT access tokens and extracts customer information
|
|
func (h *Handler) AuthMiddleware() echo.MiddlewareFunc {
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
// Extract token from Authorization header
|
|
authHeader := c.Request().Header.Get("Authorization")
|
|
if authHeader == "" {
|
|
return response.Unauthorized(c, "Authorization header required")
|
|
}
|
|
|
|
// Check if it's a Bearer token
|
|
if !strings.HasPrefix(authHeader, "Bearer ") {
|
|
return response.Unauthorized(c, "Invalid authorization format. Use 'Bearer <token>'")
|
|
}
|
|
|
|
// Extract the token
|
|
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
|
|
|
// Validate the access token using authorization service
|
|
validationResult, err := h.authService.ValidateAccessToken(tokenString)
|
|
if err != nil {
|
|
h.logger.Error("Token validation error", map[string]interface{}{
|
|
"error": err.Error(),
|
|
})
|
|
return response.Unauthorized(c, "Invalid token")
|
|
}
|
|
|
|
if !validationResult.Valid {
|
|
if validationResult.Expired {
|
|
return response.Unauthorized(c, "Token expired")
|
|
}
|
|
return response.Unauthorized(c, validationResult.Error)
|
|
}
|
|
|
|
// Extract customer information from token
|
|
customerID := validationResult.Claims.UserID
|
|
|
|
// Store customer information in context for handlers to use
|
|
c.Set("customer_id", customerID)
|
|
c.Set("customer_email", validationResult.Claims.Email)
|
|
c.Set("customer_role", validationResult.Claims.Role)
|
|
c.Set("company_id", validationResult.Claims.CompanyID)
|
|
c.Set("access_token", tokenString)
|
|
|
|
audit.EnrichEchoContext(c, audit.ActorTypeCustomer)
|
|
|
|
// Continue to next handler
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetCustomerIDFromContext extracts customer ID from Echo context
|
|
func GetCustomerIDFromContext(c echo.Context) (string, error) {
|
|
customerID, ok := c.Get("customer_id").(string)
|
|
if !ok {
|
|
return "", echo.NewHTTPError(http.StatusUnauthorized, "Customer ID not found in context")
|
|
}
|
|
return customerID, nil
|
|
}
|
|
|
|
// GetAccessTokenFromContext extracts access token from Echo context
|
|
func GetAccessTokenFromContext(c echo.Context) (string, error) {
|
|
accessToken, ok := c.Get("access_token").(string)
|
|
if !ok {
|
|
return "", echo.NewHTTPError(http.StatusUnauthorized, "Access token not found in context")
|
|
}
|
|
return accessToken, nil
|
|
}
|