mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
@@ -21,7 +21,6 @@ var dashboardPermissionTranslation = map[models.PermissionType][]string{
|
||||
models.PERMISSION_EDIT: {
|
||||
ac.ActionDashboardsRead,
|
||||
ac.ActionDashboardsWrite,
|
||||
ac.ActionDashboardsCreate,
|
||||
ac.ActionDashboardsDelete,
|
||||
},
|
||||
models.PERMISSION_ADMIN: {
|
||||
@@ -39,6 +38,7 @@ var folderPermissionTranslation = map[models.PermissionType][]string{
|
||||
dashboards.ActionFoldersRead,
|
||||
}...),
|
||||
models.PERMISSION_EDIT: append(dashboardPermissionTranslation[models.PERMISSION_EDIT], []string{
|
||||
ac.ActionDashboardsCreate,
|
||||
dashboards.ActionFoldersRead,
|
||||
dashboards.ActionFoldersWrite,
|
||||
dashboards.ActionFoldersCreate,
|
||||
@@ -56,6 +56,7 @@ var folderPermissionTranslation = map[models.PermissionType][]string{
|
||||
|
||||
func AddDashboardPermissionsMigrator(mg *migrator.Migrator) {
|
||||
mg.AddMigration("dashboard permissions", &dashboardPermissionsMigrator{})
|
||||
mg.AddMigration("dashboard permissions uid scopes", &dashboardUidPermissionMigrator{})
|
||||
}
|
||||
|
||||
var _ migrator.CodeMigration = new(dashboardPermissionsMigrator)
|
||||
@@ -219,3 +220,63 @@ func getRoleName(p models.DashboardAcl) string {
|
||||
}
|
||||
return fmt.Sprintf("managed:builtins:%s:permissions", strings.ToLower(string(*p.Role)))
|
||||
}
|
||||
|
||||
var _ migrator.CodeMigration = new(dashboardUidPermissionMigrator)
|
||||
|
||||
type dashboardUidPermissionMigrator struct {
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
func (d *dashboardUidPermissionMigrator) SQL(dialect migrator.Dialect) string {
|
||||
return "code migration"
|
||||
}
|
||||
|
||||
func (d *dashboardUidPermissionMigrator) Exec(sess *xorm.Session, migrator *migrator.Migrator) error {
|
||||
if err := d.migrateWildcards(sess); err != nil {
|
||||
return err
|
||||
}
|
||||
return d.migrateIdScopes(sess)
|
||||
}
|
||||
|
||||
func (d *dashboardUidPermissionMigrator) migrateWildcards(sess *xorm.Session) error {
|
||||
if _, err := sess.Exec("DELETE FROM permission WHERE action = 'dashboards:create' AND scope LIKE 'dashboards%'"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE permission SET scope = 'dashboards:uid:*' WHERE scope = 'dashboards:id:*'"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := sess.Exec("UPDATE permission SET scope = 'folders:uid:*' WHERE scope = 'folders:id:*'"); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *dashboardUidPermissionMigrator) migrateIdScopes(sess *xorm.Session) error {
|
||||
type dashboard struct {
|
||||
ID int64 `xorm:"id"`
|
||||
UID string `xorm:"uid"`
|
||||
IsFolder bool
|
||||
}
|
||||
var dashboards []dashboard
|
||||
if err := sess.SQL("SELECT id, uid, is_folder FROM dashboard").Find(&dashboards); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range dashboards {
|
||||
var idScope string
|
||||
var uidScope string
|
||||
|
||||
if d.IsFolder {
|
||||
idScope = ac.Scope("folders", "id", strconv.FormatInt(d.ID, 10))
|
||||
uidScope = ac.Scope("folders", "uid", d.UID)
|
||||
} else {
|
||||
idScope = ac.Scope("dashboards", "id", strconv.FormatInt(d.ID, 10))
|
||||
uidScope = ac.Scope("dashboards", "uid", d.UID)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("UPDATE permission SET scope = ? WHERE scope = ?", uidScope, idScope); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user