1
0
forked from baron/baron-sso

4단계 역할 정규화 및 dev 권한 스코프 검증 강화

This commit is contained in:
2026-03-04 13:16:34 +09:00
parent 0f8b19a9b1
commit eac16cfcd9
11 changed files with 521 additions and 177 deletions

View File

@@ -82,14 +82,14 @@ func TestDevHandler_Isolation(t *testing.T) {
app.Use(func(c *fiber.Ctx) error {
c.Locals("user_profile", &domain.UserProfileResponse{
ID: "user-a",
Role: domain.RoleUser,
Role: domain.RoleTenantAdmin,
TenantID: &tenantA,
})
return c.Next()
})
app.Get("/api/v1/dev/clients", h.ListClients)
mockKeto.On("CheckPermission", mock.Anything, "user-a", "System", "AppManager", "member").Return(false, nil)
mockKeto.On("CheckPermission", mock.Anything, "user-a", "System", "AppManager", "member").Return(true, nil)
req := httptest.NewRequest(http.MethodGet, "/api/v1/dev/clients", nil)
resp, _ := app.Test(req, -1)
@@ -105,7 +105,7 @@ func TestDevHandler_Isolation(t *testing.T) {
assert.Equal(t, "client-tenant-a", res.Items[0].ID)
})
t.Run("GetClient should enforce tenant isolation", func(t *testing.T) {
t.Run("Tenant member should be forbidden from DevFront clients", func(t *testing.T) {
app := fiber.New()
tenantA := "tenant-a"
app.Use(func(c *fiber.Ctx) error {
@@ -116,6 +116,52 @@ func TestDevHandler_Isolation(t *testing.T) {
})
return c.Next()
})
app.Get("/api/v1/dev/clients", h.ListClients)
req := httptest.NewRequest(http.MethodGet, "/api/v1/dev/clients", nil)
resp, _ := app.Test(req, -1)
assert.Equal(t, http.StatusForbidden, resp.StatusCode)
})
t.Run("RP Admin should only see managed clients", func(t *testing.T) {
app := fiber.New()
tenantA := "tenant-a"
app.Use(func(c *fiber.Ctx) error {
c.Locals("user_profile", &domain.UserProfileResponse{
ID: "rp-admin-a",
Role: domain.RoleRPAdmin,
TenantID: &tenantA,
Metadata: map[string]any{
"managed_client_ids": []any{"client-tenant-a"},
},
})
return c.Next()
})
app.Get("/api/v1/dev/clients", h.ListClients)
req := httptest.NewRequest(http.MethodGet, "/api/v1/dev/clients", nil)
resp, _ := app.Test(req, -1)
assert.Equal(t, http.StatusOK, resp.StatusCode)
var res struct {
Items []clientSummary `json:"items"`
}
json.NewDecoder(resp.Body).Decode(&res)
assert.Equal(t, 1, len(res.Items))
assert.Equal(t, "client-tenant-a", res.Items[0].ID)
})
t.Run("GetClient should enforce tenant isolation", func(t *testing.T) {
app := fiber.New()
tenantA := "tenant-a"
app.Use(func(c *fiber.Ctx) error {
c.Locals("user_profile", &domain.UserProfileResponse{
ID: "user-a",
Role: domain.RoleTenantAdmin,
TenantID: &tenantA,
})
return c.Next()
})
app.Get("/api/v1/dev/clients/:id", h.GetClient)
// Case 1: Same tenant
@@ -135,7 +181,7 @@ func TestDevHandler_Isolation(t *testing.T) {
app.Use(func(c *fiber.Ctx) error {
c.Locals("user_profile", &domain.UserProfileResponse{
ID: "user-a",
Role: domain.RoleUser,
Role: domain.RoleTenantAdmin,
TenantID: &tenantA,
})
return c.Next()