package middleware // Reference: P2E ยง2.9 โ€” SuperAdmin middleware // Middleware that verifies the user is a super_admin (platform-level administrator). // Corresponds to Chatwoot's SuperAdmin access control for platform management endpoints. import ( "net/http" "github.com/gin-gonic/gin" "github.com/gochat/gochat/internal/auth" "github.com/gochat/gochat/pkg/response" ) // SuperAdmin creates a middleware that verifies the current user has super_admin type. // Super admins are platform-level administrators that can manage all accounts, // platform apps, and system configuration. // // This checks the user's type field (not the account-level role). // user.type = "super_admin" is set at the User model level, not AccountUser. // // Usage: // router.GET("/platform/accounts", SuperAdmin(), listAllAccounts) // router.POST("/platform/apps", SuperAdmin(), createPlatformApp) // router.GET("/platform/analytics", SuperAdmin(), viewPlatformAnalytics) func SuperAdmin() gin.HandlerFunc { return func(c *gin.Context) { // Check for super_admin flag in context (set by AuthRequired middleware) userType, exists := c.Get("user_type") if !exists { // No user_type in context โ€” check claims for super_admin indication _, claimsExists := c.Get("auth_claims") if claimsExists { // Claims exist but user_type not set โ€” not super_admin } response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "Super admin access required") return } typeStr, ok := userType.(string) if !ok || typeStr != "super_admin" { response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "Super admin access required. Your account does not have platform administration privileges.") return } // Mark the context as super_admin for downstream handlers c.Set("is_super_admin", true) c.Next() } } // SuperAdminOrAdministrator creates a middleware that allows either super_admin // users or administrators within the current account context. // Useful for endpoints that should be accessible to account admins and platform admins. // // Usage: // router.DELETE("/accounts/:id", SuperAdminOrAdministrator(), deleteAccount) func SuperAdminOrAdministrator() gin.HandlerFunc { return func(c *gin.Context) { // Check super_admin first userType, exists := c.Get("user_type") if exists { typeStr, ok := userType.(string) if ok && typeStr == "super_admin" { c.Set("is_super_admin", true) c.Next() return } } // Check administrator role in policy context pc, exists := c.Get("policy_context") if !exists { response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "Super admin or administrator access required") return } policyCtx, ok := pc.(*auth.PolicyContext) if !ok { response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "Invalid policy context") return } if !policyCtx.IsAdministrator() { response.AbortWithStatusError(c, http.StatusForbidden, response.ErrForbidden, "Super admin or administrator access required") return } c.Next() } }