Files
aura-crm/core/backend/internal/auth/middleware.go
T

80 lines
2.4 KiB
Go

package auth
import (
"strings"
"github.com/gofiber/fiber/v2"
)
func Middleware() fiber.Handler {
return func(c *fiber.Ctx) error {
header := c.Get("Authorization")
if header == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "missing authorization header"})
}
parts := strings.SplitN(header, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid authorization format"})
}
claims, err := ParseToken(parts[1])
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid token"})
}
c.Locals("staffID", claims.StaffID)
c.Locals("staffName", claims.Name)
c.Locals("staffRole", claims.Role)
c.Locals("staffPermissions", claims.Permissions)
return c.Next()
}
}
// RequireRole restricts a route to the given roles. Must run after Middleware().
// Reserved for checks that are about the literal role identity (currently
// none left in this codebase — the last-owner protection in staff.Update
// checks the role column directly, not a request's claims) rather than what
// it's permitted to do; prefer RequirePermission for the latter.
func RequireRole(roles ...string) fiber.Handler {
allowed := make(map[string]bool, len(roles))
for _, r := range roles {
allowed[r] = true
}
return func(c *fiber.Ctx) error {
role, _ := c.Locals("staffRole").(string)
if !allowed[role] {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "insufficient role"})
}
return c.Next()
}
}
// RequirePermission restricts a route to staff whose role's permission set
// (baked into the JWT at login, see GenerateAccessToken) includes key. This
// is what a custom role's checkbox matrix actually gates — RequireRole
// only ever matches the three fixed system role names.
func RequirePermission(key string) fiber.Handler {
return func(c *fiber.Ctx) error {
perms, _ := c.Locals("staffPermissions").([]string)
for _, p := range perms {
if p == key {
return c.Next()
}
}
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{"error": "insufficient permissions"})
}
}
func StaffID(c *fiber.Ctx) string {
id, _ := c.Locals("staffID").(string)
return id
}
func StaffRole(c *fiber.Ctx) string {
role, _ := c.Locals("staffRole").(string)
return role
}
func StaffPermissions(c *fiber.Ctx) []string {
perms, _ := c.Locals("staffPermissions").([]string)
return perms
}