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