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