146 lines
3.6 KiB
Go
146 lines
3.6 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
"git.ma-al.com/goc_daniel/b2b/app/service/authService"
|
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
|
|
|
"github.com/gofiber/fiber/v3"
|
|
)
|
|
|
|
// AuthMiddleware creates authentication middleware
|
|
func AuthMiddleware() fiber.Handler {
|
|
authService := authService.NewAuthService()
|
|
|
|
return func(c fiber.Ctx) error {
|
|
// Get token from Authorization header
|
|
authHeader := c.Get("Authorization")
|
|
if authHeader == "" {
|
|
// Try to get from cookie
|
|
authHeader = c.Cookies("access_token")
|
|
if authHeader == "" {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "authorization token required",
|
|
})
|
|
}
|
|
} else {
|
|
// Extract token from "Bearer <token>"
|
|
parts := strings.Split(authHeader, " ")
|
|
if len(parts) != 2 || parts[0] != "Bearer" {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "invalid authorization header format",
|
|
})
|
|
}
|
|
authHeader = parts[1]
|
|
}
|
|
|
|
// Validate token
|
|
claims, err := authService.ValidateToken(authHeader)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "invalid or expired token",
|
|
})
|
|
}
|
|
|
|
// Get user from database
|
|
user, err := authService.GetUserByID(claims.UserID)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "user not found",
|
|
})
|
|
}
|
|
|
|
// Check if user is active
|
|
if !user.IsActive {
|
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
|
"error": "user account is inactive",
|
|
})
|
|
}
|
|
|
|
// Create locale. LangID is overwritten by auth Token
|
|
var userLocale model.UserLocale
|
|
userLocale.OriginalUser = user
|
|
|
|
// Check if target user is present
|
|
targetUserIDAttribute := c.Query("target_user_id")
|
|
|
|
if targetUserIDAttribute == "" {
|
|
userLocale.User = user
|
|
c.Locals(constdata.USER_LOCALE, &userLocale)
|
|
|
|
return c.Next()
|
|
}
|
|
|
|
// We now populate the target user
|
|
if model.CustomerRole(user.Role.Name) != model.RoleAdmin {
|
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
|
"error": "admin access required",
|
|
})
|
|
}
|
|
|
|
targetUserID, err := strconv.Atoi(targetUserIDAttribute)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
|
"error": "invalid target user id attribute",
|
|
})
|
|
}
|
|
|
|
// to verify target user, we use the same functionality as for verifying original user
|
|
// Get target user from database
|
|
user, err = authService.GetUserByID(uint(targetUserID))
|
|
if err != nil {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "target user not found",
|
|
})
|
|
}
|
|
|
|
// Check if target user is active
|
|
if !user.IsActive {
|
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
|
"error": "target user account is inactive",
|
|
})
|
|
}
|
|
|
|
userLocale.User = user
|
|
c.Locals(constdata.USER_LOCALE, &userLocale)
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// RequireAdmin creates admin-only middleware
|
|
func RequireAdmin() fiber.Handler {
|
|
return func(c fiber.Ctx) error {
|
|
user := c.Locals("user")
|
|
if user == nil {
|
|
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
|
|
"error": "not authenticated",
|
|
})
|
|
}
|
|
|
|
userSession, ok := user.(*model.UserSession)
|
|
if !ok {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
|
"error": "invalid user session",
|
|
})
|
|
}
|
|
|
|
if model.CustomerRole(userSession.RoleName) != model.RoleAdmin {
|
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
|
"error": "admin access required",
|
|
})
|
|
}
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// GetConfig returns the app config
|
|
func GetConfig() *config.Config {
|
|
return config.Get()
|
|
}
|