github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/app/channel.go (about)

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