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