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