RBAC: Remove the option to disable RBAC and add automated permission migrations for instances that had RBAC disabled (#66652)
* RBAC: Stop reading enabeld from ini file and always set to true * Migrations: Add a migration for rbac to reset data migrations if rbac was disabled * If rbac was disabled we reset the data and data migrations that rbac has to perform to get it to a correct state * Migrator: Store migration logs on migrator and add function to clear it from the in-memory stored logs * update tests --------- Co-authored-by: Karl Persson <kalle.persson@grafana.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package accesscontrol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
)
|
||||
|
||||
const (
|
||||
disabledMigrationID = "rbac disabled migrator"
|
||||
teamMigrationID = "teams permissions migration"
|
||||
dashboardMigrationID = "dashboard permissions"
|
||||
dashboardsUIDMigrationID = "dashboard permissions uid scopes"
|
||||
datasourceMigrationID = "data source permissions"
|
||||
datasourceUIDMigrationID = "data source uid permissions"
|
||||
managedPermissionsMigrationID = "managed permissions migration"
|
||||
alertFolderMigrationID = "managed folder permissions alert actions repeated migration"
|
||||
managedPermissionsEnterpriseMigrationID = "managed permissions migration enterprise"
|
||||
)
|
||||
|
||||
var migrations = [...]string{
|
||||
teamMigrationID,
|
||||
dashboardMigrationID,
|
||||
dashboardsUIDMigrationID,
|
||||
datasourceMigrationID,
|
||||
datasourceUIDMigrationID,
|
||||
managedPermissionsMigrationID,
|
||||
alertFolderMigrationID,
|
||||
managedPermissionsEnterpriseMigrationID,
|
||||
}
|
||||
|
||||
func AddDisabledMigrator(mg *migrator.Migrator) {
|
||||
mg.AddMigration(disabledMigrationID, &DisabledMigrator{})
|
||||
}
|
||||
|
||||
type DisabledMigrator struct {
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
func (m *DisabledMigrator) SQL(dialect migrator.Dialect) string {
|
||||
return CodeMigrationSQL
|
||||
}
|
||||
|
||||
func (m *DisabledMigrator) Exec(sess *xorm.Session, mg *migrator.Migrator) error {
|
||||
enabled := mg.Cfg.Raw.Section("rbac").Key("enabled").MustBool(true)
|
||||
if enabled {
|
||||
// if the flag is enabled we skip the reset of data migrations
|
||||
mg.Logger.Debug("skip reset of rbac data migrations")
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("DELETE FROM builtin_role WHERE role_id IN (SELECT id FROM role WHERE name LIKE 'managed:%')"); err != nil {
|
||||
return fmt.Errorf("failed to remove basic role bindings: %w", err)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("DELETE FROM team_role WHERE role_id IN (SELECT id FROM role WHERE name LIKE 'managed:%')"); err != nil {
|
||||
return fmt.Errorf("failed to remove team role bindings: %w", err)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("DELETE FROM user_role where role_id IN (SELECT id FROM role WHERE name LIKE 'managed:%')"); err != nil {
|
||||
return fmt.Errorf("failed to remove user role bindings: %w", err)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("DELETE FROM permission WHERE role_id IN (SELECT id FROM role WHERE name LIKE 'managed:%');"); err != nil {
|
||||
return fmt.Errorf("failed to remove managed rbac permission: %w", err)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec("DELETE FROM role WHERE name LIKE 'managed:%';"); err != nil {
|
||||
return fmt.Errorf("failed to remove managed rbac roles: %w", err)
|
||||
}
|
||||
|
||||
params := []interface{}{"DELETE FROM migration_log WHERE migration_id IN (?, ?, ?, ?, ?, ?, ?, ?)"}
|
||||
for _, m := range migrations {
|
||||
params = append(params, m)
|
||||
}
|
||||
|
||||
if _, err := sess.Exec(params...); err != nil {
|
||||
return fmt.Errorf("failed to remove managed permissions migrations: %w", err)
|
||||
}
|
||||
|
||||
// Note: we also need to clear migration from the in-memory representation of migration log
|
||||
mg.RemoveMigrationLogs(migrations[:]...)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/ini.v1"
|
||||
"xorm.io/xorm"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@@ -153,6 +154,7 @@ func TestMigrations(t *testing.T) {
|
||||
config: &setting.Cfg{
|
||||
EditorsCanAdmin: true,
|
||||
IsFeatureToggleEnabled: func(key string) bool { return key == "accesscontrol" },
|
||||
Raw: ini.Empty(),
|
||||
},
|
||||
expectedRolePerms: map[string][]rawPermission{
|
||||
"managed:users:1:permissions": {{Action: "teams:read", Scope: team1Scope}},
|
||||
@@ -181,6 +183,7 @@ func TestMigrations(t *testing.T) {
|
||||
desc: "without editors can admin",
|
||||
config: &setting.Cfg{
|
||||
IsFeatureToggleEnabled: func(key string) bool { return key == "accesscontrol" },
|
||||
Raw: ini.Empty(),
|
||||
},
|
||||
expectedRolePerms: map[string][]rawPermission{
|
||||
"managed:users:1:permissions": {{Action: "teams:read", Scope: team1Scope}},
|
||||
@@ -256,7 +259,10 @@ func setupTestDB(t *testing.T) *xorm.Engine {
|
||||
err = migrator.NewDialect(x).CleanDB()
|
||||
require.NoError(t, err)
|
||||
|
||||
mg := migrator.NewMigrator(x, &setting.Cfg{Logger: log.New("acmigration.test")})
|
||||
mg := migrator.NewMigrator(x, &setting.Cfg{
|
||||
Logger: log.New("acmigration.test"),
|
||||
Raw: ini.Empty(),
|
||||
})
|
||||
migrations := &migrations.OSSMigrations{}
|
||||
migrations.AddMigration(mg)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user