github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/app/user.go (about)

     1  // Copyright (c) 2016-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"bytes"
     8  	b64 "encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    11  	"hash/fnv"
    12  	"image"
    13  	"image/color"
    14  	"image/draw"
    15  	_ "image/gif"
    16  	_ "image/jpeg"
    17  	"image/png"
    18  	"io"
    19  	"io/ioutil"
    20  	"mime/multipart"
    21  	"net/http"
    22  	"path/filepath"
    23  	"strconv"
    24  	"strings"
    25  
    26  	"github.com/disintegration/imaging"
    27  	"github.com/golang/freetype"
    28  	"github.com/golang/freetype/truetype"
    29  	"github.com/xzl8028/xenia-server/einterfaces"
    30  	"github.com/xzl8028/xenia-server/mlog"
    31  	"github.com/xzl8028/xenia-server/model"
    32  	"github.com/xzl8028/xenia-server/plugin"
    33  	"github.com/xzl8028/xenia-server/services/mfa"
    34  	"github.com/xzl8028/xenia-server/store"
    35  	"github.com/xzl8028/xenia-server/utils"
    36  	"github.com/xzl8028/xenia-server/utils/fileutils"
    37  )
    38  
    39  const (
    40  	TOKEN_TYPE_PASSWORD_RECOVERY  = "password_recovery"
    41  	TOKEN_TYPE_VERIFY_EMAIL       = "verify_email"
    42  	TOKEN_TYPE_TEAM_INVITATION    = "team_invitation"
    43  	PASSWORD_RECOVER_EXPIRY_TIME  = 1000 * 60 * 60      // 1 hour
    44  	TEAM_INVITATION_EXPIRY_TIME   = 1000 * 60 * 60 * 48 // 48 hours
    45  	IMAGE_PROFILE_PIXEL_DIMENSION = 128
    46  )
    47  
    48  func (a *App) CreateUserWithToken(user *model.User, tokenId string) (*model.User, *model.AppError) {
    49  	if err := a.IsUserSignUpAllowed(); err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	token, err := a.Srv.Store.Token().GetByToken(tokenId)
    54  	if err != nil {
    55  		return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, err.Error(), http.StatusBadRequest)
    56  	}
    57  
    58  	if token.Type != TOKEN_TYPE_TEAM_INVITATION {
    59  		return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, "", http.StatusBadRequest)
    60  	}
    61  
    62  	if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME {
    63  		a.DeleteToken(token)
    64  		return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_expired.app_error", nil, "", http.StatusBadRequest)
    65  	}
    66  
    67  	tokenData := model.MapFromJson(strings.NewReader(token.Extra))
    68  
    69  	team, err := a.Srv.Store.Team().Get(tokenData["teamId"])
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	user.Email = tokenData["email"]
    75  	user.EmailVerified = true
    76  
    77  	ruser, err := a.CreateUser(user)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	if err := a.JoinUserToTeam(team, ruser, ""); err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	a.AddDirectChannels(team.Id, ruser)
    87  
    88  	if err := a.DeleteToken(token); err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	return ruser, nil
    93  }
    94  
    95  func (a *App) CreateUserWithInviteId(user *model.User, inviteId string) (*model.User, *model.AppError) {
    96  	if err := a.IsUserSignUpAllowed(); err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	team, err := a.Srv.Store.Team().GetByInviteId(inviteId)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	if team.IsGroupConstrained() {
   106  		return nil, model.NewAppError("CreateUserWithInviteId", "app.team.invite_id.group_constrained.error", nil, "", http.StatusForbidden)
   107  	}
   108  
   109  	user.EmailVerified = false
   110  
   111  	ruser, err := a.CreateUser(user)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	if err := a.JoinUserToTeam(team, ruser, ""); err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	a.AddDirectChannels(team.Id, ruser)
   121  
   122  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   123  		mlog.Error(err.Error())
   124  	}
   125  
   126  	return ruser, nil
   127  }
   128  
   129  func (a *App) CreateUserAsAdmin(user *model.User) (*model.User, *model.AppError) {
   130  	ruser, err := a.CreateUser(user)
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  
   135  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   136  		mlog.Error(err.Error())
   137  	}
   138  
   139  	return ruser, nil
   140  }
   141  
   142  func (a *App) CreateUserFromSignup(user *model.User) (*model.User, *model.AppError) {
   143  	if err := a.IsUserSignUpAllowed(); err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	if !a.IsFirstUserAccount() && !*a.Config().TeamSettings.EnableOpenServer {
   148  		err := model.NewAppError("CreateUserFromSignup", "api.user.create_user.no_open_server", nil, "email="+user.Email, http.StatusForbidden)
   149  		return nil, err
   150  	}
   151  
   152  	user.EmailVerified = false
   153  
   154  	ruser, err := a.CreateUser(user)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   160  		mlog.Error(err.Error())
   161  	}
   162  
   163  	return ruser, nil
   164  }
   165  
   166  func (a *App) IsUserSignUpAllowed() *model.AppError {
   167  	if !*a.Config().EmailSettings.EnableSignUpWithEmail || !*a.Config().TeamSettings.EnableUserCreation {
   168  		err := model.NewAppError("IsUserSignUpAllowed", "api.user.create_user.signup_email_disabled.app_error", nil, "", http.StatusNotImplemented)
   169  		return err
   170  	}
   171  	return nil
   172  }
   173  
   174  func (a *App) IsFirstUserAccount() bool {
   175  	if a.SessionCacheLength() == 0 {
   176  		count, err := a.Srv.Store.User().Count(model.UserCountOptions{IncludeDeleted: true})
   177  		if err != nil {
   178  			mlog.Error(fmt.Sprint(err))
   179  			return false
   180  		}
   181  		if count <= 0 {
   182  			return true
   183  		}
   184  	}
   185  
   186  	return false
   187  }
   188  
   189  // indexUser fetches the required information to index a user from the database and
   190  // calls the elasticsearch interface method
   191  func (a *App) indexUser(user *model.User) *model.AppError {
   192  	userTeams := <-a.Srv.Store.Team().GetTeamsByUserId(user.Id)
   193  	if userTeams.Err != nil {
   194  		return userTeams.Err
   195  	}
   196  
   197  	userTeamsIds := []string{}
   198  	for _, team := range userTeams.Data.([]*model.Team) {
   199  		userTeamsIds = append(userTeamsIds, team.Id)
   200  	}
   201  
   202  	userChannelMembers, err := a.Srv.Store.Channel().GetAllChannelMembersForUser(user.Id, false, true)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	userChannelsIds := []string{}
   208  	for channelId := range userChannelMembers {
   209  		userChannelsIds = append(userChannelsIds, channelId)
   210  	}
   211  
   212  	return a.Elasticsearch.IndexUser(user, userTeamsIds, userChannelsIds)
   213  }
   214  
   215  func (a *App) indexUserFromId(userId string) *model.AppError {
   216  	user, err := a.GetUser(userId)
   217  	if err != nil {
   218  		return err
   219  	}
   220  	return a.indexUser(user)
   221  }
   222  
   223  // CreateUser creates a user and sets several fields of the returned User struct to
   224  // their zero values.
   225  func (a *App) CreateUser(user *model.User) (*model.User, *model.AppError) {
   226  	return a.createUserOrGuest(user, false)
   227  }
   228  
   229  // CreateGuest creates a guest and sets several fields of the returned User struct to
   230  // their zero values.
   231  func (a *App) CreateGuest(user *model.User) (*model.User, *model.AppError) {
   232  	return a.createUserOrGuest(user, true)
   233  }
   234  
   235  func (a *App) createUserOrGuest(user *model.User, guest bool) (*model.User, *model.AppError) {
   236  	if !user.IsLDAPUser() && !user.IsSAMLUser() && !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) {
   237  		return nil, model.NewAppError("CreateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
   238  	}
   239  
   240  	user.Roles = model.SYSTEM_USER_ROLE_ID
   241  	if guest {
   242  		user.Roles = model.SYSTEM_GUEST_ROLE_ID
   243  	}
   244  
   245  	// Below is a special case where the first user in the entire
   246  	// system is granted the system_admin role
   247  	count, err := a.Srv.Store.User().Count(model.UserCountOptions{IncludeDeleted: true})
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	if count <= 0 {
   252  		user.Roles = model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID
   253  	}
   254  
   255  	if _, ok := utils.GetSupportedLocales()[user.Locale]; !ok {
   256  		user.Locale = *a.Config().LocalizationSettings.DefaultClientLocale
   257  	}
   258  
   259  	ruser, err := a.createUser(user)
   260  	if err != nil {
   261  		return nil, err
   262  	}
   263  	// This message goes to everyone, so the teamId, channelId and userId are irrelevant
   264  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_NEW_USER, "", "", "", nil)
   265  	message.Add("user_id", ruser.Id)
   266  	a.Publish(message)
   267  
   268  	if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil {
   269  		a.Srv.Go(func() {
   270  			pluginContext := a.PluginContext()
   271  			pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
   272  				hooks.UserHasBeenCreated(pluginContext, user)
   273  				return true
   274  			}, plugin.UserHasBeenCreatedId)
   275  		})
   276  	}
   277  
   278  	if a.IsESIndexingEnabled() {
   279  		a.Srv.Go(func() {
   280  			if err := a.indexUser(user); err != nil {
   281  				mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err))
   282  			}
   283  		})
   284  	}
   285  
   286  	return ruser, nil
   287  }
   288  
   289  func (a *App) createUser(user *model.User) (*model.User, *model.AppError) {
   290  	user.MakeNonNil()
   291  
   292  	if err := a.IsPasswordValid(user.Password); user.AuthService == "" && err != nil {
   293  		return nil, err
   294  	}
   295  
   296  	result := <-a.Srv.Store.User().Save(user)
   297  	if result.Err != nil {
   298  		mlog.Error(fmt.Sprintf("Couldn't save the user err=%v", result.Err))
   299  		return nil, result.Err
   300  	}
   301  	ruser := result.Data.(*model.User)
   302  
   303  	if user.EmailVerified {
   304  		if err := a.VerifyUserEmail(ruser.Id, user.Email); err != nil {
   305  			mlog.Error(fmt.Sprintf("Failed to set email verified err=%v", err))
   306  		}
   307  	}
   308  
   309  	pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
   310  	if err := a.Srv.Store.Preference().Save(&model.Preferences{pref}); err != nil {
   311  		mlog.Error(fmt.Sprintf("Encountered error saving tutorial preference, err=%v", err.Message))
   312  	}
   313  
   314  	ruser.Sanitize(map[string]bool{})
   315  	return ruser, nil
   316  }
   317  
   318  func (a *App) CreateOAuthUser(service string, userData io.Reader, teamId string) (*model.User, *model.AppError) {
   319  	if !*a.Config().TeamSettings.EnableUserCreation {
   320  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_user.disabled.app_error", nil, "", http.StatusNotImplemented)
   321  	}
   322  
   323  	provider := einterfaces.GetOauthProvider(service)
   324  	if provider == nil {
   325  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.not_available.app_error", map[string]interface{}{"Service": strings.Title(service)}, "", http.StatusNotImplemented)
   326  	}
   327  	user := provider.GetUserFromJson(userData)
   328  
   329  	if user == nil {
   330  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.create.app_error", map[string]interface{}{"Service": service}, "", http.StatusInternalServerError)
   331  	}
   332  
   333  	suchan := make(chan store.StoreResult, 1)
   334  	euchan := make(chan store.StoreResult, 1)
   335  	go func() {
   336  		userByAuth, err := a.Srv.Store.User().GetByAuth(user.AuthData, service)
   337  		suchan <- store.StoreResult{Data: userByAuth, Err: err}
   338  		close(suchan)
   339  	}()
   340  	go func() {
   341  		userByEmail, err := a.Srv.Store.User().GetByEmail(user.Email)
   342  		euchan <- store.StoreResult{Data: userByEmail, Err: err}
   343  		close(euchan)
   344  	}()
   345  
   346  	found := true
   347  	count := 0
   348  	for found {
   349  		if found = a.IsUsernameTaken(user.Username); found {
   350  			user.Username = user.Username + strconv.Itoa(count)
   351  			count++
   352  		}
   353  	}
   354  
   355  	if result := <-suchan; result.Err == nil {
   356  		return result.Data.(*model.User), nil
   357  	}
   358  
   359  	if result := <-euchan; result.Err == nil {
   360  		authService := result.Data.(*model.User).AuthService
   361  		if authService == "" {
   362  			return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.already_attached.app_error", map[string]interface{}{"Service": service, "Auth": model.USER_AUTH_SERVICE_EMAIL}, "email="+user.Email, http.StatusBadRequest)
   363  		}
   364  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.already_attached.app_error", map[string]interface{}{"Service": service, "Auth": authService}, "email="+user.Email, http.StatusBadRequest)
   365  	}
   366  
   367  	user.EmailVerified = true
   368  
   369  	ruser, err := a.CreateUser(user)
   370  	if err != nil {
   371  		return nil, err
   372  	}
   373  
   374  	if len(teamId) > 0 {
   375  		err = a.AddUserToTeamByTeamId(teamId, user)
   376  		if err != nil {
   377  			return nil, err
   378  		}
   379  
   380  		err = a.AddDirectChannels(teamId, user)
   381  		if err != nil {
   382  			mlog.Error(err.Error())
   383  		}
   384  	}
   385  
   386  	return ruser, nil
   387  }
   388  
   389  // CheckUserDomain checks that a user's email domain matches a list of space-delimited domains as a string.
   390  func CheckUserDomain(user *model.User, domains string) bool {
   391  	if len(domains) == 0 {
   392  		return true
   393  	}
   394  
   395  	domainArray := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1))))
   396  
   397  	for _, d := range domainArray {
   398  		if strings.HasSuffix(strings.ToLower(user.Email), "@"+d) {
   399  			return true
   400  		}
   401  	}
   402  
   403  	return false
   404  }
   405  
   406  // IsUsernameTaken checks if the username is already used by another user. Return false if the username is invalid.
   407  func (a *App) IsUsernameTaken(name string) bool {
   408  	if !model.IsValidUsername(name) {
   409  		return false
   410  	}
   411  
   412  	if result := <-a.Srv.Store.User().GetByUsername(name); result.Err != nil {
   413  		return false
   414  	}
   415  
   416  	return true
   417  }
   418  
   419  func (a *App) GetUser(userId string) (*model.User, *model.AppError) {
   420  	return a.Srv.Store.User().Get(userId)
   421  }
   422  
   423  func (a *App) GetUserByUsername(username string) (*model.User, *model.AppError) {
   424  	result := <-a.Srv.Store.User().GetByUsername(username)
   425  	if result.Err != nil && result.Err.Id == "store.sql_user.get_by_username.app_error" {
   426  		result.Err.StatusCode = http.StatusNotFound
   427  		return nil, result.Err
   428  	}
   429  	return result.Data.(*model.User), nil
   430  }
   431  
   432  func (a *App) GetUserByEmail(email string) (*model.User, *model.AppError) {
   433  	user, err := a.Srv.Store.User().GetByEmail(email)
   434  	if err != nil {
   435  		if err.Id == "store.sql_user.missing_account.const" {
   436  			err.StatusCode = http.StatusNotFound
   437  			return nil, err
   438  		}
   439  		err.StatusCode = http.StatusBadRequest
   440  		return nil, err
   441  	}
   442  	return user, nil
   443  }
   444  
   445  func (a *App) GetUserByAuth(authData *string, authService string) (*model.User, *model.AppError) {
   446  	return a.Srv.Store.User().GetByAuth(authData, authService)
   447  }
   448  
   449  func (a *App) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   450  	result := <-a.Srv.Store.User().GetAllProfiles(options)
   451  	if result.Err != nil {
   452  		return nil, result.Err
   453  	}
   454  	return result.Data.([]*model.User), nil
   455  }
   456  
   457  func (a *App) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
   458  	users, err := a.GetUsers(options)
   459  	if err != nil {
   460  		return nil, err
   461  	}
   462  
   463  	return a.sanitizeProfiles(users, asAdmin), nil
   464  }
   465  
   466  func (a *App) GetUsersEtag(restrictionsHash string) string {
   467  	return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForAllProfiles()).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   468  }
   469  
   470  func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   471  	result := <-a.Srv.Store.User().GetProfiles(options)
   472  	if result.Err != nil {
   473  		return nil, result.Err
   474  	}
   475  	return result.Data.([]*model.User), nil
   476  }
   477  
   478  func (a *App) GetUsersNotInTeam(teamId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   479  	result := <-a.Srv.Store.User().GetProfilesNotInTeam(teamId, groupConstrained, offset, limit, viewRestrictions)
   480  	if result.Err != nil {
   481  		return nil, result.Err
   482  	}
   483  	return result.Data.([]*model.User), nil
   484  }
   485  
   486  func (a *App) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
   487  	users, err := a.GetUsersInTeam(options)
   488  	if err != nil {
   489  		return nil, err
   490  	}
   491  
   492  	return a.sanitizeProfiles(users, asAdmin), nil
   493  }
   494  
   495  func (a *App) GetUsersNotInTeamPage(teamId string, groupConstrained bool, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   496  	users, err := a.GetUsersNotInTeam(teamId, groupConstrained, page*perPage, perPage, viewRestrictions)
   497  	if err != nil {
   498  		return nil, err
   499  	}
   500  
   501  	return a.sanitizeProfiles(users, asAdmin), nil
   502  }
   503  
   504  func (a *App) GetUsersInTeamEtag(teamId string, restrictionsHash string) string {
   505  	return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   506  }
   507  
   508  func (a *App) GetUsersNotInTeamEtag(teamId string, restrictionsHash string) string {
   509  	return fmt.Sprintf("%v.%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfilesNotInTeam(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress, restrictionsHash)
   510  }
   511  
   512  func (a *App) GetUsersInChannel(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   513  	result := <-a.Srv.Store.User().GetProfilesInChannel(channelId, offset, limit)
   514  	if result.Err != nil {
   515  		return nil, result.Err
   516  	}
   517  	return result.Data.([]*model.User), nil
   518  }
   519  
   520  func (a *App) GetUsersInChannelByStatus(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   521  	result := <-a.Srv.Store.User().GetProfilesInChannelByStatus(channelId, offset, limit)
   522  	if result.Err != nil {
   523  		return nil, result.Err
   524  	}
   525  	return result.Data.([]*model.User), nil
   526  }
   527  
   528  func (a *App) GetUsersInChannelMap(channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) {
   529  	users, err := a.GetUsersInChannel(channelId, offset, limit)
   530  	if err != nil {
   531  		return nil, err
   532  	}
   533  
   534  	userMap := make(map[string]*model.User, len(users))
   535  
   536  	for _, user := range users {
   537  		a.SanitizeProfile(user, asAdmin)
   538  		userMap[user.Id] = user
   539  	}
   540  
   541  	return userMap, nil
   542  }
   543  
   544  func (a *App) GetUsersInChannelPage(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   545  	users, err := a.GetUsersInChannel(channelId, page*perPage, perPage)
   546  	if err != nil {
   547  		return nil, err
   548  	}
   549  	return a.sanitizeProfiles(users, asAdmin), nil
   550  }
   551  
   552  func (a *App) GetUsersInChannelPageByStatus(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   553  	users, err := a.GetUsersInChannelByStatus(channelId, page*perPage, perPage)
   554  	if err != nil {
   555  		return nil, err
   556  	}
   557  	return a.sanitizeProfiles(users, asAdmin), nil
   558  }
   559  
   560  func (a *App) GetUsersNotInChannel(teamId string, channelId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   561  	result := <-a.Srv.Store.User().GetProfilesNotInChannel(teamId, channelId, groupConstrained, offset, limit, viewRestrictions)
   562  	if result.Err != nil {
   563  		return nil, result.Err
   564  	}
   565  	return result.Data.([]*model.User), nil
   566  }
   567  
   568  func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, groupConstrained bool, offset int, limit int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) (map[string]*model.User, *model.AppError) {
   569  	users, err := a.GetUsersNotInChannel(teamId, channelId, groupConstrained, offset, limit, viewRestrictions)
   570  	if err != nil {
   571  		return nil, err
   572  	}
   573  
   574  	userMap := make(map[string]*model.User, len(users))
   575  
   576  	for _, user := range users {
   577  		a.SanitizeProfile(user, asAdmin)
   578  		userMap[user.Id] = user
   579  	}
   580  
   581  	return userMap, nil
   582  }
   583  
   584  func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, groupConstrained bool, page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   585  	users, err := a.GetUsersNotInChannel(teamId, channelId, groupConstrained, page*perPage, perPage, viewRestrictions)
   586  	if err != nil {
   587  		return nil, err
   588  	}
   589  
   590  	return a.sanitizeProfiles(users, asAdmin), nil
   591  }
   592  
   593  func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   594  	users, err := a.GetUsersWithoutTeam(page*perPage, perPage, viewRestrictions)
   595  	if err != nil {
   596  		return nil, err
   597  	}
   598  
   599  	return a.sanitizeProfiles(users, asAdmin), nil
   600  }
   601  
   602  func (a *App) GetUsersWithoutTeam(offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   603  	result := <-a.Srv.Store.User().GetProfilesWithoutTeam(offset, limit, viewRestrictions)
   604  	if result.Err != nil {
   605  		return nil, result.Err
   606  	}
   607  	return result.Data.([]*model.User), nil
   608  }
   609  
   610  // GetTeamGroupUsers returns the users who are associated to the team via GroupTeams and GroupMembers.
   611  func (a *App) GetTeamGroupUsers(teamID string) ([]*model.User, *model.AppError) {
   612  	return a.Srv.Store.User().GetTeamGroupUsers(teamID)
   613  }
   614  
   615  // GetChannelGroupUsers returns the users who are associated to the channel via GroupChannels and GroupMembers.
   616  func (a *App) GetChannelGroupUsers(channelID string) ([]*model.User, *model.AppError) {
   617  	return a.Srv.Store.User().GetChannelGroupUsers(channelID)
   618  }
   619  
   620  func (a *App) GetUsersByIds(userIds []string, options *store.UserGetByIdsOpts) ([]*model.User, *model.AppError) {
   621  	allowFromCache := options.ViewRestrictions == nil
   622  
   623  	result := <-a.Srv.Store.User().GetProfileByIds(userIds, options, allowFromCache)
   624  	if result.Err != nil {
   625  		return nil, result.Err
   626  	}
   627  
   628  	return a.sanitizeProfiles(result.Data.([]*model.User), options.IsAdmin), nil
   629  }
   630  
   631  func (a *App) GetUsersByGroupChannelIds(channelIds []string, asAdmin bool) (map[string][]*model.User, *model.AppError) {
   632  	usersByChannelId, err := a.Srv.Store.User().GetProfileByGroupChannelIdsForUser(a.Session.UserId, channelIds)
   633  	if err != nil {
   634  		return nil, err
   635  	}
   636  	for channelId, userList := range usersByChannelId {
   637  		usersByChannelId[channelId] = a.sanitizeProfiles(userList, asAdmin)
   638  	}
   639  
   640  	return usersByChannelId, nil
   641  }
   642  
   643  func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   644  	result := <-a.Srv.Store.User().GetProfilesByUsernames(usernames, viewRestrictions)
   645  	if result.Err != nil {
   646  		return nil, result.Err
   647  	}
   648  	return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil
   649  }
   650  
   651  func (a *App) sanitizeProfiles(users []*model.User, asAdmin bool) []*model.User {
   652  	for _, u := range users {
   653  		a.SanitizeProfile(u, asAdmin)
   654  	}
   655  
   656  	return users
   657  }
   658  
   659  func (a *App) GenerateMfaSecret(userId string) (*model.MfaSecret, *model.AppError) {
   660  	user, err := a.GetUser(userId)
   661  	if err != nil {
   662  		return nil, err
   663  	}
   664  
   665  	mfaService := mfa.New(a, a.Srv.Store)
   666  	secret, img, err := mfaService.GenerateSecret(user)
   667  	if err != nil {
   668  		return nil, err
   669  	}
   670  
   671  	mfaSecret := &model.MfaSecret{Secret: secret, QRCode: b64.StdEncoding.EncodeToString(img)}
   672  	return mfaSecret, nil
   673  }
   674  
   675  func (a *App) ActivateMfa(userId, token string) *model.AppError {
   676  	user, err := a.Srv.Store.User().Get(userId)
   677  	if err != nil {
   678  		return err
   679  	}
   680  
   681  	if len(user.AuthService) > 0 && user.AuthService != model.USER_AUTH_SERVICE_LDAP {
   682  		return model.NewAppError("ActivateMfa", "api.user.activate_mfa.email_and_ldap_only.app_error", nil, "", http.StatusBadRequest)
   683  	}
   684  
   685  	mfaService := mfa.New(a, a.Srv.Store)
   686  	if err := mfaService.Activate(user, token); err != nil {
   687  		return err
   688  	}
   689  
   690  	return nil
   691  }
   692  
   693  func (a *App) DeactivateMfa(userId string) *model.AppError {
   694  	mfaService := mfa.New(a, a.Srv.Store)
   695  	if err := mfaService.Deactivate(userId); err != nil {
   696  		return err
   697  	}
   698  
   699  	return nil
   700  }
   701  
   702  func CreateProfileImage(username string, userId string, initialFont string) ([]byte, *model.AppError) {
   703  	colors := []color.NRGBA{
   704  		{197, 8, 126, 255},
   705  		{227, 207, 18, 255},
   706  		{28, 181, 105, 255},
   707  		{35, 188, 224, 255},
   708  		{116, 49, 196, 255},
   709  		{197, 8, 126, 255},
   710  		{197, 19, 19, 255},
   711  		{250, 134, 6, 255},
   712  		{227, 207, 18, 255},
   713  		{123, 201, 71, 255},
   714  		{28, 181, 105, 255},
   715  		{35, 188, 224, 255},
   716  		{116, 49, 196, 255},
   717  		{197, 8, 126, 255},
   718  		{197, 19, 19, 255},
   719  		{250, 134, 6, 255},
   720  		{227, 207, 18, 255},
   721  		{123, 201, 71, 255},
   722  		{28, 181, 105, 255},
   723  		{35, 188, 224, 255},
   724  		{116, 49, 196, 255},
   725  		{197, 8, 126, 255},
   726  		{197, 19, 19, 255},
   727  		{250, 134, 6, 255},
   728  		{227, 207, 18, 255},
   729  		{123, 201, 71, 255},
   730  	}
   731  
   732  	h := fnv.New32a()
   733  	h.Write([]byte(userId))
   734  	seed := h.Sum32()
   735  
   736  	initial := string(strings.ToUpper(username)[0])
   737  
   738  	font, err := getFont(initialFont)
   739  	if err != nil {
   740  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error(), http.StatusInternalServerError)
   741  	}
   742  
   743  	color := colors[int64(seed)%int64(len(colors))]
   744  	dstImg := image.NewRGBA(image.Rect(0, 0, IMAGE_PROFILE_PIXEL_DIMENSION, IMAGE_PROFILE_PIXEL_DIMENSION))
   745  	srcImg := image.White
   746  	draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.ZP, draw.Src)
   747  	size := float64(IMAGE_PROFILE_PIXEL_DIMENSION / 2)
   748  
   749  	c := freetype.NewContext()
   750  	c.SetFont(font)
   751  	c.SetFontSize(size)
   752  	c.SetClip(dstImg.Bounds())
   753  	c.SetDst(dstImg)
   754  	c.SetSrc(srcImg)
   755  
   756  	pt := freetype.Pt(IMAGE_PROFILE_PIXEL_DIMENSION/5, IMAGE_PROFILE_PIXEL_DIMENSION*2/3)
   757  	_, err = c.DrawString(initial, pt)
   758  	if err != nil {
   759  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.initial.app_error", nil, err.Error(), http.StatusInternalServerError)
   760  	}
   761  
   762  	buf := new(bytes.Buffer)
   763  
   764  	if imgErr := png.Encode(buf, dstImg); imgErr != nil {
   765  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.encode.app_error", nil, imgErr.Error(), http.StatusInternalServerError)
   766  	}
   767  	return buf.Bytes(), nil
   768  }
   769  
   770  func getFont(initialFont string) (*truetype.Font, error) {
   771  	// Some people have the old default font still set, so just treat that as if they're using the new default
   772  	if initialFont == "luximbi.ttf" {
   773  		initialFont = "nunito-bold.ttf"
   774  	}
   775  
   776  	fontDir, _ := fileutils.FindDir("fonts")
   777  	fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont))
   778  	if err != nil {
   779  		return nil, err
   780  	}
   781  
   782  	return freetype.ParseFont(fontBytes)
   783  }
   784  
   785  func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
   786  	if len(*a.Config().FileSettings.DriverName) == 0 {
   787  		img, appErr := a.GetDefaultProfileImage(user)
   788  		if appErr != nil {
   789  			return nil, false, appErr
   790  		}
   791  		return img, false, nil
   792  	}
   793  
   794  	path := "users/" + user.Id + "/profile.png"
   795  
   796  	data, err := a.ReadFile(path)
   797  	if err != nil {
   798  		img, appErr := a.GetDefaultProfileImage(user)
   799  		if appErr != nil {
   800  			return nil, false, appErr
   801  		}
   802  
   803  		if user.LastPictureUpdate == 0 {
   804  			if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil {
   805  				return nil, false, err
   806  			}
   807  		}
   808  		return img, true, nil
   809  	}
   810  
   811  	return data, false, nil
   812  }
   813  
   814  func (a *App) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) {
   815  	var img []byte
   816  	var appErr *model.AppError
   817  
   818  	if user.IsBot {
   819  		img = model.BotDefaultImage
   820  		appErr = nil
   821  	} else {
   822  		img, appErr = CreateProfileImage(user.Username, user.Id, *a.Config().FileSettings.InitialFont)
   823  	}
   824  	if appErr != nil {
   825  		return nil, appErr
   826  	}
   827  	return img, nil
   828  }
   829  
   830  func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError {
   831  	img, appErr := a.GetDefaultProfileImage(user)
   832  	if appErr != nil {
   833  		return appErr
   834  	}
   835  
   836  	path := "users/" + user.Id + "/profile.png"
   837  
   838  	if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil {
   839  		return err
   840  	}
   841  
   842  	if err := a.Srv.Store.User().ResetLastPictureUpdate(user.Id); err != nil {
   843  		mlog.Error(err.Error())
   844  	}
   845  
   846  	a.InvalidateCacheForUser(user.Id)
   847  
   848  	updatedUser, appErr := a.GetUser(user.Id)
   849  	if appErr != nil {
   850  		mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", user.Id), mlog.String("user_id", user.Id))
   851  		return nil
   852  	}
   853  
   854  	options := a.Config().GetSanitizeOptions()
   855  	updatedUser.SanitizeProfile(options)
   856  
   857  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
   858  	message.Add("user", updatedUser)
   859  	a.Publish(message)
   860  
   861  	return nil
   862  }
   863  
   864  func (a *App) SetProfileImage(userId string, imageData *multipart.FileHeader) *model.AppError {
   865  	file, err := imageData.Open()
   866  	if err != nil {
   867  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error(), http.StatusBadRequest)
   868  	}
   869  	defer file.Close()
   870  	return a.SetProfileImageFromMultiPartFile(userId, file)
   871  }
   872  
   873  func (a *App) SetProfileImageFromMultiPartFile(userId string, file multipart.File) *model.AppError {
   874  	// Decode image config first to check dimensions before loading the whole thing into memory later on
   875  	config, _, err := image.DecodeConfig(file)
   876  	if err != nil {
   877  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode_config.app_error", nil, err.Error(), http.StatusBadRequest)
   878  	}
   879  	if config.Width*config.Height > model.MaxImageSize {
   880  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, err.Error(), http.StatusBadRequest)
   881  	}
   882  
   883  	file.Seek(0, 0)
   884  
   885  	return a.SetProfileImageFromFile(userId, file)
   886  }
   887  
   888  func (a *App) SetProfileImageFromFile(userId string, file io.Reader) *model.AppError {
   889  
   890  	// Decode image into Image object
   891  	img, _, err := image.Decode(file)
   892  	if err != nil {
   893  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode.app_error", nil, err.Error(), http.StatusBadRequest)
   894  	}
   895  
   896  	orientation, _ := getImageOrientation(file)
   897  	img = makeImageUpright(img, orientation)
   898  
   899  	// Scale profile image
   900  	profileWidthAndHeight := 128
   901  	img = imaging.Fill(img, profileWidthAndHeight, profileWidthAndHeight, imaging.Center, imaging.Lanczos)
   902  
   903  	buf := new(bytes.Buffer)
   904  	err = png.Encode(buf, img)
   905  	if err != nil {
   906  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.encode.app_error", nil, err.Error(), http.StatusInternalServerError)
   907  	}
   908  
   909  	path := "users/" + userId + "/profile.png"
   910  
   911  	if _, err := a.WriteFile(buf, path); err != nil {
   912  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.upload_profile.app_error", nil, "", http.StatusInternalServerError)
   913  	}
   914  
   915  	<-a.Srv.Store.User().UpdateLastPictureUpdate(userId)
   916  
   917  	a.InvalidateCacheForUser(userId)
   918  
   919  	user, userErr := a.GetUser(userId)
   920  	if userErr != nil {
   921  		mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", userId), mlog.String("user_id", userId))
   922  		return nil
   923  	}
   924  
   925  	options := a.Config().GetSanitizeOptions()
   926  	user.SanitizeProfile(options)
   927  
   928  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
   929  	message.Add("user", user)
   930  	a.Publish(message)
   931  
   932  	return nil
   933  }
   934  
   935  func (a *App) UpdatePasswordAsUser(userId, currentPassword, newPassword string) *model.AppError {
   936  	user, err := a.GetUser(userId)
   937  	if err != nil {
   938  		return err
   939  	}
   940  
   941  	if user == nil {
   942  		err = model.NewAppError("updatePassword", "api.user.update_password.valid_account.app_error", nil, "", http.StatusBadRequest)
   943  		return err
   944  	}
   945  
   946  	if user.AuthData != nil && *user.AuthData != "" {
   947  		err = model.NewAppError("updatePassword", "api.user.update_password.oauth.app_error", nil, "auth_service="+user.AuthService, http.StatusBadRequest)
   948  		return err
   949  	}
   950  
   951  	if err := a.DoubleCheckPassword(user, currentPassword); err != nil {
   952  		if err.Id == "api.user.check_user_password.invalid.app_error" {
   953  			err = model.NewAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "", http.StatusBadRequest)
   954  		}
   955  		return err
   956  	}
   957  
   958  	T := utils.GetUserTranslations(user.Locale)
   959  
   960  	return a.UpdatePasswordSendEmail(user, newPassword, T("api.user.update_password.menu"))
   961  }
   962  
   963  func (a *App) userDeactivated(user *model.User) *model.AppError {
   964  	if err := a.RevokeAllSessions(user.Id); err != nil {
   965  		return err
   966  	}
   967  
   968  	a.SetStatusOffline(user.Id, false)
   969  
   970  	if *a.Config().ServiceSettings.DisableBotsWhenOwnerIsDeactivated {
   971  		a.disableUserBots(user.Id)
   972  	}
   973  
   974  	return nil
   975  }
   976  
   977  func (a *App) invalidateUserChannelMembersCaches(user *model.User) *model.AppError {
   978  	teamsForUser, err := a.GetTeamsForUser(user.Id)
   979  	if err != nil {
   980  		return err
   981  	}
   982  
   983  	for _, team := range teamsForUser {
   984  		channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id, false)
   985  		if err != nil {
   986  			return err
   987  		}
   988  
   989  		for _, channel := range *channelsForUser {
   990  			a.InvalidateCacheForChannelMembers(channel.Id)
   991  		}
   992  	}
   993  
   994  	return nil
   995  }
   996  
   997  func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.AppError) {
   998  	if active {
   999  		user.DeleteAt = 0
  1000  	} else {
  1001  		user.DeleteAt = model.GetMillis()
  1002  	}
  1003  
  1004  	userUpdate, err := a.Srv.Store.User().Update(user, true)
  1005  	if err != nil {
  1006  		return nil, err
  1007  	}
  1008  	ruser := userUpdate.New
  1009  
  1010  	if !active {
  1011  		if err := a.userDeactivated(ruser); err != nil {
  1012  			return nil, err
  1013  		}
  1014  	}
  1015  
  1016  	a.invalidateUserChannelMembersCaches(user)
  1017  
  1018  	a.sendUpdatedUserEvent(*ruser)
  1019  
  1020  	return ruser, nil
  1021  }
  1022  
  1023  func (a *App) GetSanitizeOptions(asAdmin bool) map[string]bool {
  1024  	options := a.Config().GetSanitizeOptions()
  1025  	if asAdmin {
  1026  		options["email"] = true
  1027  		options["fullname"] = true
  1028  		options["authservice"] = true
  1029  	}
  1030  	return options
  1031  }
  1032  
  1033  func (a *App) SanitizeProfile(user *model.User, asAdmin bool) {
  1034  	options := a.GetSanitizeOptions(asAdmin)
  1035  
  1036  	user.SanitizeProfile(options)
  1037  }
  1038  
  1039  func (a *App) UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) {
  1040  	updatedUser, err := a.UpdateUser(user, true)
  1041  	if err != nil {
  1042  		return nil, err
  1043  	}
  1044  
  1045  	a.sendUpdatedUserEvent(*updatedUser)
  1046  
  1047  	return updatedUser, nil
  1048  }
  1049  
  1050  func (a *App) PatchUser(userId string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) {
  1051  	user, err := a.GetUser(userId)
  1052  	if err != nil {
  1053  		return nil, err
  1054  	}
  1055  
  1056  	user.Patch(patch)
  1057  
  1058  	updatedUser, err := a.UpdateUser(user, true)
  1059  	if err != nil {
  1060  		return nil, err
  1061  	}
  1062  
  1063  	a.sendUpdatedUserEvent(*updatedUser)
  1064  
  1065  	return updatedUser, nil
  1066  }
  1067  
  1068  func (a *App) UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError) {
  1069  	if userAuth.AuthData == nil || *userAuth.AuthData == "" || userAuth.AuthService == "" {
  1070  		userAuth.AuthData = nil
  1071  		userAuth.AuthService = ""
  1072  
  1073  		if err := a.IsPasswordValid(userAuth.Password); err != nil {
  1074  			return nil, err
  1075  		}
  1076  		password := model.HashPassword(userAuth.Password)
  1077  
  1078  		if result := <-a.Srv.Store.User().UpdatePassword(userId, password); result.Err != nil {
  1079  			return nil, result.Err
  1080  		}
  1081  	} else {
  1082  		userAuth.Password = ""
  1083  
  1084  		if _, err := a.Srv.Store.User().UpdateAuthData(userId, userAuth.AuthService, userAuth.AuthData, "", false); err != nil {
  1085  			return nil, err
  1086  		}
  1087  	}
  1088  
  1089  	return userAuth, nil
  1090  }
  1091  
  1092  func (a *App) sendUpdatedUserEvent(user model.User) {
  1093  	adminCopyOfUser := user.DeepCopy()
  1094  	a.SanitizeProfile(adminCopyOfUser, true)
  1095  	adminMessage := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
  1096  	adminMessage.Add("user", *adminCopyOfUser)
  1097  	adminMessage.Broadcast.ContainsSensitiveData = true
  1098  	a.Publish(adminMessage)
  1099  
  1100  	a.SanitizeProfile(&user, false)
  1101  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
  1102  	message.Add("user", user)
  1103  	message.Broadcast.ContainsSanitizedData = true
  1104  	a.Publish(message)
  1105  }
  1106  
  1107  func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) {
  1108  	prev, err := a.Srv.Store.User().Get(user.Id)
  1109  	if err != nil {
  1110  		return nil, err
  1111  	}
  1112  
  1113  	if !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) {
  1114  		if !prev.IsLDAPUser() && !prev.IsSAMLUser() && user.Email != prev.Email {
  1115  			return nil, model.NewAppError("UpdateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
  1116  		}
  1117  	}
  1118  
  1119  	// Don't set new eMail on user account if email verification is required, this will be done as a post-verification action
  1120  	// to avoid users being able to set non-controlled eMails as their account email
  1121  	newEmail := ""
  1122  	if *a.Config().EmailSettings.RequireEmailVerification && prev.Email != user.Email {
  1123  		newEmail = user.Email
  1124  
  1125  		_, err = a.GetUserByEmail(newEmail)
  1126  		if err == nil {
  1127  			return nil, model.NewAppError("UpdateUser", "store.sql_user.update.email_taken.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
  1128  		}
  1129  
  1130  		user.Email = prev.Email
  1131  	}
  1132  
  1133  	userUpdate, err := a.Srv.Store.User().Update(user, false)
  1134  	if err != nil {
  1135  		return nil, err
  1136  	}
  1137  
  1138  	if sendNotifications {
  1139  		if userUpdate.New.Email != userUpdate.Old.Email || newEmail != "" {
  1140  			if *a.Config().EmailSettings.RequireEmailVerification {
  1141  				a.Srv.Go(func() {
  1142  					if err := a.SendEmailVerification(userUpdate.New, newEmail); err != nil {
  1143  						mlog.Error(err.Error())
  1144  					}
  1145  				})
  1146  			} else {
  1147  				a.Srv.Go(func() {
  1148  					if err := a.SendEmailChangeEmail(userUpdate.Old.Email, userUpdate.New.Email, userUpdate.New.Locale, a.GetSiteURL()); err != nil {
  1149  						mlog.Error(err.Error())
  1150  					}
  1151  				})
  1152  			}
  1153  		}
  1154  
  1155  		if userUpdate.New.Username != userUpdate.Old.Username {
  1156  			a.Srv.Go(func() {
  1157  				if err := a.SendChangeUsernameEmail(userUpdate.Old.Username, userUpdate.New.Username, userUpdate.New.Email, userUpdate.New.Locale, a.GetSiteURL()); err != nil {
  1158  					mlog.Error(err.Error())
  1159  				}
  1160  			})
  1161  		}
  1162  	}
  1163  
  1164  	a.InvalidateCacheForUser(user.Id)
  1165  
  1166  	if a.IsESIndexingEnabled() {
  1167  		a.Srv.Go(func() {
  1168  			if err := a.indexUser(user); err != nil {
  1169  				mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err))
  1170  			}
  1171  		})
  1172  	}
  1173  
  1174  	return userUpdate.New, nil
  1175  }
  1176  
  1177  func (a *App) UpdateUserActive(userId string, active bool) *model.AppError {
  1178  	user, err := a.GetUser(userId)
  1179  
  1180  	if err != nil {
  1181  		return err
  1182  	}
  1183  	if _, err = a.UpdateActive(user, active); err != nil {
  1184  		return err
  1185  	}
  1186  
  1187  	return nil
  1188  }
  1189  
  1190  func (a *App) UpdateUserNotifyProps(userId string, props map[string]string) (*model.User, *model.AppError) {
  1191  	user, err := a.GetUser(userId)
  1192  	if err != nil {
  1193  		return nil, err
  1194  	}
  1195  
  1196  	user.NotifyProps = props
  1197  
  1198  	ruser, err := a.UpdateUser(user, true)
  1199  	if err != nil {
  1200  		return nil, err
  1201  	}
  1202  
  1203  	return ruser, nil
  1204  }
  1205  
  1206  func (a *App) UpdateMfa(activate bool, userId, token string) *model.AppError {
  1207  	if activate {
  1208  		if err := a.ActivateMfa(userId, token); err != nil {
  1209  			return err
  1210  		}
  1211  	} else {
  1212  		if err := a.DeactivateMfa(userId); err != nil {
  1213  			return err
  1214  		}
  1215  	}
  1216  
  1217  	a.Srv.Go(func() {
  1218  		user, err := a.GetUser(userId)
  1219  		if err != nil {
  1220  			mlog.Error(err.Error())
  1221  			return
  1222  		}
  1223  
  1224  		if err := a.SendMfaChangeEmail(user.Email, activate, user.Locale, a.GetSiteURL()); err != nil {
  1225  			mlog.Error(err.Error())
  1226  		}
  1227  	})
  1228  
  1229  	return nil
  1230  }
  1231  
  1232  func (a *App) UpdatePasswordByUserIdSendEmail(userId, newPassword, method string) *model.AppError {
  1233  	user, err := a.GetUser(userId)
  1234  	if err != nil {
  1235  		return err
  1236  	}
  1237  
  1238  	return a.UpdatePasswordSendEmail(user, newPassword, method)
  1239  }
  1240  
  1241  func (a *App) UpdatePassword(user *model.User, newPassword string) *model.AppError {
  1242  	if err := a.IsPasswordValid(newPassword); err != nil {
  1243  		return err
  1244  	}
  1245  
  1246  	hashedPassword := model.HashPassword(newPassword)
  1247  
  1248  	if result := <-a.Srv.Store.User().UpdatePassword(user.Id, hashedPassword); result.Err != nil {
  1249  		return model.NewAppError("UpdatePassword", "api.user.update_password.failed.app_error", nil, result.Err.Error(), http.StatusInternalServerError)
  1250  	}
  1251  
  1252  	return nil
  1253  }
  1254  
  1255  func (a *App) UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError {
  1256  	if err := a.UpdatePassword(user, newPassword); err != nil {
  1257  		return err
  1258  	}
  1259  
  1260  	a.Srv.Go(func() {
  1261  		if err := a.SendPasswordChangeEmail(user.Email, method, user.Locale, a.GetSiteURL()); err != nil {
  1262  			mlog.Error(err.Error())
  1263  		}
  1264  	})
  1265  
  1266  	return nil
  1267  }
  1268  
  1269  func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError {
  1270  	token, err := a.GetPasswordRecoveryToken(userSuppliedTokenString)
  1271  	if err != nil {
  1272  		return err
  1273  	}
  1274  	if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME {
  1275  		return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
  1276  	}
  1277  
  1278  	tokenData := struct {
  1279  		UserId string
  1280  		Email  string
  1281  	}{}
  1282  
  1283  	err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
  1284  	if err2 != nil {
  1285  		return model.NewAppError("resetPassword", "api.user.reset_password.token_parse.error", nil, "", http.StatusInternalServerError)
  1286  	}
  1287  
  1288  	user, err := a.GetUser(tokenData.UserId)
  1289  	if err != nil {
  1290  		return err
  1291  	}
  1292  
  1293  	if user.Email != tokenData.Email {
  1294  		return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
  1295  	}
  1296  
  1297  	if user.IsSSOUser() {
  1298  		return model.NewAppError("ResetPasswordFromCode", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
  1299  	}
  1300  
  1301  	T := utils.GetUserTranslations(user.Locale)
  1302  
  1303  	if err := a.UpdatePasswordSendEmail(user, newPassword, T("api.user.reset_password.method")); err != nil {
  1304  		return err
  1305  	}
  1306  
  1307  	if err := a.DeleteToken(token); err != nil {
  1308  		mlog.Error(err.Error())
  1309  	}
  1310  
  1311  	return nil
  1312  }
  1313  
  1314  func (a *App) SendPasswordReset(email string, siteURL string) (bool, *model.AppError) {
  1315  	user, err := a.GetUserByEmail(email)
  1316  	if err != nil {
  1317  		return false, nil
  1318  	}
  1319  
  1320  	if user.AuthData != nil && len(*user.AuthData) != 0 {
  1321  		return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
  1322  	}
  1323  
  1324  	token, err := a.CreatePasswordRecoveryToken(user.Id, user.Email)
  1325  	if err != nil {
  1326  		return false, err
  1327  	}
  1328  
  1329  	return a.SendPasswordResetEmail(user.Email, token, user.Locale, siteURL)
  1330  }
  1331  
  1332  func (a *App) CreatePasswordRecoveryToken(userId, email string) (*model.Token, *model.AppError) {
  1333  
  1334  	tokenExtra := struct {
  1335  		UserId string
  1336  		Email  string
  1337  	}{
  1338  		userId,
  1339  		email,
  1340  	}
  1341  	jsonData, err := json.Marshal(tokenExtra)
  1342  
  1343  	if err != nil {
  1344  		return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError)
  1345  	}
  1346  
  1347  	token := model.NewToken(TOKEN_TYPE_PASSWORD_RECOVERY, string(jsonData))
  1348  
  1349  	if err := a.Srv.Store.Token().Save(token); err != nil {
  1350  		return nil, err
  1351  	}
  1352  
  1353  	return token, nil
  1354  }
  1355  
  1356  func (a *App) GetPasswordRecoveryToken(token string) (*model.Token, *model.AppError) {
  1357  	rtoken, err := a.Srv.Store.Token().GetByToken(token)
  1358  	if err != nil {
  1359  		return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.invalid_link.app_error", nil, err.Error(), http.StatusBadRequest)
  1360  	}
  1361  	if rtoken.Type != TOKEN_TYPE_PASSWORD_RECOVERY {
  1362  		return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.broken_token.app_error", nil, "", http.StatusBadRequest)
  1363  	}
  1364  	return rtoken, nil
  1365  }
  1366  
  1367  func (a *App) DeleteToken(token *model.Token) *model.AppError {
  1368  	return a.Srv.Store.Token().Delete(token.Token)
  1369  }
  1370  
  1371  func (a *App) UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) {
  1372  	user, err := a.GetUser(userId)
  1373  	if err != nil {
  1374  		err.StatusCode = http.StatusBadRequest
  1375  		return nil, err
  1376  	}
  1377  
  1378  	if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
  1379  		return nil, err
  1380  	}
  1381  
  1382  	user.Roles = newRoles
  1383  	uchan := make(chan store.StoreResult, 1)
  1384  	go func() {
  1385  		userUpdate, err := a.Srv.Store.User().Update(user, true)
  1386  		uchan <- store.StoreResult{Data: userUpdate, Err: err}
  1387  		close(uchan)
  1388  	}()
  1389  
  1390  	schan := make(chan store.StoreResult, 1)
  1391  	go func() {
  1392  		userId, err := a.Srv.Store.Session().UpdateRoles(user.Id, newRoles)
  1393  		schan <- store.StoreResult{Data: userId, Err: err}
  1394  		close(schan)
  1395  	}()
  1396  
  1397  	result := <-uchan
  1398  	if result.Err != nil {
  1399  		return nil, result.Err
  1400  	}
  1401  	ruser := result.Data.(*model.UserUpdate).New
  1402  
  1403  	if result := <-schan; result.Err != nil {
  1404  		// soft error since the user roles were still updated
  1405  		mlog.Error(fmt.Sprint(result.Err))
  1406  	}
  1407  
  1408  	a.ClearSessionCacheForUser(user.Id)
  1409  
  1410  	if sendWebSocketEvent {
  1411  		message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ROLE_UPDATED, "", "", user.Id, nil)
  1412  		message.Add("user_id", user.Id)
  1413  		message.Add("roles", newRoles)
  1414  		a.Publish(message)
  1415  	}
  1416  
  1417  	return ruser, nil
  1418  }
  1419  
  1420  func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
  1421  	mlog.Warn(fmt.Sprintf("Attempting to permanently delete account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id))
  1422  	if user.IsInRole(model.SYSTEM_ADMIN_ROLE_ID) {
  1423  		mlog.Warn(fmt.Sprintf("You are deleting %v that is a system administrator.  You may need to set another account as the system administrator using the command line tools.", user.Email))
  1424  	}
  1425  
  1426  	if _, err := a.UpdateActive(user, false); err != nil {
  1427  		return err
  1428  	}
  1429  
  1430  	if err := a.Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); err != nil {
  1431  		return err
  1432  	}
  1433  
  1434  	if err := a.Srv.Store.UserAccessToken().DeleteAllForUser(user.Id); err != nil {
  1435  		return err
  1436  	}
  1437  
  1438  	if err := a.Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); err != nil {
  1439  		return err
  1440  	}
  1441  
  1442  	if err := a.Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); err != nil {
  1443  		return err
  1444  	}
  1445  
  1446  	if err := a.Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); err != nil {
  1447  		return err
  1448  	}
  1449  
  1450  	if err := a.Srv.Store.Command().PermanentDeleteByUser(user.Id); err != nil {
  1451  		return err
  1452  	}
  1453  
  1454  	if err := a.Srv.Store.Preference().PermanentDeleteByUser(user.Id); err != nil {
  1455  		return err
  1456  	}
  1457  
  1458  	if err := a.Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); err != nil {
  1459  		return err
  1460  	}
  1461  
  1462  	if err := a.Srv.Store.Post().PermanentDeleteByUser(user.Id); err != nil {
  1463  		return err
  1464  	}
  1465  
  1466  	infos, err := a.Srv.Store.FileInfo().GetForUser(user.Id)
  1467  	if err != nil {
  1468  		mlog.Warn("Error getting file list for user from FileInfoStore")
  1469  	}
  1470  
  1471  	for _, info := range infos {
  1472  		res, err := a.FileExists(info.Path)
  1473  		if err != nil {
  1474  			mlog.Warn(
  1475  				"Error checking existence of file",
  1476  				mlog.String("path", info.Path),
  1477  				mlog.Err(err),
  1478  			)
  1479  			continue
  1480  		}
  1481  
  1482  		if !res {
  1483  			mlog.Warn("File not found", mlog.String("path", info.Path))
  1484  			continue
  1485  		}
  1486  
  1487  		err = a.RemoveFile(info.Path)
  1488  
  1489  		if err != nil {
  1490  			mlog.Warn(
  1491  				"Unable to remove file",
  1492  				mlog.String("path", info.Path),
  1493  				mlog.Err(err),
  1494  			)
  1495  		}
  1496  	}
  1497  
  1498  	if _, err := a.Srv.Store.FileInfo().PermanentDeleteByUser(user.Id); err != nil {
  1499  		return err
  1500  	}
  1501  
  1502  	if err := a.Srv.Store.User().PermanentDelete(user.Id); err != nil {
  1503  		return err
  1504  	}
  1505  
  1506  	if err := a.Srv.Store.Audit().PermanentDeleteByUser(user.Id); err != nil {
  1507  		return err
  1508  	}
  1509  
  1510  	if result := <-a.Srv.Store.Team().RemoveAllMembersByUser(user.Id); result.Err != nil {
  1511  		return result.Err
  1512  	}
  1513  
  1514  	mlog.Warn(fmt.Sprintf("Permanently deleted account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id))
  1515  
  1516  	if a.IsESIndexingEnabled() {
  1517  		a.Srv.Go(func() {
  1518  			if err := a.Elasticsearch.DeleteUser(user); err != nil {
  1519  				mlog.Error("Encountered error deleting user", mlog.String("user_id", user.Id), mlog.Err(err))
  1520  			}
  1521  		})
  1522  	}
  1523  
  1524  	return nil
  1525  }
  1526  
  1527  func (a *App) PermanentDeleteAllUsers() *model.AppError {
  1528  	result := <-a.Srv.Store.User().GetAll()
  1529  	if result.Err != nil {
  1530  		return result.Err
  1531  	}
  1532  	users := result.Data.([]*model.User)
  1533  	for _, user := range users {
  1534  		a.PermanentDeleteUser(user)
  1535  	}
  1536  
  1537  	return nil
  1538  }
  1539  
  1540  func (a *App) SendEmailVerification(user *model.User, newEmail string) *model.AppError {
  1541  	token, err := a.CreateVerifyEmailToken(user.Id, newEmail)
  1542  	if err != nil {
  1543  		return err
  1544  	}
  1545  
  1546  	if _, err := a.GetStatus(user.Id); err != nil {
  1547  		return a.SendVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token)
  1548  	}
  1549  	return a.SendEmailChangeVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token)
  1550  }
  1551  
  1552  func (a *App) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError {
  1553  	token, err := a.GetVerifyEmailToken(userSuppliedTokenString)
  1554  	if err != nil {
  1555  		return err
  1556  	}
  1557  	if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME {
  1558  		return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.link_expired.app_error", nil, "", http.StatusBadRequest)
  1559  	}
  1560  
  1561  	tokenData := struct {
  1562  		UserId string
  1563  		Email  string
  1564  	}{}
  1565  
  1566  	err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
  1567  	if err2 != nil {
  1568  		return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.token_parse.error", nil, "", http.StatusInternalServerError)
  1569  	}
  1570  
  1571  	user, err := a.GetUser(tokenData.UserId)
  1572  	if err != nil {
  1573  		return err
  1574  	}
  1575  
  1576  	if err := a.VerifyUserEmail(tokenData.UserId, tokenData.Email); err != nil {
  1577  		return err
  1578  	}
  1579  
  1580  	if user.Email != tokenData.Email {
  1581  		a.Srv.Go(func() {
  1582  			if err := a.SendEmailChangeEmail(user.Email, tokenData.Email, user.Locale, a.GetSiteURL()); err != nil {
  1583  				mlog.Error(err.Error())
  1584  			}
  1585  		})
  1586  	}
  1587  
  1588  	if err := a.DeleteToken(token); err != nil {
  1589  		mlog.Error(err.Error())
  1590  	}
  1591  
  1592  	return nil
  1593  }
  1594  
  1595  func (a *App) CreateVerifyEmailToken(userId string, newEmail string) (*model.Token, *model.AppError) {
  1596  	tokenExtra := struct {
  1597  		UserId string
  1598  		Email  string
  1599  	}{
  1600  		userId,
  1601  		newEmail,
  1602  	}
  1603  	jsonData, err := json.Marshal(tokenExtra)
  1604  
  1605  	if err != nil {
  1606  		return nil, model.NewAppError("CreateVerifyEmailToken", "api.user.create_email_token.error", nil, "", http.StatusInternalServerError)
  1607  	}
  1608  
  1609  	token := model.NewToken(TOKEN_TYPE_VERIFY_EMAIL, string(jsonData))
  1610  
  1611  	if err := a.Srv.Store.Token().Save(token); err != nil {
  1612  		return nil, err
  1613  	}
  1614  
  1615  	return token, nil
  1616  }
  1617  
  1618  func (a *App) GetVerifyEmailToken(token string) (*model.Token, *model.AppError) {
  1619  	rtoken, err := a.Srv.Store.Token().GetByToken(token)
  1620  	if err != nil {
  1621  		return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.bad_link.app_error", nil, err.Error(), http.StatusBadRequest)
  1622  	}
  1623  	if rtoken.Type != TOKEN_TYPE_VERIFY_EMAIL {
  1624  		return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.broken_token.app_error", nil, "", http.StatusBadRequest)
  1625  	}
  1626  	return rtoken, nil
  1627  }
  1628  
  1629  // GetTotalUsersStats is used for the DM list total
  1630  func (a *App) GetTotalUsersStats(viewRestrictions *model.ViewUsersRestrictions) (*model.UsersStats, *model.AppError) {
  1631  	count, err := a.Srv.Store.User().Count(model.UserCountOptions{
  1632  		IncludeBotAccounts: true,
  1633  		ViewRestrictions:   viewRestrictions,
  1634  	})
  1635  	if err != nil {
  1636  		return nil, err
  1637  	}
  1638  	stats := &model.UsersStats{
  1639  		TotalUsersCount: count,
  1640  	}
  1641  	return stats, nil
  1642  }
  1643  
  1644  func (a *App) VerifyUserEmail(userId, email string) *model.AppError {
  1645  	_, err := a.Srv.Store.User().VerifyEmail(userId, email)
  1646  	if err != nil {
  1647  		return err
  1648  	}
  1649  
  1650  	user, err := a.GetUser(userId)
  1651  
  1652  	if err != nil {
  1653  		return err
  1654  	}
  1655  
  1656  	a.sendUpdatedUserEvent(*user)
  1657  
  1658  	return nil
  1659  }
  1660  
  1661  func (a *App) SearchUsers(props *model.UserSearch, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1662  	if props.WithoutTeam {
  1663  		return a.SearchUsersWithoutTeam(props.Term, options)
  1664  	}
  1665  	if props.InChannelId != "" {
  1666  		return a.SearchUsersInChannel(props.InChannelId, props.Term, options)
  1667  	}
  1668  	if props.NotInChannelId != "" {
  1669  		return a.SearchUsersNotInChannel(props.TeamId, props.NotInChannelId, props.Term, options)
  1670  	}
  1671  	if props.NotInTeamId != "" {
  1672  		return a.SearchUsersNotInTeam(props.NotInTeamId, props.Term, options)
  1673  	}
  1674  	return a.SearchUsersInTeam(props.TeamId, props.Term, options)
  1675  }
  1676  
  1677  func (a *App) SearchUsersInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1678  	term = strings.TrimSpace(term)
  1679  	users, err := a.Srv.Store.User().SearchInChannel(channelId, term, options)
  1680  	if err != nil {
  1681  		return nil, err
  1682  	}
  1683  	for _, user := range users {
  1684  		a.SanitizeProfile(user, options.IsAdmin)
  1685  	}
  1686  
  1687  	return users, nil
  1688  }
  1689  
  1690  func (a *App) SearchUsersNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1691  	term = strings.TrimSpace(term)
  1692  	result := <-a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options)
  1693  	if result.Err != nil {
  1694  		return nil, result.Err
  1695  	}
  1696  	users := result.Data.([]*model.User)
  1697  
  1698  	for _, user := range users {
  1699  		a.SanitizeProfile(user, options.IsAdmin)
  1700  	}
  1701  
  1702  	return users, nil
  1703  }
  1704  
  1705  func (a *App) esSearchUsersInTeam(teamId, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1706  	listOfAllowedChannels, err := a.GetViewUsersRestrictionsForTeam(a.Session.UserId, teamId)
  1707  	if err != nil {
  1708  		return nil, err
  1709  	}
  1710  	if listOfAllowedChannels != nil && len(listOfAllowedChannels) == 0 {
  1711  		return []*model.User{}, nil
  1712  	}
  1713  
  1714  	usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
  1715  	if err != nil {
  1716  		return nil, err
  1717  	}
  1718  
  1719  	result := <-a.Srv.Store.User().GetProfileByIds(usersIds, nil, false)
  1720  	if result.Err != nil {
  1721  		return nil, result.Err
  1722  	}
  1723  
  1724  	users := result.Data.([]*model.User)
  1725  
  1726  	for _, user := range users {
  1727  		a.SanitizeProfile(user, options.IsAdmin)
  1728  	}
  1729  
  1730  	return users, nil
  1731  }
  1732  
  1733  func (a *App) SearchUsersInTeam(teamId, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1734  	var users []*model.User
  1735  	var err *model.AppError
  1736  	term = strings.TrimSpace(term)
  1737  
  1738  	if a.IsESAutocompletionEnabled() {
  1739  		users, err = a.esSearchUsersInTeam(teamId, term, options)
  1740  		if err != nil {
  1741  			mlog.Error("Encountered error on SearchUsersInTeam through Elasticsearch. Falling back to default search.", mlog.Err(err))
  1742  		}
  1743  	}
  1744  
  1745  	if !a.IsESAutocompletionEnabled() || err != nil {
  1746  		users, err = a.Srv.Store.User().Search(teamId, term, options)
  1747  		if err != nil {
  1748  			return nil, err
  1749  		}
  1750  
  1751  		for _, user := range users {
  1752  			a.SanitizeProfile(user, options.IsAdmin)
  1753  		}
  1754  	}
  1755  
  1756  	return users, nil
  1757  }
  1758  
  1759  func (a *App) SearchUsersNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1760  	term = strings.TrimSpace(term)
  1761  	users, err := a.Srv.Store.User().SearchNotInTeam(notInTeamId, term, options)
  1762  	if err != nil {
  1763  		return nil, err
  1764  	}
  1765  
  1766  	for _, user := range users {
  1767  		a.SanitizeProfile(user, options.IsAdmin)
  1768  	}
  1769  
  1770  	return users, nil
  1771  }
  1772  
  1773  func (a *App) SearchUsersWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1774  	term = strings.TrimSpace(term)
  1775  	users, err := a.Srv.Store.User().SearchWithoutTeam(term, options)
  1776  	if err != nil {
  1777  		return nil, err
  1778  	}
  1779  
  1780  	for _, user := range users {
  1781  		a.SanitizeProfile(user, options.IsAdmin)
  1782  	}
  1783  
  1784  	return users, nil
  1785  }
  1786  
  1787  func (a *App) esAutocompleteUsersInChannel(teamId, channelId, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInChannel, *model.AppError) {
  1788  	listOfAllowedChannels, err := a.getListOfAllowedChannelsForTeam(teamId, options.ViewRestrictions)
  1789  	if err != nil {
  1790  		return nil, err
  1791  	}
  1792  	if len(listOfAllowedChannels) == 0 {
  1793  		return &model.UserAutocompleteInChannel{}, nil
  1794  	}
  1795  	uchanIds := []string{}
  1796  	nuchanIds := []string{}
  1797  	if !strings.Contains(strings.Join(listOfAllowedChannels, "."), channelId) {
  1798  		nuchanIds, err = a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
  1799  	} else {
  1800  		uchanIds, nuchanIds, err = a.Elasticsearch.SearchUsersInChannel(teamId, channelId, listOfAllowedChannels, term, options)
  1801  	}
  1802  	if err != nil {
  1803  		return nil, err
  1804  	}
  1805  	uchan := a.Srv.Store.User().GetProfileByIds(uchanIds, nil, false)
  1806  	nuchan := a.Srv.Store.User().GetProfileByIds(nuchanIds, nil, false)
  1807  	autocomplete := &model.UserAutocompleteInChannel{}
  1808  
  1809  	result := <-uchan
  1810  	if result.Err != nil {
  1811  		return nil, result.Err
  1812  	}
  1813  	users := result.Data.([]*model.User)
  1814  
  1815  	for _, user := range users {
  1816  		a.SanitizeProfile(user, options.IsAdmin)
  1817  	}
  1818  
  1819  	autocomplete.InChannel = users
  1820  
  1821  	result = <-nuchan
  1822  	if result.Err != nil {
  1823  		return nil, result.Err
  1824  	}
  1825  	users = result.Data.([]*model.User)
  1826  
  1827  	for _, user := range users {
  1828  		a.SanitizeProfile(user, options.IsAdmin)
  1829  	}
  1830  
  1831  	autocomplete.OutOfChannel = users
  1832  
  1833  	return autocomplete, nil
  1834  }
  1835  
  1836  func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInChannel, *model.AppError) {
  1837  	var autocomplete *model.UserAutocompleteInChannel
  1838  	var err *model.AppError
  1839  	term = strings.TrimSpace(term)
  1840  
  1841  	if a.IsESAutocompletionEnabled() {
  1842  		autocomplete, err = a.esAutocompleteUsersInChannel(teamId, channelId, term, options)
  1843  		if err != nil {
  1844  			mlog.Error("Encountered error on AutocompleteUsersInChannel through Elasticsearch. Falling back to default autocompletion.", mlog.Err(err))
  1845  		}
  1846  	}
  1847  
  1848  	if !a.IsESAutocompletionEnabled() || err != nil {
  1849  		autocomplete = &model.UserAutocompleteInChannel{}
  1850  
  1851  		uchan := make(chan store.StoreResult, 1)
  1852  		go func() {
  1853  			users, err := a.Srv.Store.User().SearchInChannel(channelId, term, options)
  1854  			uchan <- store.StoreResult{Data: users, Err: err}
  1855  			close(uchan)
  1856  		}()
  1857  
  1858  		nuchan := a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options)
  1859  
  1860  		result := <-uchan
  1861  		if result.Err != nil {
  1862  			return nil, result.Err
  1863  		}
  1864  
  1865  		users := result.Data.([]*model.User)
  1866  
  1867  		for _, user := range users {
  1868  			a.SanitizeProfile(user, options.IsAdmin)
  1869  		}
  1870  
  1871  		autocomplete.InChannel = users
  1872  
  1873  		result = <-nuchan
  1874  		if result.Err != nil {
  1875  			return nil, result.Err
  1876  		}
  1877  		users = result.Data.([]*model.User)
  1878  
  1879  		for _, user := range users {
  1880  			a.SanitizeProfile(user, options.IsAdmin)
  1881  		}
  1882  
  1883  		autocomplete.OutOfChannel = users
  1884  	}
  1885  
  1886  	return autocomplete, nil
  1887  }
  1888  
  1889  func (a *App) esAutocompleteUsersInTeam(teamId, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInTeam, *model.AppError) {
  1890  	listOfAllowedChannels, err := a.getListOfAllowedChannelsForTeam(teamId, options.ViewRestrictions)
  1891  	if err != nil {
  1892  		return nil, err
  1893  	}
  1894  	if len(listOfAllowedChannels) == 0 {
  1895  		return &model.UserAutocompleteInTeam{}, nil
  1896  	}
  1897  
  1898  	usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, listOfAllowedChannels, term, options)
  1899  	if err != nil {
  1900  		return nil, err
  1901  	}
  1902  
  1903  	result := <-a.Srv.Store.User().GetProfileByIds(usersIds, nil, false)
  1904  	if result.Err != nil {
  1905  		return nil, result.Err
  1906  	}
  1907  
  1908  	users := result.Data.([]*model.User)
  1909  	for _, user := range users {
  1910  		a.SanitizeProfile(user, options.IsAdmin)
  1911  	}
  1912  
  1913  	autocomplete := &model.UserAutocompleteInTeam{}
  1914  	autocomplete.InTeam = users
  1915  
  1916  	return autocomplete, nil
  1917  }
  1918  
  1919  func (a *App) AutocompleteUsersInTeam(teamId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInTeam, *model.AppError) {
  1920  	var autocomplete *model.UserAutocompleteInTeam
  1921  	var err *model.AppError
  1922  
  1923  	term = strings.TrimSpace(term)
  1924  
  1925  	if a.IsESAutocompletionEnabled() {
  1926  		autocomplete, err = a.esAutocompleteUsersInTeam(teamId, term, options)
  1927  		if err != nil {
  1928  			mlog.Error("Encountered error on AutocompleteUsersInTeam through Elasticsearch. Falling back to default autocompletion.", mlog.Err(err))
  1929  		}
  1930  	}
  1931  
  1932  	if !a.IsESAutocompletionEnabled() || err != nil {
  1933  		autocomplete = &model.UserAutocompleteInTeam{}
  1934  		users, err := a.Srv.Store.User().Search(teamId, term, options)
  1935  		if err != nil {
  1936  			return nil, err
  1937  		}
  1938  
  1939  		for _, user := range users {
  1940  			a.SanitizeProfile(user, options.IsAdmin)
  1941  		}
  1942  
  1943  		autocomplete.InTeam = users
  1944  	}
  1945  
  1946  	return autocomplete, nil
  1947  }
  1948  
  1949  func (a *App) UpdateOAuthUserAttrs(userData io.Reader, user *model.User, provider einterfaces.OauthProvider, service string) *model.AppError {
  1950  	oauthUser := provider.GetUserFromJson(userData)
  1951  	if oauthUser == nil {
  1952  		return model.NewAppError("UpdateOAuthUserAttrs", "api.user.update_oauth_user_attrs.get_user.app_error", map[string]interface{}{"Service": service}, "", http.StatusBadRequest)
  1953  	}
  1954  
  1955  	userAttrsChanged := false
  1956  
  1957  	if oauthUser.Username != user.Username {
  1958  		if existingUser, _ := a.GetUserByUsername(oauthUser.Username); existingUser == nil {
  1959  			user.Username = oauthUser.Username
  1960  			userAttrsChanged = true
  1961  		}
  1962  	}
  1963  
  1964  	if oauthUser.GetFullName() != user.GetFullName() {
  1965  		user.FirstName = oauthUser.FirstName
  1966  		user.LastName = oauthUser.LastName
  1967  		userAttrsChanged = true
  1968  	}
  1969  
  1970  	if oauthUser.Email != user.Email {
  1971  		if existingUser, _ := a.GetUserByEmail(oauthUser.Email); existingUser == nil {
  1972  			user.Email = oauthUser.Email
  1973  			userAttrsChanged = true
  1974  		}
  1975  	}
  1976  
  1977  	if user.DeleteAt > 0 {
  1978  		// Make sure they are not disabled
  1979  		user.DeleteAt = 0
  1980  		userAttrsChanged = true
  1981  	}
  1982  
  1983  	if userAttrsChanged {
  1984  		users, err := a.Srv.Store.User().Update(user, true)
  1985  		if err != nil {
  1986  			return err
  1987  		}
  1988  
  1989  		user = users.New
  1990  		a.InvalidateCacheForUser(user.Id)
  1991  
  1992  		if a.IsESIndexingEnabled() {
  1993  			a.Srv.Go(func() {
  1994  				if err := a.indexUser(user); err != nil {
  1995  					mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err))
  1996  				}
  1997  			})
  1998  		}
  1999  	}
  2000  
  2001  	return nil
  2002  }
  2003  
  2004  func (a *App) RestrictUsersGetByPermissions(userId string, options *model.UserGetOptions) (*model.UserGetOptions, *model.AppError) {
  2005  	restrictions, err := a.GetViewUsersRestrictions(userId)
  2006  	if err != nil {
  2007  		return nil, err
  2008  	}
  2009  
  2010  	options.ViewRestrictions = restrictions
  2011  	return options, nil
  2012  }
  2013  
  2014  // FilterNonGroupTeamMembers returns the subset of the given user IDs of the users who are not members of groups
  2015  // associated to the team.
  2016  func (a *App) FilterNonGroupTeamMembers(userIDs []string, team *model.Team) ([]string, error) {
  2017  	teamGroupUsers, err := a.GetTeamGroupUsers(team.Id)
  2018  	if err != nil {
  2019  		return nil, err
  2020  	}
  2021  
  2022  	// possible if no groups associated or no group members in any of the associated groups
  2023  	if len(teamGroupUsers) == 0 {
  2024  		return userIDs, nil
  2025  	}
  2026  
  2027  	nonMemberIDs := []string{}
  2028  
  2029  	for _, userID := range userIDs {
  2030  		userIsMember := false
  2031  
  2032  		for _, pu := range teamGroupUsers {
  2033  			if pu.Id == userID {
  2034  				userIsMember = true
  2035  				break
  2036  			}
  2037  		}
  2038  
  2039  		if !userIsMember {
  2040  			nonMemberIDs = append(nonMemberIDs, userID)
  2041  		}
  2042  	}
  2043  
  2044  	return nonMemberIDs, nil
  2045  }
  2046  
  2047  // FilterNonGroupChannelMembers returns the subset of the given user IDs of the users who are not members of groups
  2048  // associated to the channel.
  2049  func (a *App) FilterNonGroupChannelMembers(userIDs []string, channel *model.Channel) ([]string, error) {
  2050  	channelGroupUsers, err := a.GetChannelGroupUsers(channel.Id)
  2051  	if err != nil {
  2052  		return nil, err
  2053  	}
  2054  
  2055  	// possible if no groups associated or no group members in any of the associated groups
  2056  	if len(channelGroupUsers) == 0 {
  2057  		return userIDs, nil
  2058  	}
  2059  
  2060  	nonMemberIDs := []string{}
  2061  
  2062  	for _, userID := range userIDs {
  2063  		userIsMember := false
  2064  
  2065  		for _, pu := range channelGroupUsers {
  2066  			if pu.Id == userID {
  2067  				userIsMember = true
  2068  				break
  2069  			}
  2070  		}
  2071  
  2072  		if !userIsMember {
  2073  			nonMemberIDs = append(nonMemberIDs, userID)
  2074  		}
  2075  	}
  2076  
  2077  	return nonMemberIDs, nil
  2078  }
  2079  
  2080  func (a *App) RestrictUsersSearchByPermissions(userId string, options *model.UserSearchOptions) (*model.UserSearchOptions, *model.AppError) {
  2081  	restrictions, err := a.GetViewUsersRestrictions(userId)
  2082  	if err != nil {
  2083  		return nil, err
  2084  	}
  2085  
  2086  	options.ViewRestrictions = restrictions
  2087  	return options, nil
  2088  }
  2089  
  2090  func (a *App) UserCanSeeOtherUser(userId string, otherUserId string) (bool, *model.AppError) {
  2091  	if userId == otherUserId {
  2092  		return true, nil
  2093  	}
  2094  
  2095  	restrictions, err := a.GetViewUsersRestrictions(userId)
  2096  	if err != nil {
  2097  		return false, err
  2098  	}
  2099  
  2100  	if restrictions == nil {
  2101  		return true, nil
  2102  	}
  2103  
  2104  	if len(restrictions.Teams) > 0 {
  2105  		result, err := a.userBelongsToTeams(otherUserId, restrictions.Teams)
  2106  		if err != nil {
  2107  			return false, err
  2108  		}
  2109  		if result {
  2110  			return true, nil
  2111  		}
  2112  	}
  2113  
  2114  	if len(restrictions.Channels) > 0 {
  2115  		result, err := a.userBelongsToChannels(otherUserId, restrictions.Channels)
  2116  		if err != nil {
  2117  			return false, err
  2118  		}
  2119  		if result {
  2120  			return true, nil
  2121  		}
  2122  	}
  2123  
  2124  	return false, nil
  2125  }
  2126  
  2127  func (a *App) userBelongsToTeams(userId string, teamIds []string) (bool, *model.AppError) {
  2128  	result := <-a.Srv.Store.Team().UserBelongsToTeams(userId, teamIds)
  2129  	if result.Err != nil {
  2130  		return false, result.Err
  2131  	}
  2132  	return result.Data.(bool), nil
  2133  }
  2134  
  2135  func (a *App) userBelongsToChannels(userId string, channelIds []string) (bool, *model.AppError) {
  2136  	return a.Srv.Store.Channel().UserBelongsToChannels(userId, channelIds)
  2137  }
  2138  
  2139  func (a *App) GetViewUsersRestrictions(userId string) (*model.ViewUsersRestrictions, *model.AppError) {
  2140  	if a.HasPermissionTo(userId, model.PERMISSION_VIEW_MEMBERS) {
  2141  		return nil, nil
  2142  	}
  2143  
  2144  	result := <-a.Srv.Store.Team().GetUserTeamIds(userId, true)
  2145  	if result.Err != nil {
  2146  		return nil, result.Err
  2147  	}
  2148  	teamIds := result.Data.([]string)
  2149  
  2150  	teamIdsWithPermission := []string{}
  2151  	teamIdsWithoutPermission := []string{}
  2152  	for _, teamId := range teamIds {
  2153  		if a.HasPermissionToTeam(userId, teamId, model.PERMISSION_VIEW_MEMBERS) {
  2154  			teamIdsWithPermission = append(teamIdsWithPermission, teamId)
  2155  		} else {
  2156  			teamIdsWithoutPermission = append(teamIdsWithoutPermission, teamId)
  2157  		}
  2158  	}
  2159  
  2160  	if len(teamIdsWithoutPermission) == 0 {
  2161  		return &model.ViewUsersRestrictions{Teams: teamIdsWithPermission}, nil
  2162  	}
  2163  
  2164  	userChannelMembers, err := a.Srv.Store.Channel().GetAllChannelMembersForUser(userId, true, true)
  2165  	if err != nil {
  2166  		return nil, err
  2167  	}
  2168  
  2169  	channelIds := []string{}
  2170  	for channelId := range userChannelMembers {
  2171  		channelIds = append(channelIds, channelId)
  2172  	}
  2173  
  2174  	return &model.ViewUsersRestrictions{Teams: teamIdsWithPermission, Channels: channelIds}, nil
  2175  }
  2176  
  2177  /**
  2178   * Returns a list with the channel ids that the user has permissions to view on a
  2179   * team. If the result is an empty list, the user can't view any channel; if it's
  2180   * nil, there are no restrictions for the user in the specified team.
  2181   */
  2182  func (a *App) GetViewUsersRestrictionsForTeam(userId string, teamId string) ([]string, *model.AppError) {
  2183  	if a.HasPermissionTo(userId, model.PERMISSION_VIEW_MEMBERS) {
  2184  		return nil, nil
  2185  	}
  2186  
  2187  	if a.HasPermissionToTeam(userId, teamId, model.PERMISSION_VIEW_MEMBERS) {
  2188  		return nil, nil
  2189  	}
  2190  
  2191  	members, err := a.Srv.Store.Channel().GetMembersForUser(teamId, userId)
  2192  	if err != nil {
  2193  		return nil, err
  2194  	}
  2195  
  2196  	channelIds := []string{}
  2197  	for _, membership := range *members {
  2198  		channelIds = append(channelIds, membership.ChannelId)
  2199  	}
  2200  
  2201  	return channelIds, nil
  2202  }
  2203  
  2204  func (a *App) getListOfAllowedChannelsForTeam(teamId string, viewRestrictions *model.ViewUsersRestrictions) ([]string, *model.AppError) {
  2205  	var listOfAllowedChannels []string
  2206  	if viewRestrictions == nil || strings.Contains(strings.Join(viewRestrictions.Teams, "."), teamId) {
  2207  		channels, err := a.Srv.Store.Channel().GetTeamChannels(teamId)
  2208  		if err != nil {
  2209  			return nil, err
  2210  		}
  2211  		channelIds := []string{}
  2212  		for _, channel := range *channels {
  2213  			channelIds = append(channelIds, channel.Id)
  2214  		}
  2215  
  2216  		return channelIds, nil
  2217  	}
  2218  
  2219  	channels, err := a.Srv.Store.Channel().GetChannelsByIds(viewRestrictions.Channels)
  2220  	if err != nil {
  2221  		return nil, err
  2222  	}
  2223  	for _, c := range channels {
  2224  		if c.TeamId == teamId {
  2225  			listOfAllowedChannels = append(listOfAllowedChannels, c.Id)
  2226  		}
  2227  	}
  2228  
  2229  	return listOfAllowedChannels, nil
  2230  }