Resource permissions: Fix permission cleanup during resource permission update (#111317)
* fix permission cleanup during resource permission update * fix template tests
This commit is contained in:
@@ -57,8 +57,9 @@ type ListResourcePermissionsQuery struct {
|
||||
}
|
||||
|
||||
type DeleteResourcePermissionsQuery struct {
|
||||
Scope string
|
||||
OrgID int64
|
||||
Scope string
|
||||
OrgID int64
|
||||
RoleName string
|
||||
}
|
||||
|
||||
type rbacAssignmentCreate struct {
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
DELETE FROM {{ .Ident .PermissionTable }} AS p
|
||||
WHERE p.scope = {{ .Arg .Scope }} AND p.action = {{ .Arg .Action }}
|
||||
AND p.role_id = (
|
||||
SELECT r.id
|
||||
FROM {{ .Ident .RoleTable }} AS r
|
||||
WHERE r.org_id = {{ .Arg .OrgID }}
|
||||
AND r.name = {{ .Arg .RoleName }}
|
||||
LIMIT 1
|
||||
)
|
||||
+6
-2
@@ -3,6 +3,10 @@ WHERE p.scope = {{ .Arg .Query.Scope }}
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM {{ .Ident .RoleTable }} as r
|
||||
WHERE r.name LIKE {{ .Arg .ManagedRolePattern }}
|
||||
AND r.org_id = {{ .Arg .Query.OrgID }}
|
||||
WHERE r.org_id = {{ .Arg .Query.OrgID }}
|
||||
{{ if .RoleName }}
|
||||
AND r.name = {{ .Arg .RoleName }}
|
||||
{{ else }}
|
||||
AND r.name LIKE {{ .Arg .ManagedRolePattern }}
|
||||
{{ end }}
|
||||
)
|
||||
|
||||
@@ -427,7 +427,13 @@ func (s *ResourcePermSqlBackend) updateResourcePermission(ctx context.Context, d
|
||||
}
|
||||
|
||||
for _, perm := range permsToRemove {
|
||||
removePermQuery, args, err := buildRemovePermissionQuery(dbHelper, perm.Scope, perm.Action, perm.RoleName, ns.OrgID)
|
||||
resourceQuery := &DeleteResourcePermissionsQuery{
|
||||
Scope: perm.Scope,
|
||||
OrgID: ns.OrgID,
|
||||
RoleName: perm.RoleName,
|
||||
}
|
||||
|
||||
removePermQuery, args, err := buildDeleteResourcePermissionsQueryFromTemplate(dbHelper, resourceQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -192,6 +192,20 @@ func setupTestRoles(t *testing.T, store db.DB) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func setupFineGrainedPermissions(t *testing.T, store db.DB) {
|
||||
sess := store.GetSqlxSession()
|
||||
|
||||
// Permissions
|
||||
_, err := sess.Exec(context.Background(),
|
||||
`INSERT INTO permission (role_id, action, scope, created, updated)
|
||||
VALUES (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)`,
|
||||
// Permissions for managed:users:2:permissions
|
||||
2, "folders:read", "folders:uid:fold1", "2025-09-02", "2025-09-02",
|
||||
2, "folders:create", "folders:uid:fold1", "2025-09-02", "2025-09-02",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestIntegration_ResourcePermSqlBackend_newRoleIterator(t *testing.T) {
|
||||
testutil.SkipIntegrationTestInShortMode(t)
|
||||
|
||||
@@ -505,6 +519,7 @@ func TestIntegration_ResourcePermSqlBackend_UpdateResourcePermission(t *testing.
|
||||
sql, err := backend.dbProvider(ctx)
|
||||
require.NoError(t, err)
|
||||
setupTestRoles(t, sql.DB)
|
||||
setupFineGrainedPermissions(t, sql.DB)
|
||||
|
||||
t.Run("should fail to update resource permission for a resource that doesn't have any permissions yet", func(t *testing.T) {
|
||||
resourcePerm := &v0alpha1.ResourcePermission{
|
||||
|
||||
@@ -23,7 +23,6 @@ var (
|
||||
roleInsertTplt = mustTemplate("role_insert.sql")
|
||||
assignmentInsertTplt = mustTemplate("assignment_insert.sql")
|
||||
permissionInsertTplt = mustTemplate("permission_insert.sql")
|
||||
permissionRemoveTplt = mustTemplate("permission_remove.sql")
|
||||
pageQueryTplt = mustTemplate("page_query.sql")
|
||||
latestUpdateTplt = mustTemplate("latest_update_query.sql")
|
||||
)
|
||||
@@ -231,43 +230,13 @@ func buildInsertPermissionQuery(dbHelper *legacysql.LegacyDatabaseHelper, roleID
|
||||
return rawQuery, req.GetArgs(), nil
|
||||
}
|
||||
|
||||
type removePermissionTemplate struct {
|
||||
sqltemplate.SQLTemplate
|
||||
PermissionTable string
|
||||
RoleTable string
|
||||
Scope string
|
||||
Action string
|
||||
OrgID int64
|
||||
RoleName string
|
||||
}
|
||||
|
||||
func (t removePermissionTemplate) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildRemovePermissionQuery(dbHelper *legacysql.LegacyDatabaseHelper, scope, action, roleName string, orgID int64) (string, []any, error) {
|
||||
req := removePermissionTemplate{
|
||||
SQLTemplate: sqltemplate.New(dbHelper.DialectForDriver()),
|
||||
PermissionTable: dbHelper.Table("permission"),
|
||||
RoleTable: dbHelper.Table("role"),
|
||||
Scope: scope,
|
||||
Action: action,
|
||||
OrgID: orgID,
|
||||
RoleName: roleName,
|
||||
}
|
||||
rawQuery, err := sqltemplate.Execute(permissionRemoveTplt, req)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("rendering sql template: %w", err)
|
||||
}
|
||||
return rawQuery, req.GetArgs(), nil
|
||||
}
|
||||
|
||||
type deleteResourcePermissionsQueryTemplate struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *DeleteResourcePermissionsQuery
|
||||
PermissionTable string
|
||||
RoleTable string
|
||||
ManagedRolePattern string
|
||||
RoleName string
|
||||
}
|
||||
|
||||
func (r deleteResourcePermissionsQueryTemplate) Validate() error {
|
||||
@@ -283,6 +252,10 @@ func buildDeleteResourcePermissionsQueryFromTemplate(sql *legacysql.LegacyDataba
|
||||
ManagedRolePattern: "managed:%",
|
||||
}
|
||||
|
||||
if query.RoleName != "" {
|
||||
req.RoleName = query.RoleName
|
||||
}
|
||||
|
||||
rawQuery, err := sqltemplate.Execute(resourcePermissionDeletionQueryTplt, req)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("execute template %q: %w", resourcePermissionDeletionQueryTplt.Name(), err)
|
||||
|
||||
@@ -43,20 +43,6 @@ func TestTemplates(t *testing.T) {
|
||||
return &v
|
||||
}
|
||||
|
||||
getRemovePermission := func(scope, action, roleName string) sqltemplate.SQLTemplate {
|
||||
v := removePermissionTemplate{
|
||||
SQLTemplate: sqltemplate.New(nodb.DialectForDriver()),
|
||||
PermissionTable: nodb.Table("permission"),
|
||||
RoleTable: nodb.Table("role"),
|
||||
Scope: scope,
|
||||
Action: action,
|
||||
OrgID: 55,
|
||||
RoleName: roleName,
|
||||
}
|
||||
v.SQLTemplate = mocks.NewTestingSQLTemplate()
|
||||
return &v
|
||||
}
|
||||
|
||||
getInsertAssignment := func(orgID int64, roleID int64, assignment rbacAssignmentCreate) sqltemplate.SQLTemplate {
|
||||
v := insertAssignmentTemplate{
|
||||
SQLTemplate: sqltemplate.New(nodb.DialectForDriver()),
|
||||
@@ -120,6 +106,7 @@ func TestTemplates(t *testing.T) {
|
||||
PermissionTable: nodb.Table("permission"),
|
||||
RoleTable: nodb.Table("role"),
|
||||
ManagedRolePattern: "managed:%",
|
||||
RoleName: q.RoleName,
|
||||
}
|
||||
v.SQLTemplate = mocks.NewTestingSQLTemplate()
|
||||
return &v
|
||||
@@ -151,12 +138,6 @@ func TestTemplates(t *testing.T) {
|
||||
}),
|
||||
},
|
||||
},
|
||||
permissionRemoveTplt: {
|
||||
{
|
||||
Name: "remove_permission",
|
||||
Data: getRemovePermission("folders:uid:folder1", "folders:edit", "managed:users:1:permissions"),
|
||||
},
|
||||
},
|
||||
assignmentInsertTplt: {
|
||||
{
|
||||
Name: "insert user assignment",
|
||||
@@ -220,6 +201,14 @@ func TestTemplates(t *testing.T) {
|
||||
OrgID: 3,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: "specific_role_cleanup_query",
|
||||
Data: getDeleteResourcePermissionsQuery(&DeleteResourcePermissionsQuery{
|
||||
Scope: "dash_123",
|
||||
OrgID: 3,
|
||||
RoleName: "managed:users:1:permissions",
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
DELETE FROM `grafana`.`permission` AS p
|
||||
WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit'
|
||||
AND p.role_id = (
|
||||
SELECT r.id
|
||||
FROM `grafana`.`role` AS r
|
||||
WHERE r.org_id = 55
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
LIMIT 1
|
||||
)
|
||||
+2
-2
@@ -3,6 +3,6 @@ WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM `grafana`.`role` as r
|
||||
WHERE r.name LIKE 'managed:%'
|
||||
AND r.org_id = 3
|
||||
WHERE r.org_id = 3
|
||||
AND r.name LIKE 'managed:%'
|
||||
)
|
||||
|
||||
Vendored
Executable
+8
@@ -0,0 +1,8 @@
|
||||
DELETE FROM `grafana`.`permission` as p
|
||||
WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM `grafana`.`role` as r
|
||||
WHERE r.org_id = 3
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
)
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
DELETE FROM "grafana"."permission" AS p
|
||||
WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit'
|
||||
AND p.role_id = (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" AS r
|
||||
WHERE r.org_id = 55
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
LIMIT 1
|
||||
)
|
||||
+2
-2
@@ -3,6 +3,6 @@ WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" as r
|
||||
WHERE r.name LIKE 'managed:%'
|
||||
AND r.org_id = 3
|
||||
WHERE r.org_id = 3
|
||||
AND r.name LIKE 'managed:%'
|
||||
)
|
||||
|
||||
Vendored
Executable
+8
@@ -0,0 +1,8 @@
|
||||
DELETE FROM "grafana"."permission" as p
|
||||
WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" as r
|
||||
WHERE r.org_id = 3
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
)
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
DELETE FROM "grafana"."permission" AS p
|
||||
WHERE p.scope = 'folders:uid:folder1' AND p.action = 'folders:edit'
|
||||
AND p.role_id = (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" AS r
|
||||
WHERE r.org_id = 55
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
LIMIT 1
|
||||
)
|
||||
+2
-2
@@ -3,6 +3,6 @@ WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" as r
|
||||
WHERE r.name LIKE 'managed:%'
|
||||
AND r.org_id = 3
|
||||
WHERE r.org_id = 3
|
||||
AND r.name LIKE 'managed:%'
|
||||
)
|
||||
|
||||
Vendored
Executable
+8
@@ -0,0 +1,8 @@
|
||||
DELETE FROM "grafana"."permission" as p
|
||||
WHERE p.scope = 'dash_123'
|
||||
AND p.role_id IN (
|
||||
SELECT r.id
|
||||
FROM "grafana"."role" as r
|
||||
WHERE r.org_id = 3
|
||||
AND r.name = 'managed:users:1:permissions'
|
||||
)
|
||||
Reference in New Issue
Block a user