Use split scopes instead of substr in search v1 (#82092)

* use split scopes instead of substr in search v1

* tests, of course

* yet, some test helpers dont use split scopes

* another test helper to fix

* add permission.identifier to group by

* check if attribute is uid

* fix tests

* use SplitScope()

* fix more tests
This commit is contained in:
Serge Zaitsev 2024-02-18 22:26:08 +01:00 committed by GitHub
parent 94a274635b
commit 1aff748e8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 49 additions and 47 deletions

View File

@ -116,7 +116,7 @@ func AddUserPermissionToDB(t testing.TB, db db.DB, user *user.SignedInUser) {
p := accesscontrol.Permission{ p := accesscontrol.Permission{
RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now(), 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) permissions = append(permissions, p)
} }

View File

@ -60,9 +60,9 @@ func SetupRBACPermission(t *testing.T, db *sqlstore.SQLStore, role *accesscontro
var acPermission []accesscontrol.Permission var acPermission []accesscontrol.Permission
for action, scopes := range user.Permissions[user.OrgID] { for action, scopes := range user.Permissions[user.OrgID] {
for _, scope := range scopes { for _, scope := range scopes {
acPermission = append(acPermission, accesscontrol.Permission{ p := accesscontrol.Permission{RoleID: role.ID, Action: action, Scope: scope, Created: time.Now(), Updated: time.Now()}
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)
} }
} }

View File

@ -148,7 +148,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
if len(toCheck) > 0 { if len(toCheck) > 0 {
if !useSelfContainedPermissions { 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) builder.WriteString(rolesFilter)
args = append(args, params...) args = append(args, params...)
@ -156,7 +156,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
builder.WriteString(" AND action = ?") builder.WriteString(" AND action = ?")
args = append(args, toCheck[0]) args = append(args, toCheck[0])
} else { } 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, toCheck...)
args = append(args, len(toCheck)) args = append(args, len(toCheck))
} }
@ -178,7 +178,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
builder.WriteString(" OR ") builder.WriteString(" OR ")
if !useSelfContainedPermissions { 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) permSelector.WriteString(rolesFilter)
permSelectorArgs = append(permSelectorArgs, params...) permSelectorArgs = append(permSelectorArgs, params...)
@ -186,7 +186,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
permSelector.WriteString(" AND action = ?") permSelector.WriteString(" AND action = ?")
permSelectorArgs = append(permSelectorArgs, toCheck[0]) permSelectorArgs = append(permSelectorArgs, toCheck[0])
} else { } 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, toCheck...)
permSelectorArgs = append(permSelectorArgs, len(toCheck)) permSelectorArgs = append(permSelectorArgs, len(toCheck))
} }
@ -258,14 +258,14 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() {
toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards) toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards)
if len(toCheck) > 0 { if len(toCheck) > 0 {
if !useSelfContainedPermissions { 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) permSelector.WriteString(rolesFilter)
permSelectorArgs = append(permSelectorArgs, params...) permSelectorArgs = append(permSelectorArgs, params...)
if len(toCheck) == 1 { if len(toCheck) == 1 {
permSelector.WriteString(" AND action = ?") permSelector.WriteString(" AND action = ?")
permSelectorArgs = append(permSelectorArgs, toCheck[0]) permSelectorArgs = append(permSelectorArgs, toCheck[0])
} else { } 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, toCheck...)
permSelectorArgs = append(permSelectorArgs, len(toCheck)) permSelectorArgs = append(permSelectorArgs, len(toCheck))
} }

View File

@ -59,7 +59,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
if len(toCheck) > 0 { if len(toCheck) > 0 {
if !useSelfContainedPermissions { 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) builder.WriteString(rolesFilter)
args = append(args, params...) args = append(args, params...)
@ -67,7 +67,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
builder.WriteString(" AND action = ?") builder.WriteString(" AND action = ?")
args = append(args, toCheck[0]) args = append(args, toCheck[0])
} else { } 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, toCheck...)
args = append(args, len(toCheck)) args = append(args, len(toCheck))
} }
@ -89,7 +89,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
builder.WriteString(" OR ") builder.WriteString(" OR ")
if !useSelfContainedPermissions { 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) permSelector.WriteString(rolesFilter)
permSelectorArgs = append(permSelectorArgs, params...) permSelectorArgs = append(permSelectorArgs, params...)
@ -97,7 +97,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
permSelector.WriteString(" AND action = ?") permSelector.WriteString(" AND action = ?")
permSelectorArgs = append(permSelectorArgs, toCheck[0]) permSelectorArgs = append(permSelectorArgs, toCheck[0])
} else { } 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, toCheck...)
permSelectorArgs = append(permSelectorArgs, len(toCheck)) permSelectorArgs = append(permSelectorArgs, len(toCheck))
} }
@ -169,14 +169,14 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses()
toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards) toCheck := actionsToCheck(f.folderActions, f.user.GetPermissions(), folderWildcards)
if len(toCheck) > 0 { if len(toCheck) > 0 {
if !useSelfContainedPermissions { 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) permSelector.WriteString(rolesFilter)
permSelectorArgs = append(permSelectorArgs, params...) permSelectorArgs = append(permSelectorArgs, params...)
if len(toCheck) == 1 { if len(toCheck) == 1 {
permSelector.WriteString(" AND action = ?") permSelector.WriteString(" AND action = ?")
permSelectorArgs = append(permSelectorArgs, toCheck[0]) permSelectorArgs = append(permSelectorArgs, toCheck[0])
} else { } 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, toCheck...)
permSelectorArgs = append(permSelectorArgs, len(toCheck)) permSelectorArgs = append(permSelectorArgs, len(toCheck))
} }

View File

@ -80,12 +80,12 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) {
desc: "Should be able to view a subset of dashboards with dashboard scopes", desc: "Should be able to view a subset of dashboards with dashboard scopes",
permission: dashboardaccess.PERMISSION_VIEW, permission: dashboardaccess.PERMISSION_VIEW,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:110"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:110", Kind: "dashboards", Identifier: "110"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:40"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:40", Kind: "dashboards", Identifier: "40"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:22"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:22", Kind: "dashboards", Identifier: "22"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:13"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:13", Kind: "dashboards", Identifier: "13"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:55"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:55", Kind: "dashboards", Identifier: "55"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:99"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:99", Kind: "dashboards", Identifier: "99"},
}, },
expectedResult: 6, expectedResult: 6,
}, },
@ -101,9 +101,9 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) {
desc: "Should be able to view a subset folders", desc: "Should be able to view a subset folders",
permission: dashboardaccess.PERMISSION_VIEW, permission: dashboardaccess.PERMISSION_VIEW,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:6"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:6", Kind: "folders", Identifier: "6"},
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:9"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:9", Kind: "folders", Identifier: "9"},
}, },
expectedResult: 3, expectedResult: 3,
}, },
@ -111,10 +111,10 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) {
desc: "Should return folders and dashboard with 'edit' permission", desc: "Should return folders and dashboard with 'edit' permission",
permission: dashboardaccess.PERMISSION_EDIT, permission: dashboardaccess.PERMISSION_EDIT,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3"}, {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"},
{Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33"}, {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"},
}, },
expectedResult: 2, 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", desc: "Should return the dashboards that the User has dashboards:write permission on in case of 'edit' permission",
permission: dashboardaccess.PERMISSION_EDIT, permission: dashboardaccess.PERMISSION_EDIT,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:31"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:31", Kind: "dashboards", Identifier: "31"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32", Kind: "dashboards", Identifier: "32"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"},
{Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33"}, {Action: dashboards.ActionDashboardsWrite, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"},
}, },
expectedResult: 1, 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", desc: "Should return the folders that the User has dashboards:create permission on in case of 'edit' permission",
permission: dashboardaccess.PERMISSION_EDIT, permission: dashboardaccess.PERMISSION_EDIT,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3"}, {Action: dashboards.ActionDashboardsCreate, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:4"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:4", Kind: "folders", Identifier: "4"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:32", Kind: "dashboards", Identifier: "32"},
{Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33"}, {Action: dashboards.ActionDashboardsRead, Scope: "dashboards:uid:33", Kind: "dashboards", Identifier: "33"},
}, },
expectedResult: 1, expectedResult: 1,
}, },
@ -147,10 +147,10 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) {
permission: dashboardaccess.PERMISSION_VIEW, permission: dashboardaccess.PERMISSION_VIEW,
queryType: searchstore.TypeAlertFolder, queryType: searchstore.TypeAlertFolder,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3"}, {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:8"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"},
{Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8"}, {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"},
}, },
expectedResult: 2, expectedResult: 2,
}, },
@ -160,8 +160,8 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) {
queryType: searchstore.TypeAlertFolder, queryType: searchstore.TypeAlertFolder,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "*"}, {Action: dashboards.ActionFoldersRead, Scope: "*"},
{Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3"}, {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:3", Kind: "folders", Identifier: "3"},
{Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8"}, {Action: accesscontrol.ActionAlertingRuleRead, Scope: "folders:uid:8", Kind: "folders", Identifier: "8"},
}, },
expectedResult: 2, expectedResult: 2,
}, },
@ -423,7 +423,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
queryType: searchstore.TypeFolder, queryType: searchstore.TypeFolder,
permission: dashboardaccess.PERMISSION_VIEW, permission: dashboardaccess.PERMISSION_VIEW,
permissions: []accesscontrol.Permission{ 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}, features: []any{featuremgmt.FlagNestedFolders},
expectedResult: []string{"parent", "subfolder"}, expectedResult: []string{"parent", "subfolder"},
@ -433,7 +433,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) {
queryType: searchstore.TypeFolder, queryType: searchstore.TypeFolder,
permission: dashboardaccess.PERMISSION_VIEW, permission: dashboardaccess.PERMISSION_VIEW,
permissions: []accesscontrol.Permission{ permissions: []accesscontrol.Permission{
{Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent"}, {Action: dashboards.ActionFoldersRead, Scope: "folders:uid:parent", Kind: "folders", Identifier: "parent"},
}, },
features: []any{}, features: []any{},
expectedResult: []string{"parent"}, expectedResult: []string{"parent"},
@ -678,6 +678,7 @@ func setupTest(t *testing.T, numFolders, numDashboards int, permissions []access
permissions[i].RoleID = role.ID permissions[i].RoleID = role.ID
permissions[i].Created = time.Now() permissions[i].Created = time.Now()
permissions[i].Updated = time.Now() permissions[i].Updated = time.Now()
permissions[i].Kind, permissions[i].Attribute, permissions[i].Identifier = permissions[i].SplitScope()
} }
if len(permissions) > 0 { if len(permissions) > 0 {
_, err = sess.InsertMulti(&permissions) _, 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].RoleID = role.ID
perms[i].Created = time.Now() perms[i].Created = time.Now()
perms[i].Updated = time.Now() perms[i].Updated = time.Now()
perms[i].Kind, perms[i].Attribute, perms[i].Identifier = perms[i].SplitScope()
} }
if len(perms) > 0 { if len(perms) > 0 {
_, err = sess.InsertMulti(&perms) _, err = sess.InsertMulti(&perms)