github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/app/team.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  	"bytes"
     8  	"fmt"
     9  	"image"
    10  	"image/png"
    11  	"mime/multipart"
    12  	"net/http"
    13  	"net/url"
    14  	"strings"
    15  
    16  	"github.com/disintegration/imaging"
    17  
    18  	"github.com/mattermost/mattermost-server/mlog"
    19  	"github.com/mattermost/mattermost-server/model"
    20  	"github.com/mattermost/mattermost-server/utils"
    21  )
    22  
    23  func (a *App) CreateTeam(team *model.Team) (*model.Team, *model.AppError) {
    24  	if result := <-a.Srv.Store.Team().Save(team); result.Err != nil {
    25  		return nil, result.Err
    26  	} else {
    27  		rteam := result.Data.(*model.Team)
    28  
    29  		if _, err := a.CreateDefaultChannels(rteam.Id); err != nil {
    30  			return nil, err
    31  		}
    32  
    33  		return rteam, nil
    34  	}
    35  }
    36  
    37  func (a *App) CreateTeamWithUser(team *model.Team, userId string) (*model.Team, *model.AppError) {
    38  	var user *model.User
    39  	var err *model.AppError
    40  	if user, err = a.GetUser(userId); err != nil {
    41  		return nil, err
    42  	} else {
    43  		team.Email = user.Email
    44  	}
    45  
    46  	if !a.isTeamEmailAllowed(user) {
    47  		return nil, model.NewAppError("isTeamEmailAllowed", "api.team.is_team_creation_allowed.domain.app_error", nil, "", http.StatusBadRequest)
    48  	}
    49  
    50  	var rteam *model.Team
    51  	if rteam, err = a.CreateTeam(team); err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	if err = a.JoinUserToTeam(rteam, user, ""); err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	return rteam, nil
    60  }
    61  
    62  func (a *App) isTeamEmailAddressAllowed(email string) bool {
    63  	email = strings.ToLower(email)
    64  	// commas and @ signs are optional
    65  	// can be in the form of "@corp.mattermost.com, mattermost.com mattermost.org" -> corp.mattermost.com mattermost.com mattermost.org
    66  	domains := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(a.Config().TeamSettings.RestrictCreationToDomains, "@", " ", -1), ",", " ", -1))))
    67  
    68  	matched := false
    69  	for _, d := range domains {
    70  		if strings.HasSuffix(email, "@"+d) {
    71  			matched = true
    72  			break
    73  		}
    74  	}
    75  
    76  	if len(a.Config().TeamSettings.RestrictCreationToDomains) > 0 && !matched {
    77  		return false
    78  	}
    79  
    80  	return true
    81  }
    82  
    83  func (a *App) isTeamEmailAllowed(user *model.User) bool {
    84  	email := strings.ToLower(user.Email)
    85  
    86  	if len(user.AuthService) > 0 && len(*user.AuthData) > 0 {
    87  		return true
    88  	}
    89  
    90  	return a.isTeamEmailAddressAllowed(email)
    91  }
    92  
    93  func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) {
    94  	var oldTeam *model.Team
    95  	var err *model.AppError
    96  	if oldTeam, err = a.GetTeam(team.Id); err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	oldTeam.DisplayName = team.DisplayName
   101  	oldTeam.Description = team.Description
   102  	oldTeam.InviteId = team.InviteId
   103  	oldTeam.AllowOpenInvite = team.AllowOpenInvite
   104  	oldTeam.CompanyName = team.CompanyName
   105  	oldTeam.AllowedDomains = team.AllowedDomains
   106  	oldTeam.LastTeamIconUpdate = team.LastTeamIconUpdate
   107  
   108  	if result := <-a.Srv.Store.Team().Update(oldTeam); result.Err != nil {
   109  		return nil, result.Err
   110  	}
   111  
   112  	a.sendTeamEvent(oldTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM)
   113  
   114  	return oldTeam, nil
   115  }
   116  
   117  func (a *App) PatchTeam(teamId string, patch *model.TeamPatch) (*model.Team, *model.AppError) {
   118  	team, err := a.GetTeam(teamId)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	team.Patch(patch)
   124  
   125  	updatedTeam, err := a.UpdateTeam(team)
   126  	if err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	a.sendTeamEvent(updatedTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM)
   131  
   132  	return updatedTeam, nil
   133  }
   134  
   135  func (a *App) sendTeamEvent(team *model.Team, event string) {
   136  	sanitizedTeam := &model.Team{}
   137  	*sanitizedTeam = *team
   138  	sanitizedTeam.Sanitize()
   139  
   140  	message := model.NewWebSocketEvent(event, "", "", "", nil)
   141  	message.Add("team", sanitizedTeam.ToJson())
   142  	a.Publish(message)
   143  }
   144  
   145  func (a *App) UpdateTeamMemberRoles(teamId string, userId string, newRoles string) (*model.TeamMember, *model.AppError) {
   146  	var member *model.TeamMember
   147  	if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil {
   148  		return nil, result.Err
   149  	} else {
   150  		members := result.Data.([]*model.TeamMember)
   151  		for _, m := range members {
   152  			if m.TeamId == teamId {
   153  				member = m
   154  			}
   155  		}
   156  	}
   157  
   158  	if member == nil {
   159  		err := model.NewAppError("UpdateTeamMemberRoles", "api.team.update_member_roles.not_a_member", nil, "userId="+userId+" teamId="+teamId, http.StatusBadRequest)
   160  		return nil, err
   161  	}
   162  
   163  	if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
   164  		return nil, err
   165  	}
   166  
   167  	member.Roles = newRoles
   168  
   169  	if result := <-a.Srv.Store.Team().UpdateMember(member); result.Err != nil {
   170  		return nil, result.Err
   171  	}
   172  
   173  	a.ClearSessionCacheForUser(userId)
   174  
   175  	a.sendUpdatedMemberRoleEvent(userId, member)
   176  
   177  	return member, nil
   178  }
   179  
   180  func (a *App) sendUpdatedMemberRoleEvent(userId string, member *model.TeamMember) {
   181  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_MEMBERROLE_UPDATED, "", "", userId, nil)
   182  	message.Add("member", member.ToJson())
   183  	a.Publish(message)
   184  }
   185  
   186  func (a *App) AddUserToTeam(teamId string, userId string, userRequestorId string) (*model.Team, *model.AppError) {
   187  	tchan := a.Srv.Store.Team().Get(teamId)
   188  	uchan := a.Srv.Store.User().Get(userId)
   189  
   190  	var team *model.Team
   191  	if result := <-tchan; result.Err != nil {
   192  		return nil, result.Err
   193  	} else {
   194  		team = result.Data.(*model.Team)
   195  	}
   196  
   197  	var user *model.User
   198  	if result := <-uchan; result.Err != nil {
   199  		return nil, result.Err
   200  	} else {
   201  		user = result.Data.(*model.User)
   202  	}
   203  
   204  	if err := a.JoinUserToTeam(team, user, userRequestorId); err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	return team, nil
   209  }
   210  
   211  func (a *App) AddUserToTeamByTeamId(teamId string, user *model.User) *model.AppError {
   212  	if result := <-a.Srv.Store.Team().Get(teamId); result.Err != nil {
   213  		return result.Err
   214  	} else {
   215  		return a.JoinUserToTeam(result.Data.(*model.Team), user, "")
   216  	}
   217  }
   218  
   219  func (a *App) AddUserToTeamByToken(userId string, tokenId string) (*model.Team, *model.AppError) {
   220  	result := <-a.Srv.Store.Token().GetByToken(tokenId)
   221  	if result.Err != nil {
   222  		return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_invalid.app_error", nil, result.Err.Error(), http.StatusBadRequest)
   223  	}
   224  
   225  	token := result.Data.(*model.Token)
   226  	if token.Type != TOKEN_TYPE_TEAM_INVITATION {
   227  		return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_invalid.app_error", nil, "", http.StatusBadRequest)
   228  	}
   229  
   230  	if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME {
   231  		a.DeleteToken(token)
   232  		return nil, model.NewAppError("AddUserToTeamByToken", "api.user.create_user.signup_link_expired.app_error", nil, "", http.StatusBadRequest)
   233  	}
   234  
   235  	tokenData := model.MapFromJson(strings.NewReader(token.Extra))
   236  
   237  	tchan := a.Srv.Store.Team().Get(tokenData["teamId"])
   238  	uchan := a.Srv.Store.User().Get(userId)
   239  
   240  	var team *model.Team
   241  	if result := <-tchan; result.Err != nil {
   242  		return nil, result.Err
   243  	} else {
   244  		team = result.Data.(*model.Team)
   245  	}
   246  
   247  	var user *model.User
   248  	if result := <-uchan; result.Err != nil {
   249  		return nil, result.Err
   250  	} else {
   251  		user = result.Data.(*model.User)
   252  	}
   253  
   254  	if err := a.JoinUserToTeam(team, user, ""); err != nil {
   255  		return nil, err
   256  	}
   257  
   258  	if err := a.DeleteToken(token); err != nil {
   259  		return nil, err
   260  	}
   261  
   262  	return team, nil
   263  }
   264  
   265  func (a *App) AddUserToTeamByInviteId(inviteId string, userId string) (*model.Team, *model.AppError) {
   266  	tchan := a.Srv.Store.Team().GetByInviteId(inviteId)
   267  	uchan := a.Srv.Store.User().Get(userId)
   268  
   269  	var team *model.Team
   270  	if result := <-tchan; result.Err != nil {
   271  		return nil, result.Err
   272  	} else {
   273  		team = result.Data.(*model.Team)
   274  	}
   275  
   276  	var user *model.User
   277  	if result := <-uchan; result.Err != nil {
   278  		return nil, result.Err
   279  	} else {
   280  		user = result.Data.(*model.User)
   281  	}
   282  
   283  	if err := a.JoinUserToTeam(team, user, ""); err != nil {
   284  		return nil, err
   285  	}
   286  
   287  	return team, nil
   288  }
   289  
   290  // Returns three values:
   291  // 1. a pointer to the team member, if successful
   292  // 2. a boolean: true if the user has a non-deleted team member for that team already, otherwise false.
   293  // 3. a pointer to an AppError if something went wrong.
   294  func (a *App) joinUserToTeam(team *model.Team, user *model.User) (*model.TeamMember, bool, *model.AppError) {
   295  	tm := &model.TeamMember{
   296  		TeamId: team.Id,
   297  		UserId: user.Id,
   298  		Roles:  model.TEAM_USER_ROLE_ID,
   299  	}
   300  
   301  	if team.Email == user.Email {
   302  		tm.Roles = model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID
   303  	}
   304  
   305  	if etmr := <-a.Srv.Store.Team().GetMember(team.Id, user.Id); etmr.Err == nil {
   306  		// Membership already exists.  Check if deleted and and update, otherwise do nothing
   307  		rtm := etmr.Data.(*model.TeamMember)
   308  
   309  		// Do nothing if already added
   310  		if rtm.DeleteAt == 0 {
   311  			return rtm, true, nil
   312  		}
   313  
   314  		if membersCount := <-a.Srv.Store.Team().GetActiveMemberCount(tm.TeamId); membersCount.Err != nil {
   315  			return nil, false, membersCount.Err
   316  		} else if membersCount.Data.(int64) >= int64(*a.Config().TeamSettings.MaxUsersPerTeam) {
   317  			return nil, false, model.NewAppError("joinUserToTeam", "app.team.join_user_to_team.max_accounts.app_error", nil, "teamId="+tm.TeamId, http.StatusBadRequest)
   318  		} else {
   319  			if tmr := <-a.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
   320  				return nil, false, tmr.Err
   321  			} else {
   322  				return tmr.Data.(*model.TeamMember), false, nil
   323  			}
   324  		}
   325  	} else {
   326  		// Membership appears to be missing.  Lets try to add.
   327  		if tmr := <-a.Srv.Store.Team().SaveMember(tm, *a.Config().TeamSettings.MaxUsersPerTeam); tmr.Err != nil {
   328  			return nil, false, tmr.Err
   329  		} else {
   330  			return tmr.Data.(*model.TeamMember), false, nil
   331  		}
   332  	}
   333  }
   334  
   335  func (a *App) JoinUserToTeam(team *model.Team, user *model.User, userRequestorId string) *model.AppError {
   336  	if _, alreadyAdded, err := a.joinUserToTeam(team, user); err != nil {
   337  		return err
   338  	} else if alreadyAdded {
   339  		return nil
   340  	}
   341  
   342  	if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil {
   343  		return uua.Err
   344  	}
   345  
   346  	channelRole := model.CHANNEL_USER_ROLE_ID
   347  
   348  	if team.Email == user.Email {
   349  		channelRole = model.CHANNEL_USER_ROLE_ID + " " + model.CHANNEL_ADMIN_ROLE_ID
   350  	}
   351  
   352  	// Soft error if there is an issue joining the default channels
   353  	if err := a.JoinDefaultChannels(team.Id, user, channelRole, userRequestorId); err != nil {
   354  		mlog.Error(fmt.Sprintf("Encountered an issue joining default channels user_id=%s, team_id=%s, err=%v", user.Id, team.Id, err), mlog.String("user_id", user.Id))
   355  	}
   356  
   357  	a.ClearSessionCacheForUser(user.Id)
   358  	a.InvalidateCacheForUser(user.Id)
   359  
   360  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", user.Id, nil)
   361  	message.Add("team_id", team.Id)
   362  	message.Add("user_id", user.Id)
   363  	a.Publish(message)
   364  
   365  	return nil
   366  }
   367  
   368  func (a *App) GetTeam(teamId string) (*model.Team, *model.AppError) {
   369  	if result := <-a.Srv.Store.Team().Get(teamId); result.Err != nil {
   370  		return nil, result.Err
   371  	} else {
   372  		return result.Data.(*model.Team), nil
   373  	}
   374  }
   375  
   376  func (a *App) GetTeamByName(name string) (*model.Team, *model.AppError) {
   377  	if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil {
   378  		result.Err.StatusCode = http.StatusNotFound
   379  		return nil, result.Err
   380  	} else {
   381  		return result.Data.(*model.Team), nil
   382  	}
   383  }
   384  
   385  func (a *App) GetTeamByInviteId(inviteId string) (*model.Team, *model.AppError) {
   386  	if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
   387  		return nil, result.Err
   388  	} else {
   389  		return result.Data.(*model.Team), nil
   390  	}
   391  }
   392  
   393  func (a *App) GetAllTeams() ([]*model.Team, *model.AppError) {
   394  	if result := <-a.Srv.Store.Team().GetAll(); result.Err != nil {
   395  		return nil, result.Err
   396  	} else {
   397  		return result.Data.([]*model.Team), nil
   398  	}
   399  }
   400  
   401  func (a *App) GetAllTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
   402  	if result := <-a.Srv.Store.Team().GetAllPage(offset, limit); result.Err != nil {
   403  		return nil, result.Err
   404  	} else {
   405  		return result.Data.([]*model.Team), nil
   406  	}
   407  }
   408  
   409  func (a *App) GetAllOpenTeams() ([]*model.Team, *model.AppError) {
   410  	if result := <-a.Srv.Store.Team().GetAllTeamListing(); result.Err != nil {
   411  		return nil, result.Err
   412  	} else {
   413  		return result.Data.([]*model.Team), nil
   414  	}
   415  }
   416  
   417  func (a *App) SearchAllTeams(term string) ([]*model.Team, *model.AppError) {
   418  	if result := <-a.Srv.Store.Team().SearchAll(term); result.Err != nil {
   419  		return nil, result.Err
   420  	} else {
   421  		return result.Data.([]*model.Team), nil
   422  	}
   423  }
   424  
   425  func (a *App) SearchOpenTeams(term string) ([]*model.Team, *model.AppError) {
   426  	if result := <-a.Srv.Store.Team().SearchOpen(term); result.Err != nil {
   427  		return nil, result.Err
   428  	} else {
   429  		return result.Data.([]*model.Team), nil
   430  	}
   431  }
   432  
   433  func (a *App) GetAllOpenTeamsPage(offset int, limit int) ([]*model.Team, *model.AppError) {
   434  	if result := <-a.Srv.Store.Team().GetAllTeamPageListing(offset, limit); result.Err != nil {
   435  		return nil, result.Err
   436  	} else {
   437  		return result.Data.([]*model.Team), nil
   438  	}
   439  }
   440  
   441  func (a *App) GetTeamsForUser(userId string) ([]*model.Team, *model.AppError) {
   442  	if result := <-a.Srv.Store.Team().GetTeamsByUserId(userId); result.Err != nil {
   443  		return nil, result.Err
   444  	} else {
   445  		return result.Data.([]*model.Team), nil
   446  	}
   447  }
   448  
   449  func (a *App) GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) {
   450  	if result := <-a.Srv.Store.Team().GetMember(teamId, userId); result.Err != nil {
   451  		return nil, result.Err
   452  	} else {
   453  		return result.Data.(*model.TeamMember), nil
   454  	}
   455  }
   456  
   457  func (a *App) GetTeamMembersForUser(userId string) ([]*model.TeamMember, *model.AppError) {
   458  	if result := <-a.Srv.Store.Team().GetTeamsForUser(userId); result.Err != nil {
   459  		return nil, result.Err
   460  	} else {
   461  		return result.Data.([]*model.TeamMember), nil
   462  	}
   463  }
   464  
   465  func (a *App) GetTeamMembers(teamId string, offset int, limit int) ([]*model.TeamMember, *model.AppError) {
   466  	if result := <-a.Srv.Store.Team().GetMembers(teamId, offset, limit); result.Err != nil {
   467  		return nil, result.Err
   468  	} else {
   469  		return result.Data.([]*model.TeamMember), nil
   470  	}
   471  }
   472  
   473  func (a *App) GetTeamMembersByIds(teamId string, userIds []string) ([]*model.TeamMember, *model.AppError) {
   474  	if result := <-a.Srv.Store.Team().GetMembersByIds(teamId, userIds); result.Err != nil {
   475  		return nil, result.Err
   476  	} else {
   477  		return result.Data.([]*model.TeamMember), nil
   478  	}
   479  }
   480  
   481  func (a *App) AddTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) {
   482  	if _, err := a.AddUserToTeam(teamId, userId, ""); err != nil {
   483  		return nil, err
   484  	}
   485  
   486  	var teamMember *model.TeamMember
   487  	var err *model.AppError
   488  	if teamMember, err = a.GetTeamMember(teamId, userId); err != nil {
   489  		return nil, err
   490  	}
   491  
   492  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil)
   493  	message.Add("team_id", teamId)
   494  	message.Add("user_id", userId)
   495  	a.Publish(message)
   496  
   497  	return teamMember, nil
   498  }
   499  
   500  func (a *App) AddTeamMembers(teamId string, userIds []string, userRequestorId string) ([]*model.TeamMember, *model.AppError) {
   501  	var members []*model.TeamMember
   502  
   503  	for _, userId := range userIds {
   504  		if _, err := a.AddUserToTeam(teamId, userId, userRequestorId); err != nil {
   505  			return nil, err
   506  		}
   507  
   508  		if teamMember, err := a.GetTeamMember(teamId, userId); err != nil {
   509  			return nil, err
   510  		} else {
   511  			members = append(members, teamMember)
   512  		}
   513  
   514  		message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_ADDED_TO_TEAM, "", "", userId, nil)
   515  		message.Add("team_id", teamId)
   516  		message.Add("user_id", userId)
   517  		a.Publish(message)
   518  	}
   519  
   520  	return members, nil
   521  }
   522  
   523  func (a *App) AddTeamMemberByToken(userId, tokenId string) (*model.TeamMember, *model.AppError) {
   524  	var team *model.Team
   525  	var err *model.AppError
   526  
   527  	if team, err = a.AddUserToTeamByToken(userId, tokenId); err != nil {
   528  		return nil, err
   529  	}
   530  
   531  	if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil {
   532  		return nil, err
   533  	} else {
   534  		return teamMember, nil
   535  	}
   536  }
   537  
   538  func (a *App) AddTeamMemberByInviteId(inviteId, userId string) (*model.TeamMember, *model.AppError) {
   539  	var team *model.Team
   540  	var err *model.AppError
   541  
   542  	if team, err = a.AddUserToTeamByInviteId(inviteId, userId); err != nil {
   543  		return nil, err
   544  	}
   545  
   546  	if teamMember, err := a.GetTeamMember(team.Id, userId); err != nil {
   547  		return nil, err
   548  	} else {
   549  		return teamMember, nil
   550  	}
   551  }
   552  
   553  func (a *App) GetTeamUnread(teamId, userId string) (*model.TeamUnread, *model.AppError) {
   554  	result := <-a.Srv.Store.Team().GetChannelUnreadsForTeam(teamId, userId)
   555  	if result.Err != nil {
   556  		return nil, result.Err
   557  	}
   558  
   559  	channelUnreads := result.Data.([]*model.ChannelUnread)
   560  	var teamUnread = &model.TeamUnread{
   561  		MsgCount:     0,
   562  		MentionCount: 0,
   563  		TeamId:       teamId,
   564  	}
   565  
   566  	for _, cu := range channelUnreads {
   567  		teamUnread.MentionCount += cu.MentionCount
   568  
   569  		if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION {
   570  			teamUnread.MsgCount += cu.MsgCount
   571  		}
   572  	}
   573  
   574  	return teamUnread, nil
   575  }
   576  
   577  func (a *App) RemoveUserFromTeam(teamId string, userId string, requestorId string) *model.AppError {
   578  	tchan := a.Srv.Store.Team().Get(teamId)
   579  	uchan := a.Srv.Store.User().Get(userId)
   580  
   581  	var team *model.Team
   582  	if result := <-tchan; result.Err != nil {
   583  		return result.Err
   584  	} else {
   585  		team = result.Data.(*model.Team)
   586  	}
   587  
   588  	var user *model.User
   589  	if result := <-uchan; result.Err != nil {
   590  		return result.Err
   591  	} else {
   592  		user = result.Data.(*model.User)
   593  	}
   594  
   595  	if err := a.LeaveTeam(team, user, requestorId); err != nil {
   596  		return err
   597  	}
   598  
   599  	return nil
   600  }
   601  
   602  func (a *App) LeaveTeam(team *model.Team, user *model.User, requestorId string) *model.AppError {
   603  	var teamMember *model.TeamMember
   604  	var err *model.AppError
   605  
   606  	if teamMember, err = a.GetTeamMember(team.Id, user.Id); err != nil {
   607  		return model.NewAppError("LeaveTeam", "api.team.remove_user_from_team.missing.app_error", nil, err.Error(), http.StatusBadRequest)
   608  	}
   609  
   610  	var channelList *model.ChannelList
   611  
   612  	if result := <-a.Srv.Store.Channel().GetChannels(team.Id, user.Id); result.Err != nil {
   613  		if result.Err.Id == "store.sql_channel.get_channels.not_found.app_error" {
   614  			channelList = &model.ChannelList{}
   615  		} else {
   616  			return result.Err
   617  		}
   618  
   619  	} else {
   620  		channelList = result.Data.(*model.ChannelList)
   621  	}
   622  
   623  	for _, channel := range *channelList {
   624  		if !channel.IsGroupOrDirect() {
   625  			a.InvalidateCacheForChannelMembers(channel.Id)
   626  			if result := <-a.Srv.Store.Channel().RemoveMember(channel.Id, user.Id); result.Err != nil {
   627  				return result.Err
   628  			}
   629  		}
   630  	}
   631  
   632  	var channel *model.Channel
   633  	if result := <-a.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, false); result.Err != nil {
   634  		return result.Err
   635  	} else {
   636  		channel = result.Data.(*model.Channel)
   637  	}
   638  
   639  	if *a.Config().ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages {
   640  		if requestorId == user.Id {
   641  			if err := a.postLeaveTeamMessage(user, channel); err != nil {
   642  				mlog.Error(fmt.Sprint("Failed to post join/leave message", err))
   643  			}
   644  		}
   645  	}
   646  
   647  	// Send the websocket message before we actually do the remove so the user being removed gets it.
   648  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_LEAVE_TEAM, team.Id, "", "", nil)
   649  	message.Add("user_id", user.Id)
   650  	message.Add("team_id", team.Id)
   651  	a.Publish(message)
   652  
   653  	teamMember.Roles = ""
   654  	teamMember.DeleteAt = model.GetMillis()
   655  
   656  	if result := <-a.Srv.Store.Team().UpdateMember(teamMember); result.Err != nil {
   657  		return result.Err
   658  	}
   659  
   660  	if uua := <-a.Srv.Store.User().UpdateUpdateAt(user.Id); uua.Err != nil {
   661  		return uua.Err
   662  	}
   663  
   664  	// delete the preferences that set the last channel used in the team and other team specific preferences
   665  	if result := <-a.Srv.Store.Preference().DeleteCategory(user.Id, team.Id); result.Err != nil {
   666  		return result.Err
   667  	}
   668  
   669  	a.ClearSessionCacheForUser(user.Id)
   670  	a.InvalidateCacheForUser(user.Id)
   671  
   672  	return nil
   673  }
   674  
   675  func (a *App) postLeaveTeamMessage(user *model.User, channel *model.Channel) *model.AppError {
   676  	post := &model.Post{
   677  		ChannelId: channel.Id,
   678  		Message:   fmt.Sprintf(utils.T("api.team.leave.left"), user.Username),
   679  		Type:      model.POST_LEAVE_TEAM,
   680  		UserId:    user.Id,
   681  		Props: model.StringInterface{
   682  			"username": user.Username,
   683  		},
   684  	}
   685  
   686  	if _, err := a.CreatePost(post, channel, false); err != nil {
   687  		return model.NewAppError("postRemoveFromChannelMessage", "api.channel.post_user_add_remove_message_and_forget.error", nil, err.Error(), http.StatusInternalServerError)
   688  	}
   689  
   690  	return nil
   691  }
   692  
   693  func (a *App) InviteNewUsersToTeam(emailList []string, teamId, senderId string) *model.AppError {
   694  	if len(emailList) == 0 {
   695  		err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.no_one.app_error", nil, "", http.StatusBadRequest)
   696  		return err
   697  	}
   698  
   699  	var invalidEmailList []string
   700  
   701  	for _, email := range emailList {
   702  		if !a.isTeamEmailAddressAllowed(email) {
   703  			invalidEmailList = append(invalidEmailList, email)
   704  		}
   705  	}
   706  
   707  	if len(invalidEmailList) > 0 {
   708  		s := strings.Join(invalidEmailList, ", ")
   709  		err := model.NewAppError("InviteNewUsersToTeam", "api.team.invite_members.invalid_email.app_error", map[string]interface{}{"Addresses": s}, "", http.StatusBadRequest)
   710  		return err
   711  	}
   712  
   713  	tchan := a.Srv.Store.Team().Get(teamId)
   714  	uchan := a.Srv.Store.User().Get(senderId)
   715  
   716  	var team *model.Team
   717  	if result := <-tchan; result.Err != nil {
   718  		return result.Err
   719  	} else {
   720  		team = result.Data.(*model.Team)
   721  	}
   722  
   723  	var user *model.User
   724  	if result := <-uchan; result.Err != nil {
   725  		return result.Err
   726  	} else {
   727  		user = result.Data.(*model.User)
   728  	}
   729  
   730  	nameFormat := *a.Config().TeamSettings.TeammateNameDisplay
   731  	a.SendInviteEmails(team, user.GetDisplayName(nameFormat), emailList, a.GetSiteURL())
   732  
   733  	return nil
   734  }
   735  
   736  func (a *App) FindTeamByName(name string) bool {
   737  	if result := <-a.Srv.Store.Team().GetByName(name); result.Err != nil {
   738  		return false
   739  	} else {
   740  		return true
   741  	}
   742  }
   743  
   744  func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userId string) ([]*model.TeamUnread, *model.AppError) {
   745  	if result := <-a.Srv.Store.Team().GetChannelUnreadsForAllTeams(excludeTeamId, userId); result.Err != nil {
   746  		return nil, result.Err
   747  	} else {
   748  		data := result.Data.([]*model.ChannelUnread)
   749  		members := []*model.TeamUnread{}
   750  		membersMap := make(map[string]*model.TeamUnread)
   751  
   752  		unreads := func(cu *model.ChannelUnread, tu *model.TeamUnread) *model.TeamUnread {
   753  			tu.MentionCount += cu.MentionCount
   754  
   755  			if cu.NotifyProps["mark_unread"] != model.CHANNEL_MARK_UNREAD_MENTION {
   756  				tu.MsgCount += cu.MsgCount
   757  			}
   758  
   759  			return tu
   760  		}
   761  
   762  		for i := range data {
   763  			id := data[i].TeamId
   764  			if mu, ok := membersMap[id]; ok {
   765  				membersMap[id] = unreads(data[i], mu)
   766  			} else {
   767  				membersMap[id] = unreads(data[i], &model.TeamUnread{
   768  					MsgCount:     0,
   769  					MentionCount: 0,
   770  					TeamId:       id,
   771  				})
   772  			}
   773  		}
   774  
   775  		for _, val := range membersMap {
   776  			members = append(members, val)
   777  		}
   778  
   779  		return members, nil
   780  	}
   781  }
   782  
   783  func (a *App) PermanentDeleteTeamId(teamId string) *model.AppError {
   784  	team, err := a.GetTeam(teamId)
   785  	if err != nil {
   786  		return err
   787  	}
   788  
   789  	return a.PermanentDeleteTeam(team)
   790  }
   791  
   792  func (a *App) PermanentDeleteTeam(team *model.Team) *model.AppError {
   793  	team.DeleteAt = model.GetMillis()
   794  	if result := <-a.Srv.Store.Team().Update(team); result.Err != nil {
   795  		return result.Err
   796  	}
   797  
   798  	if result := <-a.Srv.Store.Channel().GetTeamChannels(team.Id); result.Err != nil {
   799  		if result.Err.Id != "store.sql_channel.get_channels.not_found.app_error" {
   800  			return result.Err
   801  		}
   802  	} else {
   803  		channels := result.Data.(*model.ChannelList)
   804  		for _, c := range *channels {
   805  			a.PermanentDeleteChannel(c)
   806  		}
   807  	}
   808  
   809  	if result := <-a.Srv.Store.Team().RemoveAllMembersByTeam(team.Id); result.Err != nil {
   810  		return result.Err
   811  	}
   812  
   813  	if result := <-a.Srv.Store.Command().PermanentDeleteByTeam(team.Id); result.Err != nil {
   814  		return result.Err
   815  	}
   816  
   817  	if result := <-a.Srv.Store.Team().PermanentDelete(team.Id); result.Err != nil {
   818  		return result.Err
   819  	}
   820  
   821  	a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM)
   822  
   823  	return nil
   824  }
   825  
   826  func (a *App) SoftDeleteTeam(teamId string) *model.AppError {
   827  	team, err := a.GetTeam(teamId)
   828  	if err != nil {
   829  		return err
   830  	}
   831  
   832  	team.DeleteAt = model.GetMillis()
   833  	if result := <-a.Srv.Store.Team().Update(team); result.Err != nil {
   834  		return result.Err
   835  	}
   836  
   837  	a.sendTeamEvent(team, model.WEBSOCKET_EVENT_DELETE_TEAM)
   838  
   839  	return nil
   840  }
   841  
   842  func (a *App) GetTeamStats(teamId string) (*model.TeamStats, *model.AppError) {
   843  	tchan := a.Srv.Store.Team().GetTotalMemberCount(teamId)
   844  	achan := a.Srv.Store.Team().GetActiveMemberCount(teamId)
   845  
   846  	stats := &model.TeamStats{}
   847  	stats.TeamId = teamId
   848  
   849  	if result := <-tchan; result.Err != nil {
   850  		return nil, result.Err
   851  	} else {
   852  		stats.TotalMemberCount = result.Data.(int64)
   853  	}
   854  
   855  	if result := <-achan; result.Err != nil {
   856  		return nil, result.Err
   857  	} else {
   858  		stats.ActiveMemberCount = result.Data.(int64)
   859  	}
   860  
   861  	return stats, nil
   862  }
   863  
   864  func (a *App) GetTeamIdFromQuery(query url.Values) (string, *model.AppError) {
   865  	tokenId := query.Get("t")
   866  	inviteId := query.Get("id")
   867  
   868  	if len(tokenId) > 0 {
   869  		result := <-a.Srv.Store.Token().GetByToken(tokenId)
   870  		if result.Err != nil {
   871  			return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "", http.StatusBadRequest)
   872  		}
   873  
   874  		token := result.Data.(*model.Token)
   875  		if token.Type != TOKEN_TYPE_TEAM_INVITATION {
   876  			return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.invalid_link.app_error", nil, "", http.StatusBadRequest)
   877  		}
   878  
   879  		if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME {
   880  			a.DeleteToken(token)
   881  			return "", model.NewAppError("GetTeamIdFromQuery", "api.oauth.singup_with_oauth.expired_link.app_error", nil, "", http.StatusBadRequest)
   882  		}
   883  
   884  		tokenData := model.MapFromJson(strings.NewReader(token.Extra))
   885  
   886  		return tokenData["teamId"], nil
   887  	} else if len(inviteId) > 0 {
   888  		if result := <-a.Srv.Store.Team().GetByInviteId(inviteId); result.Err != nil {
   889  			// soft fail, so we still create user but don't auto-join team
   890  			mlog.Error(fmt.Sprintf("%v", result.Err))
   891  		} else {
   892  			return result.Data.(*model.Team).Id, nil
   893  		}
   894  	}
   895  
   896  	return "", nil
   897  }
   898  
   899  func (a *App) SanitizeTeam(session model.Session, team *model.Team) *model.Team {
   900  	if !a.SessionHasPermissionToTeam(session, team.Id, model.PERMISSION_MANAGE_TEAM) {
   901  		team.Sanitize()
   902  	}
   903  
   904  	return team
   905  }
   906  
   907  func (a *App) SanitizeTeams(session model.Session, teams []*model.Team) []*model.Team {
   908  	for _, team := range teams {
   909  		a.SanitizeTeam(session, team)
   910  	}
   911  
   912  	return teams
   913  }
   914  
   915  func (a *App) GetTeamIcon(team *model.Team) ([]byte, *model.AppError) {
   916  	if len(*a.Config().FileSettings.DriverName) == 0 {
   917  		return nil, model.NewAppError("GetTeamIcon", "api.team.get_team_icon.filesettings_no_driver.app_error", nil, "", http.StatusNotImplemented)
   918  	} else {
   919  		path := "teams/" + team.Id + "/teamIcon.png"
   920  		if data, err := a.ReadFile(path); err != nil {
   921  			return nil, model.NewAppError("GetTeamIcon", "api.team.get_team_icon.read_file.app_error", nil, err.Error(), http.StatusNotFound)
   922  		} else {
   923  			return data, nil
   924  		}
   925  	}
   926  }
   927  
   928  func (a *App) SetTeamIcon(teamId string, imageData *multipart.FileHeader) *model.AppError {
   929  	file, err := imageData.Open()
   930  	if err != nil {
   931  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.open.app_error", nil, err.Error(), http.StatusBadRequest)
   932  	}
   933  	defer file.Close()
   934  	return a.SetTeamIconFromFile(teamId, file)
   935  }
   936  
   937  func (a *App) SetTeamIconFromFile(teamId string, file multipart.File) *model.AppError {
   938  
   939  	team, getTeamErr := a.GetTeam(teamId)
   940  
   941  	if getTeamErr != nil {
   942  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.get_team.app_error", nil, getTeamErr.Error(), http.StatusBadRequest)
   943  	}
   944  
   945  	if len(*a.Config().FileSettings.DriverName) == 0 {
   946  		return model.NewAppError("setTeamIcon", "api.team.set_team_icon.storage.app_error", nil, "", http.StatusNotImplemented)
   947  	}
   948  
   949  	// Decode image config first to check dimensions before loading the whole thing into memory later on
   950  	config, _, err := image.DecodeConfig(file)
   951  	if err != nil {
   952  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.decode_config.app_error", nil, err.Error(), http.StatusBadRequest)
   953  	} else if config.Width*config.Height > model.MaxImageSize {
   954  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.too_large.app_error", nil, err.Error(), http.StatusBadRequest)
   955  	}
   956  
   957  	file.Seek(0, 0)
   958  
   959  	// Decode image into Image object
   960  	img, _, err := image.Decode(file)
   961  	if err != nil {
   962  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.decode.app_error", nil, err.Error(), http.StatusBadRequest)
   963  	}
   964  
   965  	file.Seek(0, 0)
   966  
   967  	orientation, _ := getImageOrientation(file)
   968  	img = makeImageUpright(img, orientation)
   969  
   970  	// Scale team icon
   971  	teamIconWidthAndHeight := 128
   972  	img = imaging.Fill(img, teamIconWidthAndHeight, teamIconWidthAndHeight, imaging.Center, imaging.Lanczos)
   973  
   974  	buf := new(bytes.Buffer)
   975  	err = png.Encode(buf, img)
   976  	if err != nil {
   977  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.encode.app_error", nil, err.Error(), http.StatusInternalServerError)
   978  	}
   979  
   980  	path := "teams/" + teamId + "/teamIcon.png"
   981  
   982  	if _, err := a.WriteFile(buf, path); err != nil {
   983  		return model.NewAppError("SetTeamIcon", "api.team.set_team_icon.write_file.app_error", nil, "", http.StatusInternalServerError)
   984  	}
   985  
   986  	curTime := model.GetMillis()
   987  
   988  	if result := <-a.Srv.Store.Team().UpdateLastTeamIconUpdate(teamId, curTime); result.Err != nil {
   989  		return model.NewAppError("SetTeamIcon", "api.team.team_icon.update.app_error", nil, result.Err.Error(), http.StatusBadRequest)
   990  	}
   991  
   992  	// manually set time to avoid possible cluster inconsistencies
   993  	team.LastTeamIconUpdate = curTime
   994  
   995  	a.sendTeamEvent(team, model.WEBSOCKET_EVENT_UPDATE_TEAM)
   996  
   997  	return nil
   998  }
   999  
  1000  func (a *App) RemoveTeamIcon(teamId string) *model.AppError {
  1001  	team, err := a.GetTeam(teamId)
  1002  	if err != nil {
  1003  		return model.NewAppError("RemoveTeamIcon", "api.team.remove_team_icon.get_team.app_error", nil, err.Error(), http.StatusBadRequest)
  1004  	}
  1005  
  1006  	if result := <-a.Srv.Store.Team().UpdateLastTeamIconUpdate(teamId, 0); result.Err != nil {
  1007  		return model.NewAppError("RemoveTeamIcon", "api.team.team_icon.update.app_error", nil, result.Err.Error(), http.StatusBadRequest)
  1008  	}
  1009  
  1010  	team.LastTeamIconUpdate = 0
  1011  
  1012  	a.sendTeamEvent(team, model.WEBSOCKET_EVENT_UPDATE_TEAM)
  1013  
  1014  	return nil
  1015  }