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:
Ieva
2025-09-19 14:04:05 +01:00
committed by GitHub
parent e69cc03ef9
commit b7bb62747a
16 changed files with 75 additions and 99 deletions
@@ -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
)
@@ -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",
}),
},
},
},
})
@@ -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
)
@@ -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:%'
)
@@ -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'
)
@@ -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
)
@@ -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:%'
)
@@ -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'
)
@@ -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
)
@@ -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:%'
)
@@ -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'
)