mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-07-14 07:57:26 +02:00
121 lines
3.3 KiB
Go
121 lines
3.3 KiB
Go
package security
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"cyberstrike-ai/internal/database"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestRBACMiddlewareUsesMatchedFullPath(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.Use(func(c *gin.Context) {
|
|
c.Set(ContextSessionKey, Session{
|
|
UserID: "u1",
|
|
Username: "operator",
|
|
Permissions: map[string]bool{"project:read": true},
|
|
Scope: database.RBACScopeAll,
|
|
})
|
|
c.Next()
|
|
})
|
|
router.Use(RBACMiddleware(nil))
|
|
router.GET("/api/projects/:id", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
})
|
|
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/projects/p1", nil)
|
|
router.ServeHTTP(w, req)
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d: %s", w.Code, http.StatusOK, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestRBACMiddlewareRejectsMissingPermission(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.Use(func(c *gin.Context) {
|
|
c.Set(ContextSessionKey, Session{
|
|
UserID: "u1",
|
|
Username: "viewer",
|
|
Permissions: map[string]bool{"project:read": true},
|
|
Scope: database.RBACScopeAll,
|
|
})
|
|
c.Next()
|
|
})
|
|
router.Use(RBACMiddleware(nil))
|
|
router.POST("/api/projects", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
})
|
|
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodPost, "/api/projects", nil)
|
|
router.ServeHTTP(w, req)
|
|
if w.Code != http.StatusForbidden {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusForbidden)
|
|
}
|
|
}
|
|
|
|
func TestRBACMiddlewareRejectsUnmappedProtectedRoute(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.Use(func(c *gin.Context) {
|
|
c.Set(ContextSessionKey, Session{
|
|
UserID: "u1",
|
|
Username: "admin",
|
|
Permissions: allPermissions(),
|
|
Scope: database.RBACScopeAll,
|
|
})
|
|
c.Next()
|
|
})
|
|
router.Use(RBACMiddleware(nil))
|
|
router.GET("/api/new-module", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
})
|
|
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/new-module", nil)
|
|
router.ServeHTTP(w, req)
|
|
if w.Code != http.StatusForbidden {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusForbidden)
|
|
}
|
|
}
|
|
|
|
func TestRBACMiddlewareMapsOpenAPISpec(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.Use(func(c *gin.Context) {
|
|
c.Set(ContextSessionKey, Session{
|
|
UserID: "u1",
|
|
Username: "viewer",
|
|
Permissions: map[string]bool{"openapi:read": true},
|
|
Scope: database.RBACScopeAll,
|
|
})
|
|
c.Next()
|
|
})
|
|
router.Use(RBACMiddleware(nil))
|
|
router.GET("/api/openapi/spec", func(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"ok": true})
|
|
})
|
|
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/openapi/spec", nil)
|
|
router.ServeHTTP(w, req)
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d: %s", w.Code, http.StatusOK, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestRBACResourcePickerRequiresWritePermission(t *testing.T) {
|
|
if got := permissionForRequest(http.MethodGet, "/api/rbac/resources"); got != "rbac:write" {
|
|
t.Fatalf("picker permission = %q, want rbac:write", got)
|
|
}
|
|
if got := permissionForRequest(http.MethodGet, "/api/rbac/resource-assignments"); got != "rbac:read" {
|
|
t.Fatalf("assignment list permission = %q, want rbac:read", got)
|
|
}
|
|
}
|