github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/app/syncables.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 "strings" 10 11 "github.com/mattermost/mattermost-server/v5/mlog" 12 "github.com/mattermost/mattermost-server/v5/model" 13 ) 14 15 // createDefaultChannelMemberships adds users to channels based on their group memberships and how those groups are 16 // configured to sync with channels for group members on or after the given timestamp. If a channelID is given 17 // only that channel's members are created. If channelID is nil all channel memberships are created. 18 func (a *App) createDefaultChannelMemberships(since int64, channelID *string) error { 19 channelMembers, appErr := a.ChannelMembersToAdd(since, channelID) 20 if appErr != nil { 21 return appErr 22 } 23 24 for _, userChannel := range channelMembers { 25 channel, err := a.GetChannel(userChannel.ChannelID) 26 if err != nil { 27 return err 28 } 29 30 tmem, err := a.GetTeamMember(channel.TeamId, userChannel.UserID) 31 if err != nil && err.Id != "app.team.get_member.missing.app_error" { 32 return err 33 } 34 35 // First add user to team 36 if tmem == nil { 37 _, err = a.AddTeamMember(channel.TeamId, userChannel.UserID) 38 if err != nil { 39 if err.Id == "api.team.join_user_to_team.allowed_domains.app_error" { 40 a.Log().Info("User not added to channel - the domain associated with the user is not in the list of allowed team domains", 41 mlog.String("user_id", userChannel.UserID), 42 mlog.String("channel_id", userChannel.ChannelID), 43 mlog.String("team_id", channel.TeamId), 44 ) 45 continue 46 } 47 return err 48 } 49 a.Log().Info("added teammember", 50 mlog.String("user_id", userChannel.UserID), 51 mlog.String("team_id", channel.TeamId), 52 ) 53 } 54 55 _, err = a.AddChannelMember(userChannel.UserID, channel, "", "") 56 if err != nil { 57 if err.Id == "api.channel.add_user.to.channel.failed.deleted.app_error" { 58 a.Log().Info("Not adding user to channel because they have already left the team", 59 mlog.String("user_id", userChannel.UserID), 60 mlog.String("channel_id", userChannel.ChannelID), 61 ) 62 } else { 63 return err 64 } 65 } 66 67 a.Log().Info("added channelmember", 68 mlog.String("user_id", userChannel.UserID), 69 mlog.String("channel_id", userChannel.ChannelID), 70 ) 71 } 72 73 return nil 74 } 75 76 // createDefaultTeamMemberships adds users to teams based on their group memberships and how those groups are 77 // configured to sync with teams for group members on or after the given timestamp. If a teamID is given 78 // only that team's members are created. If teamID is nil all team memberships are created. 79 func (a *App) createDefaultTeamMemberships(since int64, teamID *string) error { 80 teamMembers, appErr := a.TeamMembersToAdd(since, teamID) 81 if appErr != nil { 82 return appErr 83 } 84 85 for _, userTeam := range teamMembers { 86 _, err := a.AddTeamMember(userTeam.TeamID, userTeam.UserID) 87 if err != nil { 88 if err.Id == "api.team.join_user_to_team.allowed_domains.app_error" { 89 a.Log().Info("User not added to team - the domain associated with the user is not in the list of allowed team domains", 90 mlog.String("user_id", userTeam.UserID), 91 mlog.String("team_id", userTeam.TeamID), 92 ) 93 continue 94 } 95 return err 96 } 97 98 a.Log().Info("added teammember", 99 mlog.String("user_id", userTeam.UserID), 100 mlog.String("team_id", userTeam.TeamID), 101 ) 102 } 103 104 return nil 105 } 106 107 // CreateDefaultMemberships adds users to teams and channels based on their group memberships and how those groups 108 // are configured to sync with teams and channels for group members on or after the given timestamp. 109 func (a *App) CreateDefaultMemberships(since int64) error { 110 err := a.createDefaultTeamMemberships(since, nil) 111 if err != nil { 112 return err 113 } 114 115 err = a.createDefaultChannelMemberships(since, nil) 116 if err != nil { 117 return err 118 } 119 120 return nil 121 } 122 123 // DeleteGroupConstrainedMemberships deletes team and channel memberships of users who aren't members of the allowed 124 // groups of all group-constrained teams and channels. 125 func (a *App) DeleteGroupConstrainedMemberships() error { 126 err := a.deleteGroupConstrainedChannelMemberships(nil) 127 if err != nil { 128 return err 129 } 130 131 err = a.deleteGroupConstrainedTeamMemberships(nil) 132 if err != nil { 133 return err 134 } 135 136 return nil 137 } 138 139 // deleteGroupConstrainedTeamMemberships deletes team memberships of users who aren't members of the allowed 140 // groups of the given group-constrained team. If a teamID is given then the procedure is scoped to the given team, 141 // if teamID is nil then the procedure affects all teams. 142 func (a *App) deleteGroupConstrainedTeamMemberships(teamID *string) error { 143 teamMembers, appErr := a.TeamMembersToRemove(teamID) 144 if appErr != nil { 145 return appErr 146 } 147 148 for _, userTeam := range teamMembers { 149 err := a.RemoveUserFromTeam(userTeam.TeamId, userTeam.UserId, "") 150 if err != nil { 151 return err 152 } 153 154 a.Log().Info("removed teammember", 155 mlog.String("user_id", userTeam.UserId), 156 mlog.String("team_id", userTeam.TeamId), 157 ) 158 } 159 160 return nil 161 } 162 163 // deleteGroupConstrainedChannelMemberships deletes channel memberships of users who aren't members of the allowed 164 // groups of the given group-constrained channel. If a channelID is given then the procedure is scoped to the given team, 165 // if channelID is nil then the procedure affects all teams. 166 func (a *App) deleteGroupConstrainedChannelMemberships(channelID *string) error { 167 channelMembers, appErr := a.ChannelMembersToRemove(channelID) 168 if appErr != nil { 169 return appErr 170 } 171 172 for _, userChannel := range channelMembers { 173 channel, err := a.GetChannel(userChannel.ChannelId) 174 if err != nil { 175 return err 176 } 177 178 err = a.RemoveUserFromChannel(userChannel.UserId, "", channel) 179 if err != nil { 180 return err 181 } 182 183 a.Log().Info("removed channelmember", 184 mlog.String("user_id", userChannel.UserId), 185 mlog.String("channel_id", channel.Id), 186 ) 187 } 188 189 return nil 190 } 191 192 // SyncSyncableRoles updates the SchemeAdmin field value of the given syncable's members based on the configuration of 193 // the member's group memberships and the configuration of those groups to the syncable. This method should only 194 // be invoked on group-synced (aka group-constrained) syncables. 195 func (a *App) SyncSyncableRoles(syncableID string, syncableType model.GroupSyncableType) *model.AppError { 196 permittedAdmins, err := a.Srv().Store.Group().PermittedSyncableAdmins(syncableID, syncableType) 197 if err != nil { 198 return model.NewAppError("SyncSyncableRoles", "app.select_error", nil, err.Error(), http.StatusInternalServerError) 199 } 200 201 a.Log().Info( 202 fmt.Sprintf("Permitted admins for %s", syncableType), 203 mlog.String(strings.ToLower(fmt.Sprintf("%s_id", syncableType)), syncableID), 204 mlog.Any("permitted_admins", permittedAdmins), 205 ) 206 207 switch syncableType { 208 case model.GroupSyncableTypeTeam: 209 nErr := a.Srv().Store.Team().UpdateMembersRole(syncableID, permittedAdmins) 210 if nErr != nil { 211 return model.NewAppError("App.SyncSyncableRoles", "app.update_error", nil, nErr.Error(), http.StatusInternalServerError) 212 } 213 return nil 214 case model.GroupSyncableTypeChannel: 215 nErr := a.Srv().Store.Channel().UpdateMembersRole(syncableID, permittedAdmins) 216 if nErr != nil { 217 return model.NewAppError("App.SyncSyncableRoles", "app.update_error", nil, nErr.Error(), http.StatusInternalServerError) 218 } 219 return nil 220 default: 221 return model.NewAppError("App.SyncSyncableRoles", "groups.unsupported_syncable_type", map[string]interface{}{"Value": syncableType}, "", http.StatusInternalServerError) 222 } 223 } 224 225 // SyncRolesAndMembership updates the SchemeAdmin status and membership of all of the members of the given 226 // syncable. 227 func (a *App) SyncRolesAndMembership(syncableID string, syncableType model.GroupSyncableType) { 228 a.SyncSyncableRoles(syncableID, syncableType) 229 230 lastJob, _ := a.Srv().Store.Job().GetNewestJobByStatusAndType(model.JOB_STATUS_SUCCESS, model.JOB_TYPE_LDAP_SYNC) 231 var since int64 232 if lastJob != nil { 233 since = lastJob.StartAt 234 } 235 236 switch syncableType { 237 case model.GroupSyncableTypeTeam: 238 a.createDefaultTeamMemberships(since, &syncableID) 239 a.deleteGroupConstrainedTeamMemberships(&syncableID) 240 a.ClearTeamMembersCache(syncableID) 241 case model.GroupSyncableTypeChannel: 242 a.createDefaultChannelMemberships(since, &syncableID) 243 a.deleteGroupConstrainedChannelMemberships(&syncableID) 244 a.ClearChannelMembersCache(syncableID) 245 } 246 }