diff options
author | George Goldberg <george@gberg.me> | 2018-05-14 15:59:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-14 15:59:04 +0100 |
commit | 51bd710ecdca6628461c9fa2679737073e4d5059 (patch) | |
tree | b2a4837ced3ed515ee505728917a6630b0553f76 /store/sqlstore/team_store.go | |
parent | 91557bbd978500388a11b99401783164e143a966 (diff) | |
download | chat-51bd710ecdca6628461c9fa2679737073e4d5059.tar.gz chat-51bd710ecdca6628461c9fa2679737073e4d5059.tar.bz2 chat-51bd710ecdca6628461c9fa2679737073e4d5059.zip |
MM-9728: Online migration for advanced permissions phase 2 (#8744)
* MM-9728: Online migration for advanced permissions phase 2
* Add unit tests for new store functions.
* Move migration specific code to own file.
* Add migration state function test.
* Style fixes.
* Add i18n strings.
* Fix mocks.
* Add TestMain to migrations package tests.
* Fix typo.
* Fix review comments.
* Fix up the "Check if migration is done" check to actually work.
Diffstat (limited to 'store/sqlstore/team_store.go')
-rw-r--r-- | store/sqlstore/team_store.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/store/sqlstore/team_store.go b/store/sqlstore/team_store.go index 9e72cc82e..ea5f7fd1f 100644 --- a/store/sqlstore/team_store.go +++ b/store/sqlstore/team_store.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" + "github.com/mattermost/gorp" "github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/store" ) @@ -725,3 +726,71 @@ func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) s } }) } + +// This function does the Advanced Permissions Phase 2 migration for TeamMember objects. It performs the migration +// in batches as a single transaction per batch to ensure consistency but to also minimise execution time to avoid +// causing unnecessary table locks. **THIS FUNCTION SHOULD NOT BE USED FOR ANY OTHER PURPOSE.** Executing this function +// *after* the new Schemes functionality has been used on an installation will have unintended consequences. +func (s SqlTeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) store.StoreChannel { + return store.Do(func(result *store.StoreResult) { + var transaction *gorp.Transaction + var err error + + if transaction, err = s.GetMaster().Begin(); err != nil { + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + var teamMembers []teamMember + if _, err := transaction.Select(&teamMembers, "SELECT * from TeamMembers WHERE (TeamId, UserId) > (:FromTeamId, :FromUserId) ORDER BY TeamId, UserId LIMIT 100", map[string]interface{}{"FromTeamId": fromTeamId, "FromUserId": fromUserId}); err != nil { + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.select.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + if len(teamMembers) == 0 { + // No more team members in query result means that the migration has finished. + return + } + + for _, member := range teamMembers { + roles := strings.Fields(member.Roles) + var newRoles []string + member.SchemeAdmin = sql.NullBool{Bool: false, Valid: true} + member.SchemeUser = sql.NullBool{Bool: false, Valid: true} + for _, role := range roles { + if role == model.TEAM_ADMIN_ROLE_ID { + member.SchemeAdmin = sql.NullBool{Bool: true, Valid: true} + } else if role == model.TEAM_USER_ROLE_ID { + member.SchemeUser = sql.NullBool{Bool: true, Valid: true} + } else { + newRoles = append(newRoles, role) + } + } + member.Roles = strings.Join(newRoles, " ") + + if _, err := transaction.Update(&member); err != nil { + if err2 := transaction.Rollback(); err2 != nil { + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.rollback_transaction.app_error", nil, err2.Error(), http.StatusInternalServerError) + return + } + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.update.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + } + + if err := transaction.Commit(); err != nil { + if err2 := transaction.Rollback(); err2 != nil { + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.rollback_transaction.app_error", nil, err2.Error(), http.StatusInternalServerError) + return + } + result.Err = model.NewAppError("SqlTeamStore.MigrateTeamMembers", "store.sql_team.migrate_team_members.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError) + return + } + + data := make(map[string]string) + data["TeamId"] = teamMembers[len(teamMembers)-1].TeamId + data["UserId"] = teamMembers[len(teamMembers)-1].UserId + result.Data = data + }) +} |