github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/app/channel.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 "context" 8 "errors" 9 "fmt" 10 "net/http" 11 "strings" 12 "time" 13 14 "github.com/mattermost/mattermost-server/v5/mlog" 15 "github.com/mattermost/mattermost-server/v5/model" 16 "github.com/mattermost/mattermost-server/v5/plugin" 17 "github.com/mattermost/mattermost-server/v5/store" 18 "github.com/mattermost/mattermost-server/v5/utils" 19 ) 20 21 // CreateDefaultChannels creates channels in the given team for each channel returned by (*App).DefaultChannelNames. 22 // 23 func (a *App) CreateDefaultChannels(teamID string) ([]*model.Channel, *model.AppError) { 24 displayNames := map[string]string{ 25 "town-square": utils.T("api.channel.create_default_channels.town_square"), 26 "off-topic": utils.T("api.channel.create_default_channels.off_topic"), 27 } 28 channels := []*model.Channel{} 29 defaultChannelNames := a.DefaultChannelNames() 30 for _, name := range defaultChannelNames { 31 displayName := utils.TDefault(displayNames[name], name) 32 channel := &model.Channel{DisplayName: displayName, Name: name, Type: model.CHANNEL_OPEN, TeamId: teamID} 33 if _, err := a.CreateChannel(channel, false); err != nil { 34 return nil, err 35 } 36 channels = append(channels, channel) 37 } 38 return channels, nil 39 } 40 41 // DefaultChannelNames returns the list of system-wide default channel names. 42 // 43 // By default the list will be (not necessarily in this order): 44 // ['town-square', 'off-topic'] 45 // However, if TeamSettings.ExperimentalDefaultChannels contains a list of channels then that list will replace 46 // 'off-topic' and be included in the return results in addition to 'town-square'. For example: 47 // ['town-square', 'game-of-thrones', 'wow'] 48 // 49 func (a *App) DefaultChannelNames() []string { 50 names := []string{"town-square"} 51 52 if len(a.Config().TeamSettings.ExperimentalDefaultChannels) == 0 { 53 names = append(names, "off-topic") 54 } else { 55 seenChannels := map[string]bool{"town-square": true} 56 for _, channelName := range a.Config().TeamSettings.ExperimentalDefaultChannels { 57 if !seenChannels[channelName] { 58 names = append(names, channelName) 59 seenChannels[channelName] = true 60 } 61 } 62 } 63 64 return names 65 } 66 67 func (a *App) JoinDefaultChannels(teamID string, user *model.User, shouldBeAdmin bool, userRequestorId string) *model.AppError { 68 var requestor *model.User 69 var nErr error 70 if userRequestorId != "" { 71 requestor, nErr = a.Srv().Store.User().Get(context.Background(), userRequestorId) 72 if nErr != nil { 73 var nfErr *store.ErrNotFound 74 switch { 75 case errors.As(nErr, &nfErr): 76 return model.NewAppError("JoinDefaultChannels", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 77 default: 78 return model.NewAppError("JoinDefaultChannels", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) 79 } 80 } 81 } 82 83 var err *model.AppError 84 for _, channelName := range a.DefaultChannelNames() { 85 channel, channelErr := a.Srv().Store.Channel().GetByName(teamID, channelName, true) 86 if channelErr != nil { 87 var nfErr *store.ErrNotFound 88 switch { 89 case errors.As(err, &nfErr): 90 err = model.NewAppError("JoinDefaultChannels", "app.channel.get_by_name.missing.app_error", nil, nfErr.Error(), http.StatusNotFound) 91 default: 92 err = model.NewAppError("JoinDefaultChannels", "app.channel.get_by_name.existing.app_error", nil, channelErr.Error(), http.StatusInternalServerError) 93 } 94 continue 95 } 96 97 if channel.Type != model.CHANNEL_OPEN { 98 continue 99 } 100 101 cm := &model.ChannelMember{ 102 ChannelId: channel.Id, 103 UserId: user.Id, 104 SchemeGuest: user.IsGuest(), 105 SchemeUser: !user.IsGuest(), 106 SchemeAdmin: shouldBeAdmin, 107 NotifyProps: model.GetDefaultChannelNotifyProps(), 108 } 109 110 _, nErr = a.Srv().Store.Channel().SaveMember(cm) 111 if histErr := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); histErr != nil { 112 return model.NewAppError("JoinDefaultChannels", "app.channel_member_history.log_join_event.internal_error", nil, histErr.Error(), http.StatusInternalServerError) 113 } 114 115 if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 116 if aErr := a.postJoinMessageForDefaultChannel(user, requestor, channel); aErr != nil { 117 mlog.Warn("Failed to post join/leave message", mlog.Err(aErr)) 118 } 119 } 120 121 a.invalidateCacheForChannelMembers(channel.Id) 122 123 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil) 124 message.Add("user_id", user.Id) 125 message.Add("team_id", channel.TeamId) 126 a.Publish(message) 127 128 } 129 130 if nErr != nil { 131 var appErr *model.AppError 132 var cErr *store.ErrConflict 133 switch { 134 case errors.As(nErr, &cErr): 135 if cErr.Resource == "ChannelMembers" { 136 return model.NewAppError("JoinDefaultChannels", "app.channel.save_member.exists.app_error", nil, cErr.Error(), http.StatusBadRequest) 137 } 138 case errors.As(nErr, &appErr): 139 return appErr 140 default: 141 return model.NewAppError("JoinDefaultChannels", "app.channel.create_direct_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 142 } 143 } 144 145 return nil 146 } 147 148 func (a *App) postJoinMessageForDefaultChannel(user *model.User, requestor *model.User, channel *model.Channel) *model.AppError { 149 if channel.Name == model.DEFAULT_CHANNEL { 150 if requestor == nil { 151 if err := a.postJoinTeamMessage(user, channel); err != nil { 152 return err 153 } 154 } else { 155 if err := a.postAddToTeamMessage(requestor, user, channel, ""); err != nil { 156 return err 157 } 158 } 159 } else { 160 if requestor == nil { 161 if err := a.postJoinChannelMessage(user, channel); err != nil { 162 return err 163 } 164 } else { 165 if err := a.PostAddToChannelMessage(requestor, user, channel, ""); err != nil { 166 return err 167 } 168 } 169 } 170 171 return nil 172 } 173 174 func (a *App) CreateChannelWithUser(channel *model.Channel, userID string) (*model.Channel, *model.AppError) { 175 if channel.IsGroupOrDirect() { 176 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.direct_channel.app_error", nil, "", http.StatusBadRequest) 177 } 178 179 if channel.TeamId == "" { 180 return nil, model.NewAppError("CreateChannelWithUser", "app.channel.create_channel.no_team_id.app_error", nil, "", http.StatusBadRequest) 181 } 182 183 // Get total number of channels on current team 184 count, err := a.GetNumberOfChannelsOnTeam(channel.TeamId) 185 if err != nil { 186 return nil, err 187 } 188 189 if int64(count+1) > *a.Config().TeamSettings.MaxChannelsPerTeam { 190 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.max_channel_limit.app_error", map[string]interface{}{"MaxChannelsPerTeam": *a.Config().TeamSettings.MaxChannelsPerTeam}, "", http.StatusBadRequest) 191 } 192 193 channel.CreatorId = userID 194 195 rchannel, err := a.CreateChannel(channel, true) 196 if err != nil { 197 return nil, err 198 } 199 200 var user *model.User 201 if user, err = a.GetUser(userID); err != nil { 202 return nil, err 203 } 204 205 a.postJoinChannelMessage(user, channel) 206 207 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_CREATED, "", "", userID, nil) 208 message.Add("channel_id", channel.Id) 209 message.Add("team_id", channel.TeamId) 210 a.Publish(message) 211 212 return rchannel, nil 213 } 214 215 // RenameChannel is used to rename the channel Name and the DisplayName fields 216 func (a *App) RenameChannel(channel *model.Channel, newChannelName string, newDisplayName string) (*model.Channel, *model.AppError) { 217 if channel.Type == model.CHANNEL_DIRECT { 218 return nil, model.NewAppError("RenameChannel", "api.channel.rename_channel.cant_rename_direct_messages.app_error", nil, "", http.StatusBadRequest) 219 } 220 221 if channel.Type == model.CHANNEL_GROUP { 222 return nil, model.NewAppError("RenameChannel", "api.channel.rename_channel.cant_rename_group_messages.app_error", nil, "", http.StatusBadRequest) 223 } 224 225 channel.Name = newChannelName 226 if newDisplayName != "" { 227 channel.DisplayName = newDisplayName 228 } 229 230 newChannel, err := a.UpdateChannel(channel) 231 if err != nil { 232 return nil, err 233 } 234 235 return newChannel, nil 236 } 237 238 func (a *App) CreateChannel(channel *model.Channel, addMember bool) (*model.Channel, *model.AppError) { 239 channel.DisplayName = strings.TrimSpace(channel.DisplayName) 240 sc, nErr := a.Srv().Store.Channel().Save(channel, *a.Config().TeamSettings.MaxChannelsPerTeam) 241 if nErr != nil { 242 var invErr *store.ErrInvalidInput 243 var cErr *store.ErrConflict 244 var ltErr *store.ErrLimitExceeded 245 var appErr *model.AppError 246 switch { 247 case errors.As(nErr, &invErr): 248 switch { 249 case invErr.Entity == "Channel" && invErr.Field == "DeleteAt": 250 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save.archived_channel.app_error", nil, "", http.StatusBadRequest) 251 case invErr.Entity == "Channel" && invErr.Field == "Type": 252 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save.direct_channel.app_error", nil, "", http.StatusBadRequest) 253 case invErr.Entity == "Channel" && invErr.Field == "Id": 254 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save_channel.existing.app_error", nil, "id="+invErr.Value.(string), http.StatusBadRequest) 255 } 256 case errors.As(nErr, &cErr): 257 return sc, model.NewAppError("CreateChannel", store.ChannelExistsError, nil, cErr.Error(), http.StatusBadRequest) 258 case errors.As(nErr, <Err): 259 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save_channel.limit.app_error", nil, ltErr.Error(), http.StatusBadRequest) 260 case errors.As(nErr, &appErr): // in case we haven't converted to plain error. 261 return nil, appErr 262 default: // last fallback in case it doesn't map to an existing app error. 263 return nil, model.NewAppError("CreateChannel", "app.channel.create_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 264 } 265 } 266 267 if addMember { 268 user, nErr := a.Srv().Store.User().Get(context.Background(), channel.CreatorId) 269 if nErr != nil { 270 var nfErr *store.ErrNotFound 271 switch { 272 case errors.As(nErr, &nfErr): 273 return nil, model.NewAppError("CreateChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 274 default: 275 return nil, model.NewAppError("CreateChannel", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) 276 } 277 } 278 279 cm := &model.ChannelMember{ 280 ChannelId: sc.Id, 281 UserId: user.Id, 282 SchemeGuest: user.IsGuest(), 283 SchemeUser: !user.IsGuest(), 284 SchemeAdmin: true, 285 NotifyProps: model.GetDefaultChannelNotifyProps(), 286 } 287 288 if _, nErr := a.Srv().Store.Channel().SaveMember(cm); nErr != nil { 289 var appErr *model.AppError 290 var cErr *store.ErrConflict 291 switch { 292 case errors.As(nErr, &cErr): 293 switch cErr.Resource { 294 case "ChannelMembers": 295 return nil, model.NewAppError("CreateChannel", "app.channel.save_member.exists.app_error", nil, cErr.Error(), http.StatusBadRequest) 296 } 297 case errors.As(nErr, &appErr): 298 return nil, appErr 299 default: 300 return nil, model.NewAppError("CreateChannel", "app.channel.create_direct_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 301 } 302 } 303 304 if err := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(channel.CreatorId, sc.Id, model.GetMillis()); err != nil { 305 return nil, model.NewAppError("CreateChannel", "app.channel_member_history.log_join_event.internal_error", nil, err.Error(), http.StatusInternalServerError) 306 } 307 308 a.InvalidateCacheForUser(channel.CreatorId) 309 } 310 311 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 312 a.Srv().Go(func() { 313 pluginContext := a.PluginContext() 314 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 315 hooks.ChannelHasBeenCreated(pluginContext, sc) 316 return true 317 }, plugin.ChannelHasBeenCreatedId) 318 }) 319 } 320 321 return sc, nil 322 } 323 324 func (a *App) GetOrCreateDirectChannel(userID, otherUserID string) (*model.Channel, *model.AppError) { 325 channel, nErr := a.getDirectChannel(userID, otherUserID) 326 if nErr != nil { 327 return nil, nErr 328 } 329 330 if channel != nil { 331 return channel, nil 332 } 333 334 channel, err := a.createDirectChannel(userID, otherUserID) 335 if err != nil { 336 if err.Id == store.ChannelExistsError { 337 return channel, nil 338 } 339 return nil, err 340 } 341 342 a.WaitForChannelMembership(channel.Id, userID) 343 a.handleCreationEvent(userID, otherUserID, channel) 344 return channel, nil 345 } 346 347 func (a *App) getOrCreateDirectChannelWithUser(user, otherUser *model.User) (*model.Channel, *model.AppError) { 348 channel, nErr := a.getDirectChannel(user.Id, otherUser.Id) 349 if nErr != nil { 350 return nil, nErr 351 } 352 353 if channel != nil { 354 return channel, nil 355 } 356 357 channel, err := a.createDirectChannelWithUser(user, otherUser) 358 if err != nil { 359 if err.Id == store.ChannelExistsError { 360 return channel, nil 361 } 362 return nil, err 363 } 364 365 a.WaitForChannelMembership(channel.Id, user.Id) 366 a.handleCreationEvent(user.Id, otherUser.Id, channel) 367 return channel, nil 368 } 369 370 func (a *App) handleCreationEvent(userID, otherUserID string, channel *model.Channel) { 371 a.InvalidateCacheForUser(userID) 372 a.InvalidateCacheForUser(otherUserID) 373 374 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 375 a.Srv().Go(func() { 376 pluginContext := a.PluginContext() 377 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 378 hooks.ChannelHasBeenCreated(pluginContext, channel) 379 return true 380 }, plugin.ChannelHasBeenCreatedId) 381 }) 382 } 383 384 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil) 385 message.Add("teammate_id", otherUserID) 386 a.Publish(message) 387 } 388 389 func (a *App) createDirectChannel(userID, otherUserID string) (*model.Channel, *model.AppError) { 390 users, err := a.Srv().Store.User().GetMany(context.Background(), []string{userID, otherUserID}) 391 if err != nil { 392 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, err.Error(), http.StatusBadRequest) 393 } 394 395 if len(users) == 0 { 396 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, fmt.Sprintf("No users found for ids: %s. %s", userID, otherUserID), http.StatusBadRequest) 397 } 398 399 // We are doing this because we allow a user to create a direct channel with themselves 400 if userID == otherUserID { 401 users = append(users, users[0]) 402 } 403 404 // After we counted for direct channels with the same user, if we do not have two users then we failed to find one 405 if len(users) != 2 { 406 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, fmt.Sprintf("No users found for ids: %s. %s", userID, otherUserID), http.StatusBadRequest) 407 } 408 409 // The potential swap dance bellow is necessary in order to guarantee determinism when creating a direct channel. 410 // When we query the database for some given user ids, the database result is not deterministic, meaning we can get 411 // the same results but in different order. In order to conform the contract of Channel.CreateDirectChannel method 412 // bellow we need to identify which user is who. 413 user := users[0] 414 otherUser := users[1] 415 if user.Id != userID { 416 user = users[1] 417 otherUser = users[0] 418 } 419 return a.createDirectChannelWithUser(user, otherUser) 420 } 421 422 func (a *App) createDirectChannelWithUser(user, otherUser *model.User) (*model.Channel, *model.AppError) { 423 channel, nErr := a.Srv().Store.Channel().CreateDirectChannel(user, otherUser) 424 if nErr != nil { 425 var invErr *store.ErrInvalidInput 426 var cErr *store.ErrConflict 427 var ltErr *store.ErrLimitExceeded 428 var appErr *model.AppError 429 switch { 430 case errors.As(nErr, &invErr): 431 switch { 432 case invErr.Entity == "Channel" && invErr.Field == "DeleteAt": 433 return nil, model.NewAppError("createDirectChannelWithUser", "store.sql_channel.save.archived_channel.app_error", nil, "", http.StatusBadRequest) 434 case invErr.Entity == "Channel" && invErr.Field == "Type": 435 return nil, model.NewAppError("createDirectChannelWithUser", "store.sql_channel.save_direct_channel.not_direct.app_error", nil, "", http.StatusBadRequest) 436 case invErr.Entity == "Channel" && invErr.Field == "Id": 437 return nil, model.NewAppError("SqlChannelStore.Save", "store.sql_channel.save_channel.existing.app_error", nil, "id="+invErr.Value.(string), http.StatusBadRequest) 438 } 439 case errors.As(nErr, &cErr): 440 switch cErr.Resource { 441 case "Channel": 442 return channel, model.NewAppError("createDirectChannelWithUser", store.ChannelExistsError, nil, cErr.Error(), http.StatusBadRequest) 443 case "ChannelMembers": 444 return nil, model.NewAppError("createDirectChannelWithUser", "app.channel.save_member.exists.app_error", nil, cErr.Error(), http.StatusBadRequest) 445 } 446 case errors.As(nErr, <Err): 447 return nil, model.NewAppError("createDirectChannelWithUser", "store.sql_channel.save_channel.limit.app_error", nil, ltErr.Error(), http.StatusBadRequest) 448 case errors.As(nErr, &appErr): // in case we haven't converted to plain error. 449 return nil, appErr 450 default: // last fallback in case it doesn't map to an existing app error. 451 return nil, model.NewAppError("createDirectChannelWithUser", "app.channel.create_direct_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 452 } 453 } 454 455 if err := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); err != nil { 456 return nil, model.NewAppError("createDirectChannelWithUser", "app.channel_member_history.log_join_event.internal_error", nil, err.Error(), http.StatusInternalServerError) 457 } 458 if user.Id != otherUser.Id { 459 if err := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(otherUser.Id, channel.Id, model.GetMillis()); err != nil { 460 return nil, model.NewAppError("createDirectChannelWithUser", "app.channel_member_history.log_join_event.internal_error", nil, err.Error(), http.StatusInternalServerError) 461 } 462 } 463 464 return channel, nil 465 } 466 467 func (a *App) WaitForChannelMembership(channelId string, userID string) { 468 if len(a.Config().SqlSettings.DataSourceReplicas) == 0 { 469 return 470 } 471 472 now := model.GetMillis() 473 474 for model.GetMillis()-now < 12000 { 475 476 time.Sleep(100 * time.Millisecond) 477 478 _, err := a.Srv().Store.Channel().GetMember(channelId, userID) 479 480 // If the membership was found then return 481 if err == nil { 482 return 483 } 484 485 // If we received an error, but it wasn't a missing channel member then return 486 var nfErr *store.ErrNotFound 487 if !errors.As(err, &nfErr) { 488 return 489 } 490 } 491 492 mlog.Error("WaitForChannelMembership giving up", mlog.String("channel_id", channelId), mlog.String("user_id", userID)) 493 } 494 495 func (a *App) CreateGroupChannel(userIDs []string, creatorId string) (*model.Channel, *model.AppError) { 496 channel, err := a.createGroupChannel(userIDs) 497 if err != nil { 498 if err.Id == store.ChannelExistsError { 499 return channel, nil 500 } 501 return nil, err 502 } 503 504 for _, userID := range userIDs { 505 if userID == creatorId { 506 a.WaitForChannelMembership(channel.Id, creatorId) 507 } 508 509 a.InvalidateCacheForUser(userID) 510 } 511 512 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_GROUP_ADDED, "", channel.Id, "", nil) 513 message.Add("teammate_ids", model.ArrayToJson(userIDs)) 514 a.Publish(message) 515 516 return channel, nil 517 } 518 519 func (a *App) createGroupChannel(userIDs []string) (*model.Channel, *model.AppError) { 520 if len(userIDs) > model.CHANNEL_GROUP_MAX_USERS || len(userIDs) < model.CHANNEL_GROUP_MIN_USERS { 521 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest) 522 } 523 524 users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, nil, true) 525 if err != nil { 526 return nil, model.NewAppError("createGroupChannel", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError) 527 } 528 529 if len(users) != len(userIDs) { 530 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIDs), http.StatusBadRequest) 531 } 532 533 group := &model.Channel{ 534 Name: model.GetGroupNameFromUserIds(userIDs), 535 DisplayName: model.GetGroupDisplayNameFromUsers(users, true), 536 Type: model.CHANNEL_GROUP, 537 } 538 539 channel, nErr := a.Srv().Store.Channel().Save(group, *a.Config().TeamSettings.MaxChannelsPerTeam) 540 if nErr != nil { 541 var invErr *store.ErrInvalidInput 542 var cErr *store.ErrConflict 543 var ltErr *store.ErrLimitExceeded 544 var appErr *model.AppError 545 switch { 546 case errors.As(nErr, &invErr): 547 switch { 548 case invErr.Entity == "Channel" && invErr.Field == "DeleteAt": 549 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save.archived_channel.app_error", nil, "", http.StatusBadRequest) 550 case invErr.Entity == "Channel" && invErr.Field == "Type": 551 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save.direct_channel.app_error", nil, "", http.StatusBadRequest) 552 case invErr.Entity == "Channel" && invErr.Field == "Id": 553 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save_channel.existing.app_error", nil, "id="+invErr.Value.(string), http.StatusBadRequest) 554 } 555 case errors.As(nErr, &cErr): 556 return channel, model.NewAppError("CreateChannel", store.ChannelExistsError, nil, cErr.Error(), http.StatusBadRequest) 557 case errors.As(nErr, <Err): 558 return nil, model.NewAppError("CreateChannel", "store.sql_channel.save_channel.limit.app_error", nil, ltErr.Error(), http.StatusBadRequest) 559 case errors.As(nErr, &appErr): // in case we haven't converted to plain error. 560 return nil, appErr 561 default: // last fallback in case it doesn't map to an existing app error. 562 return nil, model.NewAppError("CreateChannel", "app.channel.create_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 563 } 564 } 565 566 for _, user := range users { 567 cm := &model.ChannelMember{ 568 UserId: user.Id, 569 ChannelId: group.Id, 570 NotifyProps: model.GetDefaultChannelNotifyProps(), 571 SchemeGuest: user.IsGuest(), 572 SchemeUser: !user.IsGuest(), 573 } 574 575 if _, nErr = a.Srv().Store.Channel().SaveMember(cm); nErr != nil { 576 var appErr *model.AppError 577 var cErr *store.ErrConflict 578 switch { 579 case errors.As(nErr, &cErr): 580 switch cErr.Resource { 581 case "ChannelMembers": 582 return nil, model.NewAppError("createGroupChannel", "app.channel.save_member.exists.app_error", nil, cErr.Error(), http.StatusBadRequest) 583 } 584 case errors.As(nErr, &appErr): 585 return nil, appErr 586 default: 587 return nil, model.NewAppError("createGroupChannel", "app.channel.create_direct_channel.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 588 } 589 } 590 if err := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); err != nil { 591 return nil, model.NewAppError("createGroupChannel", "app.channel_member_history.log_join_event.internal_error", nil, err.Error(), http.StatusInternalServerError) 592 } 593 } 594 595 return channel, nil 596 } 597 598 func (a *App) GetGroupChannel(userIDs []string) (*model.Channel, *model.AppError) { 599 if len(userIDs) > model.CHANNEL_GROUP_MAX_USERS || len(userIDs) < model.CHANNEL_GROUP_MIN_USERS { 600 return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest) 601 } 602 603 users, err := a.Srv().Store.User().GetProfileByIds(context.Background(), userIDs, nil, true) 604 if err != nil { 605 return nil, model.NewAppError("GetGroupChannel", "app.user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError) 606 } 607 608 if len(users) != len(userIDs) { 609 return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIDs), http.StatusBadRequest) 610 } 611 612 channel, appErr := a.GetChannelByName(model.GetGroupNameFromUserIds(userIDs), "", true) 613 if appErr != nil { 614 return nil, appErr 615 } 616 617 return channel, nil 618 } 619 620 // UpdateChannel updates a given channel by its Id. It also publishes the CHANNEL_UPDATED event. 621 func (a *App) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 622 _, err := a.Srv().Store.Channel().Update(channel) 623 if err != nil { 624 var appErr *model.AppError 625 var invErr *store.ErrInvalidInput 626 switch { 627 case errors.As(err, &invErr): 628 return nil, model.NewAppError("UpdateChannel", "app.channel.update.bad_id", nil, invErr.Error(), http.StatusBadRequest) 629 case errors.As(err, &appErr): 630 return nil, appErr 631 default: 632 return nil, model.NewAppError("UpdateChannel", "app.channel.update_channel.internal_error", nil, err.Error(), http.StatusInternalServerError) 633 } 634 } 635 636 a.invalidateCacheForChannel(channel) 637 638 messageWs := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_UPDATED, "", channel.Id, "", nil) 639 messageWs.Add("channel", channel.ToJson()) 640 a.Publish(messageWs) 641 642 return channel, nil 643 } 644 645 // CreateChannelScheme creates a new Scheme of scope channel and assigns it to the channel. 646 func (a *App) CreateChannelScheme(channel *model.Channel) (*model.Scheme, *model.AppError) { 647 scheme, err := a.CreateScheme(&model.Scheme{ 648 Name: model.NewId(), 649 DisplayName: model.NewId(), 650 Scope: model.SCHEME_SCOPE_CHANNEL, 651 }) 652 if err != nil { 653 return nil, err 654 } 655 656 channel.SchemeId = &scheme.Id 657 if _, err := a.UpdateChannelScheme(channel); err != nil { 658 return nil, err 659 } 660 return scheme, nil 661 } 662 663 // DeleteChannelScheme deletes a channels scheme and sets its SchemeId to nil. 664 func (a *App) DeleteChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError) { 665 if channel.SchemeId != nil && *channel.SchemeId != "" { 666 if _, err := a.DeleteScheme(*channel.SchemeId); err != nil { 667 return nil, err 668 } 669 } 670 channel.SchemeId = nil 671 return a.UpdateChannelScheme(channel) 672 } 673 674 // UpdateChannelScheme saves the new SchemeId of the channel passed. 675 func (a *App) UpdateChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError) { 676 var oldChannel *model.Channel 677 var err *model.AppError 678 if oldChannel, err = a.GetChannel(channel.Id); err != nil { 679 return nil, err 680 } 681 682 oldChannel.SchemeId = channel.SchemeId 683 return a.UpdateChannel(oldChannel) 684 } 685 686 func (a *App) UpdateChannelPrivacy(oldChannel *model.Channel, user *model.User) (*model.Channel, *model.AppError) { 687 channel, err := a.UpdateChannel(oldChannel) 688 if err != nil { 689 return channel, err 690 } 691 692 if err := a.postChannelPrivacyMessage(user, channel); err != nil { 693 if channel.Type == model.CHANNEL_OPEN { 694 channel.Type = model.CHANNEL_PRIVATE 695 } else { 696 channel.Type = model.CHANNEL_OPEN 697 } 698 // revert to previous channel privacy 699 a.UpdateChannel(channel) 700 return channel, err 701 } 702 703 a.invalidateCacheForChannel(channel) 704 705 messageWs := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_CONVERTED, channel.TeamId, "", "", nil) 706 messageWs.Add("channel_id", channel.Id) 707 a.Publish(messageWs) 708 709 return channel, nil 710 } 711 712 func (a *App) postChannelPrivacyMessage(user *model.User, channel *model.Channel) *model.AppError { 713 message := (map[string]string{ 714 model.CHANNEL_OPEN: utils.T("api.channel.change_channel_privacy.private_to_public"), 715 model.CHANNEL_PRIVATE: utils.T("api.channel.change_channel_privacy.public_to_private"), 716 })[channel.Type] 717 post := &model.Post{ 718 ChannelId: channel.Id, 719 Message: message, 720 Type: model.POST_CHANGE_CHANNEL_PRIVACY, 721 UserId: user.Id, 722 Props: model.StringInterface{ 723 "username": user.Username, 724 }, 725 } 726 727 if _, err := a.CreatePost(post, channel, false, true); err != nil { 728 return model.NewAppError("postChannelPrivacyMessage", "api.channel.post_channel_privacy_message.error", nil, err.Error(), http.StatusInternalServerError) 729 } 730 731 return nil 732 } 733 734 func (a *App) RestoreChannel(channel *model.Channel, userID string) (*model.Channel, *model.AppError) { 735 if channel.DeleteAt == 0 { 736 return nil, model.NewAppError("restoreChannel", "api.channel.restore_channel.restored.app_error", nil, "", http.StatusBadRequest) 737 } 738 739 if err := a.Srv().Store.Channel().Restore(channel.Id, model.GetMillis()); err != nil { 740 return nil, model.NewAppError("RestoreChannel", "app.channel.restore.app_error", nil, err.Error(), http.StatusInternalServerError) 741 } 742 channel.DeleteAt = 0 743 a.invalidateCacheForChannel(channel) 744 745 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_RESTORED, channel.TeamId, "", "", nil) 746 message.Add("channel_id", channel.Id) 747 a.Publish(message) 748 749 user, nErr := a.Srv().Store.User().Get(context.Background(), userID) 750 if nErr != nil { 751 var nfErr *store.ErrNotFound 752 switch { 753 case errors.As(nErr, &nfErr): 754 return nil, model.NewAppError("RestoreChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 755 default: 756 return nil, model.NewAppError("RestoreChannel", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) 757 } 758 } 759 760 if user != nil { 761 T := utils.GetUserTranslations(user.Locale) 762 763 post := &model.Post{ 764 ChannelId: channel.Id, 765 Message: T("api.channel.restore_channel.unarchived", map[string]interface{}{"Username": user.Username}), 766 Type: model.POST_CHANNEL_RESTORED, 767 UserId: userID, 768 Props: model.StringInterface{ 769 "username": user.Username, 770 }, 771 } 772 773 if _, err := a.CreatePost(post, channel, false, true); err != nil { 774 mlog.Warn("Failed to post unarchive message", mlog.Err(err)) 775 } 776 } 777 778 return channel, nil 779 } 780 781 func (a *App) PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userID string) (*model.Channel, *model.AppError) { 782 oldChannelDisplayName := channel.DisplayName 783 oldChannelHeader := channel.Header 784 oldChannelPurpose := channel.Purpose 785 786 channel.Patch(patch) 787 channel, err := a.UpdateChannel(channel) 788 if err != nil { 789 return nil, err 790 } 791 792 if oldChannelDisplayName != channel.DisplayName { 793 if err = a.PostUpdateChannelDisplayNameMessage(userID, channel, oldChannelDisplayName, channel.DisplayName); err != nil { 794 mlog.Warn(err.Error()) 795 } 796 } 797 798 if channel.Header != oldChannelHeader { 799 if err = a.PostUpdateChannelHeaderMessage(userID, channel, oldChannelHeader, channel.Header); err != nil { 800 mlog.Warn(err.Error()) 801 } 802 } 803 804 if channel.Purpose != oldChannelPurpose { 805 if err = a.PostUpdateChannelPurposeMessage(userID, channel, oldChannelPurpose, channel.Purpose); err != nil { 806 mlog.Warn(err.Error()) 807 } 808 } 809 810 return channel, nil 811 } 812 813 // GetSchemeRolesForChannel Checks if a channel or its team has an override scheme for channel roles and returns the scheme roles or default channel roles. 814 func (a *App) GetSchemeRolesForChannel(channelId string) (guestRoleName, userRoleName, adminRoleName string, err *model.AppError) { 815 channel, err := a.GetChannel(channelId) 816 if err != nil { 817 return 818 } 819 820 if channel.SchemeId != nil && *channel.SchemeId != "" { 821 var scheme *model.Scheme 822 scheme, err = a.GetScheme(*channel.SchemeId) 823 if err != nil { 824 return 825 } 826 827 guestRoleName = scheme.DefaultChannelGuestRole 828 userRoleName = scheme.DefaultChannelUserRole 829 adminRoleName = scheme.DefaultChannelAdminRole 830 831 return 832 } 833 834 return a.GetTeamSchemeChannelRoles(channel.TeamId) 835 } 836 837 // GetTeamSchemeChannelRoles Checks if a team has an override scheme and returns the scheme channel role names or default channel role names. 838 func (a *App) GetTeamSchemeChannelRoles(teamID string) (guestRoleName, userRoleName, adminRoleName string, err *model.AppError) { 839 team, err := a.GetTeam(teamID) 840 if err != nil { 841 return 842 } 843 844 if team.SchemeId != nil && *team.SchemeId != "" { 845 var scheme *model.Scheme 846 scheme, err = a.GetScheme(*team.SchemeId) 847 if err != nil { 848 return 849 } 850 851 guestRoleName = scheme.DefaultChannelGuestRole 852 userRoleName = scheme.DefaultChannelUserRole 853 adminRoleName = scheme.DefaultChannelAdminRole 854 } else { 855 guestRoleName = model.CHANNEL_GUEST_ROLE_ID 856 userRoleName = model.CHANNEL_USER_ROLE_ID 857 adminRoleName = model.CHANNEL_ADMIN_ROLE_ID 858 } 859 860 return 861 } 862 863 // GetChannelModerationsForChannel Gets a channels ChannelModerations from either the higherScoped roles or from the channel scheme roles. 864 func (a *App) GetChannelModerationsForChannel(channel *model.Channel) ([]*model.ChannelModeration, *model.AppError) { 865 guestRoleName, memberRoleName, _, err := a.GetSchemeRolesForChannel(channel.Id) 866 if err != nil { 867 return nil, err 868 } 869 870 memberRole, err := a.GetRoleByName(memberRoleName) 871 if err != nil { 872 return nil, err 873 } 874 875 var guestRole *model.Role 876 if guestRoleName != "" { 877 guestRole, err = a.GetRoleByName(guestRoleName) 878 if err != nil { 879 return nil, err 880 } 881 } 882 883 higherScopedGuestRoleName, higherScopedMemberRoleName, _, err := a.GetTeamSchemeChannelRoles(channel.TeamId) 884 if err != nil { 885 return nil, err 886 } 887 higherScopedMemberRole, err := a.GetRoleByName(higherScopedMemberRoleName) 888 if err != nil { 889 return nil, err 890 } 891 892 var higherScopedGuestRole *model.Role 893 if higherScopedGuestRoleName != "" { 894 higherScopedGuestRole, err = a.GetRoleByName(higherScopedGuestRoleName) 895 if err != nil { 896 return nil, err 897 } 898 } 899 900 return buildChannelModerations(channel.Type, memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil 901 } 902 903 // PatchChannelModerationsForChannel Updates a channels scheme roles based on a given ChannelModerationPatch, if the permissions match the higher scoped role the scheme is deleted. 904 func (a *App) PatchChannelModerationsForChannel(channel *model.Channel, channelModerationsPatch []*model.ChannelModerationPatch) ([]*model.ChannelModeration, *model.AppError) { 905 higherScopedGuestRoleName, higherScopedMemberRoleName, _, err := a.GetTeamSchemeChannelRoles(channel.TeamId) 906 if err != nil { 907 return nil, err 908 } 909 910 higherScopedMemberRole, err := a.GetRoleByName(higherScopedMemberRoleName) 911 if err != nil { 912 return nil, err 913 } 914 915 var higherScopedGuestRole *model.Role 916 if higherScopedGuestRoleName != "" { 917 higherScopedGuestRole, err = a.GetRoleByName(higherScopedGuestRoleName) 918 if err != nil { 919 return nil, err 920 } 921 } 922 923 higherScopedMemberPermissions := higherScopedMemberRole.GetChannelModeratedPermissions(channel.Type) 924 925 var higherScopedGuestPermissions map[string]bool 926 if higherScopedGuestRole != nil { 927 higherScopedGuestPermissions = higherScopedGuestRole.GetChannelModeratedPermissions(channel.Type) 928 } 929 930 for _, moderationPatch := range channelModerationsPatch { 931 if moderationPatch.Roles.Members != nil && *moderationPatch.Roles.Members && !higherScopedMemberPermissions[*moderationPatch.Name] { 932 return nil, &model.AppError{Message: "Cannot add a permission that is restricted by the team or system permission scheme"} 933 } 934 if moderationPatch.Roles.Guests != nil && *moderationPatch.Roles.Guests && !higherScopedGuestPermissions[*moderationPatch.Name] { 935 return nil, &model.AppError{Message: "Cannot add a permission that is restricted by the team or system permission scheme"} 936 } 937 } 938 939 var scheme *model.Scheme 940 // Channel has no scheme so create one 941 if channel.SchemeId == nil || *channel.SchemeId == "" { 942 scheme, err = a.CreateChannelScheme(channel) 943 if err != nil { 944 return nil, err 945 } 946 947 // Send a websocket event about this new role. The other new roles—member and guest—get emitted when they're updated. 948 var adminRole *model.Role 949 adminRole, err = a.GetRoleByName(scheme.DefaultChannelAdminRole) 950 if err != nil { 951 return nil, err 952 } 953 a.sendUpdatedRoleEvent(adminRole) 954 955 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_SCHEME_UPDATED, "", channel.Id, "", nil) 956 a.Publish(message) 957 mlog.Info("Permission scheme created.", mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 958 } else { 959 scheme, err = a.GetScheme(*channel.SchemeId) 960 if err != nil { 961 return nil, err 962 } 963 } 964 965 guestRoleName := scheme.DefaultChannelGuestRole 966 memberRoleName := scheme.DefaultChannelUserRole 967 memberRole, err := a.GetRoleByName(memberRoleName) 968 if err != nil { 969 return nil, err 970 } 971 972 var guestRole *model.Role 973 if guestRoleName != "" { 974 guestRole, err = a.GetRoleByName(guestRoleName) 975 if err != nil { 976 return nil, err 977 } 978 } 979 980 memberRolePatch := memberRole.RolePatchFromChannelModerationsPatch(channelModerationsPatch, "members") 981 var guestRolePatch *model.RolePatch 982 if guestRole != nil { 983 guestRolePatch = guestRole.RolePatchFromChannelModerationsPatch(channelModerationsPatch, "guests") 984 } 985 986 for _, channelModerationPatch := range channelModerationsPatch { 987 permissionModified := *channelModerationPatch.Name 988 if channelModerationPatch.Roles.Guests != nil && utils.StringInSlice(permissionModified, model.ChannelModeratedPermissionsChangedByPatch(guestRole, guestRolePatch)) { 989 if *channelModerationPatch.Roles.Guests { 990 mlog.Info("Permission enabled for guests.", mlog.String("permission", permissionModified), mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 991 } else { 992 mlog.Info("Permission disabled for guests.", mlog.String("permission", permissionModified), mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 993 } 994 } 995 996 if channelModerationPatch.Roles.Members != nil && utils.StringInSlice(permissionModified, model.ChannelModeratedPermissionsChangedByPatch(memberRole, memberRolePatch)) { 997 if *channelModerationPatch.Roles.Members { 998 mlog.Info("Permission enabled for members.", mlog.String("permission", permissionModified), mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 999 } else { 1000 mlog.Info("Permission disabled for members.", mlog.String("permission", permissionModified), mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 1001 } 1002 } 1003 } 1004 1005 memberRolePermissionsUnmodified := len(model.ChannelModeratedPermissionsChangedByPatch(higherScopedMemberRole, memberRolePatch)) == 0 1006 guestRolePermissionsUnmodified := len(model.ChannelModeratedPermissionsChangedByPatch(higherScopedGuestRole, guestRolePatch)) == 0 1007 if memberRolePermissionsUnmodified && guestRolePermissionsUnmodified { 1008 // The channel scheme matches the permissions of its higherScoped scheme so delete the scheme 1009 if _, err = a.DeleteChannelScheme(channel); err != nil { 1010 return nil, err 1011 } 1012 1013 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_SCHEME_UPDATED, "", channel.Id, "", nil) 1014 a.Publish(message) 1015 1016 memberRole = higherScopedMemberRole 1017 guestRole = higherScopedGuestRole 1018 mlog.Info("Permission scheme deleted.", mlog.String("channel_id", channel.Id), mlog.String("channel_name", channel.Name)) 1019 } else { 1020 memberRole, err = a.PatchRole(memberRole, memberRolePatch) 1021 if err != nil { 1022 return nil, err 1023 } 1024 guestRole, err = a.PatchRole(guestRole, guestRolePatch) 1025 if err != nil { 1026 return nil, err 1027 } 1028 } 1029 1030 return buildChannelModerations(channel.Type, memberRole, guestRole, higherScopedMemberRole, higherScopedGuestRole), nil 1031 } 1032 1033 func buildChannelModerations(channelType string, memberRole *model.Role, guestRole *model.Role, higherScopedMemberRole *model.Role, higherScopedGuestRole *model.Role) []*model.ChannelModeration { 1034 var memberPermissions, guestPermissions, higherScopedMemberPermissions, higherScopedGuestPermissions map[string]bool 1035 if memberRole != nil { 1036 memberPermissions = memberRole.GetChannelModeratedPermissions(channelType) 1037 } 1038 if guestRole != nil { 1039 guestPermissions = guestRole.GetChannelModeratedPermissions(channelType) 1040 } 1041 if higherScopedMemberRole != nil { 1042 higherScopedMemberPermissions = higherScopedMemberRole.GetChannelModeratedPermissions(channelType) 1043 } 1044 if higherScopedGuestRole != nil { 1045 higherScopedGuestPermissions = higherScopedGuestRole.GetChannelModeratedPermissions(channelType) 1046 } 1047 1048 var channelModerations []*model.ChannelModeration 1049 for _, permissionKey := range model.ChannelModeratedPermissions { 1050 roles := &model.ChannelModeratedRoles{} 1051 1052 roles.Members = &model.ChannelModeratedRole{ 1053 Value: memberPermissions[permissionKey], 1054 Enabled: higherScopedMemberPermissions[permissionKey], 1055 } 1056 1057 if permissionKey == "manage_members" { 1058 roles.Guests = nil 1059 } else { 1060 roles.Guests = &model.ChannelModeratedRole{ 1061 Value: guestPermissions[permissionKey], 1062 Enabled: higherScopedGuestPermissions[permissionKey], 1063 } 1064 } 1065 1066 moderation := &model.ChannelModeration{ 1067 Name: permissionKey, 1068 Roles: roles, 1069 } 1070 1071 channelModerations = append(channelModerations, moderation) 1072 } 1073 1074 return channelModerations 1075 } 1076 1077 func (a *App) UpdateChannelMemberRoles(channelId string, userID string, newRoles string) (*model.ChannelMember, *model.AppError) { 1078 var member *model.ChannelMember 1079 var err *model.AppError 1080 if member, err = a.GetChannelMember(channelId, userID); err != nil { 1081 return nil, err 1082 } 1083 1084 schemeGuestRole, schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(channelId) 1085 if err != nil { 1086 return nil, err 1087 } 1088 1089 prevSchemeGuestValue := member.SchemeGuest 1090 1091 var newExplicitRoles []string 1092 member.SchemeGuest = false 1093 member.SchemeUser = false 1094 member.SchemeAdmin = false 1095 1096 for _, roleName := range strings.Fields(newRoles) { 1097 var role *model.Role 1098 role, err = a.GetRoleByName(roleName) 1099 if err != nil { 1100 err.StatusCode = http.StatusBadRequest 1101 return nil, err 1102 } 1103 1104 if !role.SchemeManaged { 1105 // The role is not scheme-managed, so it's OK to apply it to the explicit roles field. 1106 newExplicitRoles = append(newExplicitRoles, roleName) 1107 } else { 1108 // The role is scheme-managed, so need to check if it is part of the scheme for this channel or not. 1109 switch roleName { 1110 case schemeAdminRole: 1111 member.SchemeAdmin = true 1112 case schemeUserRole: 1113 member.SchemeUser = true 1114 case schemeGuestRole: 1115 member.SchemeGuest = true 1116 default: 1117 // If not part of the scheme for this channel, then it is not allowed to apply it as an explicit role. 1118 return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.scheme_role.app_error", nil, "role_name="+roleName, http.StatusBadRequest) 1119 } 1120 } 1121 } 1122 1123 if member.SchemeUser && member.SchemeGuest { 1124 return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.guest_and_user.app_error", nil, "", http.StatusBadRequest) 1125 } 1126 1127 if prevSchemeGuestValue != member.SchemeGuest { 1128 return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest) 1129 } 1130 1131 member.ExplicitRoles = strings.Join(newExplicitRoles, " ") 1132 1133 return a.updateChannelMember(member) 1134 } 1135 1136 func (a *App) UpdateChannelMemberSchemeRoles(channelId string, userID string, isSchemeGuest bool, isSchemeUser bool, isSchemeAdmin bool) (*model.ChannelMember, *model.AppError) { 1137 member, err := a.GetChannelMember(channelId, userID) 1138 if err != nil { 1139 return nil, err 1140 } 1141 1142 member.SchemeAdmin = isSchemeAdmin 1143 member.SchemeUser = isSchemeUser 1144 member.SchemeGuest = isSchemeGuest 1145 1146 if member.SchemeUser && member.SchemeGuest { 1147 return nil, model.NewAppError("UpdateChannelMemberSchemeRoles", "api.channel.update_channel_member_roles.guest_and_user.app_error", nil, "", http.StatusBadRequest) 1148 } 1149 1150 // If the migration is not completed, we also need to check the default channel_admin/channel_user roles are not present in the roles field. 1151 if err = a.IsPhase2MigrationCompleted(); err != nil { 1152 member.ExplicitRoles = RemoveRoles([]string{model.CHANNEL_GUEST_ROLE_ID, model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID}, member.ExplicitRoles) 1153 } 1154 1155 return a.updateChannelMember(member) 1156 } 1157 1158 func (a *App) UpdateChannelMemberNotifyProps(data map[string]string, channelId string, userID string) (*model.ChannelMember, *model.AppError) { 1159 var member *model.ChannelMember 1160 var err *model.AppError 1161 if member, err = a.GetChannelMember(channelId, userID); err != nil { 1162 return nil, err 1163 } 1164 1165 // update whichever notify properties have been provided, but don't change the others 1166 if markUnread, exists := data[model.MARK_UNREAD_NOTIFY_PROP]; exists { 1167 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = markUnread 1168 } 1169 1170 if desktop, exists := data[model.DESKTOP_NOTIFY_PROP]; exists { 1171 member.NotifyProps[model.DESKTOP_NOTIFY_PROP] = desktop 1172 } 1173 1174 if email, exists := data[model.EMAIL_NOTIFY_PROP]; exists { 1175 member.NotifyProps[model.EMAIL_NOTIFY_PROP] = email 1176 } 1177 1178 if push, exists := data[model.PUSH_NOTIFY_PROP]; exists { 1179 member.NotifyProps[model.PUSH_NOTIFY_PROP] = push 1180 } 1181 1182 if ignoreChannelMentions, exists := data[model.IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP]; exists { 1183 member.NotifyProps[model.IGNORE_CHANNEL_MENTIONS_NOTIFY_PROP] = ignoreChannelMentions 1184 } 1185 1186 member, err = a.updateChannelMember(member) 1187 if err != nil { 1188 return nil, err 1189 } 1190 1191 a.invalidateCacheForChannelMembersNotifyProps(member.ChannelId) 1192 1193 return member, nil 1194 } 1195 1196 func (a *App) updateChannelMember(member *model.ChannelMember) (*model.ChannelMember, *model.AppError) { 1197 member, nErr := a.Srv().Store.Channel().UpdateMember(member) 1198 if nErr != nil { 1199 var appErr *model.AppError 1200 var nfErr *store.ErrNotFound 1201 switch { 1202 case errors.As(nErr, &appErr): 1203 return nil, appErr 1204 case errors.As(nErr, &nfErr): 1205 return nil, model.NewAppError("updateChannelMember", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) 1206 default: 1207 return nil, model.NewAppError("updateChannelMember", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 1208 } 1209 } 1210 1211 a.InvalidateCacheForUser(member.UserId) 1212 1213 // Notify the clients that the member notify props changed 1214 evt := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED, "", "", member.UserId, nil) 1215 evt.Add("channelMember", member.ToJson()) 1216 a.Publish(evt) 1217 1218 return member, nil 1219 } 1220 1221 func (a *App) DeleteChannel(channel *model.Channel, userID string) *model.AppError { 1222 ihc := make(chan store.StoreResult, 1) 1223 ohc := make(chan store.StoreResult, 1) 1224 1225 go func() { 1226 webhooks, err := a.Srv().Store.Webhook().GetIncomingByChannel(channel.Id) 1227 ihc <- store.StoreResult{Data: webhooks, NErr: err} 1228 close(ihc) 1229 }() 1230 1231 go func() { 1232 outgoingHooks, err := a.Srv().Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1) 1233 ohc <- store.StoreResult{Data: outgoingHooks, NErr: err} 1234 close(ohc) 1235 }() 1236 1237 var user *model.User 1238 if userID != "" { 1239 var nErr error 1240 user, nErr = a.Srv().Store.User().Get(context.Background(), userID) 1241 if nErr != nil { 1242 var nfErr *store.ErrNotFound 1243 switch { 1244 case errors.As(nErr, &nfErr): 1245 return model.NewAppError("DeleteChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 1246 default: 1247 return model.NewAppError("DeleteChannel", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) 1248 } 1249 } 1250 } 1251 1252 ihcresult := <-ihc 1253 if ihcresult.NErr != nil { 1254 return model.NewAppError("DeleteChannel", "app.webhooks.get_incoming_by_channel.app_error", nil, ihcresult.NErr.Error(), http.StatusInternalServerError) 1255 } 1256 1257 ohcresult := <-ohc 1258 if ohcresult.NErr != nil { 1259 return model.NewAppError("DeleteChannel", "app.webhooks.get_outgoing_by_channel.app_error", nil, ohcresult.NErr.Error(), http.StatusInternalServerError) 1260 } 1261 1262 incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) 1263 outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) 1264 1265 if channel.DeleteAt > 0 { 1266 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "", http.StatusBadRequest) 1267 return err 1268 } 1269 1270 if channel.Name == model.DEFAULT_CHANNEL { 1271 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 1272 return err 1273 } 1274 1275 if user != nil { 1276 T := utils.GetUserTranslations(user.Locale) 1277 1278 post := &model.Post{ 1279 ChannelId: channel.Id, 1280 Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username), 1281 Type: model.POST_CHANNEL_DELETED, 1282 UserId: userID, 1283 Props: model.StringInterface{ 1284 "username": user.Username, 1285 }, 1286 } 1287 1288 if _, err := a.CreatePost(post, channel, false, true); err != nil { 1289 mlog.Warn("Failed to post archive message", mlog.Err(err)) 1290 } 1291 } 1292 1293 now := model.GetMillis() 1294 for _, hook := range incomingHooks { 1295 if err := a.Srv().Store.Webhook().DeleteIncoming(hook.Id, now); err != nil { 1296 mlog.Warn("Encountered error deleting incoming webhook", mlog.String("hook_id", hook.Id), mlog.Err(err)) 1297 } 1298 a.invalidateCacheForWebhook(hook.Id) 1299 } 1300 1301 for _, hook := range outgoingHooks { 1302 if err := a.Srv().Store.Webhook().DeleteOutgoing(hook.Id, now); err != nil { 1303 mlog.Warn("Encountered error deleting outgoing webhook", mlog.String("hook_id", hook.Id), mlog.Err(err)) 1304 } 1305 } 1306 1307 deleteAt := model.GetMillis() 1308 1309 if err := a.Srv().Store.Channel().Delete(channel.Id, deleteAt); err != nil { 1310 return model.NewAppError("DeleteChannel", "app.channel.delete.app_error", nil, err.Error(), http.StatusInternalServerError) 1311 } 1312 a.invalidateCacheForChannel(channel) 1313 1314 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil) 1315 message.Add("channel_id", channel.Id) 1316 message.Add("delete_at", deleteAt) 1317 a.Publish(message) 1318 1319 return nil 1320 } 1321 1322 func (a *App) addUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) { 1323 if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE { 1324 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest) 1325 } 1326 1327 channelMember, nErr := a.Srv().Store.Channel().GetMember(channel.Id, user.Id) 1328 if nErr != nil { 1329 var nfErr *store.ErrNotFound 1330 if !errors.As(nErr, &nfErr) { 1331 return nil, model.NewAppError("AddUserToChannel", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 1332 } 1333 } else { 1334 return channelMember, nil 1335 } 1336 1337 if channel.IsGroupConstrained() { 1338 nonMembers, err := a.FilterNonGroupChannelMembers([]string{user.Id}, channel) 1339 if err != nil { 1340 return nil, model.NewAppError("addUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusInternalServerError) 1341 } 1342 if len(nonMembers) > 0 { 1343 return nil, model.NewAppError("addUserToChannel", "api.channel.add_members.user_denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest) 1344 } 1345 } 1346 1347 newMember := &model.ChannelMember{ 1348 ChannelId: channel.Id, 1349 UserId: user.Id, 1350 NotifyProps: model.GetDefaultChannelNotifyProps(), 1351 SchemeGuest: user.IsGuest(), 1352 SchemeUser: !user.IsGuest(), 1353 } 1354 1355 if !user.IsGuest() { 1356 var userShouldBeAdmin bool 1357 userShouldBeAdmin, appErr := a.UserIsInAdminRoleGroup(user.Id, channel.Id, model.GroupSyncableTypeChannel) 1358 if appErr != nil { 1359 return nil, appErr 1360 } 1361 newMember.SchemeAdmin = userShouldBeAdmin 1362 } 1363 1364 newMember, nErr = a.Srv().Store.Channel().SaveMember(newMember) 1365 if nErr != nil { 1366 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, fmt.Sprintf("failed to add member: user_id: %s, channel_id:%s", user.Id, channel.Id), http.StatusInternalServerError) 1367 } 1368 a.WaitForChannelMembership(channel.Id, user.Id) 1369 1370 if nErr := a.Srv().Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); nErr != nil { 1371 return nil, model.NewAppError("AddUserToChannel", "app.channel_member_history.log_join_event.internal_error", nil, nErr.Error(), http.StatusInternalServerError) 1372 } 1373 1374 a.InvalidateCacheForUser(user.Id) 1375 a.invalidateCacheForChannelMembers(channel.Id) 1376 1377 return newMember, nil 1378 } 1379 1380 func (a *App) AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) { 1381 teamMember, nErr := a.Srv().Store.Team().GetMember(channel.TeamId, user.Id) 1382 if nErr != nil { 1383 var nfErr *store.ErrNotFound 1384 switch { 1385 case errors.As(nErr, &nfErr): 1386 return nil, model.NewAppError("AddUserToChannel", "app.team.get_member.missing.app_error", nil, nfErr.Error(), http.StatusNotFound) 1387 default: 1388 return nil, model.NewAppError("AddUserToChannel", "app.team.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 1389 } 1390 } 1391 1392 if teamMember.DeleteAt > 0 { 1393 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "", http.StatusBadRequest) 1394 } 1395 1396 newMember, err := a.addUserToChannel(user, channel) 1397 if err != nil { 1398 return nil, err 1399 } 1400 1401 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil) 1402 message.Add("user_id", user.Id) 1403 message.Add("team_id", channel.TeamId) 1404 a.Publish(message) 1405 1406 return newMember, nil 1407 } 1408 1409 func (a *App) AddChannelMember(userID string, channel *model.Channel, userRequestorId string, postRootId string) (*model.ChannelMember, *model.AppError) { 1410 if member, err := a.Srv().Store.Channel().GetMember(channel.Id, userID); err != nil { 1411 var nfErr *store.ErrNotFound 1412 if !errors.As(err, &nfErr) { 1413 return nil, model.NewAppError("AddChannelMember", "app.channel.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) 1414 } 1415 } else { 1416 return member, nil 1417 } 1418 1419 var user *model.User 1420 var err *model.AppError 1421 1422 if user, err = a.GetUser(userID); err != nil { 1423 return nil, err 1424 } 1425 1426 var userRequestor *model.User 1427 if userRequestorId != "" { 1428 if userRequestor, err = a.GetUser(userRequestorId); err != nil { 1429 return nil, err 1430 } 1431 } 1432 1433 cm, err := a.AddUserToChannel(user, channel) 1434 if err != nil { 1435 return nil, err 1436 } 1437 1438 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 1439 a.Srv().Go(func() { 1440 pluginContext := a.PluginContext() 1441 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 1442 hooks.UserHasJoinedChannel(pluginContext, cm, userRequestor) 1443 return true 1444 }, plugin.UserHasJoinedChannelId) 1445 }) 1446 } 1447 1448 if userRequestorId == "" || userID == userRequestorId { 1449 a.postJoinChannelMessage(user, channel) 1450 } else { 1451 a.Srv().Go(func() { 1452 a.PostAddToChannelMessage(userRequestor, user, channel, postRootId) 1453 }) 1454 } 1455 1456 return cm, nil 1457 } 1458 1459 func (a *App) AddDirectChannels(teamID string, user *model.User) *model.AppError { 1460 var profiles []*model.User 1461 options := &model.UserGetOptions{InTeamId: teamID, Page: 0, PerPage: 100} 1462 profiles, err := a.Srv().Store.User().GetProfiles(options) 1463 if err != nil { 1464 return model.NewAppError("AddDirectChannels", "api.user.add_direct_channels_and_forget.failed.error", map[string]interface{}{"UserId": user.Id, "TeamId": teamID, "Error": err.Error()}, "", http.StatusInternalServerError) 1465 } 1466 1467 var preferences model.Preferences 1468 1469 for _, profile := range profiles { 1470 if profile.Id == user.Id { 1471 continue 1472 } 1473 1474 preference := model.Preference{ 1475 UserId: user.Id, 1476 Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, 1477 Name: profile.Id, 1478 Value: "true", 1479 } 1480 1481 preferences = append(preferences, preference) 1482 1483 if len(preferences) >= 10 { 1484 break 1485 } 1486 } 1487 1488 if err := a.Srv().Store.Preference().Save(&preferences); err != nil { 1489 return model.NewAppError("AddDirectChannels", "api.user.add_direct_channels_and_forget.failed.error", map[string]interface{}{"UserId": user.Id, "TeamId": teamID, "Error": err.Error()}, "", http.StatusInternalServerError) 1490 } 1491 1492 return nil 1493 } 1494 1495 func (a *App) PostUpdateChannelHeaderMessage(userID string, channel *model.Channel, oldChannelHeader, newChannelHeader string) *model.AppError { 1496 user, err := a.Srv().Store.User().Get(context.Background(), userID) 1497 if err != nil { 1498 return model.NewAppError("PostUpdateChannelHeaderMessage", "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error", nil, err.Error(), http.StatusBadRequest) 1499 } 1500 1501 var message string 1502 if oldChannelHeader == "" { 1503 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader) 1504 } else if newChannelHeader == "" { 1505 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader) 1506 } else { 1507 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader) 1508 } 1509 1510 post := &model.Post{ 1511 ChannelId: channel.Id, 1512 Message: message, 1513 Type: model.POST_HEADER_CHANGE, 1514 UserId: userID, 1515 Props: model.StringInterface{ 1516 "username": user.Username, 1517 "old_header": oldChannelHeader, 1518 "new_header": newChannelHeader, 1519 }, 1520 } 1521 1522 if _, err := a.CreatePost(post, channel, false, true); err != nil { 1523 return model.NewAppError("", "api.channel.post_update_channel_header_message_and_forget.post.error", nil, err.Error(), http.StatusInternalServerError) 1524 } 1525 1526 return nil 1527 } 1528 1529 func (a *App) PostUpdateChannelPurposeMessage(userID string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError { 1530 user, err := a.Srv().Store.User().Get(context.Background(), userID) 1531 if err != nil { 1532 return model.NewAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, err.Error(), http.StatusBadRequest) 1533 } 1534 1535 var message string 1536 if oldChannelPurpose == "" { 1537 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_to"), user.Username, newChannelPurpose) 1538 } else if newChannelPurpose == "" { 1539 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.removed"), user.Username, oldChannelPurpose) 1540 } else { 1541 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_from"), user.Username, oldChannelPurpose, newChannelPurpose) 1542 } 1543 1544 post := &model.Post{ 1545 ChannelId: channel.Id, 1546 Message: message, 1547 Type: model.POST_PURPOSE_CHANGE, 1548 UserId: userID, 1549 Props: model.StringInterface{ 1550 "username": user.Username, 1551 "old_purpose": oldChannelPurpose, 1552 "new_purpose": newChannelPurpose, 1553 }, 1554 } 1555 if _, err := a.CreatePost(post, channel, false, true); err != nil { 1556 return model.NewAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error(), http.StatusInternalServerError) 1557 } 1558 1559 return nil 1560 } 1561 1562 func (a *App) PostUpdateChannelDisplayNameMessage(userID string, channel *model.Channel, oldChannelDisplayName, newChannelDisplayName string) *model.AppError { 1563 user, err := a.Srv().Store.User().Get(context.Background(), userID) 1564 if err != nil { 1565 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error", nil, err.Error(), http.StatusBadRequest) 1566 } 1567 1568 message := fmt.Sprintf(utils.T("api.channel.post_update_channel_displayname_message_and_forget.updated_from"), user.Username, oldChannelDisplayName, newChannelDisplayName) 1569 1570 post := &model.Post{ 1571 ChannelId: channel.Id, 1572 Message: message, 1573 Type: model.POST_DISPLAYNAME_CHANGE, 1574 UserId: userID, 1575 Props: model.StringInterface{ 1576 "username": user.Username, 1577 "old_displayname": oldChannelDisplayName, 1578 "new_displayname": newChannelDisplayName, 1579 }, 1580 } 1581 1582 if _, err := a.CreatePost(post, channel, false, true); err != nil { 1583 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.create_post.error", nil, err.Error(), http.StatusInternalServerError) 1584 } 1585 1586 return nil 1587 } 1588 1589 func (a *App) GetChannel(channelId string) (*model.Channel, *model.AppError) { 1590 channel, err := a.Srv().Store.Channel().Get(channelId, true) 1591 if err != nil { 1592 var nfErr *store.ErrNotFound 1593 switch { 1594 case errors.As(err, &nfErr): 1595 return nil, model.NewAppError("GetChannel", "app.channel.get.existing.app_error", nil, nfErr.Error(), http.StatusNotFound) 1596 default: 1597 return nil, model.NewAppError("GetChannel", "app.channel.get.find.app_error", nil, err.Error(), http.StatusInternalServerError) 1598 } 1599 } 1600 return channel, nil 1601 } 1602 1603 func (a *App) GetChannelByName(channelName, teamID string, includeDeleted bool) (*model.Channel, *model.AppError) { 1604 var channel *model.Channel 1605 var err error 1606 1607 if includeDeleted { 1608 channel, err = a.Srv().Store.Channel().GetByNameIncludeDeleted(teamID, channelName, false) 1609 } else { 1610 channel, err = a.Srv().Store.Channel().GetByName(teamID, channelName, false) 1611 } 1612 1613 if err != nil { 1614 var nfErr *store.ErrNotFound 1615 switch { 1616 case errors.As(err, &nfErr): 1617 return nil, model.NewAppError("GetChannelByName", "app.channel.get_by_name.missing.app_error", nil, nfErr.Error(), http.StatusNotFound) 1618 default: 1619 return nil, model.NewAppError("GetChannelByName", "app.channel.get_by_name.existing.app_error", nil, err.Error(), http.StatusInternalServerError) 1620 } 1621 } 1622 1623 return channel, nil 1624 } 1625 1626 func (a *App) GetChannelsByNames(channelNames []string, teamID string) ([]*model.Channel, *model.AppError) { 1627 channels, err := a.Srv().Store.Channel().GetByNames(teamID, channelNames, true) 1628 if err != nil { 1629 return nil, model.NewAppError("GetChannelsByNames", "app.channel.get_by_name.existing.app_error", nil, err.Error(), http.StatusInternalServerError) 1630 } 1631 return channels, nil 1632 } 1633 1634 func (a *App) GetChannelByNameForTeamName(channelName, teamName string, includeDeleted bool) (*model.Channel, *model.AppError) { 1635 var team *model.Team 1636 1637 team, err := a.Srv().Store.Team().GetByName(teamName) 1638 if err != nil { 1639 var nfErr *store.ErrNotFound 1640 switch { 1641 case errors.As(err, &nfErr): 1642 return nil, model.NewAppError("GetChannelByNameForTeamName", "app.team.get_by_name.missing.app_error", nil, nfErr.Error(), http.StatusNotFound) 1643 default: 1644 return nil, model.NewAppError("GetChannelByNameForTeamName", "app.team.get_by_name.app_error", nil, err.Error(), http.StatusNotFound) 1645 } 1646 } 1647 1648 var result *model.Channel 1649 1650 var nErr error 1651 if includeDeleted { 1652 result, nErr = a.Srv().Store.Channel().GetByNameIncludeDeleted(team.Id, channelName, false) 1653 } else { 1654 result, nErr = a.Srv().Store.Channel().GetByName(team.Id, channelName, false) 1655 } 1656 1657 if nErr != nil { 1658 var nfErr *store.ErrNotFound 1659 switch { 1660 case errors.As(nErr, &nfErr): 1661 return nil, model.NewAppError("GetChannelByNameForTeamName", "app.channel.get_by_name.missing.app_error", nil, nfErr.Error(), http.StatusNotFound) 1662 default: 1663 return nil, model.NewAppError("GetChannelByNameForTeamName", "app.channel.get_by_name.existing.app_error", nil, nErr.Error(), http.StatusInternalServerError) 1664 } 1665 } 1666 1667 return result, nil 1668 } 1669 1670 func (a *App) GetChannelsForUser(teamID string, userID string, includeDeleted bool, lastDeleteAt int) (*model.ChannelList, *model.AppError) { 1671 list, err := a.Srv().Store.Channel().GetChannels(teamID, userID, includeDeleted, lastDeleteAt) 1672 if err != nil { 1673 var nfErr *store.ErrNotFound 1674 switch { 1675 case errors.As(err, &nfErr): 1676 return nil, model.NewAppError("GetChannelsForUser", "app.channel.get_channels.not_found.app_error", nil, nfErr.Error(), http.StatusNotFound) 1677 default: 1678 return nil, model.NewAppError("GetChannelsForUser", "app.channel.get_channels.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1679 } 1680 } 1681 1682 return list, nil 1683 } 1684 1685 func (a *App) GetAllChannels(page, perPage int, opts model.ChannelSearchOpts) (*model.ChannelListWithTeamData, *model.AppError) { 1686 if opts.ExcludeDefaultChannels { 1687 opts.ExcludeChannelNames = a.DefaultChannelNames() 1688 } 1689 storeOpts := store.ChannelSearchOpts{ 1690 ExcludeChannelNames: opts.ExcludeChannelNames, 1691 NotAssociatedToGroup: opts.NotAssociatedToGroup, 1692 IncludeDeleted: opts.IncludeDeleted, 1693 } 1694 channels, err := a.Srv().Store.Channel().GetAllChannels(page*perPage, perPage, storeOpts) 1695 if err != nil { 1696 return nil, model.NewAppError("GetAllChannels", "app.channel.get_all_channels.app_error", nil, err.Error(), http.StatusInternalServerError) 1697 } 1698 1699 return channels, nil 1700 } 1701 1702 func (a *App) GetAllChannelsCount(opts model.ChannelSearchOpts) (int64, *model.AppError) { 1703 if opts.ExcludeDefaultChannels { 1704 opts.ExcludeChannelNames = a.DefaultChannelNames() 1705 } 1706 storeOpts := store.ChannelSearchOpts{ 1707 ExcludeChannelNames: opts.ExcludeChannelNames, 1708 NotAssociatedToGroup: opts.NotAssociatedToGroup, 1709 IncludeDeleted: opts.IncludeDeleted, 1710 } 1711 count, err := a.Srv().Store.Channel().GetAllChannelsCount(storeOpts) 1712 if err != nil { 1713 return 0, model.NewAppError("GetAllChannelsCount", "app.channel.get_all_channels_count.app_error", nil, err.Error(), http.StatusInternalServerError) 1714 } 1715 1716 return count, nil 1717 } 1718 1719 func (a *App) GetDeletedChannels(teamID string, offset int, limit int, userID string) (*model.ChannelList, *model.AppError) { 1720 list, err := a.Srv().Store.Channel().GetDeleted(teamID, offset, limit, userID) 1721 if err != nil { 1722 var nfErr *store.ErrNotFound 1723 switch { 1724 case errors.As(err, &nfErr): 1725 return nil, model.NewAppError("GetDeletedChannels", "app.channel.get_deleted.missing.app_error", nil, err.Error(), http.StatusNotFound) 1726 default: 1727 return nil, model.NewAppError("GetDeletedChannels", "app.channel.get_deleted.existing.app_error", nil, err.Error(), http.StatusInternalServerError) 1728 } 1729 } 1730 1731 return list, nil 1732 } 1733 1734 func (a *App) GetChannelsUserNotIn(teamID string, userID string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1735 channels, err := a.Srv().Store.Channel().GetMoreChannels(teamID, userID, offset, limit) 1736 if err != nil { 1737 return nil, model.NewAppError("GetChannelsUserNotIn", "app.channel.get_more_channels.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1738 } 1739 return channels, nil 1740 } 1741 1742 func (a *App) GetPublicChannelsByIdsForTeam(teamID string, channelIds []string) (*model.ChannelList, *model.AppError) { 1743 list, err := a.Srv().Store.Channel().GetPublicChannelsByIdsForTeam(teamID, channelIds) 1744 if err != nil { 1745 var nfErr *store.ErrNotFound 1746 switch { 1747 case errors.As(err, &nfErr): 1748 return nil, model.NewAppError("GetPublicChannelsByIdsForTeam", "app.channel.get_channels_by_ids.not_found.app_error", nil, nfErr.Error(), http.StatusNotFound) 1749 default: 1750 return nil, model.NewAppError("GetPublicChannelsByIdsForTeam", "app.channel.get_channels_by_ids.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1751 } 1752 } 1753 1754 return list, nil 1755 } 1756 1757 func (a *App) GetPublicChannelsForTeam(teamID string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1758 list, err := a.Srv().Store.Channel().GetPublicChannelsForTeam(teamID, offset, limit) 1759 if err != nil { 1760 return nil, model.NewAppError("GetPublicChannelsForTeam", "app.channel.get_public_channels.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1761 } 1762 1763 return list, nil 1764 } 1765 1766 func (a *App) GetPrivateChannelsForTeam(teamID string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1767 list, err := a.Srv().Store.Channel().GetPrivateChannelsForTeam(teamID, offset, limit) 1768 if err != nil { 1769 return nil, model.NewAppError("GetPrivateChannelsForTeam", "app.channel.get_private_channels.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1770 } 1771 1772 return list, nil 1773 } 1774 1775 func (a *App) GetChannelMember(channelId string, userID string) (*model.ChannelMember, *model.AppError) { 1776 channelMember, err := a.Srv().Store.Channel().GetMember(channelId, userID) 1777 if err != nil { 1778 var nfErr *store.ErrNotFound 1779 switch { 1780 case errors.As(err, &nfErr): 1781 return nil, model.NewAppError("GetChannelMember", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) 1782 default: 1783 return nil, model.NewAppError("GetChannelMember", "app.channel.get_member.app_error", nil, err.Error(), http.StatusInternalServerError) 1784 } 1785 } 1786 1787 return channelMember, nil 1788 } 1789 1790 func (a *App) GetChannelMembersPage(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError) { 1791 channelMembers, err := a.Srv().Store.Channel().GetMembers(channelId, page*perPage, perPage) 1792 if err != nil { 1793 return nil, model.NewAppError("GetChannelMembersPage", "app.channel.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 1794 } 1795 1796 return channelMembers, nil 1797 } 1798 1799 func (a *App) GetChannelMembersTimezones(channelId string) ([]string, *model.AppError) { 1800 membersTimezones, err := a.Srv().Store.Channel().GetChannelMembersTimezones(channelId) 1801 if err != nil { 1802 return nil, model.NewAppError("GetChannelMembersTimezones", "app.channel.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 1803 } 1804 1805 var timezones []string 1806 for _, membersTimezone := range membersTimezones { 1807 if membersTimezone["automaticTimezone"] == "" && membersTimezone["manualTimezone"] == "" { 1808 continue 1809 } 1810 timezones = append(timezones, model.GetPreferredTimezone(membersTimezone)) 1811 } 1812 1813 return model.RemoveDuplicateStrings(timezones), nil 1814 } 1815 1816 func (a *App) GetChannelMembersByIds(channelId string, userIDs []string) (*model.ChannelMembers, *model.AppError) { 1817 members, err := a.Srv().Store.Channel().GetMembersByIds(channelId, userIDs) 1818 if err != nil { 1819 return nil, model.NewAppError("GetChannelMembersByIds", "app.channel.get_members_by_ids.app_error", nil, err.Error(), http.StatusInternalServerError) 1820 } 1821 1822 return members, nil 1823 } 1824 1825 func (a *App) GetChannelMembersForUser(teamID string, userID string) (*model.ChannelMembers, *model.AppError) { 1826 channelMembers, err := a.Srv().Store.Channel().GetMembersForUser(teamID, userID) 1827 if err != nil { 1828 return nil, model.NewAppError("GetChannelMembersForUser", "app.channel.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 1829 } 1830 1831 return channelMembers, nil 1832 } 1833 1834 func (a *App) GetChannelMembersForUserWithPagination(teamID, userID string, page, perPage int) ([]*model.ChannelMember, *model.AppError) { 1835 m, err := a.Srv().Store.Channel().GetMembersForUserWithPagination(teamID, userID, page, perPage) 1836 if err != nil { 1837 return nil, model.NewAppError("GetChannelMembersForUserWithPagination", "app.channel.get_members.app_error", nil, err.Error(), http.StatusInternalServerError) 1838 } 1839 1840 members := make([]*model.ChannelMember, 0) 1841 if m != nil { 1842 for _, member := range *m { 1843 member := member 1844 members = append(members, &member) 1845 } 1846 } 1847 return members, nil 1848 } 1849 1850 func (a *App) GetChannelMemberCount(channelId string) (int64, *model.AppError) { 1851 count, err := a.Srv().Store.Channel().GetMemberCount(channelId, true) 1852 if err != nil { 1853 return 0, model.NewAppError("GetChannelMemberCount", "app.channel.get_member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 1854 } 1855 1856 return count, nil 1857 } 1858 1859 func (a *App) GetChannelGuestCount(channelId string) (int64, *model.AppError) { 1860 count, err := a.Srv().Store.Channel().GetGuestCount(channelId, true) 1861 if err != nil { 1862 return 0, model.NewAppError("SqlChannelStore.GetGuestCount", "app.channel.get_member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 1863 } 1864 1865 return count, nil 1866 } 1867 1868 func (a *App) GetChannelPinnedPostCount(channelId string) (int64, *model.AppError) { 1869 count, err := a.Srv().Store.Channel().GetPinnedPostCount(channelId, true) 1870 if err != nil { 1871 return 0, model.NewAppError("GetChannelPinnedPostCount", "app.channel.get_pinnedpost_count.app_error", nil, err.Error(), http.StatusInternalServerError) 1872 } 1873 1874 return count, nil 1875 } 1876 1877 func (a *App) GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, *model.AppError) { 1878 counts, err := a.Srv().Store.Channel().GetChannelCounts(teamID, userID) 1879 if err != nil { 1880 return nil, model.NewAppError("SqlChannelStore.GetChannelCounts", "app.channel.get_channel_counts.get.app_error", nil, err.Error(), http.StatusInternalServerError) 1881 } 1882 1883 return counts, nil 1884 } 1885 1886 func (a *App) GetChannelUnread(channelId, userID string) (*model.ChannelUnread, *model.AppError) { 1887 channelUnread, err := a.Srv().Store.Channel().GetChannelUnread(channelId, userID) 1888 if err != nil { 1889 var nfErr *store.ErrNotFound 1890 switch { 1891 case errors.As(err, &nfErr): 1892 return nil, model.NewAppError("GetChannelUnread", "app.channel.get_unread.app_error", nil, nfErr.Error(), http.StatusNotFound) 1893 default: 1894 return nil, model.NewAppError("GetChannelUnread", "app.channel.get_unread.app_error", nil, err.Error(), http.StatusInternalServerError) 1895 } 1896 } 1897 1898 if channelUnread.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_MARK_UNREAD_MENTION { 1899 channelUnread.MsgCount = 0 1900 } 1901 1902 return channelUnread, nil 1903 } 1904 1905 func (a *App) JoinChannel(channel *model.Channel, userID string) *model.AppError { 1906 userChan := make(chan store.StoreResult, 1) 1907 memberChan := make(chan store.StoreResult, 1) 1908 go func() { 1909 user, err := a.Srv().Store.User().Get(context.Background(), userID) 1910 userChan <- store.StoreResult{Data: user, NErr: err} 1911 close(userChan) 1912 }() 1913 go func() { 1914 member, err := a.Srv().Store.Channel().GetMember(channel.Id, userID) 1915 memberChan <- store.StoreResult{Data: member, NErr: err} 1916 close(memberChan) 1917 }() 1918 1919 uresult := <-userChan 1920 if uresult.NErr != nil { 1921 var nfErr *store.ErrNotFound 1922 switch { 1923 case errors.As(uresult.NErr, &nfErr): 1924 return model.NewAppError("CreateChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 1925 default: 1926 return model.NewAppError("CreateChannel", "app.user.get.app_error", nil, uresult.NErr.Error(), http.StatusInternalServerError) 1927 } 1928 } 1929 1930 mresult := <-memberChan 1931 if mresult.NErr == nil && mresult.Data != nil { 1932 // user is already in the channel 1933 return nil 1934 } 1935 1936 user := uresult.Data.(*model.User) 1937 1938 if channel.Type != model.CHANNEL_OPEN { 1939 return model.NewAppError("JoinChannel", "api.channel.join_channel.permissions.app_error", nil, "", http.StatusBadRequest) 1940 } 1941 1942 cm, err := a.AddUserToChannel(user, channel) 1943 if err != nil { 1944 return err 1945 } 1946 1947 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 1948 a.Srv().Go(func() { 1949 pluginContext := a.PluginContext() 1950 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 1951 hooks.UserHasJoinedChannel(pluginContext, cm, nil) 1952 return true 1953 }, plugin.UserHasJoinedChannelId) 1954 }) 1955 } 1956 1957 if err := a.postJoinChannelMessage(user, channel); err != nil { 1958 return err 1959 } 1960 1961 return nil 1962 } 1963 1964 func (a *App) postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1965 message := fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username) 1966 postType := model.POST_JOIN_CHANNEL 1967 1968 if user.IsGuest() { 1969 message = fmt.Sprintf(utils.T("api.channel.guest_join_channel.post_and_forget"), user.Username) 1970 postType = model.POST_GUEST_JOIN_CHANNEL 1971 } 1972 1973 post := &model.Post{ 1974 ChannelId: channel.Id, 1975 Message: message, 1976 Type: postType, 1977 UserId: user.Id, 1978 Props: model.StringInterface{ 1979 "username": user.Username, 1980 }, 1981 } 1982 1983 if _, err := a.CreatePost(post, channel, false, true); err != nil { 1984 return model.NewAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1985 } 1986 1987 return nil 1988 } 1989 1990 func (a *App) postJoinTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 1991 post := &model.Post{ 1992 ChannelId: channel.Id, 1993 Message: fmt.Sprintf(utils.T("api.team.join_team.post_and_forget"), user.Username), 1994 Type: model.POST_JOIN_TEAM, 1995 UserId: user.Id, 1996 Props: model.StringInterface{ 1997 "username": user.Username, 1998 }, 1999 } 2000 2001 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2002 return model.NewAppError("postJoinTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 2003 } 2004 2005 return nil 2006 } 2007 2008 func (a *App) LeaveChannel(channelId string, userID string) *model.AppError { 2009 sc := make(chan store.StoreResult, 1) 2010 go func() { 2011 channel, err := a.Srv().Store.Channel().Get(channelId, true) 2012 sc <- store.StoreResult{Data: channel, NErr: err} 2013 close(sc) 2014 }() 2015 2016 uc := make(chan store.StoreResult, 1) 2017 go func() { 2018 user, err := a.Srv().Store.User().Get(context.Background(), userID) 2019 uc <- store.StoreResult{Data: user, NErr: err} 2020 close(uc) 2021 }() 2022 2023 mcc := make(chan store.StoreResult, 1) 2024 go func() { 2025 count, err := a.Srv().Store.Channel().GetMemberCount(channelId, false) 2026 mcc <- store.StoreResult{Data: count, NErr: err} 2027 close(mcc) 2028 }() 2029 2030 cresult := <-sc 2031 if cresult.NErr != nil { 2032 var nfErr *store.ErrNotFound 2033 switch { 2034 case errors.As(cresult.NErr, &nfErr): 2035 return model.NewAppError("LeaveChannel", "app.channel.get.existing.app_error", nil, nfErr.Error(), http.StatusNotFound) 2036 default: 2037 return model.NewAppError("LeaveChannel", "app.channel.get.find.app_error", nil, cresult.NErr.Error(), http.StatusInternalServerError) 2038 } 2039 } 2040 uresult := <-uc 2041 if uresult.NErr != nil { 2042 var nfErr *store.ErrNotFound 2043 switch { 2044 case errors.As(uresult.NErr, &nfErr): 2045 return model.NewAppError("LeaveChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 2046 default: 2047 return model.NewAppError("LeaveChannel", "app.user.get.app_error", nil, uresult.NErr.Error(), http.StatusInternalServerError) 2048 } 2049 } 2050 ccresult := <-mcc 2051 if ccresult.NErr != nil { 2052 return model.NewAppError("LeaveChannel", "app.channel.get_member_count.app_error", nil, ccresult.NErr.Error(), http.StatusInternalServerError) 2053 } 2054 2055 channel := cresult.Data.(*model.Channel) 2056 user := uresult.Data.(*model.User) 2057 membersCount := ccresult.Data.(int64) 2058 2059 if channel.IsGroupOrDirect() { 2060 err := model.NewAppError("LeaveChannel", "api.channel.leave.direct.app_error", nil, "", http.StatusBadRequest) 2061 return err 2062 } 2063 2064 if channel.Type == model.CHANNEL_PRIVATE && membersCount == 1 { 2065 err := model.NewAppError("LeaveChannel", "api.channel.leave.last_member.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 2066 return err 2067 } 2068 2069 if err := a.removeUserFromChannel(userID, userID, channel); err != nil { 2070 return err 2071 } 2072 2073 if channel.Name == model.DEFAULT_CHANNEL && !*a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 2074 return nil 2075 } 2076 2077 a.Srv().Go(func() { 2078 a.postLeaveChannelMessage(user, channel) 2079 }) 2080 2081 return nil 2082 } 2083 2084 func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 2085 post := &model.Post{ 2086 ChannelId: channel.Id, 2087 // Message here embeds `@username`, not just `username`, to ensure that mentions 2088 // treat this as a username mention even though the user has now left the channel. 2089 // The client renders its own system message, ignoring this value altogether. 2090 Message: fmt.Sprintf(utils.T("api.channel.leave.left"), fmt.Sprintf("@%s", user.Username)), 2091 Type: model.POST_LEAVE_CHANNEL, 2092 UserId: user.Id, 2093 Props: model.StringInterface{ 2094 "username": user.Username, 2095 }, 2096 } 2097 2098 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2099 return model.NewAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 2100 } 2101 2102 return nil 2103 } 2104 2105 func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 2106 message := fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username) 2107 postType := model.POST_ADD_TO_CHANNEL 2108 2109 if addedUser.IsGuest() { 2110 message = fmt.Sprintf(utils.T("api.channel.add_guest.added"), addedUser.Username, user.Username) 2111 postType = model.POST_ADD_GUEST_TO_CHANNEL 2112 } 2113 2114 post := &model.Post{ 2115 ChannelId: channel.Id, 2116 Message: message, 2117 Type: postType, 2118 UserId: user.Id, 2119 RootId: postRootId, 2120 Props: model.StringInterface{ 2121 "userId": user.Id, 2122 "username": user.Username, 2123 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 2124 "addedUsername": addedUser.Username, 2125 }, 2126 } 2127 2128 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2129 return model.NewAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 2130 } 2131 2132 return nil 2133 } 2134 2135 func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 2136 post := &model.Post{ 2137 ChannelId: channel.Id, 2138 Message: fmt.Sprintf(utils.T("api.team.add_user_to_team.added"), addedUser.Username, user.Username), 2139 Type: model.POST_ADD_TO_TEAM, 2140 UserId: user.Id, 2141 RootId: postRootId, 2142 Props: model.StringInterface{ 2143 "userId": user.Id, 2144 "username": user.Username, 2145 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 2146 "addedUsername": addedUser.Username, 2147 }, 2148 } 2149 2150 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2151 return model.NewAppError("postAddToTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 2152 } 2153 2154 return nil 2155 } 2156 2157 func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError { 2158 post := &model.Post{ 2159 ChannelId: channel.Id, 2160 // Message here embeds `@username`, not just `username`, to ensure that mentions 2161 // treat this as a username mention even though the user has now left the channel. 2162 // The client renders its own system message, ignoring this value altogether. 2163 Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), fmt.Sprintf("@%s", removedUser.Username)), 2164 Type: model.POST_REMOVE_FROM_CHANNEL, 2165 UserId: removerUserId, 2166 Props: model.StringInterface{ 2167 "removedUserId": removedUser.Id, 2168 "removedUsername": removedUser.Username, 2169 }, 2170 } 2171 2172 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2173 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 2174 } 2175 2176 return nil 2177 } 2178 2179 func (a *App) removeUserFromChannel(userIDToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 2180 user, nErr := a.Srv().Store.User().Get(context.Background(), userIDToRemove) 2181 if nErr != nil { 2182 var nfErr *store.ErrNotFound 2183 switch { 2184 case errors.As(nErr, &nfErr): 2185 return model.NewAppError("removeUserFromChannel", MissingAccountError, nil, nfErr.Error(), http.StatusNotFound) 2186 default: 2187 return model.NewAppError("removeUserFromChannel", "app.user.get.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2188 } 2189 } 2190 isGuest := user.IsGuest() 2191 2192 if channel.Name == model.DEFAULT_CHANNEL { 2193 if !isGuest { 2194 return model.NewAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 2195 } 2196 } 2197 2198 if channel.IsGroupConstrained() && userIDToRemove != removerUserId && !user.IsBot { 2199 nonMembers, err := a.FilterNonGroupChannelMembers([]string{userIDToRemove}, channel) 2200 if err != nil { 2201 return model.NewAppError("removeUserFromChannel", "api.channel.remove_user_from_channel.app_error", nil, "", http.StatusInternalServerError) 2202 } 2203 if len(nonMembers) == 0 { 2204 return model.NewAppError("removeUserFromChannel", "api.channel.remove_members.denied", map[string]interface{}{"UserIDs": nonMembers}, "", http.StatusBadRequest) 2205 } 2206 } 2207 2208 cm, err := a.GetChannelMember(channel.Id, userIDToRemove) 2209 if err != nil { 2210 return err 2211 } 2212 2213 if err := a.Srv().Store.Channel().RemoveMember(channel.Id, userIDToRemove); err != nil { 2214 return model.NewAppError("removeUserFromChannel", "app.channel.remove_member.app_error", nil, err.Error(), http.StatusInternalServerError) 2215 } 2216 if err := a.Srv().Store.ChannelMemberHistory().LogLeaveEvent(userIDToRemove, channel.Id, model.GetMillis()); err != nil { 2217 return model.NewAppError("removeUserFromChannel", "app.channel_member_history.log_leave_event.internal_error", nil, err.Error(), http.StatusInternalServerError) 2218 } 2219 2220 if isGuest { 2221 currentMembers, err := a.GetChannelMembersForUser(channel.TeamId, userIDToRemove) 2222 if err != nil { 2223 return err 2224 } 2225 if len(*currentMembers) == 0 { 2226 teamMember, err := a.GetTeamMember(channel.TeamId, userIDToRemove) 2227 if err != nil { 2228 return model.NewAppError("removeUserFromChannel", "api.team.remove_user_from_team.missing.app_error", nil, err.Error(), http.StatusBadRequest) 2229 } 2230 2231 if err = a.RemoveTeamMemberFromTeam(teamMember, removerUserId); err != nil { 2232 return err 2233 } 2234 } 2235 } 2236 2237 a.InvalidateCacheForUser(userIDToRemove) 2238 a.invalidateCacheForChannelMembers(channel.Id) 2239 2240 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 2241 var actorUser *model.User 2242 if removerUserId != "" { 2243 actorUser, _ = a.GetUser(removerUserId) 2244 } 2245 2246 a.Srv().Go(func() { 2247 pluginContext := a.PluginContext() 2248 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 2249 hooks.UserHasLeftChannel(pluginContext, cm, actorUser) 2250 return true 2251 }, plugin.UserHasLeftChannelId) 2252 }) 2253 } 2254 2255 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil) 2256 message.Add("user_id", userIDToRemove) 2257 message.Add("remover_id", removerUserId) 2258 a.Publish(message) 2259 2260 // because the removed user no longer belongs to the channel we need to send a separate websocket event 2261 userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIDToRemove, nil) 2262 userMsg.Add("channel_id", channel.Id) 2263 userMsg.Add("remover_id", removerUserId) 2264 a.Publish(userMsg) 2265 2266 return nil 2267 } 2268 2269 func (a *App) RemoveUserFromChannel(userIDToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 2270 var err *model.AppError 2271 2272 if err = a.removeUserFromChannel(userIDToRemove, removerUserId, channel); err != nil { 2273 return err 2274 } 2275 2276 var user *model.User 2277 if user, err = a.GetUser(userIDToRemove); err != nil { 2278 return err 2279 } 2280 2281 if userIDToRemove == removerUserId { 2282 if err := a.postLeaveChannelMessage(user, channel); err != nil { 2283 return err 2284 } 2285 } else { 2286 a.Srv().Go(func() { 2287 a.postRemoveFromChannelMessage(removerUserId, user, channel) 2288 }) 2289 } 2290 2291 return nil 2292 } 2293 2294 func (a *App) GetNumberOfChannelsOnTeam(teamID string) (int, *model.AppError) { 2295 // Get total number of channels on current team 2296 list, err := a.Srv().Store.Channel().GetTeamChannels(teamID) 2297 if err != nil { 2298 var nfErr *store.ErrNotFound 2299 switch { 2300 case errors.As(err, &nfErr): 2301 return 0, model.NewAppError("GetNumberOfChannelsOnTeam", "app.channel.get_channels.not_found.app_error", nil, nfErr.Error(), http.StatusNotFound) 2302 default: 2303 return 0, model.NewAppError("GetNumberOfChannelsOnTeam", "app.channel.get_channels.get.app_error", nil, err.Error(), http.StatusInternalServerError) 2304 } 2305 } 2306 return len(*list), nil 2307 } 2308 2309 func (a *App) SetActiveChannel(userID string, channelId string) *model.AppError { 2310 status, err := a.GetStatus(userID) 2311 2312 oldStatus := model.STATUS_OFFLINE 2313 2314 if err != nil { 2315 status = &model.Status{UserId: userID, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: channelId} 2316 } else { 2317 oldStatus = status.Status 2318 status.ActiveChannel = channelId 2319 if !status.Manual && channelId != "" { 2320 status.Status = model.STATUS_ONLINE 2321 } 2322 status.LastActivityAt = model.GetMillis() 2323 } 2324 2325 a.AddStatusCache(status) 2326 2327 if status.Status != oldStatus { 2328 a.BroadcastStatus(status) 2329 } 2330 2331 return nil 2332 } 2333 2334 func (a *App) UpdateChannelLastViewedAt(channelIds []string, userID string) *model.AppError { 2335 if _, err := a.Srv().Store.Channel().UpdateLastViewedAt(channelIds, userID, *a.Config().ServiceSettings.ThreadAutoFollow); err != nil { 2336 var invErr *store.ErrInvalidInput 2337 switch { 2338 case errors.As(err, &invErr): 2339 return model.NewAppError("UpdateChannelLastViewedAt", "app.channel.update_last_viewed_at.app_error", nil, invErr.Error(), http.StatusBadRequest) 2340 default: 2341 return model.NewAppError("UpdateChannelLastViewedAt", "app.channel.update_last_viewed_at.app_error", nil, err.Error(), http.StatusInternalServerError) 2342 } 2343 } 2344 2345 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 2346 for _, channelId := range channelIds { 2347 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userID, nil) 2348 message.Add("channel_id", channelId) 2349 a.Publish(message) 2350 } 2351 } 2352 2353 return nil 2354 } 2355 2356 // MarkChanelAsUnreadFromPost will take a post and set the channel as unread from that one. 2357 func (a *App) MarkChannelAsUnreadFromPost(postID string, userID string) (*model.ChannelUnreadAt, *model.AppError) { 2358 post, err := a.GetSinglePost(postID) 2359 if err != nil { 2360 return nil, err 2361 } 2362 2363 user, err := a.GetUser(userID) 2364 if err != nil { 2365 return nil, err 2366 } 2367 2368 unreadMentions, err := a.countMentionsFromPost(user, post) 2369 if err != nil { 2370 return nil, err 2371 } 2372 2373 if *a.Config().ServiceSettings.ThreadAutoFollow && post.RootId != "" { 2374 threadMembership, _ := a.Srv().Store.Thread().GetMembershipForUser(user.Id, post.RootId) 2375 if threadMembership != nil { 2376 channel, nErr := a.Srv().Store.Channel().Get(post.ChannelId, true) 2377 if nErr != nil { 2378 return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2379 } 2380 threadMembership.UnreadMentions, err = a.countThreadMentions(user, post, channel.TeamId, post.UpdateAt-1) 2381 if err != nil { 2382 return nil, err 2383 } 2384 _, nErr = a.Srv().Store.Thread().UpdateMembership(threadMembership) 2385 if nErr != nil { 2386 return nil, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2387 } 2388 } 2389 } 2390 2391 channelUnread, nErr := a.Srv().Store.Channel().UpdateLastViewedAtPost(post, userID, unreadMentions, *a.Config().ServiceSettings.ThreadAutoFollow) 2392 if nErr != nil { 2393 return channelUnread, model.NewAppError("MarkChannelAsUnreadFromPost", "app.channel.update_last_viewed_at_post.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2394 } 2395 2396 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POST_UNREAD, channelUnread.TeamId, channelUnread.ChannelId, channelUnread.UserId, nil) 2397 message.Add("msg_count", channelUnread.MsgCount) 2398 message.Add("mention_count", channelUnread.MentionCount) 2399 message.Add("last_viewed_at", channelUnread.LastViewedAt) 2400 message.Add("post_id", postID) 2401 a.Publish(message) 2402 2403 a.UpdateMobileAppBadge(userID) 2404 2405 return channelUnread, nil 2406 } 2407 2408 func (a *App) AutocompleteChannels(teamID string, term string) (*model.ChannelList, *model.AppError) { 2409 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 2410 term = strings.TrimSpace(term) 2411 2412 channelList, err := a.Srv().Store.Channel().AutocompleteInTeam(teamID, term, includeDeleted) 2413 if err != nil { 2414 return nil, model.NewAppError("AutocompleteChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2415 } 2416 2417 return channelList, nil 2418 } 2419 2420 func (a *App) AutocompleteChannelsForSearch(teamID string, userID string, term string) (*model.ChannelList, *model.AppError) { 2421 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 2422 2423 term = strings.TrimSpace(term) 2424 2425 channelList, err := a.Srv().Store.Channel().AutocompleteInTeamForSearch(teamID, userID, term, includeDeleted) 2426 if err != nil { 2427 return nil, model.NewAppError("AutocompleteChannelsForSearch", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2428 } 2429 2430 return channelList, nil 2431 } 2432 2433 // SearchAllChannels returns a list of channels, the total count of the results of the search (if the paginate search option is true), and an error. 2434 func (a *App) SearchAllChannels(term string, opts model.ChannelSearchOpts) (*model.ChannelListWithTeamData, int64, *model.AppError) { 2435 if opts.ExcludeDefaultChannels { 2436 opts.ExcludeChannelNames = a.DefaultChannelNames() 2437 } 2438 storeOpts := store.ChannelSearchOpts{ 2439 ExcludeChannelNames: opts.ExcludeChannelNames, 2440 NotAssociatedToGroup: opts.NotAssociatedToGroup, 2441 IncludeDeleted: opts.IncludeDeleted, 2442 Deleted: opts.Deleted, 2443 TeamIds: opts.TeamIds, 2444 GroupConstrained: opts.GroupConstrained, 2445 ExcludeGroupConstrained: opts.ExcludeGroupConstrained, 2446 Public: opts.Public, 2447 Private: opts.Private, 2448 Page: opts.Page, 2449 PerPage: opts.PerPage, 2450 } 2451 2452 term = strings.TrimSpace(term) 2453 2454 channelList, totalCount, err := a.Srv().Store.Channel().SearchAllChannels(term, storeOpts) 2455 if err != nil { 2456 return nil, 0, model.NewAppError("SearchAllChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2457 } 2458 2459 return channelList, totalCount, nil 2460 } 2461 2462 func (a *App) SearchChannels(teamID string, term string) (*model.ChannelList, *model.AppError) { 2463 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 2464 2465 term = strings.TrimSpace(term) 2466 2467 channelList, err := a.Srv().Store.Channel().SearchInTeam(teamID, term, includeDeleted) 2468 if err != nil { 2469 return nil, model.NewAppError("SearchChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2470 } 2471 2472 return channelList, nil 2473 } 2474 2475 func (a *App) SearchArchivedChannels(teamID string, term string, userID string) (*model.ChannelList, *model.AppError) { 2476 term = strings.TrimSpace(term) 2477 2478 channelList, err := a.Srv().Store.Channel().SearchArchivedInTeam(teamID, term, userID) 2479 if err != nil { 2480 return nil, model.NewAppError("SearchArchivedChannels", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2481 } 2482 2483 return channelList, nil 2484 } 2485 2486 func (a *App) SearchChannelsForUser(userID, teamID, term string) (*model.ChannelList, *model.AppError) { 2487 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 2488 2489 term = strings.TrimSpace(term) 2490 2491 channelList, err := a.Srv().Store.Channel().SearchForUserInTeam(userID, teamID, term, includeDeleted) 2492 if err != nil { 2493 return nil, model.NewAppError("SearchChannelsForUser", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2494 } 2495 2496 return channelList, nil 2497 } 2498 2499 func (a *App) SearchGroupChannels(userID, term string) (*model.ChannelList, *model.AppError) { 2500 if term == "" { 2501 return &model.ChannelList{}, nil 2502 } 2503 2504 channelList, err := a.Srv().Store.Channel().SearchGroupChannels(userID, term) 2505 if err != nil { 2506 return nil, model.NewAppError("SearchGroupChannels", "app.channel.search_group_channels.app_error", nil, err.Error(), http.StatusInternalServerError) 2507 } 2508 return channelList, nil 2509 } 2510 2511 func (a *App) SearchChannelsUserNotIn(teamID string, userID string, term string) (*model.ChannelList, *model.AppError) { 2512 term = strings.TrimSpace(term) 2513 channelList, err := a.Srv().Store.Channel().SearchMore(userID, teamID, term) 2514 if err != nil { 2515 return nil, model.NewAppError("SearchChannelsUserNotIn", "app.channel.search.app_error", nil, err.Error(), http.StatusInternalServerError) 2516 } 2517 2518 return channelList, nil 2519 } 2520 2521 func (a *App) MarkChannelsAsViewed(channelIds []string, userID string, currentSessionId string) (map[string]int64, *model.AppError) { 2522 // I start looking for channels with notifications before I mark it as read, to clear the push notifications if needed 2523 channelsToClearPushNotifications := []string{} 2524 if *a.Config().EmailSettings.SendPushNotifications { 2525 for _, channelId := range channelIds { 2526 channel, errCh := a.Srv().Store.Channel().Get(channelId, true) 2527 if errCh != nil { 2528 mlog.Warn("Failed to get channel", mlog.Err(errCh)) 2529 continue 2530 } 2531 2532 member, err := a.Srv().Store.Channel().GetMember(channelId, userID) 2533 if err != nil { 2534 mlog.Warn("Failed to get membership", mlog.Err(err)) 2535 continue 2536 } 2537 2538 notify := member.NotifyProps[model.PUSH_NOTIFY_PROP] 2539 if notify == model.CHANNEL_NOTIFY_DEFAULT { 2540 user, err := a.GetUser(userID) 2541 if err != nil { 2542 mlog.Warn("Failed to get user", mlog.String("user_id", userID), mlog.Err(err)) 2543 continue 2544 } 2545 notify = user.NotifyProps[model.PUSH_NOTIFY_PROP] 2546 } 2547 if notify == model.USER_NOTIFY_ALL { 2548 if count, err := a.Srv().Store.User().GetAnyUnreadPostCountForChannel(userID, channelId); err == nil { 2549 if count > 0 { 2550 channelsToClearPushNotifications = append(channelsToClearPushNotifications, channelId) 2551 } 2552 } 2553 } else if notify == model.USER_NOTIFY_MENTION || channel.Type == model.CHANNEL_DIRECT { 2554 if count, err := a.Srv().Store.User().GetUnreadCountForChannel(userID, channelId); err == nil { 2555 if count > 0 { 2556 channelsToClearPushNotifications = append(channelsToClearPushNotifications, channelId) 2557 } 2558 } 2559 } 2560 } 2561 } 2562 times, err := a.Srv().Store.Channel().UpdateLastViewedAt(channelIds, userID, *a.Config().ServiceSettings.ThreadAutoFollow) 2563 if err != nil { 2564 var invErr *store.ErrInvalidInput 2565 switch { 2566 case errors.As(err, &invErr): 2567 return nil, model.NewAppError("MarkChannelsAsViewed", "app.channel.update_last_viewed_at.app_error", nil, invErr.Error(), http.StatusBadRequest) 2568 default: 2569 return nil, model.NewAppError("MarkChannelsAsViewed", "app.channel.update_last_viewed_at.app_error", nil, err.Error(), http.StatusInternalServerError) 2570 } 2571 } 2572 2573 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 2574 for _, channelId := range channelIds { 2575 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userID, nil) 2576 message.Add("channel_id", channelId) 2577 a.Publish(message) 2578 } 2579 } 2580 for _, channelId := range channelsToClearPushNotifications { 2581 a.clearPushNotification(currentSessionId, userID, channelId) 2582 } 2583 return times, nil 2584 } 2585 2586 func (a *App) ViewChannel(view *model.ChannelView, userID string, currentSessionId string) (map[string]int64, *model.AppError) { 2587 if err := a.SetActiveChannel(userID, view.ChannelId); err != nil { 2588 return nil, err 2589 } 2590 2591 channelIds := []string{} 2592 2593 if view.ChannelId != "" { 2594 channelIds = append(channelIds, view.ChannelId) 2595 } 2596 2597 if view.PrevChannelId != "" { 2598 channelIds = append(channelIds, view.PrevChannelId) 2599 } 2600 2601 if len(channelIds) == 0 { 2602 return map[string]int64{}, nil 2603 } 2604 2605 return a.MarkChannelsAsViewed(channelIds, userID, currentSessionId) 2606 } 2607 2608 func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError { 2609 if err := a.Srv().Store.Post().PermanentDeleteByChannel(channel.Id); err != nil { 2610 return model.NewAppError("PermanentDeleteChannel", "app.post.permanent_delete_by_channel.app_error", nil, err.Error(), http.StatusInternalServerError) 2611 } 2612 2613 if err := a.Srv().Store.Channel().PermanentDeleteMembersByChannel(channel.Id); err != nil { 2614 return model.NewAppError("PermanentDeleteChannel", "app.channel.remove_member.app_error", nil, err.Error(), http.StatusInternalServerError) 2615 } 2616 2617 if err := a.Srv().Store.Webhook().PermanentDeleteIncomingByChannel(channel.Id); err != nil { 2618 return model.NewAppError("PermanentDeleteChannel", "app.webhooks.permanent_delete_incoming_by_channel.app_error", nil, err.Error(), http.StatusInternalServerError) 2619 } 2620 2621 if err := a.Srv().Store.Webhook().PermanentDeleteOutgoingByChannel(channel.Id); err != nil { 2622 return model.NewAppError("PermanentDeleteChannel", "app.webhooks.permanent_delete_outgoing_by_channel.app_error", nil, err.Error(), http.StatusInternalServerError) 2623 } 2624 2625 deleteAt := model.GetMillis() 2626 2627 if nErr := a.Srv().Store.Channel().PermanentDelete(channel.Id); nErr != nil { 2628 return model.NewAppError("PermanentDeleteChannel", "app.channel.permanent_delete.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2629 } 2630 2631 a.invalidateCacheForChannel(channel) 2632 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil) 2633 message.Add("channel_id", channel.Id) 2634 message.Add("delete_at", deleteAt) 2635 a.Publish(message) 2636 2637 return nil 2638 } 2639 2640 func (a *App) RemoveAllDeactivatedMembersFromChannel(channel *model.Channel) *model.AppError { 2641 err := a.Srv().Store.Channel().RemoveAllDeactivatedMembers(channel.Id) 2642 if err != nil { 2643 return model.NewAppError("RemoveAllDeactivatedMembersFromChannel", "app.channel.remove_all_deactivated_members.app_error", nil, err.Error(), http.StatusInternalServerError) 2644 } 2645 2646 return nil 2647 } 2648 2649 // MoveChannel method is prone to data races if someone joins to channel during the move process. However this 2650 // function is only exposed to sysadmins and the possibility of this edge case is relatively small. 2651 func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { 2652 // Check that all channel members are in the destination team. 2653 channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000) 2654 if err != nil { 2655 return err 2656 } 2657 2658 channelMemberIds := []string{} 2659 for _, channelMember := range *channelMembers { 2660 channelMemberIds = append(channelMemberIds, channelMember.UserId) 2661 } 2662 2663 if len(channelMemberIds) > 0 { 2664 teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds, nil) 2665 if err2 != nil { 2666 return err2 2667 } 2668 2669 if len(teamMembers) != len(*channelMembers) { 2670 teamMembersMap := make(map[string]*model.TeamMember, len(teamMembers)) 2671 for _, teamMember := range teamMembers { 2672 teamMembersMap[teamMember.UserId] = teamMember 2673 } 2674 for _, channelMember := range *channelMembers { 2675 if _, ok := teamMembersMap[channelMember.UserId]; !ok { 2676 mlog.Warn("Not member of the target team", mlog.String("userId", channelMember.UserId)) 2677 } 2678 } 2679 return model.NewAppError("MoveChannel", "app.channel.move_channel.members_do_not_match.error", nil, "", http.StatusInternalServerError) 2680 } 2681 } 2682 2683 // keep instance of the previous team 2684 previousTeam, nErr := a.Srv().Store.Team().Get(channel.TeamId) 2685 if nErr != nil { 2686 var nfErr *store.ErrNotFound 2687 switch { 2688 case errors.As(nErr, &nfErr): 2689 return model.NewAppError("MoveChannel", "app.team.get.find.app_error", nil, nfErr.Error(), http.StatusNotFound) 2690 default: 2691 return model.NewAppError("MoveChannel", "app.team.get.finding.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2692 } 2693 } 2694 2695 if nErr := a.Srv().Store.Channel().UpdateSidebarChannelCategoryOnMove(channel, team.Id); nErr != nil { 2696 return model.NewAppError("MoveChannel", "app.channel.sidebar_categories.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2697 } 2698 2699 channel.TeamId = team.Id 2700 if _, err := a.Srv().Store.Channel().Update(channel); err != nil { 2701 var appErr *model.AppError 2702 var invErr *store.ErrInvalidInput 2703 switch { 2704 case errors.As(err, &invErr): 2705 return model.NewAppError("MoveChannel", "app.channel.update.bad_id", nil, invErr.Error(), http.StatusBadRequest) 2706 case errors.As(err, &appErr): 2707 return appErr 2708 default: 2709 return model.NewAppError("MoveChannel", "app.channel.update_channel.internal_error", nil, err.Error(), http.StatusInternalServerError) 2710 } 2711 } 2712 2713 if incomingWebhooks, err := a.GetIncomingWebhooksForTeamPage(previousTeam.Id, 0, 10000000); err != nil { 2714 mlog.Warn("Failed to get incoming webhooks", mlog.Err(err)) 2715 } else { 2716 for _, webhook := range incomingWebhooks { 2717 if webhook.ChannelId == channel.Id { 2718 webhook.TeamId = team.Id 2719 if _, err := a.Srv().Store.Webhook().UpdateIncoming(webhook); err != nil { 2720 mlog.Warn("Failed to move incoming webhook to new team", mlog.String("webhook id", webhook.Id)) 2721 } 2722 } 2723 } 2724 } 2725 2726 if outgoingWebhooks, err := a.GetOutgoingWebhooksForTeamPage(previousTeam.Id, 0, 10000000); err != nil { 2727 mlog.Warn("Failed to get outgoing webhooks", mlog.Err(err)) 2728 } else { 2729 for _, webhook := range outgoingWebhooks { 2730 if webhook.ChannelId == channel.Id { 2731 webhook.TeamId = team.Id 2732 if _, err := a.Srv().Store.Webhook().UpdateOutgoing(webhook); err != nil { 2733 mlog.Warn("Failed to move outgoing webhook to new team.", mlog.String("webhook id", webhook.Id)) 2734 } 2735 } 2736 } 2737 } 2738 2739 if err := a.RemoveUsersFromChannelNotMemberOfTeam(user, channel, team); err != nil { 2740 mlog.Warn("error while removing non-team member users", mlog.Err(err)) 2741 } 2742 2743 if user != nil { 2744 if err := a.postChannelMoveMessage(user, channel, previousTeam); err != nil { 2745 mlog.Warn("error while posting move channel message", mlog.Err(err)) 2746 } 2747 } 2748 2749 return nil 2750 } 2751 2752 func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError { 2753 2754 post := &model.Post{ 2755 ChannelId: channel.Id, 2756 Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name), 2757 Type: model.POST_MOVE_CHANNEL, 2758 UserId: user.Id, 2759 Props: model.StringInterface{ 2760 "username": user.Username, 2761 }, 2762 } 2763 2764 if _, err := a.CreatePost(post, channel, false, true); err != nil { 2765 return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError) 2766 } 2767 2768 return nil 2769 } 2770 2771 func (a *App) RemoveUsersFromChannelNotMemberOfTeam(remover *model.User, channel *model.Channel, team *model.Team) *model.AppError { 2772 channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000) 2773 if err != nil { 2774 return err 2775 } 2776 2777 channelMemberIds := []string{} 2778 channelMemberMap := make(map[string]struct{}) 2779 for _, channelMember := range *channelMembers { 2780 channelMemberMap[channelMember.UserId] = struct{}{} 2781 channelMemberIds = append(channelMemberIds, channelMember.UserId) 2782 } 2783 2784 if len(channelMemberIds) > 0 { 2785 teamMembers, err := a.GetTeamMembersByIds(team.Id, channelMemberIds, nil) 2786 if err != nil { 2787 return err 2788 } 2789 2790 if len(teamMembers) != len(*channelMembers) { 2791 for _, teamMember := range teamMembers { 2792 delete(channelMemberMap, teamMember.UserId) 2793 } 2794 2795 var removerId string 2796 if remover != nil { 2797 removerId = remover.Id 2798 } 2799 for userID := range channelMemberMap { 2800 if err := a.removeUserFromChannel(userID, removerId, channel); err != nil { 2801 return err 2802 } 2803 } 2804 } 2805 } 2806 2807 return nil 2808 } 2809 2810 func (a *App) GetPinnedPosts(channelId string) (*model.PostList, *model.AppError) { 2811 posts, err := a.Srv().Store.Channel().GetPinnedPosts(channelId) 2812 if err != nil { 2813 return nil, model.NewAppError("GetPinnedPosts", "app.channel.pinned_posts.app_error", nil, err.Error(), http.StatusInternalServerError) 2814 } 2815 2816 return posts, nil 2817 } 2818 2819 func (a *App) ToggleMuteChannel(channelId, userID string) (*model.ChannelMember, *model.AppError) { 2820 member, nErr := a.Srv().Store.Channel().GetMember(channelId, userID) 2821 if nErr != nil { 2822 var appErr *model.AppError 2823 var nfErr *store.ErrNotFound 2824 switch { 2825 case errors.As(nErr, &appErr): 2826 return nil, appErr 2827 case errors.As(nErr, &nfErr): 2828 return nil, model.NewAppError("ToggleMuteChannel", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) 2829 default: 2830 return nil, model.NewAppError("ToggleMuteChannel", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2831 } 2832 } 2833 2834 member.SetChannelMuted(!member.IsChannelMuted()) 2835 2836 member, err := a.updateChannelMember(member) 2837 if err != nil { 2838 return nil, err 2839 } 2840 2841 a.invalidateCacheForChannelMembersNotifyProps(member.ChannelId) 2842 2843 return member, nil 2844 } 2845 2846 func (a *App) setChannelsMuted(channelIds []string, userID string, muted bool) ([]*model.ChannelMember, *model.AppError) { 2847 members, nErr := a.Srv().Store.Channel().GetMembersByChannelIds(channelIds, userID) 2848 if nErr != nil { 2849 var appErr *model.AppError 2850 switch { 2851 case errors.As(nErr, &appErr): 2852 return nil, appErr 2853 default: 2854 return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2855 } 2856 } 2857 2858 var membersToUpdate []*model.ChannelMember 2859 for _, member := range *members { 2860 if muted == member.IsChannelMuted() { 2861 continue 2862 } 2863 2864 updatedMember := member 2865 updatedMember.SetChannelMuted(muted) 2866 2867 membersToUpdate = append(membersToUpdate, &updatedMember) 2868 } 2869 2870 if len(membersToUpdate) == 0 { 2871 return nil, nil 2872 } 2873 2874 updated, nErr := a.Srv().Store.Channel().UpdateMultipleMembers(membersToUpdate) 2875 if nErr != nil { 2876 var appErr *model.AppError 2877 var nfErr *store.ErrNotFound 2878 switch { 2879 case errors.As(nErr, &appErr): 2880 return nil, appErr 2881 case errors.As(nErr, &nfErr): 2882 return nil, model.NewAppError("setChannelsMuted", MissingChannelMemberError, nil, nfErr.Error(), http.StatusNotFound) 2883 default: 2884 return nil, model.NewAppError("setChannelsMuted", "app.channel.get_member.app_error", nil, nErr.Error(), http.StatusInternalServerError) 2885 } 2886 } 2887 2888 for _, member := range updated { 2889 a.invalidateCacheForChannelMembersNotifyProps(member.ChannelId) 2890 2891 evt := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED, "", "", member.UserId, nil) 2892 evt.Add("channelMember", member.ToJson()) 2893 a.Publish(evt) 2894 } 2895 2896 return updated, nil 2897 } 2898 2899 func (a *App) FillInChannelProps(channel *model.Channel) *model.AppError { 2900 return a.FillInChannelsProps(&model.ChannelList{channel}) 2901 } 2902 2903 func (a *App) FillInChannelsProps(channelList *model.ChannelList) *model.AppError { 2904 // Group the channels by team and call GetChannelsByNames just once per team. 2905 channelsByTeam := make(map[string]model.ChannelList) 2906 for _, channel := range *channelList { 2907 channelsByTeam[channel.TeamId] = append(channelsByTeam[channel.TeamId], channel) 2908 } 2909 2910 for teamID, channelList := range channelsByTeam { 2911 allChannelMentions := make(map[string]bool) 2912 channelMentions := make(map[*model.Channel][]string, len(channelList)) 2913 2914 // Collect mentions across the channels so as to query just once for this team. 2915 for _, channel := range channelList { 2916 channelMentions[channel] = model.ChannelMentions(channel.Header) 2917 2918 for _, channelMention := range channelMentions[channel] { 2919 allChannelMentions[channelMention] = true 2920 } 2921 } 2922 2923 allChannelMentionNames := make([]string, 0, len(allChannelMentions)) 2924 for channelName := range allChannelMentions { 2925 allChannelMentionNames = append(allChannelMentionNames, channelName) 2926 } 2927 2928 if len(allChannelMentionNames) > 0 { 2929 mentionedChannels, err := a.GetChannelsByNames(allChannelMentionNames, teamID) 2930 if err != nil { 2931 return err 2932 } 2933 2934 mentionedChannelsByName := make(map[string]*model.Channel) 2935 for _, channel := range mentionedChannels { 2936 mentionedChannelsByName[channel.Name] = channel 2937 } 2938 2939 for _, channel := range channelList { 2940 channelMentionsProp := make(map[string]interface{}, len(channelMentions[channel])) 2941 for _, channelMention := range channelMentions[channel] { 2942 if mentioned, ok := mentionedChannelsByName[channelMention]; ok { 2943 if mentioned.Type == model.CHANNEL_OPEN { 2944 channelMentionsProp[mentioned.Name] = map[string]interface{}{ 2945 "display_name": mentioned.DisplayName, 2946 } 2947 } 2948 } 2949 } 2950 2951 if len(channelMentionsProp) > 0 { 2952 channel.AddProp("channel_mentions", channelMentionsProp) 2953 } else if channel.Props != nil { 2954 delete(channel.Props, "channel_mentions") 2955 } 2956 } 2957 } 2958 } 2959 2960 return nil 2961 } 2962 2963 func (a *App) ClearChannelMembersCache(channelID string) { 2964 perPage := 100 2965 page := 0 2966 2967 for { 2968 channelMembers, err := a.Srv().Store.Channel().GetMembers(channelID, page*perPage, perPage) 2969 if err != nil { 2970 a.Log().Warn("error clearing cache for channel members", mlog.String("channel_id", channelID)) 2971 break 2972 } 2973 2974 for _, channelMember := range *channelMembers { 2975 a.ClearSessionCacheForUser(channelMember.UserId) 2976 2977 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED, "", "", channelMember.UserId, nil) 2978 message.Add("channelMember", channelMember.ToJson()) 2979 a.Publish(message) 2980 } 2981 2982 length := len(*(channelMembers)) 2983 if length < perPage { 2984 break 2985 } 2986 2987 page++ 2988 } 2989 } 2990 2991 func (a *App) GetMemberCountsByGroup(channelID string, includeTimezones bool) ([]*model.ChannelMemberCountByGroup, *model.AppError) { 2992 channelMemberCounts, err := a.Srv().Store.Channel().GetMemberCountsByGroup(channelID, includeTimezones) 2993 if err != nil { 2994 return nil, model.NewAppError("GetMemberCountsByGroup", "app.channel.get_member_count.app_error", nil, err.Error(), http.StatusInternalServerError) 2995 } 2996 2997 return channelMemberCounts, nil 2998 } 2999 3000 func (a *App) getDirectChannel(userID, otherUserID string) (*model.Channel, *model.AppError) { 3001 channel, nErr := a.Srv().Store.Channel().GetByName("", model.GetDMNameFromIds(userID, otherUserID), true) 3002 if nErr != nil { 3003 var nfErr *store.ErrNotFound 3004 if errors.As(nErr, &nfErr) { 3005 return nil, nil 3006 } 3007 3008 return nil, model.NewAppError("GetOrCreateDirectChannel", "web.incoming_webhook.channel.app_error", nil, nErr.Error(), http.StatusInternalServerError) 3009 } 3010 3011 return channel, nil 3012 }