RBAC: Make uid for managed role names deterministic during migrations (#56620)

* RBAC: Change the generate uid function to be deterministic so we can avoid collision

* RBAC: Use fmt.Errorf

* RBAC: Add comment

* RBAC: Export GenerateManagedRoleUID
This commit is contained in:
Karl Persson
2022-10-17 12:15:20 +02:00
committed by GitHub
parent ecc252429e
commit 21792fdf37
2 changed files with 9 additions and 20 deletions

View File

@ -106,7 +106,7 @@ func (sp *managedPermissionMigrator) Exec(sess *xorm.Session, mg *migrator.Migra
} }
if !ok { if !ok {
uid, err := generateNewRoleUID(sess, orgID) uid, err := GenerateManagedRoleUID(orgID, managedRole)
if err != nil { if err != nil {
return err return err
} }

View File

@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/util"
) )
var ( var (
@ -137,11 +136,10 @@ func (m *permissionMigrator) createRoles(roles []*accesscontrol.Role) ([]*access
args := make([]interface{}, 0, len(roles)*5) args := make([]interface{}, 0, len(roles)*5)
for i, r := range roles { for i, r := range roles {
uid, err := generateNewRoleUID(m.sess, r.OrgID) uid, err := GenerateManagedRoleUID(r.OrgID, r.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
valueStrings[i] = "(?, ?, ?, 1, ?, ?)" valueStrings[i] = "(?, ?, ?, 1, ?, ?)"
args = append(args, r.OrgID, uid, r.Name, ts, ts) args = append(args, r.OrgID, uid, r.Name, ts, ts)
} }
@ -165,11 +163,10 @@ func (m *permissionMigrator) createRolesMySQL(roles []*accesscontrol.Role) ([]*a
args := make([]interface{}, 0, len(roles)*2) args := make([]interface{}, 0, len(roles)*2)
for i := range roles { for i := range roles {
uid, err := generateNewRoleUID(m.sess, roles[i].OrgID) uid, err := GenerateManagedRoleUID(roles[i].OrgID, roles[i].Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
roles[i].UID = uid roles[i].UID = uid
roles[i].Created = ts roles[i].Created = ts
roles[i].Updated = ts roles[i].Updated = ts
@ -210,19 +207,11 @@ func batch(count, batchSize int, eachFn func(start, end int) error) error {
return nil return nil
} }
func generateNewRoleUID(sess *xorm.Session, orgID int64) (string, error) { // GenerateManagedRoleUID generated a deterministic uid of the form `managed_{org_id}_{type}_{id}`.
for i := 0; i < 3; i++ { func GenerateManagedRoleUID(orgID int64, name string) (string, error) {
uid := util.GenerateShortUID() parts := strings.Split(name, ":")
if len(parts) != 4 {
exists, err := sess.Where("org_id=? AND uid=?", orgID, uid).Get(&accesscontrol.Role{}) return "", fmt.Errorf("unexpected role name: %s", name)
if err != nil {
return "", err
}
if !exists {
return uid, nil
}
} }
return fmt.Sprintf("managed_%d_%s_%s", orgID, parts[1], parts[2]), nil
return "", fmt.Errorf("failed to generate uid")
} }