github.com/dschalla/mattermost-server@v4.8.1-rc1+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 l4g "github.com/alecthomas/log4go" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/store" 15 "github.com/mattermost/mattermost-server/utils" 16 ) 17 18 func (a *App) CreateDefaultChannels(teamId string) ([]*model.Channel, *model.AppError) { 19 townSquare := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.town_square"), Name: "town-square", Type: model.CHANNEL_OPEN, TeamId: teamId} 20 21 if _, err := a.CreateChannel(townSquare, false); err != nil { 22 return nil, err 23 } 24 25 offTopic := &model.Channel{DisplayName: utils.T("api.channel.create_default_channels.off_topic"), Name: "off-topic", Type: model.CHANNEL_OPEN, TeamId: teamId} 26 27 if _, err := a.CreateChannel(offTopic, false); err != nil { 28 return nil, err 29 } 30 31 channels := []*model.Channel{townSquare, offTopic} 32 return channels, nil 33 } 34 35 func (a *App) JoinDefaultChannels(teamId string, user *model.User, channelRole string, userRequestorId string) *model.AppError { 36 var err *model.AppError = nil 37 38 var requestor *model.User 39 if userRequestorId != "" { 40 if u := <-a.Srv.Store.User().Get(userRequestorId); u.Err != nil { 41 return u.Err 42 } else { 43 requestor = u.Data.(*model.User) 44 } 45 } 46 47 if result := <-a.Srv.Store.Channel().GetByName(teamId, "town-square", true); result.Err != nil { 48 err = result.Err 49 } else { 50 townSquare := result.Data.(*model.Channel) 51 52 cm := &model.ChannelMember{ 53 ChannelId: townSquare.Id, 54 UserId: user.Id, 55 Roles: channelRole, 56 NotifyProps: model.GetDefaultChannelNotifyProps(), 57 } 58 59 if cmResult := <-a.Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil { 60 err = cmResult.Err 61 } 62 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, townSquare.Id, model.GetMillis()); result.Err != nil { 63 l4g.Warn("Failed to update ChannelMemberHistory table %v", result.Err) 64 } 65 66 if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 67 if requestor == nil { 68 if err := a.postJoinTeamMessage(user, townSquare); err != nil { 69 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 70 } 71 } else { 72 if err := a.postAddToTeamMessage(requestor, user, townSquare, ""); err != nil { 73 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 74 } 75 } 76 } 77 78 a.InvalidateCacheForChannelMembers(result.Data.(*model.Channel).Id) 79 } 80 81 if result := <-a.Srv.Store.Channel().GetByName(teamId, "off-topic", true); result.Err != nil { 82 err = result.Err 83 } else if offTopic := result.Data.(*model.Channel); offTopic.Type == model.CHANNEL_OPEN { 84 85 cm := &model.ChannelMember{ 86 ChannelId: offTopic.Id, 87 UserId: user.Id, 88 Roles: channelRole, 89 NotifyProps: model.GetDefaultChannelNotifyProps(), 90 } 91 92 if cmResult := <-a.Srv.Store.Channel().SaveMember(cm); cmResult.Err != nil { 93 err = cmResult.Err 94 } 95 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, offTopic.Id, model.GetMillis()); result.Err != nil { 96 l4g.Warn("Failed to update ChannelMemberHistory table %v", result.Err) 97 } 98 99 if requestor == nil { 100 if err := a.postJoinChannelMessage(user, offTopic); err != nil { 101 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 102 } 103 } else { 104 if err := a.PostAddToChannelMessage(requestor, user, offTopic, ""); err != nil { 105 l4g.Error(utils.T("api.channel.post_user_add_remove_message_and_forget.error"), err) 106 } 107 } 108 109 a.InvalidateCacheForChannelMembers(result.Data.(*model.Channel).Id) 110 } 111 112 return err 113 } 114 115 func (a *App) CreateChannelWithUser(channel *model.Channel, userId string) (*model.Channel, *model.AppError) { 116 if channel.IsGroupOrDirect() { 117 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.direct_channel.app_error", nil, "", http.StatusBadRequest) 118 } 119 120 if strings.Index(channel.Name, "__") > 0 { 121 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.invalid_character.app_error", nil, "", http.StatusBadRequest) 122 } 123 124 if len(channel.TeamId) == 0 { 125 return nil, model.NewAppError("CreateChannelWithUser", "app.channel.create_channel.no_team_id.app_error", nil, "", http.StatusBadRequest) 126 } 127 128 // Get total number of channels on current team 129 if count, err := a.GetNumberOfChannelsOnTeam(channel.TeamId); err != nil { 130 return nil, err 131 } else { 132 if int64(count+1) > *a.Config().TeamSettings.MaxChannelsPerTeam { 133 return nil, model.NewAppError("CreateChannelWithUser", "api.channel.create_channel.max_channel_limit.app_error", map[string]interface{}{"MaxChannelsPerTeam": *a.Config().TeamSettings.MaxChannelsPerTeam}, "", http.StatusBadRequest) 134 } 135 } 136 137 channel.CreatorId = userId 138 139 rchannel, err := a.CreateChannel(channel, true) 140 if err != nil { 141 return nil, err 142 } 143 144 var user *model.User 145 if user, err = a.GetUser(userId); err != nil { 146 return nil, err 147 } 148 149 a.postJoinChannelMessage(user, channel) 150 151 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_CREATED, "", "", userId, nil) 152 message.Add("channel_id", channel.Id) 153 message.Add("team_id", channel.TeamId) 154 a.Publish(message) 155 156 return rchannel, nil 157 } 158 159 func (a *App) CreateChannel(channel *model.Channel, addMember bool) (*model.Channel, *model.AppError) { 160 if result := <-a.Srv.Store.Channel().Save(channel, *a.Config().TeamSettings.MaxChannelsPerTeam); result.Err != nil { 161 return nil, result.Err 162 } else { 163 sc := result.Data.(*model.Channel) 164 165 if addMember { 166 cm := &model.ChannelMember{ 167 ChannelId: sc.Id, 168 UserId: channel.CreatorId, 169 Roles: model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID, 170 NotifyProps: model.GetDefaultChannelNotifyProps(), 171 } 172 173 if cmresult := <-a.Srv.Store.Channel().SaveMember(cm); cmresult.Err != nil { 174 return nil, cmresult.Err 175 } 176 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(channel.CreatorId, sc.Id, model.GetMillis()); result.Err != nil { 177 l4g.Warn("Failed to update ChannelMemberHistory table %v", result.Err) 178 } 179 180 a.InvalidateCacheForUser(channel.CreatorId) 181 } 182 183 return sc, nil 184 } 185 } 186 187 func (a *App) CreateDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) { 188 if channel, err := a.createDirectChannel(userId, otherUserId); err != nil { 189 if err.Id == store.CHANNEL_EXISTS_ERROR { 190 return channel, nil 191 } else { 192 return nil, err 193 } 194 } else { 195 a.WaitForChannelMembership(channel.Id, userId) 196 197 a.InvalidateCacheForUser(userId) 198 a.InvalidateCacheForUser(otherUserId) 199 200 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_DIRECT_ADDED, "", channel.Id, "", nil) 201 message.Add("teammate_id", otherUserId) 202 a.Publish(message) 203 204 return channel, nil 205 } 206 } 207 208 func (a *App) createDirectChannel(userId string, otherUserId string) (*model.Channel, *model.AppError) { 209 uc1 := a.Srv.Store.User().Get(userId) 210 uc2 := a.Srv.Store.User().Get(otherUserId) 211 212 if result := <-uc1; result.Err != nil { 213 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, userId, http.StatusBadRequest) 214 } 215 216 if result := <-uc2; result.Err != nil { 217 return nil, model.NewAppError("CreateDirectChannel", "api.channel.create_direct_channel.invalid_user.app_error", nil, otherUserId, http.StatusBadRequest) 218 } 219 220 if result := <-a.Srv.Store.Channel().CreateDirectChannel(userId, otherUserId); result.Err != nil { 221 if result.Err.Id == store.CHANNEL_EXISTS_ERROR { 222 return result.Data.(*model.Channel), result.Err 223 } else { 224 return nil, result.Err 225 } 226 } else { 227 channel := result.Data.(*model.Channel) 228 return channel, nil 229 } 230 } 231 232 func (a *App) WaitForChannelMembership(channelId string, userId string) { 233 if len(a.Config().SqlSettings.DataSourceReplicas) > 0 { 234 now := model.GetMillis() 235 236 for model.GetMillis()-now < 12000 { 237 238 time.Sleep(100 * time.Millisecond) 239 240 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 241 242 // If the membership was found then return 243 if result.Err == nil { 244 return 245 } 246 247 // If we recieved a error but it wasn't a missing channel member then return 248 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 249 return 250 } 251 } 252 253 l4g.Error("WaitForChannelMembership giving up channelId=%v userId=%v", channelId, userId) 254 } 255 } 256 257 func (a *App) CreateGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) { 258 if channel, err := a.createGroupChannel(userIds, creatorId); err != nil { 259 if err.Id == store.CHANNEL_EXISTS_ERROR { 260 return channel, nil 261 } else { 262 return nil, err 263 } 264 } else { 265 for _, userId := range userIds { 266 if userId == creatorId { 267 a.WaitForChannelMembership(channel.Id, creatorId) 268 } 269 270 a.InvalidateCacheForUser(userId) 271 } 272 273 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_GROUP_ADDED, "", channel.Id, "", nil) 274 message.Add("teammate_ids", model.ArrayToJson(userIds)) 275 a.Publish(message) 276 277 return channel, nil 278 } 279 } 280 281 func (a *App) createGroupChannel(userIds []string, creatorId string) (*model.Channel, *model.AppError) { 282 if len(userIds) > model.CHANNEL_GROUP_MAX_USERS || len(userIds) < model.CHANNEL_GROUP_MIN_USERS { 283 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_size.app_error", nil, "", http.StatusBadRequest) 284 } 285 286 var users []*model.User 287 if result := <-a.Srv.Store.User().GetProfileByIds(userIds, true); result.Err != nil { 288 return nil, result.Err 289 } else { 290 users = result.Data.([]*model.User) 291 } 292 293 if len(users) != len(userIds) { 294 return nil, model.NewAppError("CreateGroupChannel", "api.channel.create_group.bad_user.app_error", nil, "user_ids="+model.ArrayToJson(userIds), http.StatusBadRequest) 295 } 296 297 group := &model.Channel{ 298 Name: model.GetGroupNameFromUserIds(userIds), 299 DisplayName: model.GetGroupDisplayNameFromUsers(users, true), 300 Type: model.CHANNEL_GROUP, 301 } 302 303 if result := <-a.Srv.Store.Channel().Save(group, *a.Config().TeamSettings.MaxChannelsPerTeam); result.Err != nil { 304 if result.Err.Id == store.CHANNEL_EXISTS_ERROR { 305 return result.Data.(*model.Channel), result.Err 306 } else { 307 return nil, result.Err 308 } 309 } else { 310 channel := result.Data.(*model.Channel) 311 312 for _, user := range users { 313 cm := &model.ChannelMember{ 314 UserId: user.Id, 315 ChannelId: group.Id, 316 NotifyProps: model.GetDefaultChannelNotifyProps(), 317 Roles: model.CHANNEL_USER_ROLE_ID, 318 } 319 320 if result := <-a.Srv.Store.Channel().SaveMember(cm); result.Err != nil { 321 return nil, result.Err 322 } 323 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 324 l4g.Warn("Failed to update ChannelMemberHistory table %v", result.Err) 325 } 326 } 327 328 return channel, nil 329 } 330 } 331 332 func (a *App) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 333 if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { 334 return nil, result.Err 335 } else { 336 a.InvalidateCacheForChannel(channel) 337 338 messageWs := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_UPDATED, "", channel.Id, "", nil) 339 messageWs.Add("channel", channel.ToJson()) 340 a.Publish(messageWs) 341 342 return channel, nil 343 } 344 } 345 346 func (a *App) UpdateChannelPrivacy(oldChannel *model.Channel, user *model.User) (*model.Channel, *model.AppError) { 347 if channel, err := a.UpdateChannel(oldChannel); err != nil { 348 return channel, err 349 } else { 350 if err := a.postChannelPrivacyMessage(user, channel); err != nil { 351 if channel.Type == model.CHANNEL_OPEN { 352 channel.Type = model.CHANNEL_PRIVATE 353 } else { 354 channel.Type = model.CHANNEL_OPEN 355 } 356 // revert to previous channel privacy 357 a.UpdateChannel(channel) 358 return channel, err 359 } 360 361 return channel, nil 362 } 363 } 364 365 func (a *App) postChannelPrivacyMessage(user *model.User, channel *model.Channel) *model.AppError { 366 privacy := (map[string]string{ 367 model.CHANNEL_OPEN: "private_to_public", 368 model.CHANNEL_PRIVATE: "public_to_private", 369 })[channel.Type] 370 post := &model.Post{ 371 ChannelId: channel.Id, 372 Message: fmt.Sprintf(utils.T("api.channel.change_channel_privacy." + privacy)), 373 Type: model.POST_CHANGE_CHANNEL_PRIVACY, 374 UserId: user.Id, 375 Props: model.StringInterface{ 376 "username": user.Username, 377 }, 378 } 379 380 if _, err := a.CreatePost(post, channel, false); err != nil { 381 return model.NewAppError("postChannelPrivacyMessage", "api.channel.post_channel_privacy_message.error", nil, err.Error(), http.StatusInternalServerError) 382 } 383 384 return nil 385 } 386 387 func (a *App) RestoreChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 388 if result := <-a.Srv.Store.Channel().Restore(channel.Id, model.GetMillis()); result.Err != nil { 389 return nil, result.Err 390 } else { 391 return channel, nil 392 } 393 } 394 395 func (a *App) PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userId string) (*model.Channel, *model.AppError) { 396 oldChannelDisplayName := channel.DisplayName 397 oldChannelHeader := channel.Header 398 oldChannelPurpose := channel.Purpose 399 400 channel.Patch(patch) 401 channel, err := a.UpdateChannel(channel) 402 if err != nil { 403 return nil, err 404 } 405 406 if oldChannelDisplayName != channel.DisplayName { 407 if err := a.PostUpdateChannelDisplayNameMessage(userId, channel, oldChannelDisplayName, channel.DisplayName); err != nil { 408 l4g.Error(err.Error()) 409 } 410 } 411 412 if channel.Header != oldChannelHeader { 413 if err := a.PostUpdateChannelHeaderMessage(userId, channel, oldChannelHeader, channel.Header); err != nil { 414 l4g.Error(err.Error()) 415 } 416 } 417 418 if channel.Purpose != oldChannelPurpose { 419 if err := a.PostUpdateChannelPurposeMessage(userId, channel, oldChannelPurpose, channel.Purpose); err != nil { 420 l4g.Error(err.Error()) 421 } 422 } 423 424 return channel, err 425 } 426 427 func (a *App) UpdateChannelMemberRoles(channelId string, userId string, newRoles string) (*model.ChannelMember, *model.AppError) { 428 var member *model.ChannelMember 429 var err *model.AppError 430 if member, err = a.GetChannelMember(channelId, userId); err != nil { 431 return nil, err 432 } 433 434 member.Roles = newRoles 435 436 if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil { 437 return nil, result.Err 438 } 439 440 a.InvalidateCacheForUser(userId) 441 return member, nil 442 } 443 444 func (a *App) UpdateChannelMemberNotifyProps(data map[string]string, channelId string, userId string) (*model.ChannelMember, *model.AppError) { 445 var member *model.ChannelMember 446 var err *model.AppError 447 if member, err = a.GetChannelMember(channelId, userId); err != nil { 448 return nil, err 449 } 450 451 // update whichever notify properties have been provided, but don't change the others 452 if markUnread, exists := data[model.MARK_UNREAD_NOTIFY_PROP]; exists { 453 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = markUnread 454 } 455 456 if desktop, exists := data[model.DESKTOP_NOTIFY_PROP]; exists { 457 member.NotifyProps[model.DESKTOP_NOTIFY_PROP] = desktop 458 } 459 460 if email, exists := data[model.EMAIL_NOTIFY_PROP]; exists { 461 member.NotifyProps[model.EMAIL_NOTIFY_PROP] = email 462 } 463 464 if push, exists := data[model.PUSH_NOTIFY_PROP]; exists { 465 member.NotifyProps[model.PUSH_NOTIFY_PROP] = push 466 } 467 468 if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil { 469 return nil, result.Err 470 } else { 471 a.InvalidateCacheForUser(userId) 472 a.InvalidateCacheForChannelMembersNotifyProps(channelId) 473 return member, nil 474 } 475 } 476 477 func (a *App) DeleteChannel(channel *model.Channel, userId string) *model.AppError { 478 ihc := a.Srv.Store.Webhook().GetIncomingByChannel(channel.Id) 479 ohc := a.Srv.Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1) 480 481 var user *model.User 482 if userId != "" { 483 uc := a.Srv.Store.User().Get(userId) 484 uresult := <-uc 485 if uresult.Err != nil { 486 return uresult.Err 487 } 488 user = uresult.Data.(*model.User) 489 } 490 491 if ihcresult := <-ihc; ihcresult.Err != nil { 492 return ihcresult.Err 493 } else if ohcresult := <-ohc; ohcresult.Err != nil { 494 return ohcresult.Err 495 } else { 496 incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) 497 outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) 498 499 if channel.DeleteAt > 0 { 500 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "", http.StatusBadRequest) 501 return err 502 } 503 504 if channel.Name == model.DEFAULT_CHANNEL { 505 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 506 return err 507 } 508 509 if user != nil { 510 T := utils.GetUserTranslations(user.Locale) 511 512 post := &model.Post{ 513 ChannelId: channel.Id, 514 Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username), 515 Type: model.POST_CHANNEL_DELETED, 516 UserId: userId, 517 Props: model.StringInterface{ 518 "username": user.Username, 519 }, 520 } 521 522 if _, err := a.CreatePost(post, channel, false); err != nil { 523 l4g.Error(utils.T("api.channel.delete_channel.failed_post.error"), err) 524 } 525 } 526 527 now := model.GetMillis() 528 for _, hook := range incomingHooks { 529 if result := <-a.Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil { 530 l4g.Error(utils.T("api.channel.delete_channel.incoming_webhook.error"), hook.Id) 531 } 532 a.InvalidateCacheForWebhook(hook.Id) 533 } 534 535 for _, hook := range outgoingHooks { 536 if result := <-a.Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil { 537 l4g.Error(utils.T("api.channel.delete_channel.outgoing_webhook.error"), hook.Id) 538 } 539 } 540 541 if dresult := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil { 542 return dresult.Err 543 } 544 a.InvalidateCacheForChannel(channel) 545 546 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil) 547 message.Add("channel_id", channel.Id) 548 549 a.Publish(message) 550 } 551 552 return nil 553 } 554 555 func (a *App) addUserToChannel(user *model.User, channel *model.Channel, teamMember *model.TeamMember) (*model.ChannelMember, *model.AppError) { 556 if channel.DeleteAt > 0 { 557 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.deleted.app_error", nil, "", http.StatusBadRequest) 558 } 559 560 if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE { 561 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest) 562 } 563 564 cmchan := a.Srv.Store.Channel().GetMember(channel.Id, user.Id) 565 566 if result := <-cmchan; result.Err != nil { 567 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 568 return nil, result.Err 569 } 570 } else { 571 channelMember := result.Data.(*model.ChannelMember) 572 return channelMember, nil 573 } 574 575 newMember := &model.ChannelMember{ 576 ChannelId: channel.Id, 577 UserId: user.Id, 578 NotifyProps: model.GetDefaultChannelNotifyProps(), 579 Roles: model.CHANNEL_USER_ROLE_ID, 580 } 581 if result := <-a.Srv.Store.Channel().SaveMember(newMember); result.Err != nil { 582 l4g.Error("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err) 583 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "", http.StatusInternalServerError) 584 } 585 a.WaitForChannelMembership(channel.Id, user.Id) 586 587 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 588 l4g.Warn("Failed to update ChannelMemberHistory table %v", result.Err) 589 } 590 591 a.InvalidateCacheForUser(user.Id) 592 a.InvalidateCacheForChannelMembers(channel.Id) 593 594 return newMember, nil 595 } 596 597 func (a *App) AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) { 598 tmchan := a.Srv.Store.Team().GetMember(channel.TeamId, user.Id) 599 var teamMember *model.TeamMember 600 601 if result := <-tmchan; result.Err != nil { 602 return nil, result.Err 603 } else { 604 teamMember = result.Data.(*model.TeamMember) 605 if teamMember.DeleteAt > 0 { 606 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "", http.StatusBadRequest) 607 } 608 } 609 610 newMember, err := a.addUserToChannel(user, channel, teamMember) 611 if err != nil { 612 return nil, err 613 } 614 615 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil) 616 message.Add("user_id", user.Id) 617 message.Add("team_id", channel.TeamId) 618 a.Publish(message) 619 620 return newMember, nil 621 } 622 623 func (a *App) AddChannelMember(userId string, channel *model.Channel, userRequestorId string, postRootId string) (*model.ChannelMember, *model.AppError) { 624 if result := <-a.Srv.Store.Channel().GetMember(channel.Id, userId); result.Err != nil { 625 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 626 return nil, result.Err 627 } 628 } else { 629 return result.Data.(*model.ChannelMember), nil 630 } 631 632 var user *model.User 633 var err *model.AppError 634 635 if user, err = a.GetUser(userId); err != nil { 636 return nil, err 637 } 638 639 var userRequestor *model.User 640 if userRequestor, err = a.GetUser(userRequestorId); err != nil { 641 return nil, err 642 } 643 644 cm, err := a.AddUserToChannel(user, channel) 645 if err != nil { 646 return nil, err 647 } 648 649 if userId == userRequestorId { 650 a.postJoinChannelMessage(user, channel) 651 } else { 652 a.Go(func() { 653 a.PostAddToChannelMessage(userRequestor, user, channel, postRootId) 654 }) 655 } 656 657 a.UpdateChannelLastViewedAt([]string{channel.Id}, userRequestor.Id) 658 659 return cm, nil 660 } 661 662 func (a *App) AddDirectChannels(teamId string, user *model.User) *model.AppError { 663 var profiles []*model.User 664 if result := <-a.Srv.Store.User().GetProfiles(teamId, 0, 100); result.Err != nil { 665 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) 666 } else { 667 profiles = result.Data.([]*model.User) 668 } 669 670 var preferences model.Preferences 671 672 for _, profile := range profiles { 673 if profile.Id == user.Id { 674 continue 675 } 676 677 preference := model.Preference{ 678 UserId: user.Id, 679 Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, 680 Name: profile.Id, 681 Value: "true", 682 } 683 684 preferences = append(preferences, preference) 685 686 if len(preferences) >= 10 { 687 break 688 } 689 } 690 691 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 692 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) 693 } 694 695 return nil 696 } 697 698 func (a *App) PostUpdateChannelHeaderMessage(userId string, channel *model.Channel, oldChannelHeader, newChannelHeader string) *model.AppError { 699 uc := a.Srv.Store.User().Get(userId) 700 701 if uresult := <-uc; uresult.Err != nil { 702 return model.NewAppError("PostUpdateChannelHeaderMessage", "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 703 } else { 704 user := uresult.Data.(*model.User) 705 706 var message string 707 if oldChannelHeader == "" { 708 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader) 709 } else if newChannelHeader == "" { 710 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader) 711 } else { 712 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader) 713 } 714 715 post := &model.Post{ 716 ChannelId: channel.Id, 717 Message: message, 718 Type: model.POST_HEADER_CHANGE, 719 UserId: userId, 720 Props: model.StringInterface{ 721 "username": user.Username, 722 "old_header": oldChannelHeader, 723 "new_header": newChannelHeader, 724 }, 725 } 726 727 if _, err := a.CreatePost(post, channel, false); err != nil { 728 return model.NewAppError("", "api.channel.post_update_channel_header_message_and_forget.post.error", nil, err.Error(), http.StatusInternalServerError) 729 } 730 } 731 732 return nil 733 } 734 735 func (a *App) PostUpdateChannelPurposeMessage(userId string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError { 736 uc := a.Srv.Store.User().Get(userId) 737 738 if uresult := <-uc; uresult.Err != nil { 739 return model.NewAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 740 } else { 741 user := uresult.Data.(*model.User) 742 743 var message string 744 if oldChannelPurpose == "" { 745 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_to"), user.Username, newChannelPurpose) 746 } else if newChannelPurpose == "" { 747 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.removed"), user.Username, oldChannelPurpose) 748 } else { 749 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_from"), user.Username, oldChannelPurpose, newChannelPurpose) 750 } 751 752 post := &model.Post{ 753 ChannelId: channel.Id, 754 Message: message, 755 Type: model.POST_PURPOSE_CHANGE, 756 UserId: userId, 757 Props: model.StringInterface{ 758 "username": user.Username, 759 "old_purpose": oldChannelPurpose, 760 "new_purpose": newChannelPurpose, 761 }, 762 } 763 if _, err := a.CreatePost(post, channel, false); err != nil { 764 return model.NewAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error(), http.StatusInternalServerError) 765 } 766 } 767 768 return nil 769 } 770 771 func (a *App) PostUpdateChannelDisplayNameMessage(userId string, channel *model.Channel, oldChannelDisplayName, newChannelDisplayName string) *model.AppError { 772 uc := a.Srv.Store.User().Get(userId) 773 774 if uresult := <-uc; uresult.Err != nil { 775 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 776 } else { 777 user := uresult.Data.(*model.User) 778 779 message := fmt.Sprintf(utils.T("api.channel.post_update_channel_displayname_message_and_forget.updated_from"), user.Username, oldChannelDisplayName, newChannelDisplayName) 780 781 post := &model.Post{ 782 ChannelId: channel.Id, 783 Message: message, 784 Type: model.POST_DISPLAYNAME_CHANGE, 785 UserId: userId, 786 Props: model.StringInterface{ 787 "username": user.Username, 788 "old_displayname": oldChannelDisplayName, 789 "new_displayname": newChannelDisplayName, 790 }, 791 } 792 793 if _, err := a.CreatePost(post, channel, false); err != nil { 794 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.create_post.error", nil, err.Error(), http.StatusInternalServerError) 795 } 796 } 797 798 return nil 799 } 800 801 func (a *App) GetChannel(channelId string) (*model.Channel, *model.AppError) { 802 if result := <-a.Srv.Store.Channel().Get(channelId, true); result.Err != nil && result.Err.Id == "store.sql_channel.get.existing.app_error" { 803 result.Err.StatusCode = http.StatusNotFound 804 return nil, result.Err 805 } else if result.Err != nil { 806 result.Err.StatusCode = http.StatusBadRequest 807 return nil, result.Err 808 } else { 809 return result.Data.(*model.Channel), nil 810 } 811 } 812 813 func (a *App) GetChannelByName(channelName, teamId string) (*model.Channel, *model.AppError) { 814 if result := <-a.Srv.Store.Channel().GetByName(teamId, channelName, true); result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 815 result.Err.StatusCode = http.StatusNotFound 816 return nil, result.Err 817 } else if result.Err != nil { 818 result.Err.StatusCode = http.StatusBadRequest 819 return nil, result.Err 820 } else { 821 return result.Data.(*model.Channel), nil 822 } 823 } 824 825 func (a *App) GetChannelsByNames(channelNames []string, teamId string) ([]*model.Channel, *model.AppError) { 826 if result := <-a.Srv.Store.Channel().GetByNames(teamId, channelNames, true); result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 827 result.Err.StatusCode = http.StatusNotFound 828 return nil, result.Err 829 } else if result.Err != nil { 830 result.Err.StatusCode = http.StatusBadRequest 831 return nil, result.Err 832 } else { 833 return result.Data.([]*model.Channel), nil 834 } 835 } 836 837 func (a *App) GetChannelByNameForTeamName(channelName, teamName string) (*model.Channel, *model.AppError) { 838 var team *model.Team 839 840 if result := <-a.Srv.Store.Team().GetByName(teamName); result.Err != nil { 841 result.Err.StatusCode = http.StatusNotFound 842 return nil, result.Err 843 } else { 844 team = result.Data.(*model.Team) 845 } 846 847 if result := <-a.Srv.Store.Channel().GetByName(team.Id, channelName, true); result.Err != nil && result.Err.Id == "store.sql_channel.get_by_name.missing.app_error" { 848 result.Err.StatusCode = http.StatusNotFound 849 return nil, result.Err 850 } else if result.Err != nil { 851 result.Err.StatusCode = http.StatusBadRequest 852 return nil, result.Err 853 } else { 854 return result.Data.(*model.Channel), nil 855 } 856 } 857 858 func (a *App) GetChannelsForUser(teamId string, userId string) (*model.ChannelList, *model.AppError) { 859 if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId); result.Err != nil { 860 return nil, result.Err 861 } else { 862 return result.Data.(*model.ChannelList), nil 863 } 864 } 865 866 func (a *App) GetDeletedChannels(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 867 if result := <-a.Srv.Store.Channel().GetDeleted(teamId, offset, limit); result.Err != nil { 868 return nil, result.Err 869 } else { 870 return result.Data.(*model.ChannelList), nil 871 } 872 } 873 874 func (a *App) GetChannelsUserNotIn(teamId string, userId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 875 if result := <-a.Srv.Store.Channel().GetMoreChannels(teamId, userId, offset, limit); result.Err != nil { 876 return nil, result.Err 877 } else { 878 return result.Data.(*model.ChannelList), nil 879 } 880 } 881 882 func (a *App) GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*model.ChannelList, *model.AppError) { 883 if result := <-a.Srv.Store.Channel().GetPublicChannelsByIdsForTeam(teamId, channelIds); result.Err != nil { 884 return nil, result.Err 885 } else { 886 return result.Data.(*model.ChannelList), nil 887 } 888 } 889 890 func (a *App) GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 891 if result := <-a.Srv.Store.Channel().GetPublicChannelsForTeam(teamId, offset, limit); result.Err != nil { 892 return nil, result.Err 893 } else { 894 return result.Data.(*model.ChannelList), nil 895 } 896 } 897 898 func (a *App) GetChannelMember(channelId string, userId string) (*model.ChannelMember, *model.AppError) { 899 if result := <-a.Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil { 900 return nil, result.Err 901 } else { 902 return result.Data.(*model.ChannelMember), nil 903 } 904 } 905 906 func (a *App) GetChannelMembersPage(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError) { 907 if result := <-a.Srv.Store.Channel().GetMembers(channelId, page*perPage, perPage); result.Err != nil { 908 return nil, result.Err 909 } else { 910 return result.Data.(*model.ChannelMembers), nil 911 } 912 } 913 914 func (a *App) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) { 915 if result := <-a.Srv.Store.Channel().GetMembersByIds(channelId, userIds); result.Err != nil { 916 return nil, result.Err 917 } else { 918 return result.Data.(*model.ChannelMembers), nil 919 } 920 } 921 922 func (a *App) GetChannelMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError) { 923 if result := <-a.Srv.Store.Channel().GetMembersForUser(teamId, userId); result.Err != nil { 924 return nil, result.Err 925 } else { 926 return result.Data.(*model.ChannelMembers), nil 927 } 928 } 929 930 func (a *App) GetChannelMemberCount(channelId string) (int64, *model.AppError) { 931 if result := <-a.Srv.Store.Channel().GetMemberCount(channelId, true); result.Err != nil { 932 return 0, result.Err 933 } else { 934 return result.Data.(int64), nil 935 } 936 } 937 938 func (a *App) GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, *model.AppError) { 939 if result := <-a.Srv.Store.Channel().GetChannelCounts(teamId, userId); result.Err != nil { 940 return nil, result.Err 941 } else { 942 return result.Data.(*model.ChannelCounts), nil 943 } 944 } 945 946 func (a *App) GetChannelUnread(channelId, userId string) (*model.ChannelUnread, *model.AppError) { 947 result := <-a.Srv.Store.Channel().GetChannelUnread(channelId, userId) 948 if result.Err != nil { 949 return nil, result.Err 950 } 951 channelUnread := result.Data.(*model.ChannelUnread) 952 953 if channelUnread.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_MARK_UNREAD_MENTION { 954 channelUnread.MsgCount = 0 955 } 956 957 return channelUnread, nil 958 } 959 960 func (a *App) JoinChannel(channel *model.Channel, userId string) *model.AppError { 961 if channel.DeleteAt > 0 { 962 return model.NewAppError("JoinChannel", "api.channel.join_channel.already_deleted.app_error", nil, "", http.StatusBadRequest) 963 } 964 965 userChan := a.Srv.Store.User().Get(userId) 966 memberChan := a.Srv.Store.Channel().GetMember(channel.Id, userId) 967 968 if uresult := <-userChan; uresult.Err != nil { 969 return uresult.Err 970 } else if mresult := <-memberChan; mresult.Err == nil && mresult.Data != nil { 971 // user is already in the channel 972 return nil 973 } else { 974 user := uresult.Data.(*model.User) 975 976 if channel.Type == model.CHANNEL_OPEN { 977 if _, err := a.AddUserToChannel(user, channel); err != nil { 978 return err 979 } 980 981 if err := a.postJoinChannelMessage(user, channel); err != nil { 982 return err 983 } 984 } else { 985 return model.NewAppError("JoinChannel", "api.channel.join_channel.permissions.app_error", nil, "", http.StatusBadRequest) 986 } 987 } 988 989 return nil 990 } 991 992 func (a *App) postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 993 post := &model.Post{ 994 ChannelId: channel.Id, 995 Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), 996 Type: model.POST_JOIN_CHANNEL, 997 UserId: user.Id, 998 Props: model.StringInterface{ 999 "username": user.Username, 1000 }, 1001 } 1002 1003 if _, err := a.CreatePost(post, channel, false); err != nil { 1004 return model.NewAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1005 } 1006 1007 return nil 1008 } 1009 1010 func (a *App) postJoinTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 1011 post := &model.Post{ 1012 ChannelId: channel.Id, 1013 Message: fmt.Sprintf(utils.T("api.team.join_team.post_and_forget"), user.Username), 1014 Type: model.POST_JOIN_TEAM, 1015 UserId: user.Id, 1016 Props: model.StringInterface{ 1017 "username": user.Username, 1018 }, 1019 } 1020 1021 if _, err := a.CreatePost(post, channel, false); err != nil { 1022 return model.NewAppError("postJoinTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1023 } 1024 1025 return nil 1026 } 1027 1028 func (a *App) LeaveChannel(channelId string, userId string) *model.AppError { 1029 sc := a.Srv.Store.Channel().Get(channelId, true) 1030 uc := a.Srv.Store.User().Get(userId) 1031 ccm := a.Srv.Store.Channel().GetMemberCount(channelId, false) 1032 1033 if cresult := <-sc; cresult.Err != nil { 1034 return cresult.Err 1035 } else if uresult := <-uc; uresult.Err != nil { 1036 return cresult.Err 1037 } else if ccmresult := <-ccm; ccmresult.Err != nil { 1038 return ccmresult.Err 1039 } else { 1040 channel := cresult.Data.(*model.Channel) 1041 user := uresult.Data.(*model.User) 1042 membersCount := ccmresult.Data.(int64) 1043 1044 if channel.IsGroupOrDirect() { 1045 err := model.NewAppError("LeaveChannel", "api.channel.leave.direct.app_error", nil, "", http.StatusBadRequest) 1046 return err 1047 } 1048 1049 if channel.Type == model.CHANNEL_PRIVATE && membersCount == 1 { 1050 err := model.NewAppError("LeaveChannel", "api.channel.leave.last_member.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 1051 return err 1052 } 1053 1054 if err := a.removeUserFromChannel(userId, userId, channel); err != nil { 1055 return err 1056 } 1057 1058 if channel.Name == model.DEFAULT_CHANNEL && *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages == false { 1059 return nil 1060 } 1061 1062 a.Go(func() { 1063 a.postLeaveChannelMessage(user, channel) 1064 }) 1065 } 1066 1067 return nil 1068 } 1069 1070 func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1071 post := &model.Post{ 1072 ChannelId: channel.Id, 1073 Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), 1074 Type: model.POST_LEAVE_CHANNEL, 1075 UserId: user.Id, 1076 Props: model.StringInterface{ 1077 "username": user.Username, 1078 }, 1079 } 1080 1081 if _, err := a.CreatePost(post, channel, false); err != nil { 1082 return model.NewAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1083 } 1084 1085 return nil 1086 } 1087 1088 func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1089 post := &model.Post{ 1090 ChannelId: channel.Id, 1091 Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username), 1092 Type: model.POST_ADD_TO_CHANNEL, 1093 UserId: user.Id, 1094 RootId: postRootId, 1095 Props: model.StringInterface{ 1096 "username": user.Username, 1097 "addedUsername": addedUser.Username, 1098 }, 1099 } 1100 1101 if _, err := a.CreatePost(post, channel, false); err != nil { 1102 return model.NewAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1103 } 1104 1105 return nil 1106 } 1107 1108 func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1109 post := &model.Post{ 1110 ChannelId: channel.Id, 1111 Message: fmt.Sprintf(utils.T("api.team.add_user_to_team.added"), addedUser.Username, user.Username), 1112 Type: model.POST_ADD_TO_TEAM, 1113 UserId: user.Id, 1114 RootId: postRootId, 1115 Props: model.StringInterface{ 1116 "username": user.Username, 1117 "addedUsername": addedUser.Username, 1118 }, 1119 } 1120 1121 if _, err := a.CreatePost(post, channel, false); err != nil { 1122 return model.NewAppError("postAddToTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1123 } 1124 1125 return nil 1126 } 1127 1128 func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError { 1129 post := &model.Post{ 1130 ChannelId: channel.Id, 1131 Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username), 1132 Type: model.POST_REMOVE_FROM_CHANNEL, 1133 UserId: removerUserId, 1134 Props: model.StringInterface{ 1135 "removedUsername": removedUser.Username, 1136 }, 1137 } 1138 1139 if _, err := a.CreatePost(post, channel, false); err != nil { 1140 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1141 } 1142 1143 return nil 1144 } 1145 1146 func (a *App) removeUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1147 if channel.DeleteAt > 0 { 1148 err := model.NewAppError("RemoveUserFromChannel", "api.channel.remove_user_from_channel.deleted.app_error", nil, "", http.StatusBadRequest) 1149 return err 1150 } 1151 1152 if channel.Name == model.DEFAULT_CHANNEL { 1153 return model.NewAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 1154 } 1155 1156 if cmresult := <-a.Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil { 1157 return cmresult.Err 1158 } 1159 if cmhResult := <-a.Srv.Store.ChannelMemberHistory().LogLeaveEvent(userIdToRemove, channel.Id, model.GetMillis()); cmhResult.Err != nil { 1160 return cmhResult.Err 1161 } 1162 1163 a.InvalidateCacheForUser(userIdToRemove) 1164 a.InvalidateCacheForChannelMembers(channel.Id) 1165 1166 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil) 1167 message.Add("user_id", userIdToRemove) 1168 message.Add("remover_id", removerUserId) 1169 a.Go(func() { 1170 a.Publish(message) 1171 }) 1172 1173 // because the removed user no longer belongs to the channel we need to send a separate websocket event 1174 userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIdToRemove, nil) 1175 userMsg.Add("channel_id", channel.Id) 1176 userMsg.Add("remover_id", removerUserId) 1177 a.Go(func() { 1178 a.Publish(userMsg) 1179 }) 1180 1181 return nil 1182 } 1183 1184 func (a *App) RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1185 var err *model.AppError 1186 if err = a.removeUserFromChannel(userIdToRemove, removerUserId, channel); err != nil { 1187 return err 1188 } 1189 1190 var user *model.User 1191 if user, err = a.GetUser(userIdToRemove); err != nil { 1192 return err 1193 } 1194 1195 if userIdToRemove == removerUserId { 1196 a.postLeaveChannelMessage(user, channel) 1197 } else { 1198 a.Go(func() { 1199 a.postRemoveFromChannelMessage(removerUserId, user, channel) 1200 }) 1201 } 1202 1203 return nil 1204 } 1205 1206 func (a *App) GetNumberOfChannelsOnTeam(teamId string) (int, *model.AppError) { 1207 // Get total number of channels on current team 1208 if result := <-a.Srv.Store.Channel().GetTeamChannels(teamId); result.Err != nil { 1209 return 0, result.Err 1210 } else { 1211 return len(*result.Data.(*model.ChannelList)), nil 1212 } 1213 } 1214 1215 func (a *App) SetActiveChannel(userId string, channelId string) *model.AppError { 1216 status, err := a.GetStatus(userId) 1217 1218 oldStatus := model.STATUS_OFFLINE 1219 1220 if err != nil { 1221 status = &model.Status{UserId: userId, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: channelId} 1222 } else { 1223 oldStatus = status.Status 1224 status.ActiveChannel = channelId 1225 if !status.Manual && channelId != "" { 1226 status.Status = model.STATUS_ONLINE 1227 } 1228 status.LastActivityAt = model.GetMillis() 1229 } 1230 1231 a.AddStatusCache(status) 1232 1233 if status.Status != oldStatus { 1234 a.BroadcastStatus(status) 1235 } 1236 1237 return nil 1238 } 1239 1240 func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError { 1241 if result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); result.Err != nil { 1242 return result.Err 1243 } 1244 1245 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 1246 for _, channelId := range channelIds { 1247 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1248 message.Add("channel_id", channelId) 1249 a.Go(func() { 1250 a.Publish(message) 1251 }) 1252 } 1253 } 1254 1255 return nil 1256 } 1257 1258 func (a *App) AutocompleteChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1259 if result := <-a.Srv.Store.Channel().AutocompleteInTeam(teamId, term); result.Err != nil { 1260 return nil, result.Err 1261 } else { 1262 return result.Data.(*model.ChannelList), nil 1263 } 1264 } 1265 1266 func (a *App) SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1267 if result := <-a.Srv.Store.Channel().SearchInTeam(teamId, term); result.Err != nil { 1268 return nil, result.Err 1269 } else { 1270 return result.Data.(*model.ChannelList), nil 1271 } 1272 } 1273 1274 func (a *App) SearchChannelsUserNotIn(teamId string, userId string, term string) (*model.ChannelList, *model.AppError) { 1275 if result := <-a.Srv.Store.Channel().SearchMore(userId, teamId, term); result.Err != nil { 1276 return nil, result.Err 1277 } else { 1278 return result.Data.(*model.ChannelList), nil 1279 } 1280 } 1281 1282 func (a *App) ViewChannel(view *model.ChannelView, userId string, clearPushNotifications bool) (map[string]int64, *model.AppError) { 1283 if err := a.SetActiveChannel(userId, view.ChannelId); err != nil { 1284 return nil, err 1285 } 1286 1287 channelIds := []string{} 1288 1289 if len(view.ChannelId) > 0 { 1290 channelIds = append(channelIds, view.ChannelId) 1291 } 1292 1293 var pchan store.StoreChannel 1294 if len(view.PrevChannelId) > 0 { 1295 channelIds = append(channelIds, view.PrevChannelId) 1296 1297 if *a.Config().EmailSettings.SendPushNotifications && clearPushNotifications && len(view.ChannelId) > 0 { 1298 pchan = a.Srv.Store.User().GetUnreadCountForChannel(userId, view.ChannelId) 1299 } 1300 } 1301 1302 if len(channelIds) == 0 { 1303 return map[string]int64{}, nil 1304 } 1305 1306 uchan := a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId) 1307 1308 if pchan != nil { 1309 if result := <-pchan; result.Err != nil { 1310 return nil, result.Err 1311 } else { 1312 if result.Data.(int64) > 0 { 1313 a.ClearPushNotification(userId, view.ChannelId) 1314 } 1315 } 1316 } 1317 1318 var times map[string]int64 1319 if result := <-uchan; result.Err != nil { 1320 return nil, result.Err 1321 } else { 1322 times = result.Data.(map[string]int64) 1323 } 1324 1325 if *a.Config().ServiceSettings.EnableChannelViewedMessages && model.IsValidId(view.ChannelId) { 1326 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1327 message.Add("channel_id", view.ChannelId) 1328 a.Go(func() { 1329 a.Publish(message) 1330 }) 1331 } 1332 1333 return times, nil 1334 } 1335 1336 func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError { 1337 if result := <-a.Srv.Store.Post().PermanentDeleteByChannel(channel.Id); result.Err != nil { 1338 return result.Err 1339 } 1340 1341 if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByChannel(channel.Id); result.Err != nil { 1342 return result.Err 1343 } 1344 1345 if result := <-a.Srv.Store.Webhook().PermanentDeleteIncomingByChannel(channel.Id); result.Err != nil { 1346 return result.Err 1347 } 1348 1349 if result := <-a.Srv.Store.Webhook().PermanentDeleteOutgoingByChannel(channel.Id); result.Err != nil { 1350 return result.Err 1351 } 1352 1353 if result := <-a.Srv.Store.Channel().PermanentDelete(channel.Id); result.Err != nil { 1354 return result.Err 1355 } 1356 1357 return nil 1358 } 1359 1360 // This function is intended for use from the CLI. It is not robust against people joining the channel while the move 1361 // is in progress, and therefore should not be used from the API without first fixing this potential race condition. 1362 func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { 1363 // Check that all channel members are in the destination team. 1364 if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil { 1365 return err 1366 } else { 1367 channelMemberIds := []string{} 1368 for _, channelMember := range *channelMembers { 1369 channelMemberIds = append(channelMemberIds, channelMember.UserId) 1370 } 1371 1372 if teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds); err != nil { 1373 return err2 1374 } else { 1375 if len(teamMembers) != len(*channelMembers) { 1376 return model.NewAppError("MoveChannel", "app.channel.move_channel.members_do_not_match.error", nil, "", http.StatusInternalServerError) 1377 } 1378 } 1379 } 1380 1381 // keep instance of the previous team 1382 var previousTeam *model.Team 1383 if result := <-a.Srv.Store.Team().Get(channel.TeamId); result.Err != nil { 1384 return result.Err 1385 } else { 1386 previousTeam = result.Data.(*model.Team) 1387 } 1388 channel.TeamId = team.Id 1389 if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { 1390 return result.Err 1391 } 1392 a.postChannelMoveMessage(user, channel, previousTeam) 1393 1394 return nil 1395 } 1396 1397 func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError { 1398 1399 post := &model.Post{ 1400 ChannelId: channel.Id, 1401 Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name), 1402 Type: model.POST_MOVE_CHANNEL, 1403 UserId: user.Id, 1404 Props: model.StringInterface{ 1405 "username": user.Username, 1406 }, 1407 } 1408 1409 if _, err := a.CreatePost(post, channel, false); err != nil { 1410 return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError) 1411 } 1412 1413 return nil 1414 } 1415 1416 func (a *App) GetPinnedPosts(channelId string) (*model.PostList, *model.AppError) { 1417 if result := <-a.Srv.Store.Channel().GetPinnedPosts(channelId); result.Err != nil { 1418 return nil, result.Err 1419 } else { 1420 return result.Data.(*model.PostList), nil 1421 } 1422 } 1423 1424 func (a *App) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 1425 result := <-a.Srv.Store.Channel().GetByName("", model.GetDMNameFromIds(userId1, userId2), true) 1426 if result.Err != nil && result.Err.Id == store.MISSING_CHANNEL_ERROR { 1427 result := <-a.Srv.Store.Channel().CreateDirectChannel(userId1, userId2) 1428 if result.Err != nil { 1429 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, http.StatusBadRequest) 1430 } 1431 a.InvalidateCacheForUser(userId1) 1432 a.InvalidateCacheForUser(userId2) 1433 return result.Data.(*model.Channel), nil 1434 } else if result.Err != nil { 1435 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, result.Err.StatusCode) 1436 } 1437 return result.Data.(*model.Channel), nil 1438 }