github.com/spline-fu/mattermost-server@v4.10.10+incompatible/app/channel.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 "net/http" 9 "strings" 10 "time" 11 12 "github.com/mattermost/mattermost-server/mlog" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/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 mlog.Warn(fmt.Sprintf("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 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 70 } 71 } else { 72 if err := a.postAddToTeamMessage(requestor, user, townSquare, ""); err != nil { 73 mlog.Error(fmt.Sprint("Failed to post join/leave message", 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 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 97 } 98 99 if requestor == nil { 100 if err := a.postJoinChannelMessage(user, offTopic); err != nil { 101 mlog.Error(fmt.Sprint("Failed to post join/leave message", err)) 102 } 103 } else { 104 if err := a.PostAddToChannelMessage(requestor, user, offTopic, ""); err != nil { 105 mlog.Error(fmt.Sprint("Failed to post join/leave message", 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 mlog.Warn(fmt.Sprintf("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 mlog.Warn(fmt.Sprintf("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 mlog.Warn(fmt.Sprintf("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 received 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 mlog.Error(fmt.Sprintf("WaitForChannelMembership giving up channelId=%v userId=%v", channelId, userId), mlog.String("user_id", 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 mlog.Warn(fmt.Sprintf("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 mlog.Error(err.Error()) 417 } 418 } 419 420 if channel.Header != oldChannelHeader { 421 if err := a.PostUpdateChannelHeaderMessage(userId, channel, oldChannelHeader, channel.Header); err != nil { 422 mlog.Error(err.Error()) 423 } 424 } 425 426 if channel.Purpose != oldChannelPurpose { 427 if err := a.PostUpdateChannelPurposeMessage(userId, channel, oldChannelPurpose, channel.Purpose); err != nil { 428 mlog.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 if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil { 443 return nil, err 444 } 445 446 member.Roles = newRoles 447 448 if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil { 449 return nil, result.Err 450 } 451 452 a.InvalidateCacheForUser(userId) 453 return member, nil 454 } 455 456 func (a *App) UpdateChannelMemberNotifyProps(data map[string]string, channelId string, userId string) (*model.ChannelMember, *model.AppError) { 457 var member *model.ChannelMember 458 var err *model.AppError 459 if member, err = a.GetChannelMember(channelId, userId); err != nil { 460 return nil, err 461 } 462 463 // update whichever notify properties have been provided, but don't change the others 464 if markUnread, exists := data[model.MARK_UNREAD_NOTIFY_PROP]; exists { 465 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = markUnread 466 } 467 468 if desktop, exists := data[model.DESKTOP_NOTIFY_PROP]; exists { 469 member.NotifyProps[model.DESKTOP_NOTIFY_PROP] = desktop 470 } 471 472 if email, exists := data[model.EMAIL_NOTIFY_PROP]; exists { 473 member.NotifyProps[model.EMAIL_NOTIFY_PROP] = email 474 } 475 476 if push, exists := data[model.PUSH_NOTIFY_PROP]; exists { 477 member.NotifyProps[model.PUSH_NOTIFY_PROP] = push 478 } 479 480 if result := <-a.Srv.Store.Channel().UpdateMember(member); result.Err != nil { 481 return nil, result.Err 482 } else { 483 a.InvalidateCacheForUser(userId) 484 a.InvalidateCacheForChannelMembersNotifyProps(channelId) 485 // Notify the clients that the member notify props changed 486 evt := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_MEMBER_UPDATED, "", "", userId, nil) 487 evt.Add("channelMember", member.ToJson()) 488 a.Publish(evt) 489 return member, nil 490 } 491 } 492 493 func (a *App) DeleteChannel(channel *model.Channel, userId string) *model.AppError { 494 ihc := a.Srv.Store.Webhook().GetIncomingByChannel(channel.Id) 495 ohc := a.Srv.Store.Webhook().GetOutgoingByChannel(channel.Id, -1, -1) 496 497 var user *model.User 498 if userId != "" { 499 uc := a.Srv.Store.User().Get(userId) 500 uresult := <-uc 501 if uresult.Err != nil { 502 return uresult.Err 503 } 504 user = uresult.Data.(*model.User) 505 } 506 507 if ihcresult := <-ihc; ihcresult.Err != nil { 508 return ihcresult.Err 509 } else if ohcresult := <-ohc; ohcresult.Err != nil { 510 return ohcresult.Err 511 } else { 512 incomingHooks := ihcresult.Data.([]*model.IncomingWebhook) 513 outgoingHooks := ohcresult.Data.([]*model.OutgoingWebhook) 514 515 if channel.DeleteAt > 0 { 516 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.deleted.app_error", nil, "", http.StatusBadRequest) 517 return err 518 } 519 520 if channel.Name == model.DEFAULT_CHANNEL { 521 err := model.NewAppError("deleteChannel", "api.channel.delete_channel.cannot.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 522 return err 523 } 524 525 if user != nil { 526 T := utils.GetUserTranslations(user.Locale) 527 528 post := &model.Post{ 529 ChannelId: channel.Id, 530 Message: fmt.Sprintf(T("api.channel.delete_channel.archived"), user.Username), 531 Type: model.POST_CHANNEL_DELETED, 532 UserId: userId, 533 Props: model.StringInterface{ 534 "username": user.Username, 535 }, 536 } 537 538 if _, err := a.CreatePost(post, channel, false); err != nil { 539 mlog.Error(fmt.Sprintf("Failed to post archive message %v", err)) 540 } 541 } 542 543 now := model.GetMillis() 544 for _, hook := range incomingHooks { 545 if result := <-a.Srv.Store.Webhook().DeleteIncoming(hook.Id, now); result.Err != nil { 546 mlog.Error(fmt.Sprintf("Encountered error deleting incoming webhook, id=%v", hook.Id)) 547 } 548 a.InvalidateCacheForWebhook(hook.Id) 549 } 550 551 for _, hook := range outgoingHooks { 552 if result := <-a.Srv.Store.Webhook().DeleteOutgoing(hook.Id, now); result.Err != nil { 553 mlog.Error(fmt.Sprintf("Encountered error deleting outgoing webhook, id=%v", hook.Id)) 554 } 555 } 556 557 if dresult := <-a.Srv.Store.Channel().Delete(channel.Id, model.GetMillis()); dresult.Err != nil { 558 return dresult.Err 559 } 560 a.InvalidateCacheForChannel(channel) 561 562 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_DELETED, channel.TeamId, "", "", nil) 563 message.Add("channel_id", channel.Id) 564 a.Publish(message) 565 } 566 567 return nil 568 } 569 570 func (a *App) addUserToChannel(user *model.User, channel *model.Channel, teamMember *model.TeamMember) (*model.ChannelMember, *model.AppError) { 571 if channel.DeleteAt > 0 { 572 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.deleted.app_error", nil, "", http.StatusBadRequest) 573 } 574 575 if channel.Type != model.CHANNEL_OPEN && channel.Type != model.CHANNEL_PRIVATE { 576 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user_to_channel.type.app_error", nil, "", http.StatusBadRequest) 577 } 578 579 cmchan := a.Srv.Store.Channel().GetMember(channel.Id, user.Id) 580 581 if result := <-cmchan; result.Err != nil { 582 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 583 return nil, result.Err 584 } 585 } else { 586 channelMember := result.Data.(*model.ChannelMember) 587 return channelMember, nil 588 } 589 590 newMember := &model.ChannelMember{ 591 ChannelId: channel.Id, 592 UserId: user.Id, 593 NotifyProps: model.GetDefaultChannelNotifyProps(), 594 Roles: model.CHANNEL_USER_ROLE_ID, 595 } 596 if result := <-a.Srv.Store.Channel().SaveMember(newMember); result.Err != nil { 597 mlog.Error(fmt.Sprintf("Failed to add member user_id=%v channel_id=%v err=%v", user.Id, channel.Id, result.Err), mlog.String("user_id", user.Id)) 598 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.app_error", nil, "", http.StatusInternalServerError) 599 } 600 a.WaitForChannelMembership(channel.Id, user.Id) 601 602 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis()); result.Err != nil { 603 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 604 } 605 606 a.InvalidateCacheForUser(user.Id) 607 a.InvalidateCacheForChannelMembers(channel.Id) 608 609 return newMember, nil 610 } 611 612 func (a *App) AddUserToChannel(user *model.User, channel *model.Channel) (*model.ChannelMember, *model.AppError) { 613 tmchan := a.Srv.Store.Team().GetMember(channel.TeamId, user.Id) 614 var teamMember *model.TeamMember 615 616 if result := <-tmchan; result.Err != nil { 617 return nil, result.Err 618 } else { 619 teamMember = result.Data.(*model.TeamMember) 620 if teamMember.DeleteAt > 0 { 621 return nil, model.NewAppError("AddUserToChannel", "api.channel.add_user.to.channel.failed.deleted.app_error", nil, "", http.StatusBadRequest) 622 } 623 } 624 625 newMember, err := a.addUserToChannel(user, channel, teamMember) 626 if err != nil { 627 return nil, err 628 } 629 630 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ADDED, "", channel.Id, "", nil) 631 message.Add("user_id", user.Id) 632 message.Add("team_id", channel.TeamId) 633 a.Publish(message) 634 635 return newMember, nil 636 } 637 638 func (a *App) AddChannelMember(userId string, channel *model.Channel, userRequestorId string, postRootId string) (*model.ChannelMember, *model.AppError) { 639 if result := <-a.Srv.Store.Channel().GetMember(channel.Id, userId); result.Err != nil { 640 if result.Err.Id != store.MISSING_CHANNEL_MEMBER_ERROR { 641 return nil, result.Err 642 } 643 } else { 644 return result.Data.(*model.ChannelMember), nil 645 } 646 647 var user *model.User 648 var err *model.AppError 649 650 if user, err = a.GetUser(userId); err != nil { 651 return nil, err 652 } 653 654 var userRequestor *model.User 655 if userRequestorId != "" { 656 if userRequestor, err = a.GetUser(userRequestorId); err != nil { 657 return nil, err 658 } 659 } 660 661 cm, err := a.AddUserToChannel(user, channel) 662 if err != nil { 663 return nil, err 664 } 665 666 if userRequestorId == "" || userId == userRequestorId { 667 a.postJoinChannelMessage(user, channel) 668 } else { 669 a.Go(func() { 670 a.PostAddToChannelMessage(userRequestor, user, channel, postRootId) 671 }) 672 } 673 674 if userRequestor != nil { 675 a.UpdateChannelLastViewedAt([]string{channel.Id}, userRequestor.Id) 676 } 677 678 return cm, nil 679 } 680 681 func (a *App) AddDirectChannels(teamId string, user *model.User) *model.AppError { 682 var profiles []*model.User 683 if result := <-a.Srv.Store.User().GetProfiles(teamId, 0, 100); result.Err != nil { 684 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) 685 } else { 686 profiles = result.Data.([]*model.User) 687 } 688 689 var preferences model.Preferences 690 691 for _, profile := range profiles { 692 if profile.Id == user.Id { 693 continue 694 } 695 696 preference := model.Preference{ 697 UserId: user.Id, 698 Category: model.PREFERENCE_CATEGORY_DIRECT_CHANNEL_SHOW, 699 Name: profile.Id, 700 Value: "true", 701 } 702 703 preferences = append(preferences, preference) 704 705 if len(preferences) >= 10 { 706 break 707 } 708 } 709 710 if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil { 711 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) 712 } 713 714 return nil 715 } 716 717 func (a *App) PostUpdateChannelHeaderMessage(userId string, channel *model.Channel, oldChannelHeader, newChannelHeader string) *model.AppError { 718 uc := a.Srv.Store.User().Get(userId) 719 720 if uresult := <-uc; uresult.Err != nil { 721 return model.NewAppError("PostUpdateChannelHeaderMessage", "api.channel.post_update_channel_header_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 722 } else { 723 user := uresult.Data.(*model.User) 724 725 var message string 726 if oldChannelHeader == "" { 727 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_to"), user.Username, newChannelHeader) 728 } else if newChannelHeader == "" { 729 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.removed"), user.Username, oldChannelHeader) 730 } else { 731 message = fmt.Sprintf(utils.T("api.channel.post_update_channel_header_message_and_forget.updated_from"), user.Username, oldChannelHeader, newChannelHeader) 732 } 733 734 post := &model.Post{ 735 ChannelId: channel.Id, 736 Message: message, 737 Type: model.POST_HEADER_CHANGE, 738 UserId: userId, 739 Props: model.StringInterface{ 740 "username": user.Username, 741 "old_header": oldChannelHeader, 742 "new_header": newChannelHeader, 743 }, 744 } 745 746 if _, err := a.CreatePost(post, channel, false); err != nil { 747 return model.NewAppError("", "api.channel.post_update_channel_header_message_and_forget.post.error", nil, err.Error(), http.StatusInternalServerError) 748 } 749 } 750 751 return nil 752 } 753 754 func (a *App) PostUpdateChannelPurposeMessage(userId string, channel *model.Channel, oldChannelPurpose string, newChannelPurpose string) *model.AppError { 755 uc := a.Srv.Store.User().Get(userId) 756 757 if uresult := <-uc; uresult.Err != nil { 758 return model.NewAppError("PostUpdateChannelPurposeMessage", "app.channel.post_update_channel_purpose_message.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 759 } else { 760 user := uresult.Data.(*model.User) 761 762 var message string 763 if oldChannelPurpose == "" { 764 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_to"), user.Username, newChannelPurpose) 765 } else if newChannelPurpose == "" { 766 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.removed"), user.Username, oldChannelPurpose) 767 } else { 768 message = fmt.Sprintf(utils.T("app.channel.post_update_channel_purpose_message.updated_from"), user.Username, oldChannelPurpose, newChannelPurpose) 769 } 770 771 post := &model.Post{ 772 ChannelId: channel.Id, 773 Message: message, 774 Type: model.POST_PURPOSE_CHANGE, 775 UserId: userId, 776 Props: model.StringInterface{ 777 "username": user.Username, 778 "old_purpose": oldChannelPurpose, 779 "new_purpose": newChannelPurpose, 780 }, 781 } 782 if _, err := a.CreatePost(post, channel, false); err != nil { 783 return model.NewAppError("", "app.channel.post_update_channel_purpose_message.post.error", nil, err.Error(), http.StatusInternalServerError) 784 } 785 } 786 787 return nil 788 } 789 790 func (a *App) PostUpdateChannelDisplayNameMessage(userId string, channel *model.Channel, oldChannelDisplayName, newChannelDisplayName string) *model.AppError { 791 uc := a.Srv.Store.User().Get(userId) 792 793 if uresult := <-uc; uresult.Err != nil { 794 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.retrieve_user.error", nil, uresult.Err.Error(), http.StatusBadRequest) 795 } else { 796 user := uresult.Data.(*model.User) 797 798 message := fmt.Sprintf(utils.T("api.channel.post_update_channel_displayname_message_and_forget.updated_from"), user.Username, oldChannelDisplayName, newChannelDisplayName) 799 800 post := &model.Post{ 801 ChannelId: channel.Id, 802 Message: message, 803 Type: model.POST_DISPLAYNAME_CHANGE, 804 UserId: userId, 805 Props: model.StringInterface{ 806 "username": user.Username, 807 "old_displayname": oldChannelDisplayName, 808 "new_displayname": newChannelDisplayName, 809 }, 810 } 811 812 if _, err := a.CreatePost(post, channel, false); err != nil { 813 return model.NewAppError("PostUpdateChannelDisplayNameMessage", "api.channel.post_update_channel_displayname_message_and_forget.create_post.error", nil, err.Error(), http.StatusInternalServerError) 814 } 815 } 816 817 return nil 818 } 819 820 func (a *App) GetChannel(channelId string) (*model.Channel, *model.AppError) { 821 if result := <-a.Srv.Store.Channel().Get(channelId, true); result.Err != nil && result.Err.Id == "store.sql_channel.get.existing.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) GetChannelByName(channelName, teamId string) (*model.Channel, *model.AppError) { 833 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" { 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) GetChannelsByNames(channelNames []string, teamId string) ([]*model.Channel, *model.AppError) { 845 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" { 846 result.Err.StatusCode = http.StatusNotFound 847 return nil, result.Err 848 } else if result.Err != nil { 849 result.Err.StatusCode = http.StatusBadRequest 850 return nil, result.Err 851 } else { 852 return result.Data.([]*model.Channel), nil 853 } 854 } 855 856 func (a *App) GetChannelByNameForTeamName(channelName, teamName string) (*model.Channel, *model.AppError) { 857 var team *model.Team 858 859 if result := <-a.Srv.Store.Team().GetByName(teamName); result.Err != nil { 860 result.Err.StatusCode = http.StatusNotFound 861 return nil, result.Err 862 } else { 863 team = result.Data.(*model.Team) 864 } 865 866 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" { 867 result.Err.StatusCode = http.StatusNotFound 868 return nil, result.Err 869 } else if result.Err != nil { 870 result.Err.StatusCode = http.StatusBadRequest 871 return nil, result.Err 872 } else { 873 return result.Data.(*model.Channel), nil 874 } 875 } 876 877 func (a *App) GetChannelsForUser(teamId string, userId string) (*model.ChannelList, *model.AppError) { 878 if result := <-a.Srv.Store.Channel().GetChannels(teamId, userId); result.Err != nil { 879 return nil, result.Err 880 } else { 881 return result.Data.(*model.ChannelList), nil 882 } 883 } 884 885 func (a *App) GetDeletedChannels(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 886 if result := <-a.Srv.Store.Channel().GetDeleted(teamId, offset, limit); result.Err != nil { 887 return nil, result.Err 888 } else { 889 return result.Data.(*model.ChannelList), nil 890 } 891 } 892 893 func (a *App) GetChannelsUserNotIn(teamId string, userId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 894 if result := <-a.Srv.Store.Channel().GetMoreChannels(teamId, userId, offset, limit); result.Err != nil { 895 return nil, result.Err 896 } else { 897 return result.Data.(*model.ChannelList), nil 898 } 899 } 900 901 func (a *App) GetPublicChannelsByIdsForTeam(teamId string, channelIds []string) (*model.ChannelList, *model.AppError) { 902 if result := <-a.Srv.Store.Channel().GetPublicChannelsByIdsForTeam(teamId, channelIds); result.Err != nil { 903 return nil, result.Err 904 } else { 905 return result.Data.(*model.ChannelList), nil 906 } 907 } 908 909 func (a *App) GetPublicChannelsForTeam(teamId string, offset int, limit int) (*model.ChannelList, *model.AppError) { 910 if result := <-a.Srv.Store.Channel().GetPublicChannelsForTeam(teamId, offset, limit); result.Err != nil { 911 return nil, result.Err 912 } else { 913 return result.Data.(*model.ChannelList), nil 914 } 915 } 916 917 func (a *App) GetChannelMember(channelId string, userId string) (*model.ChannelMember, *model.AppError) { 918 if result := <-a.Srv.Store.Channel().GetMember(channelId, userId); result.Err != nil { 919 return nil, result.Err 920 } else { 921 return result.Data.(*model.ChannelMember), nil 922 } 923 } 924 925 func (a *App) GetChannelMembersPage(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError) { 926 if result := <-a.Srv.Store.Channel().GetMembers(channelId, page*perPage, perPage); result.Err != nil { 927 return nil, result.Err 928 } else { 929 return result.Data.(*model.ChannelMembers), nil 930 } 931 } 932 933 func (a *App) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) { 934 if result := <-a.Srv.Store.Channel().GetMembersByIds(channelId, userIds); result.Err != nil { 935 return nil, result.Err 936 } else { 937 return result.Data.(*model.ChannelMembers), nil 938 } 939 } 940 941 func (a *App) GetChannelMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError) { 942 if result := <-a.Srv.Store.Channel().GetMembersForUser(teamId, userId); result.Err != nil { 943 return nil, result.Err 944 } else { 945 return result.Data.(*model.ChannelMembers), nil 946 } 947 } 948 949 func (a *App) GetChannelMemberCount(channelId string) (int64, *model.AppError) { 950 if result := <-a.Srv.Store.Channel().GetMemberCount(channelId, true); result.Err != nil { 951 return 0, result.Err 952 } else { 953 return result.Data.(int64), nil 954 } 955 } 956 957 func (a *App) GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, *model.AppError) { 958 if result := <-a.Srv.Store.Channel().GetChannelCounts(teamId, userId); result.Err != nil { 959 return nil, result.Err 960 } else { 961 return result.Data.(*model.ChannelCounts), nil 962 } 963 } 964 965 func (a *App) GetChannelUnread(channelId, userId string) (*model.ChannelUnread, *model.AppError) { 966 result := <-a.Srv.Store.Channel().GetChannelUnread(channelId, userId) 967 if result.Err != nil { 968 return nil, result.Err 969 } 970 channelUnread := result.Data.(*model.ChannelUnread) 971 972 if channelUnread.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_MARK_UNREAD_MENTION { 973 channelUnread.MsgCount = 0 974 } 975 976 return channelUnread, nil 977 } 978 979 func (a *App) JoinChannel(channel *model.Channel, userId string) *model.AppError { 980 if channel.DeleteAt > 0 { 981 return model.NewAppError("JoinChannel", "api.channel.join_channel.already_deleted.app_error", nil, "", http.StatusBadRequest) 982 } 983 984 userChan := a.Srv.Store.User().Get(userId) 985 memberChan := a.Srv.Store.Channel().GetMember(channel.Id, userId) 986 987 if uresult := <-userChan; uresult.Err != nil { 988 return uresult.Err 989 } else if mresult := <-memberChan; mresult.Err == nil && mresult.Data != nil { 990 // user is already in the channel 991 return nil 992 } else { 993 user := uresult.Data.(*model.User) 994 995 if channel.Type == model.CHANNEL_OPEN { 996 if _, err := a.AddUserToChannel(user, channel); err != nil { 997 return err 998 } 999 1000 if err := a.postJoinChannelMessage(user, channel); err != nil { 1001 return err 1002 } 1003 } else { 1004 return model.NewAppError("JoinChannel", "api.channel.join_channel.permissions.app_error", nil, "", http.StatusBadRequest) 1005 } 1006 } 1007 1008 return nil 1009 } 1010 1011 func (a *App) postJoinChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1012 post := &model.Post{ 1013 ChannelId: channel.Id, 1014 Message: fmt.Sprintf(utils.T("api.channel.join_channel.post_and_forget"), user.Username), 1015 Type: model.POST_JOIN_CHANNEL, 1016 UserId: user.Id, 1017 Props: model.StringInterface{ 1018 "username": user.Username, 1019 }, 1020 } 1021 1022 if _, err := a.CreatePost(post, channel, false); err != nil { 1023 return model.NewAppError("postJoinChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1024 } 1025 1026 return nil 1027 } 1028 1029 func (a *App) postJoinTeamMessage(user *model.User, channel *model.Channel) *model.AppError { 1030 post := &model.Post{ 1031 ChannelId: channel.Id, 1032 Message: fmt.Sprintf(utils.T("api.team.join_team.post_and_forget"), user.Username), 1033 Type: model.POST_JOIN_TEAM, 1034 UserId: user.Id, 1035 Props: model.StringInterface{ 1036 "username": user.Username, 1037 }, 1038 } 1039 1040 if _, err := a.CreatePost(post, channel, false); err != nil { 1041 return model.NewAppError("postJoinTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1042 } 1043 1044 return nil 1045 } 1046 1047 func (a *App) LeaveChannel(channelId string, userId string) *model.AppError { 1048 sc := a.Srv.Store.Channel().Get(channelId, true) 1049 uc := a.Srv.Store.User().Get(userId) 1050 ccm := a.Srv.Store.Channel().GetMemberCount(channelId, false) 1051 1052 if cresult := <-sc; cresult.Err != nil { 1053 return cresult.Err 1054 } else if uresult := <-uc; uresult.Err != nil { 1055 return cresult.Err 1056 } else if ccmresult := <-ccm; ccmresult.Err != nil { 1057 return ccmresult.Err 1058 } else { 1059 channel := cresult.Data.(*model.Channel) 1060 user := uresult.Data.(*model.User) 1061 membersCount := ccmresult.Data.(int64) 1062 1063 if channel.IsGroupOrDirect() { 1064 err := model.NewAppError("LeaveChannel", "api.channel.leave.direct.app_error", nil, "", http.StatusBadRequest) 1065 return err 1066 } 1067 1068 if channel.Type == model.CHANNEL_PRIVATE && membersCount == 1 { 1069 err := model.NewAppError("LeaveChannel", "api.channel.leave.last_member.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 1070 return err 1071 } 1072 1073 if err := a.removeUserFromChannel(userId, userId, channel); err != nil { 1074 return err 1075 } 1076 1077 if channel.Name == model.DEFAULT_CHANNEL && !*a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages { 1078 return nil 1079 } 1080 1081 a.Go(func() { 1082 a.postLeaveChannelMessage(user, channel) 1083 }) 1084 } 1085 1086 return nil 1087 } 1088 1089 func (a *App) postLeaveChannelMessage(user *model.User, channel *model.Channel) *model.AppError { 1090 post := &model.Post{ 1091 ChannelId: channel.Id, 1092 Message: fmt.Sprintf(utils.T("api.channel.leave.left"), user.Username), 1093 Type: model.POST_LEAVE_CHANNEL, 1094 UserId: user.Id, 1095 Props: model.StringInterface{ 1096 "username": user.Username, 1097 }, 1098 } 1099 1100 if _, err := a.CreatePost(post, channel, false); err != nil { 1101 return model.NewAppError("postLeaveChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1102 } 1103 1104 return nil 1105 } 1106 1107 func (a *App) PostAddToChannelMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1108 post := &model.Post{ 1109 ChannelId: channel.Id, 1110 Message: fmt.Sprintf(utils.T("api.channel.add_member.added"), addedUser.Username, user.Username), 1111 Type: model.POST_ADD_TO_CHANNEL, 1112 UserId: user.Id, 1113 RootId: postRootId, 1114 Props: model.StringInterface{ 1115 "userId": user.Id, 1116 "username": user.Username, 1117 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 1118 "addedUsername": addedUser.Username, 1119 }, 1120 } 1121 1122 if _, err := a.CreatePost(post, channel, false); err != nil { 1123 return model.NewAppError("postAddToChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1124 } 1125 1126 return nil 1127 } 1128 1129 func (a *App) postAddToTeamMessage(user *model.User, addedUser *model.User, channel *model.Channel, postRootId string) *model.AppError { 1130 post := &model.Post{ 1131 ChannelId: channel.Id, 1132 Message: fmt.Sprintf(utils.T("api.team.add_user_to_team.added"), addedUser.Username, user.Username), 1133 Type: model.POST_ADD_TO_TEAM, 1134 UserId: user.Id, 1135 RootId: postRootId, 1136 Props: model.StringInterface{ 1137 "userId": user.Id, 1138 "username": user.Username, 1139 model.POST_PROPS_ADDED_USER_ID: addedUser.Id, 1140 "addedUsername": addedUser.Username, 1141 }, 1142 } 1143 1144 if _, err := a.CreatePost(post, channel, false); err != nil { 1145 return model.NewAppError("postAddToTeamMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1146 } 1147 1148 return nil 1149 } 1150 1151 func (a *App) postRemoveFromChannelMessage(removerUserId string, removedUser *model.User, channel *model.Channel) *model.AppError { 1152 post := &model.Post{ 1153 ChannelId: channel.Id, 1154 Message: fmt.Sprintf(utils.T("api.channel.remove_member.removed"), removedUser.Username), 1155 Type: model.POST_REMOVE_FROM_CHANNEL, 1156 UserId: removerUserId, 1157 Props: model.StringInterface{ 1158 "removedUserId": removedUser.Id, 1159 "removedUsername": removedUser.Username, 1160 }, 1161 } 1162 1163 if _, err := a.CreatePost(post, channel, false); err != nil { 1164 return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError) 1165 } 1166 1167 return nil 1168 } 1169 1170 func (a *App) removeUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1171 if channel.DeleteAt > 0 { 1172 err := model.NewAppError("RemoveUserFromChannel", "api.channel.remove_user_from_channel.deleted.app_error", nil, "", http.StatusBadRequest) 1173 return err 1174 } 1175 1176 if channel.Name == model.DEFAULT_CHANNEL { 1177 return model.NewAppError("RemoveUserFromChannel", "api.channel.remove.default.app_error", map[string]interface{}{"Channel": model.DEFAULT_CHANNEL}, "", http.StatusBadRequest) 1178 } 1179 1180 if cmresult := <-a.Srv.Store.Channel().RemoveMember(channel.Id, userIdToRemove); cmresult.Err != nil { 1181 return cmresult.Err 1182 } 1183 if cmhResult := <-a.Srv.Store.ChannelMemberHistory().LogLeaveEvent(userIdToRemove, channel.Id, model.GetMillis()); cmhResult.Err != nil { 1184 return cmhResult.Err 1185 } 1186 1187 a.InvalidateCacheForUser(userIdToRemove) 1188 a.InvalidateCacheForChannelMembers(channel.Id) 1189 1190 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", channel.Id, "", nil) 1191 message.Add("user_id", userIdToRemove) 1192 message.Add("remover_id", removerUserId) 1193 a.Publish(message) 1194 1195 // because the removed user no longer belongs to the channel we need to send a separate websocket event 1196 userMsg := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_REMOVED, "", "", userIdToRemove, nil) 1197 userMsg.Add("channel_id", channel.Id) 1198 userMsg.Add("remover_id", removerUserId) 1199 a.Publish(userMsg) 1200 1201 return nil 1202 } 1203 1204 func (a *App) RemoveUserFromChannel(userIdToRemove string, removerUserId string, channel *model.Channel) *model.AppError { 1205 var err *model.AppError 1206 if err = a.removeUserFromChannel(userIdToRemove, removerUserId, channel); err != nil { 1207 return err 1208 } 1209 1210 var user *model.User 1211 if user, err = a.GetUser(userIdToRemove); err != nil { 1212 return err 1213 } 1214 1215 if userIdToRemove == removerUserId { 1216 a.postLeaveChannelMessage(user, channel) 1217 } else { 1218 a.Go(func() { 1219 a.postRemoveFromChannelMessage(removerUserId, user, channel) 1220 }) 1221 } 1222 1223 return nil 1224 } 1225 1226 func (a *App) GetNumberOfChannelsOnTeam(teamId string) (int, *model.AppError) { 1227 // Get total number of channels on current team 1228 if result := <-a.Srv.Store.Channel().GetTeamChannels(teamId); result.Err != nil { 1229 return 0, result.Err 1230 } else { 1231 return len(*result.Data.(*model.ChannelList)), nil 1232 } 1233 } 1234 1235 func (a *App) SetActiveChannel(userId string, channelId string) *model.AppError { 1236 status, err := a.GetStatus(userId) 1237 1238 oldStatus := model.STATUS_OFFLINE 1239 1240 if err != nil { 1241 status = &model.Status{UserId: userId, Status: model.STATUS_ONLINE, Manual: false, LastActivityAt: model.GetMillis(), ActiveChannel: channelId} 1242 } else { 1243 oldStatus = status.Status 1244 status.ActiveChannel = channelId 1245 if !status.Manual && channelId != "" { 1246 status.Status = model.STATUS_ONLINE 1247 } 1248 status.LastActivityAt = model.GetMillis() 1249 } 1250 1251 a.AddStatusCache(status) 1252 1253 if status.Status != oldStatus { 1254 a.BroadcastStatus(status) 1255 } 1256 1257 return nil 1258 } 1259 1260 func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError { 1261 if result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); result.Err != nil { 1262 return result.Err 1263 } 1264 1265 if *a.Config().ServiceSettings.EnableChannelViewedMessages { 1266 for _, channelId := range channelIds { 1267 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1268 message.Add("channel_id", channelId) 1269 a.Publish(message) 1270 } 1271 } 1272 1273 return nil 1274 } 1275 1276 func (a *App) AutocompleteChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1277 if result := <-a.Srv.Store.Channel().AutocompleteInTeam(teamId, term); result.Err != nil { 1278 return nil, result.Err 1279 } else { 1280 return result.Data.(*model.ChannelList), nil 1281 } 1282 } 1283 1284 func (a *App) SearchChannels(teamId string, term string) (*model.ChannelList, *model.AppError) { 1285 if result := <-a.Srv.Store.Channel().SearchInTeam(teamId, term); result.Err != nil { 1286 return nil, result.Err 1287 } else { 1288 return result.Data.(*model.ChannelList), nil 1289 } 1290 } 1291 1292 func (a *App) SearchChannelsUserNotIn(teamId string, userId string, term string) (*model.ChannelList, *model.AppError) { 1293 if result := <-a.Srv.Store.Channel().SearchMore(userId, teamId, term); result.Err != nil { 1294 return nil, result.Err 1295 } else { 1296 return result.Data.(*model.ChannelList), nil 1297 } 1298 } 1299 1300 func (a *App) ViewChannel(view *model.ChannelView, userId string, clearPushNotifications bool) (map[string]int64, *model.AppError) { 1301 if err := a.SetActiveChannel(userId, view.ChannelId); err != nil { 1302 return nil, err 1303 } 1304 1305 channelIds := []string{} 1306 1307 if len(view.ChannelId) > 0 { 1308 channelIds = append(channelIds, view.ChannelId) 1309 } 1310 1311 var pchan store.StoreChannel 1312 if len(view.PrevChannelId) > 0 { 1313 channelIds = append(channelIds, view.PrevChannelId) 1314 1315 if *a.Config().EmailSettings.SendPushNotifications && clearPushNotifications && len(view.ChannelId) > 0 { 1316 pchan = a.Srv.Store.User().GetUnreadCountForChannel(userId, view.ChannelId) 1317 } 1318 } 1319 1320 if len(channelIds) == 0 { 1321 return map[string]int64{}, nil 1322 } 1323 1324 uchan := a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId) 1325 1326 if pchan != nil { 1327 if result := <-pchan; result.Err != nil { 1328 return nil, result.Err 1329 } else { 1330 if result.Data.(int64) > 0 { 1331 a.ClearPushNotification(userId, view.ChannelId) 1332 } 1333 } 1334 } 1335 1336 var times map[string]int64 1337 if result := <-uchan; result.Err != nil { 1338 return nil, result.Err 1339 } else { 1340 times = result.Data.(map[string]int64) 1341 } 1342 1343 if *a.Config().ServiceSettings.EnableChannelViewedMessages && model.IsValidId(view.ChannelId) { 1344 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) 1345 message.Add("channel_id", view.ChannelId) 1346 a.Publish(message) 1347 } 1348 1349 return times, nil 1350 } 1351 1352 func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError { 1353 if result := <-a.Srv.Store.Post().PermanentDeleteByChannel(channel.Id); result.Err != nil { 1354 return result.Err 1355 } 1356 1357 if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByChannel(channel.Id); result.Err != nil { 1358 return result.Err 1359 } 1360 1361 if result := <-a.Srv.Store.Webhook().PermanentDeleteIncomingByChannel(channel.Id); result.Err != nil { 1362 return result.Err 1363 } 1364 1365 if result := <-a.Srv.Store.Webhook().PermanentDeleteOutgoingByChannel(channel.Id); result.Err != nil { 1366 return result.Err 1367 } 1368 1369 if result := <-a.Srv.Store.Channel().PermanentDelete(channel.Id); result.Err != nil { 1370 return result.Err 1371 } 1372 1373 return nil 1374 } 1375 1376 // This function is intended for use from the CLI. It is not robust against people joining the channel while the move 1377 // is in progress, and therefore should not be used from the API without first fixing this potential race condition. 1378 func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { 1379 // Check that all channel members are in the destination team. 1380 if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil { 1381 return err 1382 } else { 1383 channelMemberIds := []string{} 1384 for _, channelMember := range *channelMembers { 1385 channelMemberIds = append(channelMemberIds, channelMember.UserId) 1386 } 1387 1388 if teamMembers, err2 := a.GetTeamMembersByIds(team.Id, channelMemberIds); err != nil { 1389 return err2 1390 } else { 1391 if len(teamMembers) != len(*channelMembers) { 1392 return model.NewAppError("MoveChannel", "app.channel.move_channel.members_do_not_match.error", nil, "", http.StatusInternalServerError) 1393 } 1394 } 1395 } 1396 1397 // keep instance of the previous team 1398 var previousTeam *model.Team 1399 if result := <-a.Srv.Store.Team().Get(channel.TeamId); result.Err != nil { 1400 return result.Err 1401 } else { 1402 previousTeam = result.Data.(*model.Team) 1403 } 1404 channel.TeamId = team.Id 1405 if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { 1406 return result.Err 1407 } 1408 a.postChannelMoveMessage(user, channel, previousTeam) 1409 1410 return nil 1411 } 1412 1413 func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError { 1414 1415 post := &model.Post{ 1416 ChannelId: channel.Id, 1417 Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name), 1418 Type: model.POST_MOVE_CHANNEL, 1419 UserId: user.Id, 1420 Props: model.StringInterface{ 1421 "username": user.Username, 1422 }, 1423 } 1424 1425 if _, err := a.CreatePost(post, channel, false); err != nil { 1426 return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError) 1427 } 1428 1429 return nil 1430 } 1431 1432 func (a *App) GetPinnedPosts(channelId string) (*model.PostList, *model.AppError) { 1433 if result := <-a.Srv.Store.Channel().GetPinnedPosts(channelId); result.Err != nil { 1434 return nil, result.Err 1435 } else { 1436 return result.Data.(*model.PostList), nil 1437 } 1438 } 1439 1440 func (a *App) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 1441 result := <-a.Srv.Store.Channel().GetByName("", model.GetDMNameFromIds(userId1, userId2), true) 1442 if result.Err != nil && result.Err.Id == store.MISSING_CHANNEL_ERROR { 1443 result := <-a.Srv.Store.Channel().CreateDirectChannel(userId1, userId2) 1444 if result.Err != nil { 1445 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, http.StatusBadRequest) 1446 } 1447 a.InvalidateCacheForUser(userId1) 1448 a.InvalidateCacheForUser(userId2) 1449 1450 channel := result.Data.(*model.Channel) 1451 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(userId1, channel.Id, model.GetMillis()); result.Err != nil { 1452 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 1453 } 1454 if result := <-a.Srv.Store.ChannelMemberHistory().LogJoinEvent(userId2, channel.Id, model.GetMillis()); result.Err != nil { 1455 mlog.Warn(fmt.Sprintf("Failed to update ChannelMemberHistory table %v", result.Err)) 1456 } 1457 1458 return channel, nil 1459 } else if result.Err != nil { 1460 return nil, model.NewAppError("GetOrCreateDMChannel", "web.incoming_webhook.channel.app_error", nil, "err="+result.Err.Message, result.Err.StatusCode) 1461 } 1462 return result.Data.(*model.Channel), nil 1463 } 1464 1465 func (a *App) ToggleMuteChannel(channelId string, userId string) *model.ChannelMember { 1466 result := <-a.Srv.Store.Channel().GetMember(channelId, userId) 1467 1468 if result.Err != nil { 1469 return nil 1470 } 1471 1472 member := result.Data.(*model.ChannelMember) 1473 1474 if member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_NOTIFY_MENTION { 1475 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_MARK_UNREAD_ALL 1476 } else { 1477 member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = model.CHANNEL_NOTIFY_MENTION 1478 } 1479 1480 a.Srv.Store.Channel().UpdateMember(member) 1481 return member 1482 }