github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/app/migrations.go (about) 1 // Copyright (c) 2016-present Xenia, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "reflect" 9 10 "github.com/xzl8028/xenia-server/mlog" 11 "github.com/xzl8028/xenia-server/model" 12 "github.com/xzl8028/xenia-server/utils" 13 ) 14 15 const ADVANCED_PERMISSIONS_MIGRATION_KEY = "AdvancedPermissionsMigrationComplete" 16 const EMOJIS_PERMISSIONS_MIGRATION_KEY = "EmojisPermissionsMigrationComplete" 17 const GUEST_ROLES_CREATION_MIGRATION_KEY = "GuestRolesCreationMigrationComplete" 18 19 // This function migrates the default built in roles from code/config to the database. 20 func (a *App) DoAdvancedPermissionsMigration() { 21 // If the migration is already marked as completed, don't do it again. 22 if _, err := a.Srv.Store.System().GetByName(ADVANCED_PERMISSIONS_MIGRATION_KEY); err == nil { 23 return 24 } 25 26 mlog.Info("Migrating roles to database.") 27 roles := model.MakeDefaultRoles() 28 roles = utils.SetRolePermissionsFromConfig(roles, a.Config(), a.License() != nil) 29 30 allSucceeded := true 31 32 for _, role := range roles { 33 _, err := a.Srv.Store.Role().Save(role) 34 if err == nil { 35 continue 36 } 37 38 // If this failed for reasons other than the role already existing, don't mark the migration as done. 39 fetchedRole, err := a.Srv.Store.Role().GetByName(role.Name) 40 if err != nil { 41 mlog.Critical("Failed to migrate role to database.", mlog.Err(err)) 42 allSucceeded = false 43 continue 44 } 45 46 // If the role already existed, check it is the same and update if not. 47 if !reflect.DeepEqual(fetchedRole.Permissions, role.Permissions) || 48 fetchedRole.DisplayName != role.DisplayName || 49 fetchedRole.Description != role.Description || 50 fetchedRole.SchemeManaged != role.SchemeManaged { 51 role.Id = fetchedRole.Id 52 if _, err = a.Srv.Store.Role().Save(role); err != nil { 53 // Role is not the same, but failed to update. 54 mlog.Critical("Failed to migrate role to database.", mlog.Err(err)) 55 allSucceeded = false 56 } 57 } 58 } 59 60 if !allSucceeded { 61 return 62 } 63 64 config := a.Config() 65 if *config.ServiceSettings.DEPRECATED_DO_NOT_USE_AllowEditPost == model.ALLOW_EDIT_POST_ALWAYS { 66 *config.ServiceSettings.PostEditTimeLimit = -1 67 if err := a.SaveConfig(config, true); err != nil { 68 mlog.Error("Failed to update config in Advanced Permissions Phase 1 Migration.", mlog.Err(err)) 69 } 70 } 71 72 system := model.System{ 73 Name: ADVANCED_PERMISSIONS_MIGRATION_KEY, 74 Value: "true", 75 } 76 77 if err := a.Srv.Store.System().Save(&system); err != nil { 78 mlog.Critical("Failed to mark advanced permissions migration as completed.", mlog.Err(err)) 79 } 80 } 81 82 func (a *App) SetPhase2PermissionsMigrationStatus(isComplete bool) error { 83 if !isComplete { 84 if _, err := a.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2); err != nil { 85 return err 86 } 87 } 88 a.Srv.phase2PermissionsMigrationComplete = isComplete 89 return nil 90 } 91 92 func (a *App) DoEmojisPermissionsMigration() { 93 // If the migration is already marked as completed, don't do it again. 94 if _, err := a.Srv.Store.System().GetByName(EMOJIS_PERMISSIONS_MIGRATION_KEY); err == nil { 95 return 96 } 97 98 var role *model.Role = nil 99 var systemAdminRole *model.Role = nil 100 var err *model.AppError = nil 101 102 mlog.Info("Migrating emojis config to database.") 103 switch *a.Config().ServiceSettings.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation { 104 case model.RESTRICT_EMOJI_CREATION_ALL: 105 role, err = a.GetRoleByName(model.SYSTEM_USER_ROLE_ID) 106 if err != nil { 107 mlog.Critical("Failed to migrate emojis creation permissions from xenia config.", mlog.Err(err)) 108 return 109 } 110 case model.RESTRICT_EMOJI_CREATION_ADMIN: 111 role, err = a.GetRoleByName(model.TEAM_ADMIN_ROLE_ID) 112 if err != nil { 113 mlog.Critical("Failed to migrate emojis creation permissions from xenia config.", mlog.Err(err)) 114 return 115 } 116 case model.RESTRICT_EMOJI_CREATION_SYSTEM_ADMIN: 117 role = nil 118 default: 119 mlog.Critical("Failed to migrate emojis creation permissions from xenia config. Invalid restrict emoji creation setting") 120 return 121 } 122 123 if role != nil { 124 role.Permissions = append(role.Permissions, model.PERMISSION_CREATE_EMOJIS.Id, model.PERMISSION_DELETE_EMOJIS.Id) 125 if _, err = a.Srv.Store.Role().Save(role); err != nil { 126 mlog.Critical("Failed to migrate emojis creation permissions from xenia config.", mlog.Err(err)) 127 return 128 } 129 } 130 131 systemAdminRole, err = a.GetRoleByName(model.SYSTEM_ADMIN_ROLE_ID) 132 if err != nil { 133 mlog.Critical("Failed to migrate emojis creation permissions from xenia config.", mlog.Err(err)) 134 return 135 } 136 137 systemAdminRole.Permissions = append(systemAdminRole.Permissions, model.PERMISSION_CREATE_EMOJIS.Id, model.PERMISSION_DELETE_EMOJIS.Id) 138 systemAdminRole.Permissions = append(systemAdminRole.Permissions, model.PERMISSION_DELETE_OTHERS_EMOJIS.Id) 139 if _, err := a.Srv.Store.Role().Save(systemAdminRole); err != nil { 140 mlog.Critical("Failed to migrate emojis creation permissions from xenia config.", mlog.Err(err)) 141 return 142 } 143 144 system := model.System{ 145 Name: EMOJIS_PERMISSIONS_MIGRATION_KEY, 146 Value: "true", 147 } 148 149 if err := a.Srv.Store.System().Save(&system); err != nil { 150 mlog.Critical("Failed to mark emojis permissions migration as completed.", mlog.Err(err)) 151 } 152 } 153 154 func (a *App) DoGuestRolesCreationMigration() { 155 // If the migration is already marked as completed, don't do it again. 156 if _, err := a.Srv.Store.System().GetByName(GUEST_ROLES_CREATION_MIGRATION_KEY); err == nil { 157 return 158 } 159 160 roles := model.MakeDefaultRoles() 161 162 allSucceeded := true 163 if _, err := a.Srv.Store.Role().GetByName(model.CHANNEL_GUEST_ROLE_ID); err != nil { 164 if _, err := a.Srv.Store.Role().Save(roles[model.CHANNEL_GUEST_ROLE_ID]); err != nil { 165 mlog.Critical("Failed to create new guest role to database.", mlog.Err(err)) 166 allSucceeded = false 167 } 168 } 169 if _, err := a.Srv.Store.Role().GetByName(model.TEAM_GUEST_ROLE_ID); err != nil { 170 if _, err := a.Srv.Store.Role().Save(roles[model.TEAM_GUEST_ROLE_ID]); err != nil { 171 mlog.Critical("Failed to create new guest role to database.", mlog.Err(err)) 172 allSucceeded = false 173 } 174 } 175 if _, err := a.Srv.Store.Role().GetByName(model.SYSTEM_GUEST_ROLE_ID); err != nil { 176 if _, err := a.Srv.Store.Role().Save(roles[model.SYSTEM_GUEST_ROLE_ID]); err != nil { 177 mlog.Critical("Failed to create new guest role to database.", mlog.Err(err)) 178 allSucceeded = false 179 } 180 } 181 182 resultSchemes := <-a.Srv.Store.Scheme().GetAllPage("", 0, 1000000) 183 if resultSchemes.Err != nil { 184 mlog.Critical("Failed to get all schemes.", mlog.Err(resultSchemes.Err)) 185 allSucceeded = false 186 } 187 schemes := resultSchemes.Data.([]*model.Scheme) 188 for _, scheme := range schemes { 189 if scheme.DefaultTeamGuestRole == "" || scheme.DefaultChannelGuestRole == "" { 190 // Team Guest Role 191 teamGuestRole := &model.Role{ 192 Name: model.NewId(), 193 DisplayName: fmt.Sprintf("Team Guest Role for Scheme %s", scheme.Name), 194 Permissions: roles[model.TEAM_GUEST_ROLE_ID].Permissions, 195 SchemeManaged: true, 196 } 197 198 if savedRole, err := a.Srv.Store.Role().Save(teamGuestRole); err != nil { 199 mlog.Critical("Failed to create new guest role for custom scheme.", mlog.Err(err)) 200 allSucceeded = false 201 } else { 202 scheme.DefaultTeamGuestRole = savedRole.Name 203 } 204 205 // Channel Guest Role 206 channelGuestRole := &model.Role{ 207 Name: model.NewId(), 208 DisplayName: fmt.Sprintf("Channel Guest Role for Scheme %s", scheme.Name), 209 Permissions: roles[model.CHANNEL_GUEST_ROLE_ID].Permissions, 210 SchemeManaged: true, 211 } 212 213 if savedRole, err := a.Srv.Store.Role().Save(channelGuestRole); err != nil { 214 mlog.Critical("Failed to create new guest role for custom scheme.", mlog.Err(err)) 215 allSucceeded = false 216 } else { 217 scheme.DefaultChannelGuestRole = savedRole.Name 218 } 219 220 result := <-a.Srv.Store.Scheme().Save(scheme) 221 if result.Err != nil { 222 mlog.Critical("Failed to update custom scheme.", mlog.Err(result.Err)) 223 allSucceeded = false 224 } 225 } 226 } 227 228 if !allSucceeded { 229 return 230 } 231 232 system := model.System{ 233 Name: GUEST_ROLES_CREATION_MIGRATION_KEY, 234 Value: "true", 235 } 236 237 if err := a.Srv.Store.System().Save(&system); err != nil { 238 mlog.Critical("Failed to mark guest roles creation migration as completed.", mlog.Err(err)) 239 } 240 } 241 242 func (a *App) DoAppMigrations() { 243 a.DoAdvancedPermissionsMigration() 244 a.DoEmojisPermissionsMigration() 245 a.DoGuestRolesCreationMigration() 246 // This migration always must be the last, because can be based on previous 247 // migrations. For example, it needs the guest roles migration. 248 a.DoPermissionsMigrations() 249 }