Team/User: UID migrations (#82298)

* Add user uid migration to run on every startup to protect against empty values in a upgrade downgrade scenario

* Add team uid migration to run on every startup to protect against empty values in a upgrade downgrade scenario

* Run team uid migration
This commit is contained in:
Karl Persson
2024-02-12 14:48:29 +01:00
committed by GitHub
parent 685e84b1f8
commit 1315c67c8b
12 changed files with 84 additions and 16 deletions
+23
View File
@@ -11,6 +11,7 @@ import (
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/auth/identity"
"github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
@@ -600,3 +601,25 @@ func (ss *xormStore) getTeamMembers(ctx context.Context, query *team.GetTeamMemb
func (ss *xormStore) RegisterDelete(query string) {
ss.deletes = append(ss.deletes, query)
}
// This is just to ensure that all teams have a valid uid.
// To protect against upgrade / downgrade we need to run this for a couple of releases.
// FIXME: Remove this migration and make uid field required https://github.com/grafana/identity-access-team/issues/552
func (ss *xormStore) uidMigration() error {
return ss.db.WithDbSession(context.Background(), func(sess *db.Session) error {
switch ss.db.GetDBType() {
case migrator.SQLite:
_, err := sess.Exec("UPDATE team SET uid=printf('t%09d',id) WHERE uid IS NULL;")
return err
case migrator.Postgres:
_, err := sess.Exec("UPDATE team SET uid='t' || lpad('' || id::text,9,'0') WHERE uid IS NULL;")
return err
case migrator.MySQL:
_, err := sess.Exec("UPDATE team SET uid=concat('t',lpad(id,9,'0')) WHERE uid IS NULL;")
return err
default:
// this branch should be unreachable
return nil
}
})
}
+8 -4
View File
@@ -35,7 +35,8 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
}
t.Run("Testing Team commands and queries", func(t *testing.T) {
sqlStore := db.InitTestDB(t)
teamSvc := ProvideService(sqlStore, sqlStore.Cfg)
teamSvc, err := ProvideService(sqlStore, sqlStore.Cfg)
require.NoError(t, err)
testUser := &user.SignedInUser{
OrgID: 1,
Permissions: map[int64]map[string][]string{
@@ -489,7 +490,8 @@ func TestIntegrationSQLStore_SearchTeams(t *testing.T) {
}
store := db.InitTestDB(t, db.InitTestDBOpt{})
teamSvc := ProvideService(store, store.Cfg)
teamSvc, err := ProvideService(store, store.Cfg)
require.NoError(t, err)
// Seed 10 teams
for i := 1; i <= 10; i++ {
@@ -525,7 +527,8 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) {
// Seed 2 teams with 2 members
setup := func(store *sqlstore.SQLStore) {
teamSvc := ProvideService(store, store.Cfg)
teamSvc, err := ProvideService(store, store.Cfg)
require.NoError(t, err)
team1, errCreateTeam := teamSvc.CreateTeam("group1 name", "test1@example.org", testOrgID)
require.NoError(t, errCreateTeam)
team2, errCreateTeam := teamSvc.CreateTeam("group2 name", "test2@example.org", testOrgID)
@@ -559,7 +562,8 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) {
store := db.InitTestDB(t, db.InitTestDBOpt{})
setup(store)
teamSvc := ProvideService(store, store.Cfg)
teamSvc, err := ProvideService(store, store.Cfg)
require.NoError(t, err)
type getTeamMembersTestCase struct {
desc string
+7 -2
View File
@@ -13,8 +13,13 @@ type Service struct {
store store
}
func ProvideService(db db.DB, cfg *setting.Cfg) team.Service {
return &Service{store: &xormStore{db: db, cfg: cfg, deletes: []string{}}}
func ProvideService(db db.DB, cfg *setting.Cfg) (team.Service, error) {
store := &xormStore{db: db, cfg: cfg, deletes: []string{}}
if err := store.uidMigration(); err != nil {
return nil, err
}
return &Service{store: &xormStore{db: db, cfg: cfg, deletes: []string{}}}, nil
}
func (s *Service) CreateTeam(name, email string, orgID int64) (team.Team, error) {