diff --git a/pkg/services/accesscontrol/actest/common.go b/pkg/services/accesscontrol/actest/common.go index 6be44a69119..c5c95462f51 100644 --- a/pkg/services/accesscontrol/actest/common.go +++ b/pkg/services/accesscontrol/actest/common.go @@ -116,7 +116,7 @@ func AddUserPermissionToDB(t testing.TB, db db.DB, user *user.SignedInUser) { p := accesscontrol.Permission{ RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now(), } - //p.Kind, p.Attribute, p.Identifier = p.SplitScope() + p.Kind, p.Attribute, p.Identifier = p.SplitScope() permissions = append(permissions, p) } diff --git a/pkg/services/annotations/testutil/testutil.go b/pkg/services/annotations/testutil/testutil.go index 40bd57b614d..2e24e3a2c9b 100644 --- a/pkg/services/annotations/testutil/testutil.go +++ b/pkg/services/annotations/testutil/testutil.go @@ -60,9 +60,9 @@ func SetupRBACPermission(t *testing.T, db *sqlstore.SQLStore, role *accesscontro var acPermission []accesscontrol.Permission for action, scopes := range user.Permissions[user.OrgID] { for _, scope := range scopes { - acPermission = append(acPermission, accesscontrol.Permission{ - RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now(), - }) + p := accesscontrol.Permission{RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now()} + p.Kind, p.Attribute, p.Identifier = p.SplitScope() + acPermission = append(acPermission, p) } } diff --git a/pkg/services/sqlstore/permissions/dashboard.go b/pkg/services/sqlstore/permissions/dashboard.go index 1f8bee79bd1..a91f2ff9103 100644 --- a/pkg/services/sqlstore/permissions/dashboard.go +++ b/pkg/services/sqlstore/permissions/dashboard.go @@ -148,7 +148,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { if len(toCheck) > 0 { if !useSelfContainedPermissions { - builder.WriteString("(dashboard.uid IN (SELECT substr(scope, 16) FROM permission WHERE scope LIKE 'dashboards:uid:%'") + builder.WriteString("(dashboard.uid IN (SELECT identifier FROM permission WHERE kind = 'dashboards' AND attribute = 'uid'") builder.WriteString(rolesFilter) args = append(args, params...) @@ -156,7 +156,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { builder.WriteString(" AND action = ?") args = append(args, toCheck[0]) } else { - builder.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + builder.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") args = append(args, toCheck...) args = append(args, len(toCheck)) } @@ -178,7 +178,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { builder.WriteString(" OR ") if !useSelfContainedPermissions { - permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%' ") + permSelector.WriteString("(SELECT identifier FROM permission WHERE kind = 'folders' AND attribute = 'uid'") permSelector.WriteString(rolesFilter) permSelectorArgs = append(permSelectorArgs, params...) @@ -186,7 +186,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { permSelector.WriteString(" AND action = ?") permSelectorArgs = append(permSelectorArgs, toCheck[0]) } else { - permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") permSelectorArgs = append(permSelectorArgs, toCheck...) permSelectorArgs = append(permSelectorArgs, len(toCheck)) } @@ -258,14 +258,14 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards) if len(toCheck) > 0 { if !useSelfContainedPermissions { - permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%'") + permSelector.WriteString("(SELECT identifier FROM permission WHERE kind = 'folders' AND attribute = 'uid'") permSelector.WriteString(rolesFilter) permSelectorArgs = append(permSelectorArgs, params...) if len(toCheck) == 1 { permSelector.WriteString(" AND action = ?") permSelectorArgs = append(permSelectorArgs, toCheck[0]) } else { - permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") permSelectorArgs = append(permSelectorArgs, toCheck...) permSelectorArgs = append(permSelectorArgs, len(toCheck)) } diff --git a/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go b/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go index f2b5f432d71..120b432a57e 100644 --- a/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go +++ b/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go @@ -59,7 +59,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() if len(toCheck) > 0 { if !useSelfContainedPermissions { - builder.WriteString("(dashboard.uid IN (SELECT substr(scope, 16) FROM permission WHERE scope LIKE 'dashboards:uid:%'") + builder.WriteString("(dashboard.uid IN (SELECT identifier FROM permission WHERE kind = 'dashboards' AND attribute = 'uid'") builder.WriteString(rolesFilter) args = append(args, params...) @@ -67,7 +67,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() builder.WriteString(" AND action = ?") args = append(args, toCheck[0]) } else { - builder.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + builder.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") args = append(args, toCheck...) args = append(args, len(toCheck)) } @@ -89,7 +89,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() builder.WriteString(" OR ") if !useSelfContainedPermissions { - permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%' ") + permSelector.WriteString("(SELECT identifier FROM permission WHERE kind = 'folders' AND attribute = 'uid'") permSelector.WriteString(rolesFilter) permSelectorArgs = append(permSelectorArgs, params...) @@ -97,7 +97,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() permSelector.WriteString(" AND action = ?") permSelectorArgs = append(permSelectorArgs, toCheck[0]) } else { - permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") permSelectorArgs = append(permSelectorArgs, toCheck...) permSelectorArgs = append(permSelectorArgs, len(toCheck)) } @@ -169,14 +169,14 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards) if len(toCheck) > 0 { if !useSelfContainedPermissions { - permSelector.WriteString("(SELECT substr(scope, 13) FROM permission WHERE scope LIKE 'folders:uid:%'") + permSelector.WriteString("(SELECT identifier FROM permission WHERE kind = 'folders' AND attribute = 'uid'") permSelector.WriteString(rolesFilter) permSelectorArgs = append(permSelectorArgs, params...) if len(toCheck) == 1 { permSelector.WriteString(" AND action = ?") permSelectorArgs = append(permSelectorArgs, toCheck[0]) } else { - permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope HAVING COUNT(action) = ?") + permSelector.WriteString(" AND action IN (?" + strings.Repeat(", ?", len(toCheck)-1) + ") GROUP BY role_id, scope, identifier HAVING COUNT(action) = ?") permSelectorArgs = append(permSelectorArgs, toCheck...) permSelectorArgs = append(permSelectorArgs, len(toCheck)) } diff --git a/pkg/services/sqlstore/permissions/dashboard_test.go b/pkg/services/sqlstore/permissions/dashboard_test.go index a586e78b052..48613ab14cd 100644 --- a/pkg/services/sqlstore/permissions/dashboard_test.go +++ b/pkg/services/sqlstore/permissions/dashboard_test.go @@ -80,12 +80,12 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { desc: "Should be able to view a subset of dashboards with dashboard scopes", permission: dashboardaccess.PERMISSION_VIEW, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:110"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:40"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:22"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:13"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:55"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:99"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:110", Kind: "dashboards", Identifier: "110"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:40", Kind: "dashboards", Identifier: "40"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:22", Kind: "dashboards", Identifier: "22"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:13", Kind: "dashboards", Identifier: "13"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:55", Kind: "dashboards", Identifier: "55"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:99", Kind: "dashboards", Identifier: "99"}, }, expectedResult: 6, }, @@ -101,9 +101,9 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { desc: "Should be able to view a subset folders", permission: dashboardaccess.PERMISSION_VIEW, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:6"}, - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:9"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:6", Kind: "folders", Identifier: "6"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:9", Kind: "folders", Identifier: "9"}, }, expectedResult: 3, }, @@ -111,10 +111,10 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { desc: "Should return folders and dashboard with 'edit' permission", permission: dashboardaccess.PERMISSION_EDIT, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, - {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, - {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"}, + {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"}, }, expectedResult: 2, }, @@ -122,11 +122,11 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { desc: "Should return the dashboards that the User has dashboards:write permission on in case of 'edit' permission", permission: dashboardaccess.PERMISSION_EDIT, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:31"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, - {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:31", Kind: "dashboards", Identifier: "31"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32", Kind: "dashboards", Identifier: "32"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"}, + {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"}, }, expectedResult: 1, }, @@ -134,11 +134,11 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { desc: "Should return the folders that the User has dashboards:create permission on in case of 'edit' permission", permission: dashboardaccess.PERMISSION_EDIT, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, - {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3"}, - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:4"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32"}, - {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:4", Kind: "folders", Identifier: "4"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32", Kind: "dashboards", Identifier: "32"}, + {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"}, }, expectedResult: 1, }, @@ -147,10 +147,10 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { permission: dashboardaccess.PERMISSION_VIEW, queryType: searchstore.TypeAlertFolder, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, - {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3"}, - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:8"}, - {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"}, + {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"}, }, expectedResult: 2, }, @@ -160,8 +160,8 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { queryType: searchstore.TypeAlertFolder, permissions: []accesscontrol.Permission{ {Action: dashboards.ActionFoldersRead, Scope: "*"}, - {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3"}, - {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8"}, + {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"}, + {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"}, }, expectedResult: 2, }, @@ -423,7 +423,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) { queryType: searchstore.TypeFolder, permission: dashboardaccess.PERMISSION_VIEW, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent", Kind: "folders", Identifier: "parent"}, }, features: []any{featuremgmt.FlagNestedFolders}, expectedResult: []string{"parent", "subfolder"}, @@ -433,7 +433,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) { queryType: searchstore.TypeFolder, permission: dashboardaccess.PERMISSION_VIEW, permissions: []accesscontrol.Permission{ - {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"}, + {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent", Kind: "folders", Identifier: "parent"}, }, features: []any{}, expectedResult: []string{"parent"}, @@ -678,6 +678,7 @@ func setupTest(t *testing.T, numFolders, numDashboards int, permissions []access permissions[i].RoleID = role.ID permissions[i].Created = time.Now() permissions[i].Updated = time.Now() + permissions[i].Kind, permissions[i].Attribute, permissions[i].Identifier = permissions[i].SplitScope() } if len(permissions) > 0 { _, err = sess.InsertMulti(&permissions) @@ -769,6 +770,7 @@ func setupNestedTest(t *testing.T, usr *user.SignedInUser, perms []accesscontrol perms[i].RoleID = role.ID perms[i].Created = time.Now() perms[i].Updated = time.Now() + perms[i].Kind, perms[i].Attribute, perms[i].Identifier = perms[i].SplitScope() } if len(perms) > 0 { _, err = sess.InsertMulti(&perms)