119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.ma-al.com/goc_marek/timetracker/app/config"
|
|
"git.ma-al.com/goc_marek/timetracker/app/model"
|
|
"git.ma-al.com/goc_marek/timetracker/app/service/authService"
|
|
|
|
"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",
|
|
})
|
|
}
|
|
|
|
// Set user in context
|
|
c.Locals("user", user.ToSession())
|
|
c.Locals("userID", user.ID)
|
|
|
|
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 userSession.Role != model.RoleAdmin {
|
|
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
|
"error": "admin access required",
|
|
})
|
|
}
|
|
|
|
return c.Next()
|
|
}
|
|
}
|
|
|
|
// GetUserID extracts user ID from context
|
|
func GetUserID(c fiber.Ctx) uint {
|
|
userID, ok := c.Locals("userID").(uint)
|
|
if !ok {
|
|
return 0
|
|
}
|
|
return userID
|
|
}
|
|
|
|
// GetUser extracts user from context
|
|
func GetUser(c fiber.Ctx) *model.UserSession {
|
|
user, ok := c.Locals("user").(*model.UserSession)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
return user
|
|
}
|
|
|
|
// GetConfig returns the app config
|
|
func GetConfig() *config.Config {
|
|
return config.Get()
|
|
}
|