github.com/lologarithm/mattermost-server@v5.3.2-0.20181002060438-c82a84ed765b+incompatible/app/channel.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 "strings" 10 "time" 11 12 "github.com/mattermost/mattermost-server/mlog" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/plugin" 15 "github.com/mattermost/mattermost-server/store" 16 "github.com/mattermost/mattermost-server/utils" 17 ) 18 19 func (a *App) CreateDefaultChannels(teamId string) ([]*model.Channel, *model.AppError) { 20 townSquare := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.town_square"), Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId} 21 22 if _, err := a.CreateChannel(townSquare, false); err != nil { 23 return nil, err 24 } 25 26 offTopic := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.off_topic"), Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId} 27 28 if _, err := a.CreateChannel(offTopic, false); err != nil { 29 return nil, err 30 } 31 32 channels := []*model.Channel{townSquare, offTopic} 33 return channels, nil 34 } 35 36 func (a *App) JoinDefaultChannels(teamId string, user *model.User, shouldBeAdmin bool, userRequestorId string) *model.AppError { 37 var err *model.AppError = nil 38 39 var requestor *model.User 40 if userRequestorId != "" { 41 u := <-a.Srv.Store.User().Get(userRequestorId) 42 if u.Err != nil { 43 return u.Err 44 } 45 requestor = u.Data.(*model.User) 46 } 47 48 defaultChannelList := []string{"town-square"} 49 50 if len(a.Config().TeamSettings.ExperimentalDefaultChannels) == 0 { 51 defaultChannelList = append(defaultChannelList, "off-topic") 52 } else { 53 seenChannels := map[string]bool{} 54 for _, channelName := range a.Config().TeamSettings.ExperimentalDefaultChannels { 55 if !seenChannels[channelName] { 56 defaultChannelList = append(defaultChannelList, channelName) 57 seenChannels[channelName] = true 58 } 59 } 60 } 61 62 for _, channelName := range defaultChannelList { 63 if result := <-a.Srv.Store.Channel().GetByName(teamId, channelName, true); result.Err != nil { 64 err = result.Err 65 } else { 66 67 channel := result.Data.(*model.Channel) 68 69 if channel.Type != model.CHANNEL_OPEN { 70 continue 71 } 72 73 cm := &model.ChannelMember{ 74 ChannelId: channel.Id, 75 UserId: user.Id, 76 SchemeUser: true, 77 SchemeAdmin: shouldBeAdmin, 78 NotifyProps: model.GetDefaultChannelNotifyProps(), 79 } 80 81 if cmResult := <-a.Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil { 82 err = cmResult.Err 83 } 84 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 85 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 86 } 87 88 if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 89 if channel.Name == model.DEFAULT_CHANNEL { 90 if requestor == nil { 91 if err := a.postJoinTeamMessage(user, channel); err != nil { 92 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 93 } 94 } else { 95 if err := a.postAddToTeamMessage(requestor, user, channel, ""); err != nil { 96 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 97 } 98 } 99 } else { 100 if requestor == nil { 101 if err := a.postJoinChannelMessage(user, channel); err != nil { 102 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 103 } 104 } else { 105 if err := a.PostAddToChannelMessage(requestor, user, channel, ""); err != nil { 106 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 107 } 108 } 109 } 110 } 111 112 a.InvalidateCacheForChannelMembers(result.Data.(*model.Channel).Id) 113 } 114 } 115 116 return err 117 } 118 119 func (a *App) CreateChannelWithUser(channel *model.Channel, userId string) (*model.Channel, *model.AppError) { 120 if channel.IsGroupOrDirect() { 121 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.direct_channel.app_error", nil, "", http.StatusBadRequest) 122 } 123 124 if strings.Index(channel.Name, "__") > 0 { 125 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.invalid_character.app_error", nil, "", http.StatusBadRequest) 126 } 127 128 if len(channel.TeamId) == 0 { 129 return nil, model.NewAppError("CreateChannelWithUser", "app.channel.create_channel.no_team_id.app_error", nil, "", http.StatusBadRequest) 130 } 131 132 // Get total number of channels on current team 133 count, err := a.GetNumberOfChannelsOnTeam(channel.TeamId) 134 if err != nil { 135 return nil, err 136 } 137 138 if int64(count+1) > *a.Config().TeamSettings.MaxChannelsPerTeam { 139 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.max_channel_limit.app_error", map[string]interface{}{"MaxChannelsPerTeam": *a.Config().TeamSettings.MaxChannelsPerTeam}, "", http.StatusBadRequest) 140 } 141 142 channel.CreatorId = userId 143 144 rchannel, err := a.CreateChannel(channel, true) 145 if err != nil { 146 return nil, err 147 } 148 149 var user *model.User 150 if user, err = a.GetUser(userId); err != nil { 151 return nil, err 152 } 153 154 a.postJoinChannelMessage(user, channel) 155 156 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_CREATED, "", "", userId, nil) 157 message.Add("channel_id", channel.Id) 158 message.Add("team_id", channel.TeamId) 159 a.Publish(message) 160 161 return rchannel, nil 162 } 163 164 // RenameChannel is used to rename the channel Name and the DisplayName fields 165 func (a *App) RenameChannel(channel *model.Channel, newChannelName string, newDisplayName string) (*model.Channel, *model.AppError) { 166 channel.Name = newChannelName 167 if newDisplayName != "" { 168 channel.DisplayName = newDisplayName 169 } 170 171 newChannel, err := a.UpdateChannel(channel) 172 if err != nil { 173 return nil, err 174 } 175 176 return newChannel, nil 177 } 178 179 func (a *App) CreateChannel(channel *model.Channel, addMember bool) (*model.Channel, *model.AppError) { 180 result := <-a.Srv.Store.Channel().Save(channel, *a.Config().TeamSettings.MaxChannelsPerTeam) 181 if result.Err != nil { 182 return nil, result.Err 183 } 184 185 sc := result.Data.(*model.Channel) 186 187 if addMember { 188 cm := &model.ChannelMember{ 189 ChannelId: sc.Id, 190 UserId: channel.CreatorId, 191 SchemeUser: true, 192 SchemeAdmin: true, 193 NotifyProps: model.GetDefaultChannelNotifyProps(), 194 } 195 196 if cmresult := <-a.Srv.Store.Channel().SaveMember(cm); cmresult.Err != nil { 197 return nil, cmresult.Err 198 } 199 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(channel.CreatorId, sc.Id, model.GetMillis()); result.Err != nil { 200 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 201 } 202 203 a.InvalidateCacheForUser(channel.CreatorId) 204 } 205 206 if a.PluginsReady() { 207 a.Go(func() { 208 pluginContext := &plugin.Context{} 209 a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 210 hooks.ChannelHasBeenCreated(pluginContext, sc) 211 return true 212 }, plugin.ChannelHasBeenCreatedId) 213 }) 214 } 215 216 return sc, nil 217 } 218 219 func (a *App) CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) { 220 channel, err := a.createDirectChannel(userId, otherUserId) 221 if err != nil { 222 if err.Id == store.CHANNEL_EXISTS_ERROR { 223 return channel, nil 224 } 225 return nil, err 226 } 227 228 a.WaitForChannelMembership(channel.Id, userId) 229 230 a.InvalidateCacheForUser(userId) 231 a.InvalidateCacheForUser(otherUserId) 232 233 if a.PluginsReady() { 234 a.Go(func() { 235 pluginContext := &plugin.Context{} 236 a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 237 hooks.ChannelHasBeenCreated(pluginContext, channel) 238 return true 239 }, plugin.ChannelHasBeenCreatedId) 240 }) 241 } 242 243 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil) 244 message.Add("teammate_id", otherUserId) 245 a.Publish(message) 246 247 return channel, nil 248 } 249 250 func (a *App) createDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) { 251 uc1 := a.Srv.Store.User().Get(userId) 252 uc2 := a.Srv.Store.User().Get(otherUserId) 253 254 if result := <-uc1; result.Err != nil { 255 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, userId, http.StatusBadRequest) 256 } 257 258 if result := <-uc2; result.Err != nil { 259 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, otherUserId, http.StatusBadRequest) 260 } 261 262 result := <-a.Srv.Store.Channel().CreateDirectChannel(userId, otherUserId) 263 if result.Err != nil { 264 if result.Err.Id == store.CHANNEL_EXISTS_ERROR { 265 return result.Data.(*model.Channel), result.Err 266 } 267 return nil, result.Err 268 } 269 270 channel := result.Data.(*model.Channel) 271 272 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(userId, channel.Id, model.GetMillis()); result.Err != nil { 273 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 274 } 275 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(otherUserId, channel.Id, model.GetMillis()); result.Err != nil { 276 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 277 } 278 279 return channel, nil 280 } 281 282 func (a *App) WaitForChannelMembership(channelId string, userId string) { 283 if len(a.Config().SqlSettings.DataSourceReplicas) == 0 { 284 return 285 } 286 287 now := model.GetMillis() 288 289 for model.GetMillis()-now < 12000 { 290 291 time.Sleep(100 * time.Millisecond) 292 293 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 294 295 // If the membership was found then return 296 if result.Err == nil { 297 return 298 } 299 300 // If we received a error but it wasn't a missing channel member then return 301 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 302 return 303 } 304 } 305 306 mlog.Error(fmt.Sprintf("WaitForChannelMembership giving up channelId=%v userId=%v", channelId, userId), mlog.String("user_id", userId)) 307 } 308 309 func (a *App) CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) { 310 channel, err := a.createGroupChannel(userIds, creatorId) 311 if err != nil { 312 if err.Id == store.CHANNEL_EXISTS_ERROR { 313 return channel, nil 314 } 315 return nil, err 316 } 317 318 for _, userId := range userIds { 319 if userId == creatorId { 320 a.WaitForChannelMembership(channel.Id, creatorId) 321 } 322 323 a.InvalidateCacheForUser(userId) 324 } 325 326 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_GROUP_ADDED, "", channel.Id, "", nil) 327 message.Add("teammate_ids", model.ArrayToJson(userIds)) 328 a.Publish(message) 329 330 return channel, nil 331 } 332 333 func (a *App) createGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) { 334 if len(userIds) > model.CHANNEL_GROUP_MAX_USERS || len(userIds) < model.CHANNEL_GROUP_MIN_USERS { 335 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest) 336 } 337 338 result := <-a.Srv.Store.User().GetProfileByIds(userIds, true) 339 if result.Err != nil { 340 return nil, result.Err 341 } 342 users := result.Data.([]*model.User) 343 344 if len(users) != len(userIds) { 345 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIds), http.StatusBadRequest) 346 } 347 348 group := &model.Channel{ 349 Name: model.GetGroupNameFromUserIds(userIds), 350 DisplayName: model.GetGroupDisplayNameFromUsers(users, true), 351 Type: model.CHANNEL_GROUP, 352 } 353 354 result = <-a.Srv.Store.Channel().Save(group, *a.Config().TeamSettings.MaxChannelsPerTeam) 355 if result.Err != nil { 356 if result.Err.Id == store.CHANNEL_EXISTS_ERROR { 357 return result.Data.(*model.Channel), result.Err 358 } 359 return nil, result.Err 360 } 361 channel := result.Data.(*model.Channel) 362 363 for _, user := range users { 364 cm := &model.ChannelMember{ 365 UserId: user.Id, 366 ChannelId: group.Id, 367 NotifyProps: model.GetDefaultChannelNotifyProps(), 368 SchemeUser: true, 369 } 370 371 if result := <-a.Srv.Store.Channel().SaveMember(cm); result.Err != nil { 372 return nil, result.Err 373 } 374 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 375 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 376 } 377 } 378 379 return channel, nil 380 } 381 382 func (a *App) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError) { 383 if len(userIds) > model.CHANNEL_GROUP_MAX_USERS || len(userIds) < model.CHANNEL_GROUP_MIN_USERS { 384 return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest) 385 } 386 387 result := <-a.Srv.Store.User().GetProfileByIds(userIds, true) 388 if result.Err != nil { 389 return nil, result.Err 390 } 391 users := result.Data.([]*model.User) 392 393 if len(users) != len(userIds) { 394 return nil, model.NewAppError("GetGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIds), http.StatusBadRequest) 395 } 396 397 channel, err := a.GetChannelByName(model.GetGroupNameFromUserIds(userIds), "", true) 398 if err != nil { 399 return nil, err 400 } 401 402 return channel, nil 403 } 404 405 func (a *App) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 406 result := <-a.Srv.Store.Channel().Update(channel) 407 if result.Err != nil { 408 return nil, result.Err 409 } 410 411 a.InvalidateCacheForChannel(channel) 412 413 messageWs := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_UPDATED, "", channel.Id, "", nil) 414 messageWs.Add("channel", channel.ToJson()) 415 a.Publish(messageWs) 416 417 return channel, nil 418 } 419 420 func (a *App) UpdateChannelScheme(channel *model.Channel) (*model.Channel, *model.AppError) { 421 var oldChannel *model.Channel 422 var err *model.AppError 423 if oldChannel, err = a.GetChannel(channel.Id); err != nil { 424 return nil, err 425 } 426 427 oldChannel.SchemeId = channel.SchemeId 428 429 newChannel, err := a.UpdateChannel(oldChannel) 430 if err != nil { 431 return nil, err 432 } 433 434 return newChannel, nil 435 } 436 437 func (a *App) UpdateChannelPrivacy(oldChannel *model.Channel, user *model.User) (*model.Channel, *model.AppError) { 438 channel, err := a.UpdateChannel(oldChannel) 439 if err != nil { 440 return channel, err 441 } 442 443 if err := a.postChannelPrivacyMessage(user, channel); err != nil { 444 if channel.Type == model.CHANNEL_OPEN { 445 channel.Type = model.CHANNEL_PRIVATE 446 } else { 447 channel.Type = model.CHANNEL_OPEN 448 } 449 // revert to previous channel privacy 450 a.UpdateChannel(channel) 451 return channel, err 452 } 453 454 a.InvalidateCacheForChannel(channel) 455 456 messageWs := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_CONVERTED, channel.TeamId, "", "", nil) 457 messageWs.Add("channel_id", channel.Id) 458 a.Publish(messageWs) 459 460 return channel, nil 461 } 462 463 func (a *App) postChannelPrivacyMessage(user *model.User, channel *model.Channel) *model.AppError { 464 message := (map[string]string{ 465 model.CHANNEL_OPEN: utils.T("api.channel.change_channel_privacy.private_to_public"), 466 model.CHANNEL_PRIVATE: utils.T("api.channel.change_channel_privacy.public_to_private"), 467 })[channel.Type] 468 post := &model.Post{ 469 ChannelId: channel.Id, 470 Message: message, 471 Type: model.POST_CHANGE_CHANNEL_PRIVACY, 472 UserId: user.Id, 473 Props: model.StringInterface{ 474 "username": user.Username, 475 }, 476 } 477 478 if _, err := a.CreatePost(post, channel, false); err != nil { 479 return model.NewAppError("postChannelPrivacyMessage", "api.channel.post_channel_privacy_message.error", nil, err.Error(), http.StatusInternalServerError) 480 } 481 482 return nil 483 } 484 485 func (a *App) RestoreChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 486 result := <-a.Srv.Store.Channel().Restore(channel.Id, model.GetMillis()) 487 if result.Err != nil { 488 return nil, result.Err 489 } 490 return channel, nil 491 } 492 493 func (a *App) PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userId string) (*model.Channel, *model.AppError) { 494 oldChannelDisplayName := channel.DisplayName 495 oldChannelHeader := channel.Header 496 oldChannelPurpose := channel.Purpose 497 498 channel.Patch(patch) 499 channel, err := a.UpdateChannel(channel) 500 if err != nil { 501 return nil, err 502 } 503 504 if oldChannelDisplayName != channel.DisplayName { 505 if err := a.PostUpdateChannelDisplayNameMessage(userId, channel, oldChannelDisplayName, channel.DisplayName); err != nil { 506 mlog.Error(err.Error()) 507 } 508 } 509 510 if channel.Header != oldChannelHeader { 511 if err := a.PostUpdateChannelHeaderMessage(userId, channel, oldChannelHeader, channel.Header); err != nil { 512 mlog.Error(err.Error()) 513 } 514 } 515 516 if channel.Purpose != oldChannelPurpose { 517 if err := a.PostUpdateChannelPurposeMessage(userId, channel, oldChannelPurpose, channel.Purpose); err != nil { 518 mlog.Error(err.Error()) 519 } 520 } 521 522 return channel, err 523 } 524 525 func (a *App) GetSchemeRolesForChannel(channelId string) (string, string, *model.AppError) { 526 var channel *model.Channel 527 var err *model.AppError 528 529 if channel, err = a.GetChannel(channelId); err != nil { 530 return "", "", err 531 } 532 533 if channel.SchemeId != nil && len(*channel.SchemeId) != 0 { 534 scheme, err := a.GetScheme(*channel.SchemeId) 535 if err != nil { 536 return "", "", err 537 } 538 return scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil 539 } 540 541 var team *model.Team 542 543 if team, err = a.GetTeam(channel.TeamId); err != nil { 544 return "", "", err 545 } 546 547 if team.SchemeId != nil && len(*team.SchemeId) != 0 { 548 scheme, err := a.GetScheme(*team.SchemeId) 549 if err != nil { 550 return "", "", err 551 } 552 return scheme.DefaultChannelUserRole, scheme.DefaultChannelAdminRole, nil 553 } 554 555 return model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID, nil 556 } 557 558 func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) { 559 var member *model.ChannelMember 560 var err *model.AppError 561 if member, err = a.GetChannelMember(channelId, userId); err != nil { 562 return nil, err 563 } 564 565 schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(channelId) 566 if err != nil { 567 return nil, err 568 } 569 570 var newExplicitRoles []string 571 member.SchemeUser = false 572 member.SchemeAdmin = false 573 574 for _, roleName := range strings.Fields(newRoles) { 575 role, err := a.GetRoleByName(roleName) 576 if err != nil { 577 err.StatusCode = http.StatusBadRequest 578 return nil, err 579 } 580 581 if !role.SchemeManaged { 582 // The role is not scheme-managed, so it's OK to apply it to the explicit roles field. 583 newExplicitRoles = append(newExplicitRoles, roleName) 584 } else { 585 // The role is scheme-managed, so need to check if it is part of the scheme for this channel or not. 586 switch roleName { 587 case schemeAdminRole: 588 member.SchemeAdmin = true 589 case schemeUserRole: 590 member.SchemeUser = true 591 default: 592 // If not part of the scheme for this channel, then it is not allowed to apply it as an explicit role. 593 return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.scheme_role.app_error", nil, "role_name="+roleName, http.StatusBadRequest) 594 } 595 } 596 } 597 598 member.ExplicitRoles = strings.Join(newExplicitRoles, " ") 599 600 result := <-a.Srv.Store.Channel().UpdateMember(member) 601 if result.Err != nil { 602 return nil, result.Err 603 } 604 member = result.Data.(*model.ChannelMember) 605 606 a.InvalidateCacheForUser(userId) 607 return member, nil 608 } 609 610 func (a *App) UpdateChannelMemberSchemeRoles(channelId string, userId string, isSchemeUser bool, isSchemeAdmin bool) (*model.ChannelMember, *model.AppError) { 611 member, err := a.GetChannelMember(channelId, userId) 612 if err != nil { 613 return nil, err 614 } 615 616 member.SchemeAdmin = isSchemeAdmin 617 member.SchemeUser = isSchemeUser 618 619 // 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. 620 if err = a.IsPhase2MigrationCompleted(); err != nil { 621 member.ExplicitRoles = RemoveRoles([]string{model.CHANNEL_USER_ROLE_ID, model.CHANNEL_ADMIN_ROLE_ID}, member.ExplicitRoles) 622 } 623 624 result := <-a.Srv.Store.Channel().UpdateMember(member) 625 if result.Err != nil { 626 return nil, result.Err 627 } 628 member = result.Data.(*model.ChannelMember) 629 630 a.InvalidateCacheForUser(userId) 631 return member, nil 632 } 633 634 func (a *App) UpdateChannelMemberNotifyProps(data map[string]string, channelId string, userId string) (*model.ChannelMember, *model.AppError) { 635 var member *model.ChannelMember 636 var err *model.AppError 637 if member, err = a.GetChannelMember(channelId, userId); err != nil { 638 return nil, err 639 } 640 641 // update whichever notify properties have been provided, but don't change the others 642 if markUnread, exists := data[model.MARK_UNREAD_NOTIFY_PROP]; exists { 643 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = markUnread 644 } 645 646 if desktop, exists := data[model.DESKTOP_NOTIFY_PROP]; exists { 647 member.NotifyProps[model.DESKTOP_NOTIFY_PROP] = desktop 648 } 649 650 if email, exists := data[model.EMAIL_NOTIFY_PROP]; exists { 651 member.NotifyProps[model.EMAIL_NOTIFY_PROP] = email 652 } 653 654 if push, exists := data[model.PUSH_NOTIFY_PROP]; exists { 655 member.NotifyProps[model.PUSH_NOTIFY_PROP] = push 656 } 657 658 result := <-a.Srv.Store.Channel().UpdateMember(member) 659 if result.Err != nil { 660 return nil, result.Err 661 } 662 663 a.InvalidateCacheForUser(userId) 664 a.InvalidateCacheForChannelMembersNotifyProps(channelId) 665 // Notify the clients that the member notify props changed 666 evt := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED, "", "", userId, nil) 667 evt.Add("channelMember", member.ToJson()) 668 a.Publish(evt) 669 return member, nil 670 } 671 672 func (a *App) DeleteChannel(channel *model.Channel, userId string) *model.AppError { 673 ihc := a.Srv.Store.Webhook().GetIncomingByChannel(channel.Id) 674 ohc := a.Srv.Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1) 675 676 var user *model.User 677 if userId != "" { 678 uc := a.Srv.Store.User().Get(userId) 679 uresult := <-uc 680 if uresult.Err != nil { 681 return uresult.Err 682 } 683 user = uresult.Data.(*model.User) 684 } 685 686 ihcresult := <-ihc 687 if ihcresult.Err != nil { 688 return ihcresult.Err 689 } 690 691 ohcresult := <-ohc 692 if ohcresult.Err != nil { 693 return ohcresult.Err 694 } 695 696 incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) 697 outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) 698 699 if channel.DeleteAt > 0 { 700 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "", http.StatusBadRequest) 701 return err 702 } 703 704 if channel.Name == model.DEFAULT_CHANNEL { 705 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 706 return err 707 } 708 709 if user != nil { 710 T := utils.GetUserTranslations(user.Locale) 711 712 post := &model.Post{ 713 ChannelId: channel.Id, 714 Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username), 715 Type: model.POST_CHANNEL_DELETED, 716 UserId: userId, 717 Props: model.StringInterface{ 718 "username": user.Username, 719 }, 720 } 721 722 if _, err := a.CreatePost(post, channel, false); err != nil { 723 mlog.Error(fmt.Sprintf("Failed to post archive message %v", err)) 724 } 725 } 726 727 now := model.GetMillis() 728 for _, hook := range incomingHooks { 729 if result := <-a.Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil { 730 mlog.Error(fmt.Sprintf("Encountered error deleting incoming webhook, id=%v", hook.Id)) 731 } 732 a.InvalidateCacheForWebhook(hook.Id) 733 } 734 735 for _, hook := range outgoingHooks { 736 if result := <-a.Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil { 737 mlog.Error(fmt.Sprintf("Encountered error deleting outgoing webhook, id=%v", hook.Id)) 738 } 739 } 740 741 deleteAt := model.GetMillis() 742 743 if dresult := <-a.Srv.Store.Channel().Delete(channel.Id, deleteAt); dresult.Err != nil { 744 return dresult.Err 745 } 746 a.InvalidateCacheForChannel(channel) 747 748 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil) 749 message.Add("channel_id", channel.Id) 750 message.Add("delete_at", deleteAt) 751 a.Publish(message) 752 753 return nil 754 } 755 756 func (a *App) addUserToChannel(user *model.User, channel *model.Channel, teamMember *model.TeamMember) (*model.ChannelMember, *model.AppError) { 757 if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE { 758 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest) 759 } 760 761 cmchan := a.Srv.Store.Channel().GetMember(channel.Id, user.Id) 762 763 if result := <-cmchan; result.Err != nil { 764 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 765 return nil, result.Err 766 } 767 } else { 768 channelMember := result.Data.(*model.ChannelMember) 769 return channelMember, nil 770 } 771 772 newMember := &model.ChannelMember{ 773 ChannelId: channel.Id, 774 UserId: user.Id, 775 NotifyProps: model.GetDefaultChannelNotifyProps(), 776 SchemeUser: true, 777 } 778 if result := <-a.Srv.Store.Channel().SaveMember(newMember); result.Err != nil { 779 mlog.Error(fmt.Sprintf("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err), mlog.String("user_id", user.Id)) 780 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "", http.StatusInternalServerError) 781 } 782 a.WaitForChannelMembership(channel.Id, user.Id) 783 784 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 785 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 786 } 787 788 a.InvalidateCacheForUser(user.Id) 789 a.InvalidateCacheForChannelMembers(channel.Id) 790 791 return newMember, nil 792 } 793 794 func (a *App) AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) { 795 tmchan := a.Srv.Store.Team().GetMember(channel.TeamId, user.Id) 796 var teamMember *model.TeamMember 797 798 result := <-tmchan 799 if result.Err != nil { 800 return nil, result.Err 801 } 802 teamMember = result.Data.(*model.TeamMember) 803 if teamMember.DeleteAt > 0 { 804 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "", http.StatusBadRequest) 805 } 806 807 newMember, err := a.addUserToChannel(user, channel, teamMember) 808 if err != nil { 809 return nil, err 810 } 811 812 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil) 813 message.Add("user_id", user.Id) 814 message.Add("team_id", channel.TeamId) 815 a.Publish(message) 816 817 return newMember, nil 818 } 819 820 func (a *App) AddChannelMember(userId string, channel *model.Channel, userRequestorId string, postRootId string, clearPushNotifications bool) (*model.ChannelMember, *model.AppError) { 821 if result := <-a.Srv.Store.Channel().GetMember(channel.Id, userId); result.Err != nil { 822 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 823 return nil, result.Err 824 } 825 } else { 826 return result.Data.(*model.ChannelMember), nil 827 } 828 829 var user *model.User 830 var err *model.AppError 831 832 if user, err = a.GetUser(userId); err != nil { 833 return nil, err 834 } 835 836 var userRequestor *model.User 837 if userRequestorId != "" { 838 if userRequestor, err = a.GetUser(userRequestorId); err != nil { 839 return nil, err 840 } 841 } 842 843 cm, err := a.AddUserToChannel(user, channel) 844 if err != nil { 845 return nil, err 846 } 847 848 if a.PluginsReady() { 849 a.Go(func() { 850 pluginContext := &plugin.Context{} 851 a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 852 hooks.UserHasJoinedChannel(pluginContext, cm, userRequestor) 853 return true 854 }, plugin.UserHasJoinedChannelId) 855 }) 856 } 857 858 if userRequestorId == "" || userId == userRequestorId { 859 a.postJoinChannelMessage(user, channel) 860 } else { 861 a.Go(func() { 862 a.PostAddToChannelMessage(userRequestor, user, channel, postRootId) 863 }) 864 } 865 866 if userRequestor != nil { 867 a.MarkChannelsAsViewed([]string{channel.Id}, userRequestor.Id, clearPushNotifications) 868 } 869 870 return cm, nil 871 } 872 873 func (a *App) AddDirectChannels(teamId string, user *model.User) *model.AppError { 874 var profiles []*model.User 875 result := <-a.Srv.Store.User().GetProfiles(teamId, 0, 100) 876 if result.Err != nil { 877 return model.NewAppError("AddDirectChannels", "api.user.add_direct_channels_and_forget.failed.error", map[string]interface{}{"UserId": user.Id, "TeamId": teamId, "Error": result.Err.Error()}, "", http.StatusInternalServerError) 878 } 879 profiles = result.Data.([]*model.User) 880 881 var preferences model.Preferences 882 883 for _, profile := range profiles { 884 if profile.Id == user.Id { 885 continue 886 } 887 888 preference := model.Preference{ 889 UserId: user.Id, 890 Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, 891 Name: profile.Id, 892 Value: "true", 893 } 894 895 preferences = append(preferences, preference) 896 897 if len(preferences) >= 10 { 898 break 899 } 900 } 901 902 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 903 return model.NewAppError("AddDirectChannels", "api.user.add_direct_channels_and_forget.failed.error", map[string]interface{}{"UserId": user.Id, "TeamId": teamId, "Error": result.Err.Error()}, "", http.StatusInternalServerError) 904 } 905 906 return nil 907 } 908 909 func (a *App) PostUpdateChannelHeaderMessage(userId string, channel *model.Channel, oldChannelHeader, newChannelHeader string) *model.AppError { 910 uc := a.Srv.Store.User().Get(userId) 911 912 uresult := <-uc 913 if uresult.Err != nil { 914 return model.NewAppError("PostUpdateChannelHeaderMessage", "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 915 } 916 917 user := uresult.Data.(*model.User) 918 919 var message string 920 if oldChannelHeader == "" { 921 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader) 922 } else if newChannelHeader == "" { 923 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader) 924 } else { 925 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader) 926 } 927 928 post := &model.Post{ 929 ChannelId: channel.Id, 930 Message: message, 931 Type: model.POST_HEADER_CHANGE, 932 UserId: userId, 933 Props: model.StringInterface{ 934 "username": user.Username, 935 "old_header": oldChannelHeader, 936 "new_header": newChannelHeader, 937 }, 938 } 939 940 if _, err := a.CreatePost(post, channel, false); err != nil { 941 return model.NewAppError("", "api.channel.post_update_channel_header_message_and_forget.post.error", nil, err.Error(), http.StatusInternalServerError) 942 } 943 944 return nil 945 } 946 947 func (a *App) PostUpdateChannelPurposeMessage(userId string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError { 948 uc := a.Srv.Store.User().Get(userId) 949 950 uresult := <-uc 951 if uresult.Err != nil { 952 return model.NewAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 953 } 954 955 user := uresult.Data.(*model.User) 956 957 var message string 958 if oldChannelPurpose == "" { 959 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_to"), user.Username, newChannelPurpose) 960 } else if newChannelPurpose == "" { 961 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.removed"), user.Username, oldChannelPurpose) 962 } else { 963 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_from"), user.Username, oldChannelPurpose, newChannelPurpose) 964 } 965 966 post := &model.Post{ 967 ChannelId: channel.Id, 968 Message: message, 969 Type: model.POST_PURPOSE_CHANGE, 970 UserId: userId, 971 Props: model.StringInterface{ 972 "username": user.Username, 973 "old_purpose": oldChannelPurpose, 974 "new_purpose": newChannelPurpose, 975 }, 976 } 977 if _, err := a.CreatePost(post, channel, false); err != nil { 978 return model.NewAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error(), http.StatusInternalServerError) 979 } 980 981 return nil 982 } 983 984 func (a *App) PostUpdateChannelDisplayNameMessage(userId string, channel *model.Channel, oldChannelDisplayName, newChannelDisplayName string) *model.AppError { 985 uc := a.Srv.Store.User().Get(userId) 986 987 uresult := <-uc 988 if uresult.Err != nil { 989 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 990 } 991 992 user := uresult.Data.(*model.User) 993 994 message := fmt.Sprintf(utils.T("api.channel.post_update_channel_displayname_message_and_forget.updated_from"), user.Username, oldChannelDisplayName, newChannelDisplayName) 995 996 post := &model.Post{ 997 ChannelId: channel.Id, 998 Message: message, 999 Type: model.POST_DISPLAYNAME_CHANGE, 1000 UserId: userId, 1001 Props: model.StringInterface{ 1002 "username": user.Username, 1003 "old_displayname": oldChannelDisplayName, 1004 "new_displayname": newChannelDisplayName, 1005 }, 1006 } 1007 1008 if _, err := a.CreatePost(post, channel, false); err != nil { 1009 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.create_post.error", nil, err.Error(), http.StatusInternalServerError) 1010 } 1011 1012 return nil 1013 } 1014 1015 func (a *App) GetChannel(channelId string) (*model.Channel, *model.AppError) { 1016 result := <-a.Srv.Store.Channel().Get(channelId, true) 1017 if result.Err != nil { 1018 if result.Err.Id == "store.sql_channel.get.existing.app_error" { 1019 result.Err.StatusCode = http.StatusNotFound 1020 return nil, result.Err 1021 } 1022 result.Err.StatusCode = http.StatusBadRequest 1023 return nil, result.Err 1024 } 1025 return result.Data.(*model.Channel), nil 1026 } 1027 1028 func (a *App) GetChannelByName(channelName, teamId string, includeDeleted bool) (*model.Channel, *model.AppError) { 1029 var result store.StoreResult 1030 1031 if includeDeleted { 1032 result = <-a.Srv.Store.Channel().GetByNameIncludeDeleted(teamId, channelName, false) 1033 } else { 1034 result = <-a.Srv.Store.Channel().GetByName(teamId, channelName, false) 1035 } 1036 1037 if result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 1038 result.Err.StatusCode = http.StatusNotFound 1039 return nil, result.Err 1040 } 1041 1042 if result.Err != nil { 1043 result.Err.StatusCode = http.StatusBadRequest 1044 return nil, result.Err 1045 } 1046 1047 return result.Data.(*model.Channel), nil 1048 } 1049 1050 func (a *App) GetChannelsByNames(channelNames []string, teamId string) ([]*model.Channel, *model.AppError) { 1051 result := <-a.Srv.Store.Channel().GetByNames(teamId, channelNames, true) 1052 if result.Err != nil { 1053 if result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 1054 result.Err.StatusCode = http.StatusNotFound 1055 return nil, result.Err 1056 } 1057 result.Err.StatusCode = http.StatusBadRequest 1058 return nil, result.Err 1059 } 1060 return result.Data.([]*model.Channel), nil 1061 } 1062 1063 func (a *App) GetChannelByNameForTeamName(channelName, teamName string, includeDeleted bool) (*model.Channel, *model.AppError) { 1064 var team *model.Team 1065 1066 result := <-a.Srv.Store.Team().GetByName(teamName) 1067 if result.Err != nil { 1068 result.Err.StatusCode = http.StatusNotFound 1069 return nil, result.Err 1070 } 1071 team = result.Data.(*model.Team) 1072 1073 if includeDeleted { 1074 result = <-a.Srv.Store.Channel().GetByNameIncludeDeleted(team.Id, channelName, false) 1075 } else { 1076 result = <-a.Srv.Store.Channel().GetByName(team.Id, channelName, false) 1077 } 1078 1079 if result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 1080 result.Err.StatusCode = http.StatusNotFound 1081 return nil, result.Err 1082 } 1083 1084 if result.Err != nil { 1085 result.Err.StatusCode = http.StatusBadRequest 1086 return nil, result.Err 1087 } 1088 1089 return result.Data.(*model.Channel), nil 1090 } 1091 1092 func (a *App) GetChannelsForUser(teamId string, userId string, includeDeleted bool) (*model.ChannelList, *model.AppError) { 1093 result := <-a.Srv.Store.Channel().GetChannels(teamId, userId, includeDeleted) 1094 if result.Err != nil { 1095 return nil, result.Err 1096 } 1097 return result.Data.(*model.ChannelList), nil 1098 } 1099 1100 func (a *App) GetDeletedChannels(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1101 result := <-a.Srv.Store.Channel().GetDeleted(teamId, offset, limit) 1102 if result.Err != nil { 1103 return nil, result.Err 1104 } 1105 return result.Data.(*model.ChannelList), nil 1106 } 1107 1108 func (a *App) GetChannelsUserNotIn(teamId string, userId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1109 result := <-a.Srv.Store.Channel().GetMoreChannels(teamId, userId, offset, limit) 1110 if result.Err != nil { 1111 return nil, result.Err 1112 } 1113 return result.Data.(*model.ChannelList), nil 1114 } 1115 1116 func (a *App) GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*model.ChannelList, *model.AppError) { 1117 result := <-a.Srv.Store.Channel().GetPublicChannelsByIdsForTeam(teamId, channelIds) 1118 if result.Err != nil { 1119 return nil, result.Err 1120 } 1121 return result.Data.(*model.ChannelList), nil 1122 } 1123 1124 func (a *App) GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 1125 result := <-a.Srv.Store.Channel().GetPublicChannelsForTeam(teamId, offset, limit) 1126 if result.Err != nil { 1127 return nil, result.Err 1128 } 1129 return result.Data.(*model.ChannelList), nil 1130 } 1131 1132 func (a *App) GetChannelMember(channelId string, userId string) (*model.ChannelMember, *model.AppError) { 1133 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 1134 if result.Err != nil { 1135 return nil, result.Err 1136 } 1137 return result.Data.(*model.ChannelMember), nil 1138 } 1139 1140 func (a *App) GetChannelMembersPage(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError) { 1141 result := <-a.Srv.Store.Channel().GetMembers(channelId, page*perPage, perPage) 1142 if result.Err != nil { 1143 return nil, result.Err 1144 } 1145 return result.Data.(*model.ChannelMembers), nil 1146 } 1147 1148 func (a *App) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) { 1149 result := <-a.Srv.Store.Channel().GetMembersByIds(channelId, userIds) 1150 if result.Err != nil { 1151 return nil, result.Err 1152 } 1153 return result.Data.(*model.ChannelMembers), nil 1154 } 1155 1156 func (a *App) GetChannelMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError) { 1157 result := <-a.Srv.Store.Channel().GetMembersForUser(teamId, userId) 1158 if result.Err != nil { 1159 return nil, result.Err 1160 } 1161 return result.Data.(*model.ChannelMembers), nil 1162 } 1163 1164 func (a *App) GetChannelMemberCount(channelId string) (int64, *model.AppError) { 1165 result := <-a.Srv.Store.Channel().GetMemberCount(channelId, true) 1166 if result.Err != nil { 1167 return 0, result.Err 1168 } 1169 return result.Data.(int64), nil 1170 } 1171 1172 func (a *App) GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, *model.AppError) { 1173 result := <-a.Srv.Store.Channel().GetChannelCounts(teamId, userId) 1174 if result.Err != nil { 1175 return nil, result.Err 1176 } 1177 return result.Data.(*model.ChannelCounts), nil 1178 } 1179 1180 func (a *App) GetChannelUnread(channelId, userId string) (*model.ChannelUnread, *model.AppError) { 1181 result := <-a.Srv.Store.Channel().GetChannelUnread(channelId, userId) 1182 if result.Err != nil { 1183 return nil, result.Err 1184 } 1185 channelUnread := result.Data.(*model.ChannelUnread) 1186 1187 if channelUnread.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_MARK_UNREAD_MENTION { 1188 channelUnread.MsgCount = 0 1189 } 1190 1191 return channelUnread, nil 1192 } 1193 1194 func (a *App) JoinChannel(channel *model.Channel, userId string) *model.AppError { 1195 userChan := a.Srv.Store.User().Get(userId) 1196 memberChan := a.Srv.Store.Channel().GetMember(channel.Id, userId) 1197 1198 uresult := <-userChan 1199 if uresult.Err != nil { 1200 return uresult.Err 1201 } 1202 1203 mresult := <-memberChan 1204 if mresult.Err == nil && mresult.Data != nil { 1205 // user is already in the channel 1206 return nil 1207 } 1208 1209 user := uresult.Data.(*model.User) 1210 1211 if channel.Type != model.CHANNEL_OPEN { 1212 return model.NewAppError("JoinChannel", "api.channel.join_channel.permissions.app_error", nil, "", http.StatusBadRequest) 1213 } 1214 1215 cm, err := a.AddUserToChannel(user, channel) 1216 if err != nil { 1217 return err 1218 } 1219 1220 if a.PluginsReady() { 1221 a.Go(func() { 1222 pluginContext := &plugin.Context{} 1223 a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 1224 hooks.UserHasJoinedChannel(pluginContext, cm, nil) 1225 return true 1226 }, plugin.UserHasJoinedChannelId) 1227 }) 1228 } 1229 1230 if err := a.postJoinChannelMessage(user, channel); err != nil { 1231 return err 1232 } 1233 1234 return nil 1235 } 1236 1237 func (a *App) postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1238 post := &model.Post{ 1239 ChannelId: channel.Id, 1240 Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), 1241 Type: model.POST_JOIN_CHANNEL, 1242 UserId: user.Id, 1243 Props: model.StringInterface{ 1244 "username": user.Username, 1245 }, 1246 } 1247 1248 if _, err := a.CreatePost(post, channel, false); err != nil { 1249 return model.NewAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1250 } 1251 1252 return nil 1253 } 1254 1255 func (a *App) postJoinTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 1256 post := &model.Post{ 1257 ChannelId: channel.Id, 1258 Message: fmt.Sprintf(utils.T("api.team.join_team.post_and_forget"), user.Username), 1259 Type: model.POST_JOIN_TEAM, 1260 UserId: user.Id, 1261 Props: model.StringInterface{ 1262 "username": user.Username, 1263 }, 1264 } 1265 1266 if _, err := a.CreatePost(post, channel, false); err != nil { 1267 return model.NewAppError("postJoinTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1268 } 1269 1270 return nil 1271 } 1272 1273 func (a *App) LeaveChannel(channelId string, userId string) *model.AppError { 1274 sc := a.Srv.Store.Channel().Get(channelId, true) 1275 uc := a.Srv.Store.User().Get(userId) 1276 ccm := a.Srv.Store.Channel().GetMemberCount(channelId, false) 1277 1278 cresult := <-sc 1279 if cresult.Err != nil { 1280 return cresult.Err 1281 } 1282 uresult := <-uc 1283 if uresult.Err != nil { 1284 return cresult.Err 1285 } 1286 ccmresult := <-ccm 1287 if ccmresult.Err != nil { 1288 return ccmresult.Err 1289 } 1290 1291 channel := cresult.Data.(*model.Channel) 1292 user := uresult.Data.(*model.User) 1293 membersCount := ccmresult.Data.(int64) 1294 1295 if channel.IsGroupOrDirect() { 1296 err := model.NewAppError("LeaveChannel", "api.channel.leave.direct.app_error", nil, "", http.StatusBadRequest) 1297 return err 1298 } 1299 1300 if channel.Type == model.CHANNEL_PRIVATE && membersCount == 1 { 1301 err := model.NewAppError("LeaveChannel", "api.channel.leave.last_member.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 1302 return err 1303 } 1304 1305 if err := a.removeUserFromChannel(userId, userId, channel); err != nil { 1306 return err 1307 } 1308 1309 if channel.Name == model.DEFAULT_CHANNEL && !*a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 1310 return nil 1311 } 1312 1313 a.Go(func() { 1314 a.postLeaveChannelMessage(user, channel) 1315 }) 1316 1317 return nil 1318 } 1319 1320 func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1321 post := &model.Post{ 1322 ChannelId: channel.Id, 1323 Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), 1324 Type: model.POST_LEAVE_CHANNEL, 1325 UserId: user.Id, 1326 Props: model.StringInterface{ 1327 "username": user.Username, 1328 }, 1329 } 1330 1331 if _, err := a.CreatePost(post, channel, false); err != nil { 1332 return model.NewAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1333 } 1334 1335 return nil 1336 } 1337 1338 func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1339 post := &model.Post{ 1340 ChannelId: channel.Id, 1341 Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username), 1342 Type: model.POST_ADD_TO_CHANNEL, 1343 UserId: user.Id, 1344 RootId: postRootId, 1345 Props: model.StringInterface{ 1346 "userId": user.Id, 1347 "username": user.Username, 1348 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 1349 "addedUsername": addedUser.Username, 1350 }, 1351 } 1352 1353 if _, err := a.CreatePost(post, channel, false); err != nil { 1354 return model.NewAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1355 } 1356 1357 return nil 1358 } 1359 1360 func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1361 post := &model.Post{ 1362 ChannelId: channel.Id, 1363 Message: fmt.Sprintf(utils.T("api.team.add_user_to_team.added"), addedUser.Username, user.Username), 1364 Type: model.POST_ADD_TO_TEAM, 1365 UserId: user.Id, 1366 RootId: postRootId, 1367 Props: model.StringInterface{ 1368 "userId": user.Id, 1369 "username": user.Username, 1370 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 1371 "addedUsername": addedUser.Username, 1372 }, 1373 } 1374 1375 if _, err := a.CreatePost(post, channel, false); err != nil { 1376 return model.NewAppError("postAddToTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1377 } 1378 1379 return nil 1380 } 1381 1382 func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError { 1383 post := &model.Post{ 1384 ChannelId: channel.Id, 1385 Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username), 1386 Type: model.POST_REMOVE_FROM_CHANNEL, 1387 UserId: removerUserId, 1388 Props: model.StringInterface{ 1389 "removedUserId": removedUser.Id, 1390 "removedUsername": removedUser.Username, 1391 }, 1392 } 1393 1394 if _, err := a.CreatePost(post, channel, false); err != nil { 1395 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1396 } 1397 1398 return nil 1399 } 1400 1401 func (a *App) removeUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1402 if channel.Name == model.DEFAULT_CHANNEL { 1403 return model.NewAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 1404 } 1405 1406 cm, err := a.GetChannelMember(channel.Id, userIdToRemove) 1407 if err != nil { 1408 return err 1409 } 1410 1411 if cmresult := <-a.Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil { 1412 return cmresult.Err 1413 } 1414 if cmhResult := <-a.Srv.Store.ChannelMemberHistory().LogLeaveEvent(userIdToRemove, channel.Id, model.GetMillis()); cmhResult.Err != nil { 1415 return cmhResult.Err 1416 } 1417 1418 a.InvalidateCacheForUser(userIdToRemove) 1419 a.InvalidateCacheForChannelMembers(channel.Id) 1420 1421 if a.PluginsReady() { 1422 1423 var actorUser *model.User 1424 if removerUserId != "" { 1425 actorUser, _ = a.GetUser(removerUserId) 1426 } 1427 1428 a.Go(func() { 1429 pluginContext := &plugin.Context{} 1430 a.Plugins.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 1431 hooks.UserHasLeftChannel(pluginContext, cm, actorUser) 1432 return true 1433 }, plugin.UserHasLeftChannelId) 1434 }) 1435 } 1436 1437 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil) 1438 message.Add("user_id", userIdToRemove) 1439 message.Add("remover_id", removerUserId) 1440 a.Publish(message) 1441 1442 // because the removed user no longer belongs to the channel we need to send a separate websocket event 1443 userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIdToRemove, nil) 1444 userMsg.Add("channel_id", channel.Id) 1445 userMsg.Add("remover_id", removerUserId) 1446 a.Publish(userMsg) 1447 1448 return nil 1449 } 1450 1451 func (a *App) RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1452 var err *model.AppError 1453 1454 if err = a.removeUserFromChannel(userIdToRemove, removerUserId, channel); err != nil { 1455 return err 1456 } 1457 1458 var user *model.User 1459 if user, err = a.GetUser(userIdToRemove); err != nil { 1460 return err 1461 } 1462 1463 if userIdToRemove == removerUserId { 1464 a.postLeaveChannelMessage(user, channel) 1465 } else { 1466 a.Go(func() { 1467 a.postRemoveFromChannelMessage(removerUserId, user, channel) 1468 }) 1469 } 1470 1471 return nil 1472 } 1473 1474 func (a *App) GetNumberOfChannelsOnTeam(teamId string) (int, *model.AppError) { 1475 // Get total number of channels on current team 1476 result := <-a.Srv.Store.Channel().GetTeamChannels(teamId) 1477 if result.Err != nil { 1478 return 0, result.Err 1479 } 1480 return len(*result.Data.(*model.ChannelList)), nil 1481 } 1482 1483 func (a *App) SetActiveChannel(userId string, channelId string) *model.AppError { 1484 status, err := a.GetStatus(userId) 1485 1486 oldStatus := model.STATUS_OFFLINE 1487 1488 if err != nil { 1489 status = &model.Status{UserId: userId, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: channelId} 1490 } else { 1491 oldStatus = status.Status 1492 status.ActiveChannel = channelId 1493 if !status.Manual && channelId != "" { 1494 status.Status = model.STATUS_ONLINE 1495 } 1496 status.LastActivityAt = model.GetMillis() 1497 } 1498 1499 a.AddStatusCache(status) 1500 1501 if status.Status != oldStatus { 1502 a.BroadcastStatus(status) 1503 } 1504 1505 return nil 1506 } 1507 1508 func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError { 1509 if result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); result.Err != nil { 1510 return result.Err 1511 } 1512 1513 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 1514 for _, channelId := range channelIds { 1515 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1516 message.Add("channel_id", channelId) 1517 a.Publish(message) 1518 } 1519 } 1520 1521 return nil 1522 } 1523 1524 func (a *App) AutocompleteChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1525 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 1526 1527 result := <-a.Srv.Store.Channel().AutocompleteInTeam(teamId, term, includeDeleted) 1528 if result.Err != nil { 1529 return nil, result.Err 1530 } 1531 return result.Data.(*model.ChannelList), nil 1532 } 1533 1534 func (a *App) AutocompleteChannelsForSearch(teamId string, userId string, term string) (*model.ChannelList, *model.AppError) { 1535 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 1536 1537 result := <-a.Srv.Store.Channel().AutocompleteInTeamForSearch(teamId, userId, term, includeDeleted) 1538 if result.Err != nil { 1539 return nil, result.Err 1540 } 1541 return result.Data.(*model.ChannelList), nil 1542 } 1543 1544 func (a *App) SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1545 includeDeleted := *a.Config().TeamSettings.ExperimentalViewArchivedChannels 1546 1547 result := <-a.Srv.Store.Channel().SearchInTeam(teamId, term, includeDeleted) 1548 if result.Err != nil { 1549 return nil, result.Err 1550 } 1551 return result.Data.(*model.ChannelList), nil 1552 } 1553 1554 func (a *App) SearchChannelsUserNotIn(teamId string, userId string, term string) (*model.ChannelList, *model.AppError) { 1555 result := <-a.Srv.Store.Channel().SearchMore(userId, teamId, term) 1556 if result.Err != nil { 1557 return nil, result.Err 1558 } 1559 return result.Data.(*model.ChannelList), nil 1560 } 1561 1562 func (a *App) MarkChannelsAsViewed(channelIds []string, userId string, clearPushNotifications bool) (map[string]int64, *model.AppError) { 1563 // I start looking for channels with notifications before I mark it as read, to clear the push notifications if needed 1564 channelsToClearPushNotifications := []string{} 1565 if *a.Config().EmailSettings.SendPushNotifications && clearPushNotifications { 1566 for _, channelId := range channelIds { 1567 if model.IsValidId(channelId) { 1568 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 1569 if result.Err != nil { 1570 mlog.Warn(fmt.Sprintf("Failed to get membership %v", result.Err)) 1571 continue 1572 } 1573 member := result.Data.(*model.ChannelMember) 1574 1575 notify := member.NotifyProps[model.PUSH_NOTIFY_PROP] 1576 if notify == model.CHANNEL_NOTIFY_DEFAULT { 1577 user, _ := a.GetUser(userId) 1578 notify = user.NotifyProps[model.PUSH_NOTIFY_PROP] 1579 } 1580 if notify == model.USER_NOTIFY_ALL { 1581 if result := <-a.Srv.Store.User().GetAnyUnreadPostCountForChannel(userId, channelId); result.Err == nil { 1582 if result.Data.(int64) > 0 { 1583 channelsToClearPushNotifications = append(channelsToClearPushNotifications, channelId) 1584 } 1585 } 1586 } else if notify == model.USER_NOTIFY_MENTION { 1587 if result := <-a.Srv.Store.User().GetUnreadCountForChannel(userId, channelId); result.Err == nil { 1588 if result.Data.(int64) > 0 { 1589 channelsToClearPushNotifications = append(channelsToClearPushNotifications, channelId) 1590 } 1591 } 1592 } 1593 } 1594 } 1595 } 1596 result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId) 1597 if result.Err != nil { 1598 return nil, result.Err 1599 } 1600 1601 times := result.Data.(map[string]int64) 1602 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 1603 for _, channelId := range channelIds { 1604 if model.IsValidId(channelId) { 1605 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1606 message.Add("channel_id", channelId) 1607 a.Publish(message) 1608 } 1609 } 1610 } 1611 for _, channelId := range channelsToClearPushNotifications { 1612 a.ClearPushNotification(userId, channelId) 1613 } 1614 return times, nil 1615 } 1616 1617 func (a *App) ViewChannel(view *model.ChannelView, userId string, clearPushNotifications bool) (map[string]int64, *model.AppError) { 1618 if err := a.SetActiveChannel(userId, view.ChannelId); err != nil { 1619 return nil, err 1620 } 1621 1622 channelIds := []string{} 1623 1624 if len(view.ChannelId) > 0 { 1625 channelIds = append(channelIds, view.ChannelId) 1626 } 1627 1628 if len(view.PrevChannelId) > 0 { 1629 channelIds = append(channelIds, view.PrevChannelId) 1630 } 1631 1632 if len(channelIds) == 0 { 1633 return map[string]int64{}, nil 1634 } 1635 1636 return a.MarkChannelsAsViewed(channelIds, userId, clearPushNotifications) 1637 } 1638 1639 func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError { 1640 if result := <-a.Srv.Store.Post().PermanentDeleteByChannel(channel.Id); result.Err != nil { 1641 return result.Err 1642 } 1643 1644 if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByChannel(channel.Id); result.Err != nil { 1645 return result.Err 1646 } 1647 1648 if result := <-a.Srv.Store.Webhook().PermanentDeleteIncomingByChannel(channel.Id); result.Err != nil { 1649 return result.Err 1650 } 1651 1652 if result := <-a.Srv.Store.Webhook().PermanentDeleteOutgoingByChannel(channel.Id); result.Err != nil { 1653 return result.Err 1654 } 1655 1656 if result := <-a.Srv.Store.Channel().PermanentDelete(channel.Id); result.Err != nil { 1657 return result.Err 1658 } 1659 1660 return nil 1661 } 1662 1663 // This function is intended for use from the CLI. It is not robust against people joining the channel while the move 1664 // is in progress, and therefore should not be used from the API without first fixing this potential race condition. 1665 func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { 1666 // Check that all channel members are in the destination team. 1667 channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000) 1668 if err != nil { 1669 return err 1670 } 1671 1672 channelMemberIds := []string{} 1673 for _, channelMember := range *channelMembers { 1674 channelMemberIds = append(channelMemberIds, channelMember.UserId) 1675 } 1676 1677 teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds) 1678 if err2 != nil { 1679 return err2 1680 } 1681 1682 if len(teamMembers) != len(*channelMembers) { 1683 return model.NewAppError("MoveChannel", "app.channel.move_channel.members_do_not_match.error", nil, "", http.StatusInternalServerError) 1684 } 1685 1686 // keep instance of the previous team 1687 var previousTeam *model.Team 1688 result := <-a.Srv.Store.Team().Get(channel.TeamId) 1689 if result.Err != nil { 1690 return result.Err 1691 } 1692 previousTeam = result.Data.(*model.Team) 1693 1694 channel.TeamId = team.Id 1695 if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { 1696 return result.Err 1697 } 1698 a.postChannelMoveMessage(user, channel, previousTeam) 1699 1700 return nil 1701 } 1702 1703 func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError { 1704 1705 post := &model.Post{ 1706 ChannelId: channel.Id, 1707 Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name), 1708 Type: model.POST_MOVE_CHANNEL, 1709 UserId: user.Id, 1710 Props: model.StringInterface{ 1711 "username": user.Username, 1712 }, 1713 } 1714 1715 if _, err := a.CreatePost(post, channel, false); err != nil { 1716 return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError) 1717 } 1718 1719 return nil 1720 } 1721 1722 func (a *App) GetPinnedPosts(channelId string) (*model.PostList, *model.AppError) { 1723 result := <-a.Srv.Store.Channel().GetPinnedPosts(channelId) 1724 if result.Err != nil { 1725 return nil, result.Err 1726 } 1727 return result.Data.(*model.PostList), nil 1728 } 1729 1730 func (a *App) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 1731 result := <-a.Srv.Store.Channel().GetByName("", model.GetDMNameFromIds(userId1, userId2), true) 1732 if result.Err != nil { 1733 if result.Err.Id == store.MISSING_CHANNEL_ERROR { 1734 result := <-a.Srv.Store.Channel().CreateDirectChannel(userId1, userId2) 1735 if result.Err != nil { 1736 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, http.StatusBadRequest) 1737 } 1738 a.InvalidateCacheForUser(userId1) 1739 a.InvalidateCacheForUser(userId2) 1740 1741 channel := result.Data.(*model.Channel) 1742 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(userId1, channel.Id, model.GetMillis()); result.Err != nil { 1743 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 1744 } 1745 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(userId2, channel.Id, model.GetMillis()); result.Err != nil { 1746 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 1747 } 1748 1749 return channel, nil 1750 } 1751 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, result.Err.StatusCode) 1752 } 1753 return result.Data.(*model.Channel), nil 1754 } 1755 1756 func (a *App) ToggleMuteChannel(channelId string, userId string) *model.ChannelMember { 1757 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 1758 1759 if result.Err != nil { 1760 return nil 1761 } 1762 1763 member := result.Data.(*model.ChannelMember) 1764 1765 if member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_NOTIFY_MENTION { 1766 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_MARK_UNREAD_ALL 1767 } else { 1768 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION 1769 } 1770 1771 a.Srv.Store.Channel().UpdateMember(member) 1772 return member 1773 } 1774 1775 func (a *App) FillInChannelProps(channel *model.Channel) *model.AppError { 1776 return a.FillInChannelsProps(&model.ChannelList{channel}) 1777 } 1778 1779 func (a *App) FillInChannelsProps(channelList *model.ChannelList) *model.AppError { 1780 // Group the channels by team and call GetChannelsByNames just once per team. 1781 channelsByTeam := make(map[string]model.ChannelList) 1782 for _, channel := range *channelList { 1783 channelsByTeam[channel.TeamId] = append(channelsByTeam[channel.TeamId], channel) 1784 } 1785 1786 for teamId, channelList := range channelsByTeam { 1787 allChannelMentions := make(map[string]bool) 1788 channelMentions := make(map[*model.Channel][]string, len(channelList)) 1789 1790 // Collect mentions across the channels so as to query just once for this team. 1791 for _, channel := range channelList { 1792 channelMentions[channel] = model.ChannelMentions(channel.Header) 1793 1794 for _, channelMention := range channelMentions[channel] { 1795 allChannelMentions[channelMention] = true 1796 } 1797 } 1798 1799 allChannelMentionNames := make([]string, 0, len(allChannelMentions)) 1800 for channelName := range allChannelMentions { 1801 allChannelMentionNames = append(allChannelMentionNames, channelName) 1802 } 1803 1804 if len(allChannelMentionNames) > 0 { 1805 mentionedChannels, err := a.GetChannelsByNames(allChannelMentionNames, teamId) 1806 if err != nil { 1807 return err 1808 } 1809 1810 mentionedChannelsByName := make(map[string]*model.Channel) 1811 for _, channel := range mentionedChannels { 1812 mentionedChannelsByName[channel.Name] = channel 1813 } 1814 1815 for _, channel := range channelList { 1816 channelMentionsProp := make(map[string]interface{}, len(channelMentions[channel])) 1817 for _, channelMention := range channelMentions[channel] { 1818 if mentioned, ok := mentionedChannelsByName[channelMention]; ok { 1819 if mentioned.Type == model.CHANNEL_OPEN { 1820 channelMentionsProp[mentioned.Name] = map[string]interface{}{ 1821 "display_name": mentioned.DisplayName, 1822 } 1823 } 1824 } 1825 } 1826 1827 if len(channelMentionsProp) > 0 { 1828 channel.AddProp("channel_mentions", channelMentionsProp) 1829 } else if channel.Props != nil { 1830 delete(channel.Props, "channel_mentions") 1831 } 1832 } 1833 } 1834 } 1835 1836 return nil 1837 }