Access control: use uid for dashboard and folder scopes (#46807)

* use uid:s for folder and dashboard permissions

* evaluate folder and dashboard permissions based on uids

* add dashboard.uid to accept list

* Check for exact suffix

* Check parent folder on create

* update test

* drop dashboard:create actions with dashboard scope

* fix typo

* AccessControl: test id 0 scope conversion

* AccessControl: store only parent folder UID

* AccessControl: extract general as a constant

* FolderServices: Prevent creation of a folder uid'd general

* FolderServices: Test folder creation prevention

* Update pkg/services/guardian/accesscontrol_guardian.go

* FolderServices: fix mock call expect

* FolderServices: remove uneeded mocks

Co-authored-by: jguer <joao.guerreiro@grafana.com>
This commit is contained in:
Karl Persson
2022-03-30 15:14:26 +02:00
committed by GitHub
co-authored by jguer
parent 56e9c24f08
commit a5e4a533fa
21 changed files with 369 additions and 256 deletions
@@ -110,15 +110,16 @@ func (f AccessControlDashboardPermissionFilter) Where() (string, []interface{})
if len(f.dashboardActions) > 0 {
builder.WriteString("((")
dashFilter, _ := accesscontrol.Filter(f.User, "dashboard.id", "dashboards:id:", f.dashboardActions...)
dashFilter, _ := accesscontrol.Filter(f.User, "dashboard.uid", dashboards.ScopeDashboardsPrefix, f.dashboardActions...)
builder.WriteString(dashFilter.Where)
args = append(args, dashFilter.Args...)
builder.WriteString(" OR ")
builder.WriteString(" OR dashboard.folder_id IN(SELECT id FROM dashboard WHERE ")
dashFolderFilter, _ := accesscontrol.Filter(f.User, "dashboard.uid", dashboards.ScopeFoldersPrefix, f.dashboardActions...)
dashFolderFilter, _ := accesscontrol.Filter(f.User, "dashboard.folder_id", "folders:id:", f.dashboardActions...)
builder.WriteString(dashFolderFilter.Where)
builder.WriteString(") AND NOT dashboard.is_folder)")
builder.WriteString(")) AND NOT dashboard.is_folder)")
args = append(args, dashFolderFilter.Args...)
}
@@ -127,12 +128,11 @@ func (f AccessControlDashboardPermissionFilter) Where() (string, []interface{})
builder.WriteString(" OR ")
}
builder.WriteString("(")
folderFilter, _ := accesscontrol.Filter(f.User, "dashboard.id", "folders:id:", f.folderActions...)
folderFilter, _ := accesscontrol.Filter(f.User, "dashboard.uid", dashboards.ScopeFoldersPrefix, f.folderActions...)
builder.WriteString(folderFilter.Where)
builder.WriteString(" AND dashboard.is_folder)")
args = append(args, folderFilter.Args...)
}
builder.WriteString(")")
return builder.String(), args
}
@@ -108,7 +108,7 @@ func TestAccessControlDashboardPermissionFilter_Where(t *testing.T) {
title: "folder and dashboard actions are defined",
dashboardActions: []string{"test"},
folderActions: []string{"test"},
expectedResult: "((( 1 = 0 OR 1 = 0) AND NOT dashboard.is_folder) OR ( 1 = 0 AND dashboard.is_folder))",
expectedResult: "((( 1 = 0 OR dashboard.folder_id IN(SELECT id FROM dashboard WHERE 1 = 0)) AND NOT dashboard.is_folder) OR ( 1 = 0 AND dashboard.is_folder))",
},
{
title: "folder actions are defined but not dashboard actions",
@@ -120,7 +120,7 @@ func TestAccessControlDashboardPermissionFilter_Where(t *testing.T) {
title: "dashboard actions are defined but not folder actions",
dashboardActions: []string{"test"},
folderActions: nil,
expectedResult: "((( 1 = 0 OR 1 = 0) AND NOT dashboard.is_folder))",
expectedResult: "((( 1 = 0 OR dashboard.folder_id IN(SELECT id FROM dashboard WHERE 1 = 0)) AND NOT dashboard.is_folder))",
},
{
title: "dashboard actions are defined but not folder actions",