Files
user-system/internal/api/middleware/rbac_test.go

115 lines
3.1 KiB
Go

package middleware
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func performRBACRequest(t *testing.T, setup func(*gin.Context), middleware gin.HandlerFunc) *httptest.ResponseRecorder {
t.Helper()
gin.SetMode(gin.TestMode)
recorder := httptest.NewRecorder()
router := gin.New()
if setup != nil {
router.Use(setup)
}
router.Use(middleware)
router.GET("/protected", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"code": 0})
})
req := httptest.NewRequest(http.MethodGet, "/protected", nil)
router.ServeHTTP(recorder, req)
return recorder
}
func TestRequirePermissionRejectsMissingPermission(t *testing.T) {
recorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyPermissionCodes, []string{"users:read"})
c.Next()
}, RequirePermission("users:write"))
if recorder.Code != http.StatusForbidden {
t.Fatalf("expected 403, got %d", recorder.Code)
}
}
func TestRequirePermissionAllowsMatchingPermission(t *testing.T) {
recorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyPermissionCodes, []string{"users:read"})
c.Next()
}, RequirePermission("users:read"))
if recorder.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", recorder.Code)
}
}
func TestRequireAllPermissionsRequiresEveryCode(t *testing.T) {
recorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyPermissionCodes, []string{"users:read"})
c.Next()
}, RequireAllPermissions("users:read", "users:write"))
if recorder.Code != http.StatusForbidden {
t.Fatalf("expected 403, got %d", recorder.Code)
}
}
func TestRequireAnyPermissionIsAliasOfRequirePermission(t *testing.T) {
recorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyPermissionCodes, []string{"users:write"})
c.Next()
}, RequireAnyPermission("users:read", "users:write"))
if recorder.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", recorder.Code)
}
}
func TestRequireRoleAndAdminOnly(t *testing.T) {
roleRecorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyRoleCodes, []string{"auditor"})
c.Next()
}, RequireRole("admin"))
if roleRecorder.Code != http.StatusForbidden {
t.Fatalf("expected role check to return 403, got %d", roleRecorder.Code)
}
adminRecorder := performRBACRequest(t, func(c *gin.Context) {
c.Set(ContextKeyRoleCodes, []string{"admin"})
c.Next()
}, AdminOnly())
if adminRecorder.Code != http.StatusOK {
t.Fatalf("expected admin check to return 200, got %d", adminRecorder.Code)
}
}
func TestRBACHelpersHandleMissingContextValues(t *testing.T) {
gin.SetMode(gin.TestMode)
recorder := httptest.NewRecorder()
c, _ := gin.CreateTestContext(recorder)
c.Request = httptest.NewRequest(http.MethodGet, "/protected", nil)
if got := GetRoleCodes(c); got != nil {
t.Fatalf("GetRoleCodes() = %#v, want nil", got)
}
if got := GetPermissionCodes(c); got != nil {
t.Fatalf("GetPermissionCodes() = %#v, want nil", got)
}
if IsAdmin(c) {
t.Fatal("IsAdmin() = true, want false")
}
c.Set(ContextKeyRoleCodes, []string{"admin"})
c.Set(ContextKeyPermissionCodes, []string{"users:read"})
if !IsAdmin(c) {
t.Fatal("IsAdmin() = false, want true")
}
}