mirror of https://github.com/veypi/OneAuth.git
test: Update tests for scoped RBAC and remove org tests
- Remove org-related test cases from edge_case_test.go
- Remove OrgResp type from main_test.go
- Update none_auth_test removing org endpoints
- Add permission grants in OAuth tests for proper access control
- Fix race condition tests with retry logic for SQLite locking
- Update resource_perm_test to accept 401 or 403 status codes
- Add new role_access_test.go for role API permission testing
- Add new scoped_auth_test.go for scoped permission testing
master
parent
b378c3c5c4
commit
56d87ec18a
@ -0,0 +1,54 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/veypi/vbase/auth"
|
||||||
|
"github.com/veypi/vbase/cfg"
|
||||||
|
"github.com/veypi/vbase/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRoleApiAccess(t *testing.T) {
|
||||||
|
ensureUsers(t)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Ensure Admin has * permission
|
||||||
|
// Clean up any previous permissions for Admin
|
||||||
|
cfg.DB().Where("user_id = ?", AdminID).Delete(&models.Permission{})
|
||||||
|
|
||||||
|
// Grant Admin * permission
|
||||||
|
if err := auth.VBaseAuth.Grant(ctx, AdminID, "*", auth.LevelAdmin); err != nil {
|
||||||
|
t.Fatalf("Failed to grant admin permission: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Admin Access (Wildcard *)
|
||||||
|
t.Run("Admin_Access_Role_List", func(t *testing.T) {
|
||||||
|
resp := doRequest(t, "GET", "/api/roles", nil, AdminToken)
|
||||||
|
assertStatus(t, resp, 200)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. User Access (No Permission)
|
||||||
|
t.Run("User_NoAccess_Role_List", func(t *testing.T) {
|
||||||
|
// Ensure User1 has NO role:* permission
|
||||||
|
cfg.DB().Where("user_id = ?", User1ID).Delete(&models.Permission{})
|
||||||
|
|
||||||
|
resp := doRequest(t, "GET", "/api/roles", nil, User1Token)
|
||||||
|
// Should be 403 or 401
|
||||||
|
if resp.Code != 403 && resp.Code != 401 {
|
||||||
|
t.Errorf("Expected 403/401, got %d", resp.Code)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 3. User Access (With Permission)
|
||||||
|
t.Run("User_WithPermission_Role_List", func(t *testing.T) {
|
||||||
|
// Grant role:* (Read) to User1
|
||||||
|
if err := auth.VBaseAuth.Grant(ctx, User1ID, "role:*", auth.LevelRead); err != nil {
|
||||||
|
t.Fatalf("Failed to grant role permission: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := doRequest(t, "GET", "/api/roles", nil, User1Token)
|
||||||
|
assertStatus(t, resp, 200)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,151 @@
|
|||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/veypi/vbase/auth"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestScopedAuth(t *testing.T) {
|
||||||
|
ensureUsers(t)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// 1. Test Scoped Permission Assignment
|
||||||
|
t.Run("Scoped Permission Assignment", func(t *testing.T) {
|
||||||
|
scope := "test_scope_1"
|
||||||
|
testAuth := auth.Factory.New(scope)
|
||||||
|
|
||||||
|
// Grant 'resource:read' to User1 in test_scope
|
||||||
|
permID := "resource:read"
|
||||||
|
level := auth.LevelRead
|
||||||
|
|
||||||
|
if err := testAuth.Grant(ctx, User1ID, permID, level); err != nil {
|
||||||
|
t.Fatalf("Failed to grant permission: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Check within the same scope
|
||||||
|
if !testAuth.Check(ctx, User1ID, permID, level) {
|
||||||
|
t.Errorf("Expected User1 to have %s in %s scope", permID, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Check in global VBaseAuth scope (should be false)
|
||||||
|
if auth.VBaseAuth.Check(ctx, User1ID, permID, level) {
|
||||||
|
t.Errorf("Expected User1 NOT to have %s in 'vb' scope", permID)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. Test Hierarchy (Admin Inheritance vs Normal Strictness)
|
||||||
|
t.Run("Hierarchy Checks", func(t *testing.T) {
|
||||||
|
scope := "test_scope_2"
|
||||||
|
testAuth := auth.Factory.New(scope)
|
||||||
|
|
||||||
|
// Case A: Normal Level (Read) - Exact Match Only
|
||||||
|
// Grant "project:p1" (Read)
|
||||||
|
if err := testAuth.Grant(ctx, User1ID, "project:p1", auth.LevelRead); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Exact Match -> Should Pass
|
||||||
|
if !testAuth.Check(ctx, User1ID, "project:p1", auth.LevelRead) {
|
||||||
|
t.Error("Exact match 'project:p1' failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Child "project:p1:task:t1" -> Should Fail (Normal levels don't inherit downwards)
|
||||||
|
if testAuth.Check(ctx, User1ID, "project:p1:task:t1", auth.LevelRead) {
|
||||||
|
t.Error("Normal level 'project:p1' should NOT imply 'project:p1:task:t1'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case B: Admin Level - Downward Inheritance
|
||||||
|
// Grant "org:o1" (Admin)
|
||||||
|
if err := testAuth.Grant(ctx, User1ID, "org:o1", auth.LevelAdmin); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Child "org:o1:project:p2" -> Should Pass
|
||||||
|
if !testAuth.Check(ctx, User1ID, "org:o1:project:p2", auth.LevelRead) {
|
||||||
|
t.Error("Admin level 'org:o1' SHOULD imply 'org:o1:project:p2'")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Wildcard "*" (Admin)
|
||||||
|
if err := testAuth.Grant(ctx, User1ID, "*", auth.LevelAdmin); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// Should have access to everything
|
||||||
|
if !testAuth.Check(ctx, User1ID, "anything:anywhere", auth.LevelAdmin) {
|
||||||
|
t.Error("Wildcard '*' should grant access to everything")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 3. Test ListResources
|
||||||
|
t.Run("ListResources", func(t *testing.T) {
|
||||||
|
scope := "test_scope_3"
|
||||||
|
testAuth := auth.Factory.New(scope)
|
||||||
|
|
||||||
|
// Setup:
|
||||||
|
// User1 has:
|
||||||
|
// - project:p1 (Read)
|
||||||
|
// - project:p2:task:t1 (Write) -> Should imply project:p2 (Read)
|
||||||
|
// - project:p3 (Admin)
|
||||||
|
|
||||||
|
testAuth.Grant(ctx, User1ID, "project:p1", auth.LevelRead)
|
||||||
|
testAuth.Grant(ctx, User1ID, "project:p2:task:t1", auth.LevelWrite)
|
||||||
|
testAuth.Grant(ctx, User1ID, "project:p3", auth.LevelAdmin)
|
||||||
|
|
||||||
|
resources, err := testAuth.ListResources(ctx, User1ID, "project")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ListResources failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check p1
|
||||||
|
if l, ok := resources["p1"]; !ok || l != auth.LevelRead {
|
||||||
|
t.Errorf("Expected p1: %d, got %v", auth.LevelRead, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check p2 (Implication from child)
|
||||||
|
if l, ok := resources["p2"]; !ok || l != auth.LevelRead {
|
||||||
|
t.Errorf("Expected p2: %d (implied read), got %v", auth.LevelRead, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check p3
|
||||||
|
if l, ok := resources["p3"]; !ok || l != auth.LevelAdmin {
|
||||||
|
t.Errorf("Expected p3: %d, got %v", auth.LevelAdmin, l)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 4. Test ListUsers
|
||||||
|
t.Run("ListUsers", func(t *testing.T) {
|
||||||
|
scope := "test_scope_4"
|
||||||
|
testAuth := auth.Factory.New(scope)
|
||||||
|
|
||||||
|
// Setup:
|
||||||
|
// User1 has group:g1:project:p1 (Read)
|
||||||
|
// User2 has group:g1:project:p1 (Admin)
|
||||||
|
// User3 has group:g1 (Admin) -> Parent Admin (Valid even depth)
|
||||||
|
// User4 has group:g1:project:p1:task:t1 (Read) -> Child
|
||||||
|
|
||||||
|
testAuth.Grant(ctx, User1ID, "group:g1:project:p1", auth.LevelRead)
|
||||||
|
testAuth.Grant(ctx, User2ID, "group:g1:project:p1", auth.LevelAdmin)
|
||||||
|
testAuth.Grant(ctx, AdminID, "group:g1", auth.LevelAdmin) // Parent (depth 2)
|
||||||
|
testAuth.Grant(ctx, "user4", "group:g1:project:p1:task:t1", auth.LevelRead)
|
||||||
|
|
||||||
|
users, err := testAuth.ListUsers(ctx, "group:g1:project:p1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ListUsers failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if users[User1ID] != auth.LevelRead {
|
||||||
|
t.Errorf("Expected User1: Read, got %v", users[User1ID])
|
||||||
|
}
|
||||||
|
if users[User2ID] != auth.LevelAdmin {
|
||||||
|
t.Errorf("Expected User2: Admin, got %v", users[User2ID])
|
||||||
|
}
|
||||||
|
if users[AdminID] != auth.LevelAdmin {
|
||||||
|
t.Errorf("Expected Admin: Admin (inherited), got %v", users[AdminID])
|
||||||
|
}
|
||||||
|
if _, ok := users["user4"]; ok {
|
||||||
|
t.Error("User4 should NOT appear in ListUsers('group:g1:project:p1')")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue