package authorization import ( "errors" "fmt" "server/internal/auth" "server/internal/models" "strings" "github.com/gofiber/fiber/v3" "gorm.io/gorm" ) var Endpoints map[string]int type Permission int type Role struct { Name string Permissions Permission } const ( SuperAdminPermission Permission = 0b1111111111111111 AdminPermission Permission = 0b0111111111111111 ManagerPermission Permission = 0b0010111111111111 ContentCreatorPermission Permission = 0b0001111111111111 UserPermission Permission = 0b0000000000000011 GuestPermission Permission = 0b0000000000000001 ) var Roles = []Role{ {"superadmin", SuperAdminPermission}, {"admin", AdminPermission}, {"manager", ManagerPermission}, {"content_creator", ContentCreatorPermission}, {"user", UserPermission}, {"guest", GuestPermission}, } func init() { Endpoints = make(map[string]int) } func RegisterEndpoint(key string, permission int) { Endpoints[key] = permission } // RequireEndpointPermission enforces permission mapping defined in role config. // If the endpoint is not configured, or mapped to "*", it allows the request. func RequireEndpointPermission(authService *auth.AuthService, dbConn *gorm.DB) fiber.Handler { return func(c fiber.Ctx) error { fmt.Printf("Checking permissions for %s%s\n", strings.TrimSpace(c.Method()), strings.TrimSpace(c.Path())) perm := Endpoints[strings.TrimSpace(c.Method())+strings.TrimSpace(c.Path())] if perm == 0 { return c.Next() } tokenString := c.Get("Auth-Token") if tokenString == "" { return fiber.NewError(fiber.StatusUnauthorized, "missing token header") } claims, err := authService.ValidateAccessToken(tokenString) if err != nil { return fiber.NewError(fiber.StatusUnauthorized, err.Error()) } c.Locals("authClaims", claims) var user models.User if err := dbConn.Select("roles").Where("email = ?", claims.Username).First(&user).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return fiber.NewError(fiber.StatusUnauthorized, "user not found") } return fiber.NewError(fiber.StatusInternalServerError, "failed to load user roles") } // user need to have at least one role that satisfies the permission requirement if user.Roles == nil { return fiber.NewError(fiber.StatusForbidden, "insufficient permissions") } return c.Next() } }