github.com/spline-fu/mattermost-server@v4.10.10+incompatible/app/channel.go (about)

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