github.com/vnforks/kid@v5.11.1+incompatible/app/permissions_migrations.go (about) 1 // Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "github.com/mattermost/mattermost-server/model" 8 ) 9 10 type permissionTransformation struct { 11 On func(string, map[string]map[string]bool) bool 12 Add []string 13 Remove []string 14 } 15 type permissionsMap []permissionTransformation 16 17 const ( 18 MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split" 19 MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split" 20 MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS = "list_join_public_private_teams" 21 MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER = "remove_permanent_delete_user" 22 MIGRATION_KEY_ADD_BOT_PERMISSIONS = "add_bot_permissions" 23 MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER = "apply_channel_manage_delete_to_channel_user" 24 MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user" 25 26 PERMISSION_MANAGE_SYSTEM = "manage_system" 27 PERMISSION_MANAGE_EMOJIS = "manage_emojis" 28 PERMISSION_MANAGE_OTHERS_EMOJIS = "manage_others_emojis" 29 PERMISSION_CREATE_EMOJIS = "create_emojis" 30 PERMISSION_DELETE_EMOJIS = "delete_emojis" 31 PERMISSION_DELETE_OTHERS_EMOJIS = "delete_others_emojis" 32 PERMISSION_MANAGE_WEBHOOKS = "manage_webhooks" 33 PERMISSION_MANAGE_OTHERS_WEBHOOKS = "manage_others_webhooks" 34 PERMISSION_MANAGE_INCOMING_WEBHOOKS = "manage_incoming_webhooks" 35 PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS = "manage_others_incoming_webhooks" 36 PERMISSION_MANAGE_OUTGOING_WEBHOOKS = "manage_outgoing_webhooks" 37 PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS = "manage_others_outgoing_webhooks" 38 PERMISSION_LIST_PUBLIC_TEAMS = "list_public_teams" 39 PERMISSION_LIST_PRIVATE_TEAMS = "list_private_teams" 40 PERMISSION_JOIN_PUBLIC_TEAMS = "join_public_teams" 41 PERMISSION_JOIN_PRIVATE_TEAMS = "join_private_teams" 42 PERMISSION_PERMANENT_DELETE_USER = "permanent_delete_user" 43 PERMISSION_CREATE_BOT = "create_bot" 44 PERMISSION_READ_BOTS = "read_bots" 45 PERMISSION_READ_OTHERS_BOTS = "read_others_bots" 46 PERMISSION_MANAGE_BOTS = "manage_bots" 47 PERMISSION_MANAGE_OTHERS_BOTS = "manage_others_bots" 48 PERMISSION_DELETE_PUBLIC_CHANNEL = "delete_public_channel" 49 PERMISSION_DELETE_PRIVATE_CHANNEL = "delete_private_channel" 50 PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES = "manage_public_channel_properties" 51 PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES = "manage_private_channel_properties" 52 ) 53 54 func isRole(role string) func(string, map[string]map[string]bool) bool { 55 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 56 return roleName == role 57 } 58 } 59 60 func permissionExists(permission string) func(string, map[string]map[string]bool) bool { 61 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 62 val, ok := permissionsMap[roleName][permission] 63 return ok && val 64 } 65 } 66 67 func permissionNotExists(permission string) func(string, map[string]map[string]bool) bool { 68 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 69 val, ok := permissionsMap[roleName][permission] 70 return !(ok && val) 71 } 72 } 73 74 func onOtherRole(otherRole string, function func(string, map[string]map[string]bool) bool) func(string, map[string]map[string]bool) bool { 75 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 76 return function(otherRole, permissionsMap) 77 } 78 } 79 80 func permissionOr(funcs ...func(string, map[string]map[string]bool) bool) func(string, map[string]map[string]bool) bool { 81 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 82 for _, f := range funcs { 83 if f(roleName, permissionsMap) { 84 return true 85 } 86 } 87 return false 88 } 89 } 90 91 func permissionAnd(funcs ...func(string, map[string]map[string]bool) bool) func(string, map[string]map[string]bool) bool { 92 return func(roleName string, permissionsMap map[string]map[string]bool) bool { 93 for _, f := range funcs { 94 if !f(roleName, permissionsMap) { 95 return false 96 } 97 } 98 return true 99 } 100 } 101 102 func applyPermissionsMap(roleName string, roleMap map[string]map[string]bool, migrationMap permissionsMap) []string { 103 var result []string 104 105 for _, transformation := range migrationMap { 106 if transformation.On(roleName, roleMap) { 107 for _, permission := range transformation.Add { 108 roleMap[roleName][permission] = true 109 } 110 for _, permission := range transformation.Remove { 111 roleMap[roleName][permission] = false 112 } 113 } 114 } 115 116 for key, active := range roleMap[roleName] { 117 if active { 118 result = append(result, key) 119 } 120 } 121 return result 122 } 123 124 func (a *App) doPermissionsMigration(key string, migrationMap permissionsMap) *model.AppError { 125 if result := <-a.Srv.Store.System().GetByName(key); result.Err == nil { 126 return nil 127 } 128 129 roles, err := a.GetAllRoles() 130 if err != nil { 131 return err 132 } 133 134 roleMap := make(map[string]map[string]bool) 135 for _, role := range roles { 136 roleMap[role.Name] = make(map[string]bool) 137 for _, permission := range role.Permissions { 138 roleMap[role.Name][permission] = true 139 } 140 } 141 142 for _, role := range roles { 143 role.Permissions = applyPermissionsMap(role.Name, roleMap, migrationMap) 144 if result := <-a.Srv.Store.Role().Save(role); result.Err != nil { 145 return result.Err 146 } 147 } 148 149 if result := <-a.Srv.Store.System().Save(&model.System{Name: key, Value: "true"}); result.Err != nil { 150 return result.Err 151 } 152 return nil 153 } 154 155 func getEmojisPermissionsSplitMigration() permissionsMap { 156 return permissionsMap{ 157 permissionTransformation{ 158 On: permissionExists(PERMISSION_MANAGE_EMOJIS), 159 Add: []string{PERMISSION_CREATE_EMOJIS, PERMISSION_DELETE_EMOJIS}, 160 Remove: []string{PERMISSION_MANAGE_EMOJIS}, 161 }, 162 permissionTransformation{ 163 On: permissionExists(PERMISSION_MANAGE_OTHERS_EMOJIS), 164 Add: []string{PERMISSION_DELETE_OTHERS_EMOJIS}, 165 Remove: []string{PERMISSION_MANAGE_OTHERS_EMOJIS}, 166 }, 167 } 168 } 169 170 func getWebhooksPermissionsSplitMigration() permissionsMap { 171 return permissionsMap{ 172 permissionTransformation{ 173 On: permissionExists(PERMISSION_MANAGE_WEBHOOKS), 174 Add: []string{PERMISSION_MANAGE_INCOMING_WEBHOOKS, PERMISSION_MANAGE_OUTGOING_WEBHOOKS}, 175 Remove: []string{PERMISSION_MANAGE_WEBHOOKS}, 176 }, 177 permissionTransformation{ 178 On: permissionExists(PERMISSION_MANAGE_OTHERS_WEBHOOKS), 179 Add: []string{PERMISSION_MANAGE_OTHERS_INCOMING_WEBHOOKS, PERMISSION_MANAGE_OTHERS_OUTGOING_WEBHOOKS}, 180 Remove: []string{PERMISSION_MANAGE_OTHERS_WEBHOOKS}, 181 }, 182 } 183 } 184 185 func getListJoinPublicPrivateTeamsPermissionsMigration() permissionsMap { 186 return permissionsMap{ 187 permissionTransformation{ 188 On: isRole(model.SYSTEM_ADMIN_ROLE_ID), 189 Add: []string{PERMISSION_LIST_PRIVATE_TEAMS, PERMISSION_JOIN_PRIVATE_TEAMS}, 190 Remove: []string{}, 191 }, 192 permissionTransformation{ 193 On: isRole(model.SYSTEM_USER_ROLE_ID), 194 Add: []string{PERMISSION_LIST_PUBLIC_TEAMS, PERMISSION_JOIN_PUBLIC_TEAMS}, 195 Remove: []string{}, 196 }, 197 } 198 } 199 200 func removePermanentDeleteUserMigration() permissionsMap { 201 return permissionsMap{ 202 permissionTransformation{ 203 On: permissionExists(PERMISSION_PERMANENT_DELETE_USER), 204 Remove: []string{PERMISSION_PERMANENT_DELETE_USER}, 205 }, 206 } 207 } 208 209 func getAddBotPermissionsMigration() permissionsMap { 210 return permissionsMap{ 211 permissionTransformation{ 212 On: isRole(model.SYSTEM_ADMIN_ROLE_ID), 213 Add: []string{PERMISSION_CREATE_BOT, PERMISSION_READ_BOTS, PERMISSION_READ_OTHERS_BOTS, PERMISSION_MANAGE_BOTS, PERMISSION_MANAGE_OTHERS_BOTS}, 214 Remove: []string{}, 215 }, 216 } 217 } 218 219 func applyChannelManageDeleteToChannelUser() permissionsMap { 220 return permissionsMap{ 221 permissionTransformation{ 222 On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES))), 223 Add: []string{PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES}, 224 }, 225 permissionTransformation{ 226 On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_DELETE_PRIVATE_CHANNEL))), 227 Add: []string{PERMISSION_DELETE_PRIVATE_CHANNEL}, 228 }, 229 permissionTransformation{ 230 On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES))), 231 Add: []string{PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES}, 232 }, 233 permissionTransformation{ 234 On: permissionAnd(isRole(model.CHANNEL_USER_ROLE_ID), onOtherRole(model.TEAM_USER_ROLE_ID, permissionExists(PERMISSION_DELETE_PUBLIC_CHANNEL))), 235 Add: []string{PERMISSION_DELETE_PUBLIC_CHANNEL}, 236 }, 237 } 238 } 239 240 func removeChannelManageDeleteFromTeamUser() permissionsMap { 241 return permissionsMap{ 242 permissionTransformation{ 243 On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES)), 244 Remove: []string{PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES}, 245 }, 246 permissionTransformation{ 247 On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_DELETE_PRIVATE_CHANNEL)), 248 Remove: []string{model.PERMISSION_DELETE_PRIVATE_CHANNEL.Id}, 249 }, 250 permissionTransformation{ 251 On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES)), 252 Remove: []string{PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES}, 253 }, 254 permissionTransformation{ 255 On: permissionAnd(isRole(model.TEAM_USER_ROLE_ID), permissionExists(PERMISSION_DELETE_PUBLIC_CHANNEL)), 256 Remove: []string{PERMISSION_DELETE_PUBLIC_CHANNEL}, 257 }, 258 } 259 } 260 261 // DoPermissionsMigrations execute all the permissions migrations need by the current version. 262 func (a *App) DoPermissionsMigrations() *model.AppError { 263 PermissionsMigrations := []struct { 264 Key string 265 Migration func() permissionsMap 266 }{ 267 {Key: MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration}, 268 {Key: MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration}, 269 {Key: MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration}, 270 {Key: MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Migration: removePermanentDeleteUserMigration}, 271 {Key: MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: getAddBotPermissionsMigration}, 272 {Key: MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: applyChannelManageDeleteToChannelUser}, 273 {Key: MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser}, 274 } 275 276 for _, migration := range PermissionsMigrations { 277 if err := a.doPermissionsMigration(migration.Key, migration.Migration()); err != nil { 278 return err 279 } 280 } 281 return nil 282 }