github.com/vnforks/kid@v5.11.1+incompatible/app/channel.go (about)

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