diff --git a/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go b/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go index e9b704cf548..5e697e9e5b6 100644 --- a/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go +++ b/pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go @@ -175,8 +175,15 @@ type FolderPermissionsService struct { *resourcepermissions.Service } -var FolderViewActions = []string{dashboards.ActionFoldersRead} -var FolderEditActions = append(FolderViewActions, []string{dashboards.ActionFoldersWrite, dashboards.ActionFoldersDelete, dashboards.ActionDashboardsCreate}...) +var FolderViewActions = []string{dashboards.ActionFoldersRead, accesscontrol.ActionAlertingRuleRead} +var FolderEditActions = append(FolderViewActions, []string{ + dashboards.ActionFoldersWrite, + dashboards.ActionFoldersDelete, + dashboards.ActionDashboardsCreate, + accesscontrol.ActionAlertingRuleCreate, + accesscontrol.ActionAlertingRuleUpdate, + accesscontrol.ActionAlertingRuleDelete, +}...) var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFoldersPermissionsRead, dashboards.ActionFoldersPermissionsWrite}...) func ProvideFolderPermissions( diff --git a/pkg/services/sqlstore/migrations/accesscontrol/dashboard_permissions.go b/pkg/services/sqlstore/migrations/accesscontrol/dashboard_permissions.go index 7ba629bfd80..c11711ed0e7 100644 --- a/pkg/services/sqlstore/migrations/accesscontrol/dashboard_permissions.go +++ b/pkg/services/sqlstore/migrations/accesscontrol/dashboard_permissions.go @@ -294,3 +294,127 @@ func (m *managedFolderCreateAction) Exec(sess *xorm.Session, migrator *migrator. } return nil } + +const managedFolderAlertActionsMigratorID = "managed folder permissions alert actions migration" + +func AddManagedFolderAlertActionsMigration(mg *migrator.Migrator) { + mg.AddMigration(managedFolderAlertActionsMigratorID, &managedFolderAlertActionsMigrator{}) +} + +type managedFolderAlertActionsMigrator struct { + migrator.MigrationBase +} + +func (m *managedFolderAlertActionsMigrator) SQL(dialect migrator.Dialect) string { + return CodeMigrationSQL +} + +func (m *managedFolderAlertActionsMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) error { + var ids []interface{} + if err := sess.SQL("SELECT id FROM role WHERE name LIKE 'managed:%'").Find(&ids); err != nil { + return err + } + + if len(ids) == 0 { + return nil + } + + var permissions []ac.Permission + if err := sess.SQL("SELECT role_id, action, scope FROM permission WHERE role_id IN(?"+strings.Repeat(" ,?", len(ids)-1)+") AND scope LIKE 'folders:%'", ids...).Find(&permissions); err != nil { + return err + } + + mapped := make(map[int64]map[string][]ac.Permission, len(ids)-1) + for _, p := range permissions { + if mapped[p.RoleID] == nil { + mapped[p.RoleID] = make(map[string][]ac.Permission) + } + mapped[p.RoleID][p.Scope] = append(mapped[p.RoleID][p.Scope], p) + } + + var toAdd []ac.Permission + now := time.Now() + + for id, a := range mapped { + for scope, p := range a { + if hasFolderView(p) { + toAdd = append(toAdd, ac.Permission{ + RoleID: id, + Updated: now, + Created: now, + Scope: scope, + Action: ac.ActionAlertingRuleRead, + }) + } + + if hasFolderAdmin(p) || hasFolderEdit(p) { + toAdd = append( + toAdd, + ac.Permission{ + RoleID: id, + Updated: now, + Created: now, + Scope: scope, + Action: ac.ActionAlertingRuleCreate, + }, + ac.Permission{ + RoleID: id, + Updated: now, + Created: now, + Scope: scope, + Action: ac.ActionAlertingRuleDelete, + }, + ac.Permission{ + RoleID: id, + Updated: now, + Created: now, + Scope: scope, + Action: ac.ActionAlertingRuleUpdate, + }, + ) + } + } + } + + if len(toAdd) == 0 { + return nil + } + + err := batch(len(toAdd), batchSize, func(start, end int) error { + if _, err := sess.InsertMulti(toAdd[start:end]); err != nil { + return err + } + return nil + }) + + if err != nil { + return err + } + + return nil +} + +func hasFolderAdmin(permissions []ac.Permission) bool { + return hasActions(folderPermissionTranslation[models.PERMISSION_ADMIN], permissions) +} + +func hasFolderEdit(permissions []ac.Permission) bool { + return hasActions(folderPermissionTranslation[models.PERMISSION_EDIT], permissions) +} + +func hasFolderView(permissions []ac.Permission) bool { + return hasActions(folderPermissionTranslation[models.PERMISSION_VIEW], permissions) +} + +func hasActions(actions []string, permissions []ac.Permission) bool { + var contains int + for _, action := range actions { + for _, p := range permissions { + if action == p.Action { + contains++ + break + } + } + } + return contains >= len(actions) +} diff --git a/pkg/services/sqlstore/migrations/migrations.go b/pkg/services/sqlstore/migrations/migrations.go index 3e60ddff3c2..5804bce53a1 100644 --- a/pkg/services/sqlstore/migrations/migrations.go +++ b/pkg/services/sqlstore/migrations/migrations.go @@ -89,6 +89,7 @@ func (*OSSMigrations) AddMigration(mg *Migrator) { addDbFileStorageMigration(mg) accesscontrol.AddManagedPermissionsMigration(mg) + accesscontrol.AddManagedFolderAlertActionsMigration(mg) } func addMigrationLogMigrations(mg *Migrator) {