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
@@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/util"
)
@@ -311,6 +312,9 @@ func (fr *FileReader) getOrCreateFolderID(ctx context.Context, cfg *config, serv
dash.Overwrite = true
dash.OrgId = cfg.OrgID
// set dashboard folderUid if given
if cfg.FolderUID == accesscontrol.GeneralFolderUID {
return 0, models.ErrFolderInvalidUID
}
dash.Dashboard.SetUid(cfg.FolderUID)
dbDash, err := service.SaveFolderForProvisionedDashboards(ctx, dash)
if err != nil {
@@ -390,6 +390,26 @@ func TestDashboardFileReader(t *testing.T) {
require.NoError(t, err)
})
t.Run("should not create dashboard folder with uid general", func(t *testing.T) {
setup()
cfg := &config{
Name: "DefaultB",
Type: "file",
OrgID: 1,
Folder: "TEAM B",
FolderUID: "general",
Options: map[string]interface{}{
"folder": defaultDashboards,
},
}
r, err := NewDashboardFileReader(cfg, logger, nil)
require.NoError(t, err)
_, err = r.getOrCreateFolderID(context.Background(), cfg, fakeService, cfg.Folder)
require.ErrorIs(t, err, models.ErrFolderInvalidUID)
})
t.Run("Walking the folder with dashboards", func(t *testing.T) {
setup()
noFiles := map[string]os.FileInfo{}