github.com/ashishbhate/mattermost-server@v5.11.1+incompatible/app/user.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  	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/mattermost/mattermost-server/einterfaces"
    30  	"github.com/mattermost/mattermost-server/mlog"
    31  	"github.com/mattermost/mattermost-server/model"
    32  	"github.com/mattermost/mattermost-server/plugin"
    33  	"github.com/mattermost/mattermost-server/services/mfa"
    34  	"github.com/mattermost/mattermost-server/utils"
    35  	"github.com/mattermost/mattermost-server/utils/fileutils"
    36  )
    37  
    38  const (
    39  	TOKEN_TYPE_PASSWORD_RECOVERY  = "password_recovery"
    40  	TOKEN_TYPE_VERIFY_EMAIL       = "verify_email"
    41  	TOKEN_TYPE_TEAM_INVITATION    = "team_invitation"
    42  	PASSWORD_RECOVER_EXPIRY_TIME  = 1000 * 60 * 60      // 1 hour
    43  	TEAM_INVITATION_EXPIRY_TIME   = 1000 * 60 * 60 * 48 // 48 hours
    44  	IMAGE_PROFILE_PIXEL_DIMENSION = 128
    45  )
    46  
    47  func (a *App) CreateUserWithToken(user *model.User, tokenId string) (*model.User, *model.AppError) {
    48  	if err := a.IsUserSignUpAllowed(); err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	result := <-a.Srv.Store.Token().GetByToken(tokenId)
    53  	if result.Err != nil {
    54  		return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, result.Err.Error(), http.StatusBadRequest)
    55  	}
    56  
    57  	token := result.Data.(*model.Token)
    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  	result = <-a.Srv.Store.Team().Get(tokenData["teamId"])
    70  	if result.Err != nil {
    71  		return nil, result.Err
    72  	}
    73  	team := result.Data.(*model.Team)
    74  
    75  	user.Email = tokenData["email"]
    76  	user.EmailVerified = true
    77  
    78  	ruser, err := a.CreateUser(user)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	if err := a.JoinUserToTeam(team, ruser, ""); err != nil {
    84  		return nil, err
    85  	}
    86  
    87  	a.AddDirectChannels(team.Id, ruser)
    88  
    89  	if err := a.DeleteToken(token); err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	return ruser, nil
    94  }
    95  
    96  func (a *App) CreateUserWithInviteId(user *model.User, inviteId string) (*model.User, *model.AppError) {
    97  	if err := a.IsUserSignUpAllowed(); err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	result := <-a.Srv.Store.Team().GetByInviteId(inviteId)
   102  	if result.Err != nil {
   103  		return nil, result.Err
   104  	}
   105  	team := result.Data.(*model.Team)
   106  
   107  	user.EmailVerified = false
   108  
   109  	ruser, err := a.CreateUser(user)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  
   114  	if err := a.JoinUserToTeam(team, ruser, ""); err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	a.AddDirectChannels(team.Id, ruser)
   119  
   120  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   121  		mlog.Error(err.Error())
   122  	}
   123  
   124  	return ruser, nil
   125  }
   126  
   127  func (a *App) CreateUserAsAdmin(user *model.User) (*model.User, *model.AppError) {
   128  	ruser, err := a.CreateUser(user)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   134  		mlog.Error(err.Error())
   135  	}
   136  
   137  	return ruser, nil
   138  }
   139  
   140  func (a *App) CreateUserFromSignup(user *model.User) (*model.User, *model.AppError) {
   141  	if err := a.IsUserSignUpAllowed(); err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	if !a.IsFirstUserAccount() && !*a.Config().TeamSettings.EnableOpenServer {
   146  		err := model.NewAppError("CreateUserFromSignup", "api.user.create_user.no_open_server", nil, "email="+user.Email, http.StatusForbidden)
   147  		return nil, err
   148  	}
   149  
   150  	user.EmailVerified = false
   151  
   152  	ruser, err := a.CreateUser(user)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  
   157  	if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil {
   158  		mlog.Error(err.Error())
   159  	}
   160  
   161  	return ruser, nil
   162  }
   163  
   164  func (a *App) IsUserSignUpAllowed() *model.AppError {
   165  	if !*a.Config().EmailSettings.EnableSignUpWithEmail || !*a.Config().TeamSettings.EnableUserCreation {
   166  		err := model.NewAppError("IsUserSignUpAllowed", "api.user.create_user.signup_email_disabled.app_error", nil, "", http.StatusNotImplemented)
   167  		return err
   168  	}
   169  	return nil
   170  }
   171  
   172  func (a *App) IsFirstUserAccount() bool {
   173  	if a.SessionCacheLength() == 0 {
   174  		cr := <-a.Srv.Store.User().Count(model.UserCountOptions{
   175  			IncludeDeleted: true,
   176  		})
   177  		if cr.Err != nil {
   178  			mlog.Error(fmt.Sprint(cr.Err))
   179  			return false
   180  		}
   181  		if cr.Data.(int64) <= 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 := <-a.Srv.Store.Channel().GetAllChannelMembersForUser(user.Id, false, true)
   203  	if userChannelMembers.Err != nil {
   204  		return userChannelMembers.Err
   205  	}
   206  
   207  	userChannelsIds := []string{}
   208  	for channelId := range userChannelMembers.Data.(map[string]string) {
   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  	if !user.IsLDAPUser() && !user.IsSAMLUser() && !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) {
   227  		return nil, model.NewAppError("CreateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
   228  	}
   229  
   230  	user.Roles = model.SYSTEM_USER_ROLE_ID
   231  
   232  	// Below is a special case where the first user in the entire
   233  	// system is granted the system_admin role
   234  	result := <-a.Srv.Store.User().Count(model.UserCountOptions{
   235  		IncludeDeleted: true,
   236  	})
   237  	if result.Err != nil {
   238  		return nil, result.Err
   239  	}
   240  	if result.Data.(int64) <= 0 {
   241  		user.Roles = model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID
   242  	}
   243  
   244  	if _, ok := utils.GetSupportedLocales()[user.Locale]; !ok {
   245  		user.Locale = *a.Config().LocalizationSettings.DefaultClientLocale
   246  	}
   247  
   248  	ruser, err := a.createUser(user)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  	// This message goes to everyone, so the teamId, channelId and userId are irrelevant
   253  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_NEW_USER, "", "", "", nil)
   254  	message.Add("user_id", ruser.Id)
   255  	a.Publish(message)
   256  
   257  	if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil {
   258  		a.Srv.Go(func() {
   259  			pluginContext := a.PluginContext()
   260  			pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
   261  				hooks.UserHasBeenCreated(pluginContext, user)
   262  				return true
   263  			}, plugin.UserHasBeenCreatedId)
   264  		})
   265  	}
   266  
   267  	return ruser, nil
   268  }
   269  
   270  func (a *App) createUser(user *model.User) (*model.User, *model.AppError) {
   271  	user.MakeNonNil()
   272  
   273  	if err := a.IsPasswordValid(user.Password); user.AuthService == "" && err != nil {
   274  		return nil, err
   275  	}
   276  
   277  	result := <-a.Srv.Store.User().Save(user)
   278  	if result.Err != nil {
   279  		mlog.Error(fmt.Sprintf("Couldn't save the user err=%v", result.Err))
   280  		return nil, result.Err
   281  	}
   282  	ruser := result.Data.(*model.User)
   283  
   284  	if user.EmailVerified {
   285  		if err := a.VerifyUserEmail(ruser.Id, user.Email); err != nil {
   286  			mlog.Error(fmt.Sprintf("Failed to set email verified err=%v", err))
   287  		}
   288  	}
   289  
   290  	pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"}
   291  	if presult := <-a.Srv.Store.Preference().Save(&model.Preferences{pref}); presult.Err != nil {
   292  		mlog.Error(fmt.Sprintf("Encountered error saving tutorial preference, err=%v", presult.Err.Message))
   293  	}
   294  
   295  	ruser.Sanitize(map[string]bool{})
   296  	return ruser, nil
   297  }
   298  
   299  func (a *App) CreateOAuthUser(service string, userData io.Reader, teamId string) (*model.User, *model.AppError) {
   300  	if !*a.Config().TeamSettings.EnableUserCreation {
   301  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_user.disabled.app_error", nil, "", http.StatusNotImplemented)
   302  	}
   303  
   304  	provider := einterfaces.GetOauthProvider(service)
   305  	if provider == nil {
   306  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.not_available.app_error", map[string]interface{}{"Service": strings.Title(service)}, "", http.StatusNotImplemented)
   307  	}
   308  	user := provider.GetUserFromJson(userData)
   309  
   310  	if user == nil {
   311  		return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.create.app_error", map[string]interface{}{"Service": service}, "", http.StatusInternalServerError)
   312  	}
   313  
   314  	suchan := a.Srv.Store.User().GetByAuth(user.AuthData, service)
   315  	euchan := a.Srv.Store.User().GetByEmail(user.Email)
   316  
   317  	found := true
   318  	count := 0
   319  	for found {
   320  		if found = a.IsUsernameTaken(user.Username); found {
   321  			user.Username = user.Username + strconv.Itoa(count)
   322  			count++
   323  		}
   324  	}
   325  
   326  	if result := <-suchan; result.Err == nil {
   327  		return result.Data.(*model.User), nil
   328  	}
   329  
   330  	if result := <-euchan; result.Err == nil {
   331  		authService := result.Data.(*model.User).AuthService
   332  		if authService == "" {
   333  			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)
   334  		}
   335  		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)
   336  	}
   337  
   338  	user.EmailVerified = true
   339  
   340  	ruser, err := a.CreateUser(user)
   341  	if err != nil {
   342  		return nil, err
   343  	}
   344  
   345  	if len(teamId) > 0 {
   346  		err = a.AddUserToTeamByTeamId(teamId, user)
   347  		if err != nil {
   348  			return nil, err
   349  		}
   350  
   351  		err = a.AddDirectChannels(teamId, user)
   352  		if err != nil {
   353  			mlog.Error(err.Error())
   354  		}
   355  	}
   356  
   357  	return ruser, nil
   358  }
   359  
   360  // CheckUserDomain checks that a user's email domain matches a list of space-delimited domains as a string.
   361  func CheckUserDomain(user *model.User, domains string) bool {
   362  	if len(domains) == 0 {
   363  		return true
   364  	}
   365  
   366  	domainArray := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1))))
   367  
   368  	for _, d := range domainArray {
   369  		if strings.HasSuffix(strings.ToLower(user.Email), "@"+d) {
   370  			return true
   371  		}
   372  	}
   373  
   374  	return false
   375  }
   376  
   377  // IsUsernameTaken checks if the username is already used by another user. Return false if the username is invalid.
   378  func (a *App) IsUsernameTaken(name string) bool {
   379  	if !model.IsValidUsername(name) {
   380  		return false
   381  	}
   382  
   383  	if result := <-a.Srv.Store.User().GetByUsername(name); result.Err != nil {
   384  		return false
   385  	}
   386  
   387  	return true
   388  }
   389  
   390  func (a *App) GetUser(userId string) (*model.User, *model.AppError) {
   391  	result := <-a.Srv.Store.User().Get(userId)
   392  	if result.Err != nil {
   393  		return nil, result.Err
   394  	}
   395  	return result.Data.(*model.User), nil
   396  }
   397  
   398  func (a *App) GetUserByUsername(username string) (*model.User, *model.AppError) {
   399  	result := <-a.Srv.Store.User().GetByUsername(username)
   400  	if result.Err != nil && result.Err.Id == "store.sql_user.get_by_username.app_error" {
   401  		result.Err.StatusCode = http.StatusNotFound
   402  		return nil, result.Err
   403  	}
   404  	return result.Data.(*model.User), nil
   405  }
   406  
   407  func (a *App) GetUserByEmail(email string) (*model.User, *model.AppError) {
   408  	result := <-a.Srv.Store.User().GetByEmail(email)
   409  	if result.Err != nil {
   410  		if result.Err.Id == "store.sql_user.missing_account.const" {
   411  			result.Err.StatusCode = http.StatusNotFound
   412  			return nil, result.Err
   413  		}
   414  		result.Err.StatusCode = http.StatusBadRequest
   415  		return nil, result.Err
   416  	}
   417  	return result.Data.(*model.User), nil
   418  }
   419  
   420  func (a *App) GetUserByAuth(authData *string, authService string) (*model.User, *model.AppError) {
   421  	result := <-a.Srv.Store.User().GetByAuth(authData, authService)
   422  	if result.Err != nil {
   423  		return nil, result.Err
   424  	}
   425  	return result.Data.(*model.User), nil
   426  }
   427  
   428  func (a *App) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   429  	result := <-a.Srv.Store.User().GetAllProfiles(options)
   430  	if result.Err != nil {
   431  		return nil, result.Err
   432  	}
   433  	return result.Data.([]*model.User), nil
   434  }
   435  
   436  func (a *App) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
   437  	users, err := a.GetUsers(options)
   438  	if err != nil {
   439  		return nil, err
   440  	}
   441  
   442  	return a.sanitizeProfiles(users, asAdmin), nil
   443  }
   444  
   445  func (a *App) GetUsersEtag() string {
   446  	return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForAllProfiles()).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
   447  }
   448  
   449  func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   450  	result := <-a.Srv.Store.User().GetProfiles(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) GetUsersNotInTeam(teamId string, offset int, limit int) ([]*model.User, *model.AppError) {
   458  	result := <-a.Srv.Store.User().GetProfilesNotInTeam(teamId, offset, limit)
   459  	if result.Err != nil {
   460  		return nil, result.Err
   461  	}
   462  	return result.Data.([]*model.User), nil
   463  }
   464  
   465  func (a *App) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) {
   466  	users, err := a.GetUsersInTeam(options)
   467  	if err != nil {
   468  		return nil, err
   469  	}
   470  
   471  	return a.sanitizeProfiles(users, asAdmin), nil
   472  }
   473  
   474  func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   475  	users, err := a.GetUsersNotInTeam(teamId, page*perPage, perPage)
   476  	if err != nil {
   477  		return nil, err
   478  	}
   479  
   480  	return a.sanitizeProfiles(users, asAdmin), nil
   481  }
   482  
   483  func (a *App) GetUsersInTeamEtag(teamId string) string {
   484  	return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
   485  }
   486  
   487  func (a *App) GetUsersNotInTeamEtag(teamId string) string {
   488  	return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfilesNotInTeam(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress)
   489  }
   490  
   491  func (a *App) GetUsersInChannel(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   492  	result := <-a.Srv.Store.User().GetProfilesInChannel(channelId, offset, limit)
   493  	if result.Err != nil {
   494  		return nil, result.Err
   495  	}
   496  	return result.Data.([]*model.User), nil
   497  }
   498  
   499  func (a *App) GetUsersInChannelByStatus(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   500  	result := <-a.Srv.Store.User().GetProfilesInChannelByStatus(channelId, offset, limit)
   501  	if result.Err != nil {
   502  		return nil, result.Err
   503  	}
   504  	return result.Data.([]*model.User), nil
   505  }
   506  
   507  func (a *App) GetUsersInChannelMap(channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) {
   508  	users, err := a.GetUsersInChannel(channelId, offset, limit)
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  
   513  	userMap := make(map[string]*model.User, len(users))
   514  
   515  	for _, user := range users {
   516  		a.SanitizeProfile(user, asAdmin)
   517  		userMap[user.Id] = user
   518  	}
   519  
   520  	return userMap, nil
   521  }
   522  
   523  func (a *App) GetUsersInChannelPage(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   524  	users, err := a.GetUsersInChannel(channelId, page*perPage, perPage)
   525  	if err != nil {
   526  		return nil, err
   527  	}
   528  	return a.sanitizeProfiles(users, asAdmin), nil
   529  }
   530  
   531  func (a *App) GetUsersInChannelPageByStatus(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   532  	users, err := a.GetUsersInChannelByStatus(channelId, page*perPage, perPage)
   533  	if err != nil {
   534  		return nil, err
   535  	}
   536  	return a.sanitizeProfiles(users, asAdmin), nil
   537  }
   538  
   539  func (a *App) GetUsersNotInChannel(teamId string, channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   540  	result := <-a.Srv.Store.User().GetProfilesNotInChannel(teamId, channelId, offset, limit)
   541  	if result.Err != nil {
   542  		return nil, result.Err
   543  	}
   544  	return result.Data.([]*model.User), nil
   545  }
   546  
   547  func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) {
   548  	users, err := a.GetUsersNotInChannel(teamId, channelId, offset, limit)
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  
   553  	userMap := make(map[string]*model.User, len(users))
   554  
   555  	for _, user := range users {
   556  		a.SanitizeProfile(user, asAdmin)
   557  		userMap[user.Id] = user
   558  	}
   559  
   560  	return userMap, nil
   561  }
   562  
   563  func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   564  	users, err := a.GetUsersNotInChannel(teamId, channelId, page*perPage, perPage)
   565  	if err != nil {
   566  		return nil, err
   567  	}
   568  
   569  	return a.sanitizeProfiles(users, asAdmin), nil
   570  }
   571  
   572  func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) {
   573  	users, err := a.GetUsersWithoutTeam(page*perPage, perPage)
   574  	if err != nil {
   575  		return nil, err
   576  	}
   577  
   578  	return a.sanitizeProfiles(users, asAdmin), nil
   579  }
   580  
   581  func (a *App) GetUsersWithoutTeam(offset int, limit int) ([]*model.User, *model.AppError) {
   582  	result := <-a.Srv.Store.User().GetProfilesWithoutTeam(offset, limit)
   583  	if result.Err != nil {
   584  		return nil, result.Err
   585  	}
   586  	return result.Data.([]*model.User), nil
   587  }
   588  
   589  func (a *App) GetUsersByIds(userIds []string, asAdmin bool) ([]*model.User, *model.AppError) {
   590  	result := <-a.Srv.Store.User().GetProfileByIds(userIds, true)
   591  	if result.Err != nil {
   592  		return nil, result.Err
   593  	}
   594  	return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil
   595  }
   596  
   597  func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool) ([]*model.User, *model.AppError) {
   598  	result := <-a.Srv.Store.User().GetProfilesByUsernames(usernames, "")
   599  	if result.Err != nil {
   600  		return nil, result.Err
   601  	}
   602  	return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil
   603  }
   604  
   605  func (a *App) sanitizeProfiles(users []*model.User, asAdmin bool) []*model.User {
   606  	for _, u := range users {
   607  		a.SanitizeProfile(u, asAdmin)
   608  	}
   609  
   610  	return users
   611  }
   612  
   613  func (a *App) GenerateMfaSecret(userId string) (*model.MfaSecret, *model.AppError) {
   614  	user, err := a.GetUser(userId)
   615  	if err != nil {
   616  		return nil, err
   617  	}
   618  
   619  	mfaService := mfa.New(a, a.Srv.Store)
   620  	secret, img, err := mfaService.GenerateSecret(user)
   621  	if err != nil {
   622  		return nil, err
   623  	}
   624  
   625  	mfaSecret := &model.MfaSecret{Secret: secret, QRCode: b64.StdEncoding.EncodeToString(img)}
   626  	return mfaSecret, nil
   627  }
   628  
   629  func (a *App) ActivateMfa(userId, token string) *model.AppError {
   630  	result := <-a.Srv.Store.User().Get(userId)
   631  	if result.Err != nil {
   632  		return result.Err
   633  	}
   634  	user := result.Data.(*model.User)
   635  
   636  	if len(user.AuthService) > 0 && user.AuthService != model.USER_AUTH_SERVICE_LDAP {
   637  		return model.NewAppError("ActivateMfa", "api.user.activate_mfa.email_and_ldap_only.app_error", nil, "", http.StatusBadRequest)
   638  	}
   639  
   640  	mfaService := mfa.New(a, a.Srv.Store)
   641  	if err := mfaService.Activate(user, token); err != nil {
   642  		return err
   643  	}
   644  
   645  	return nil
   646  }
   647  
   648  func (a *App) DeactivateMfa(userId string) *model.AppError {
   649  	mfaService := mfa.New(a, a.Srv.Store)
   650  	if err := mfaService.Deactivate(userId); err != nil {
   651  		return err
   652  	}
   653  
   654  	return nil
   655  }
   656  
   657  func CreateProfileImage(username string, userId string, initialFont string) ([]byte, *model.AppError) {
   658  	colors := []color.NRGBA{
   659  		{197, 8, 126, 255},
   660  		{227, 207, 18, 255},
   661  		{28, 181, 105, 255},
   662  		{35, 188, 224, 255},
   663  		{116, 49, 196, 255},
   664  		{197, 8, 126, 255},
   665  		{197, 19, 19, 255},
   666  		{250, 134, 6, 255},
   667  		{227, 207, 18, 255},
   668  		{123, 201, 71, 255},
   669  		{28, 181, 105, 255},
   670  		{35, 188, 224, 255},
   671  		{116, 49, 196, 255},
   672  		{197, 8, 126, 255},
   673  		{197, 19, 19, 255},
   674  		{250, 134, 6, 255},
   675  		{227, 207, 18, 255},
   676  		{123, 201, 71, 255},
   677  		{28, 181, 105, 255},
   678  		{35, 188, 224, 255},
   679  		{116, 49, 196, 255},
   680  		{197, 8, 126, 255},
   681  		{197, 19, 19, 255},
   682  		{250, 134, 6, 255},
   683  		{227, 207, 18, 255},
   684  		{123, 201, 71, 255},
   685  	}
   686  
   687  	h := fnv.New32a()
   688  	h.Write([]byte(userId))
   689  	seed := h.Sum32()
   690  
   691  	initial := string(strings.ToUpper(username)[0])
   692  
   693  	font, err := getFont(initialFont)
   694  	if err != nil {
   695  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error(), http.StatusInternalServerError)
   696  	}
   697  
   698  	color := colors[int64(seed)%int64(len(colors))]
   699  	dstImg := image.NewRGBA(image.Rect(0, 0, IMAGE_PROFILE_PIXEL_DIMENSION, IMAGE_PROFILE_PIXEL_DIMENSION))
   700  	srcImg := image.White
   701  	draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.ZP, draw.Src)
   702  	size := float64(IMAGE_PROFILE_PIXEL_DIMENSION / 2)
   703  
   704  	c := freetype.NewContext()
   705  	c.SetFont(font)
   706  	c.SetFontSize(size)
   707  	c.SetClip(dstImg.Bounds())
   708  	c.SetDst(dstImg)
   709  	c.SetSrc(srcImg)
   710  
   711  	pt := freetype.Pt(IMAGE_PROFILE_PIXEL_DIMENSION/5, IMAGE_PROFILE_PIXEL_DIMENSION*2/3)
   712  	_, err = c.DrawString(initial, pt)
   713  	if err != nil {
   714  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.initial.app_error", nil, err.Error(), http.StatusInternalServerError)
   715  	}
   716  
   717  	buf := new(bytes.Buffer)
   718  
   719  	if imgErr := png.Encode(buf, dstImg); imgErr != nil {
   720  		return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.encode.app_error", nil, imgErr.Error(), http.StatusInternalServerError)
   721  	}
   722  	return buf.Bytes(), nil
   723  }
   724  
   725  func getFont(initialFont string) (*truetype.Font, error) {
   726  	// Some people have the old default font still set, so just treat that as if they're using the new default
   727  	if initialFont == "luximbi.ttf" {
   728  		initialFont = "nunito-bold.ttf"
   729  	}
   730  
   731  	fontDir, _ := fileutils.FindDir("fonts")
   732  	fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont))
   733  	if err != nil {
   734  		return nil, err
   735  	}
   736  
   737  	return freetype.ParseFont(fontBytes)
   738  }
   739  
   740  func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) {
   741  	if len(*a.Config().FileSettings.DriverName) == 0 {
   742  		img, appErr := a.GetDefaultProfileImage(user)
   743  		if appErr != nil {
   744  			return nil, false, appErr
   745  		}
   746  		return img, false, nil
   747  	}
   748  
   749  	path := "users/" + user.Id + "/profile.png"
   750  
   751  	data, err := a.ReadFile(path)
   752  	if err != nil {
   753  		img, appErr := a.GetDefaultProfileImage(user)
   754  		if appErr != nil {
   755  			return nil, false, appErr
   756  		}
   757  
   758  		if user.LastPictureUpdate == 0 {
   759  			if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil {
   760  				return nil, false, err
   761  			}
   762  		}
   763  		return img, true, nil
   764  	}
   765  
   766  	return data, false, nil
   767  }
   768  
   769  func (a *App) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) {
   770  	var img []byte
   771  	var appErr *model.AppError
   772  
   773  	if user.IsBot {
   774  		img = model.BotDefaultImage
   775  		appErr = nil
   776  	} else {
   777  		img, appErr = CreateProfileImage(user.Username, user.Id, *a.Config().FileSettings.InitialFont)
   778  	}
   779  	if appErr != nil {
   780  		return nil, appErr
   781  	}
   782  	return img, nil
   783  }
   784  
   785  func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError {
   786  	img, appErr := a.GetDefaultProfileImage(user)
   787  	if appErr != nil {
   788  		return appErr
   789  	}
   790  
   791  	path := "users/" + user.Id + "/profile.png"
   792  
   793  	if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil {
   794  		return err
   795  	}
   796  
   797  	<-a.Srv.Store.User().ResetLastPictureUpdate(user.Id)
   798  
   799  	a.InvalidateCacheForUser(user.Id)
   800  
   801  	updatedUser, appErr := a.GetUser(user.Id)
   802  	if appErr != nil {
   803  		mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", user.Id), mlog.String("user_id", user.Id))
   804  		return nil
   805  	}
   806  
   807  	options := a.Config().GetSanitizeOptions()
   808  	updatedUser.SanitizeProfile(options)
   809  
   810  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
   811  	message.Add("user", updatedUser)
   812  	a.Publish(message)
   813  
   814  	return nil
   815  }
   816  
   817  func (a *App) SetProfileImage(userId string, imageData *multipart.FileHeader) *model.AppError {
   818  	file, err := imageData.Open()
   819  	if err != nil {
   820  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error(), http.StatusBadRequest)
   821  	}
   822  	defer file.Close()
   823  	return a.SetProfileImageFromMultiPartFile(userId, file)
   824  }
   825  
   826  func (a *App) SetProfileImageFromMultiPartFile(userId string, file multipart.File) *model.AppError {
   827  	// Decode image config first to check dimensions before loading the whole thing into memory later on
   828  	config, _, err := image.DecodeConfig(file)
   829  	if err != nil {
   830  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode_config.app_error", nil, err.Error(), http.StatusBadRequest)
   831  	}
   832  	if config.Width*config.Height > model.MaxImageSize {
   833  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, err.Error(), http.StatusBadRequest)
   834  	}
   835  
   836  	file.Seek(0, 0)
   837  
   838  	return a.SetProfileImageFromFile(userId, file)
   839  }
   840  
   841  func (a *App) SetProfileImageFromFile(userId string, file io.Reader) *model.AppError {
   842  
   843  	// Decode image into Image object
   844  	img, _, err := image.Decode(file)
   845  	if err != nil {
   846  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode.app_error", nil, err.Error(), http.StatusBadRequest)
   847  	}
   848  
   849  	orientation, _ := getImageOrientation(file)
   850  	img = makeImageUpright(img, orientation)
   851  
   852  	// Scale profile image
   853  	profileWidthAndHeight := 128
   854  	img = imaging.Fill(img, profileWidthAndHeight, profileWidthAndHeight, imaging.Center, imaging.Lanczos)
   855  
   856  	buf := new(bytes.Buffer)
   857  	err = png.Encode(buf, img)
   858  	if err != nil {
   859  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.encode.app_error", nil, err.Error(), http.StatusInternalServerError)
   860  	}
   861  
   862  	path := "users/" + userId + "/profile.png"
   863  
   864  	if _, err := a.WriteFile(buf, path); err != nil {
   865  		return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.upload_profile.app_error", nil, "", http.StatusInternalServerError)
   866  	}
   867  
   868  	<-a.Srv.Store.User().UpdateLastPictureUpdate(userId)
   869  
   870  	a.InvalidateCacheForUser(userId)
   871  
   872  	user, userErr := a.GetUser(userId)
   873  	if userErr != nil {
   874  		mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", userId), mlog.String("user_id", userId))
   875  		return nil
   876  	}
   877  
   878  	options := a.Config().GetSanitizeOptions()
   879  	user.SanitizeProfile(options)
   880  
   881  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
   882  	message.Add("user", user)
   883  	a.Publish(message)
   884  
   885  	return nil
   886  }
   887  
   888  func (a *App) UpdatePasswordAsUser(userId, currentPassword, newPassword string) *model.AppError {
   889  	user, err := a.GetUser(userId)
   890  	if err != nil {
   891  		return err
   892  	}
   893  
   894  	if user == nil {
   895  		err = model.NewAppError("updatePassword", "api.user.update_password.valid_account.app_error", nil, "", http.StatusBadRequest)
   896  		return err
   897  	}
   898  
   899  	if user.AuthData != nil && *user.AuthData != "" {
   900  		err = model.NewAppError("updatePassword", "api.user.update_password.oauth.app_error", nil, "auth_service="+user.AuthService, http.StatusBadRequest)
   901  		return err
   902  	}
   903  
   904  	if err := a.DoubleCheckPassword(user, currentPassword); err != nil {
   905  		if err.Id == "api.user.check_user_password.invalid.app_error" {
   906  			err = model.NewAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "", http.StatusBadRequest)
   907  		}
   908  		return err
   909  	}
   910  
   911  	T := utils.GetUserTranslations(user.Locale)
   912  
   913  	return a.UpdatePasswordSendEmail(user, newPassword, T("api.user.update_password.menu"))
   914  }
   915  
   916  func (a *App) userDeactivated(user *model.User) *model.AppError {
   917  	if err := a.RevokeAllSessions(user.Id); err != nil {
   918  		return err
   919  	}
   920  
   921  	a.SetStatusOffline(user.Id, false)
   922  
   923  	if *a.Config().ServiceSettings.DisableBotsWhenOwnerIsDeactivated {
   924  		a.disableUserBots(user.Id)
   925  	}
   926  
   927  	return nil
   928  }
   929  
   930  func (a *App) invalidateUserChannelMembersCaches(user *model.User) *model.AppError {
   931  	teamsForUser, err := a.GetTeamsForUser(user.Id)
   932  	if err != nil {
   933  		return err
   934  	}
   935  
   936  	for _, team := range teamsForUser {
   937  		channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id, false)
   938  		if err != nil {
   939  			return err
   940  		}
   941  
   942  		for _, channel := range *channelsForUser {
   943  			a.InvalidateCacheForChannelMembers(channel.Id)
   944  		}
   945  	}
   946  
   947  	return nil
   948  }
   949  
   950  func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.AppError) {
   951  	if active {
   952  		user.DeleteAt = 0
   953  	} else {
   954  		user.DeleteAt = model.GetMillis()
   955  	}
   956  
   957  	result := <-a.Srv.Store.User().Update(user, true)
   958  	if result.Err != nil {
   959  		return nil, result.Err
   960  	}
   961  	ruser := result.Data.([2]*model.User)[0]
   962  
   963  	if !active {
   964  		if err := a.userDeactivated(ruser); err != nil {
   965  			return nil, err
   966  		}
   967  	}
   968  
   969  	a.invalidateUserChannelMembersCaches(user)
   970  
   971  	a.sendUpdatedUserEvent(*ruser)
   972  
   973  	return ruser, nil
   974  }
   975  
   976  func (a *App) GetSanitizeOptions(asAdmin bool) map[string]bool {
   977  	options := a.Config().GetSanitizeOptions()
   978  	if asAdmin {
   979  		options["email"] = true
   980  		options["fullname"] = true
   981  		options["authservice"] = true
   982  	}
   983  	return options
   984  }
   985  
   986  func (a *App) SanitizeProfile(user *model.User, asAdmin bool) {
   987  	options := a.GetSanitizeOptions(asAdmin)
   988  
   989  	user.SanitizeProfile(options)
   990  }
   991  
   992  func (a *App) UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) {
   993  	updatedUser, err := a.UpdateUser(user, true)
   994  	if err != nil {
   995  		return nil, err
   996  	}
   997  
   998  	a.sendUpdatedUserEvent(*updatedUser)
   999  
  1000  	return updatedUser, nil
  1001  }
  1002  
  1003  func (a *App) PatchUser(userId string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) {
  1004  	user, err := a.GetUser(userId)
  1005  	if err != nil {
  1006  		return nil, err
  1007  	}
  1008  
  1009  	user.Patch(patch)
  1010  
  1011  	updatedUser, err := a.UpdateUser(user, true)
  1012  	if err != nil {
  1013  		return nil, err
  1014  	}
  1015  
  1016  	a.sendUpdatedUserEvent(*updatedUser)
  1017  
  1018  	return updatedUser, nil
  1019  }
  1020  
  1021  func (a *App) UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError) {
  1022  	if userAuth.AuthData == nil || *userAuth.AuthData == "" || userAuth.AuthService == "" {
  1023  		userAuth.AuthData = nil
  1024  		userAuth.AuthService = ""
  1025  
  1026  		if err := a.IsPasswordValid(userAuth.Password); err != nil {
  1027  			return nil, err
  1028  		}
  1029  		password := model.HashPassword(userAuth.Password)
  1030  
  1031  		if result := <-a.Srv.Store.User().UpdatePassword(userId, password); result.Err != nil {
  1032  			return nil, result.Err
  1033  		}
  1034  	} else {
  1035  		userAuth.Password = ""
  1036  
  1037  		if result := <-a.Srv.Store.User().UpdateAuthData(userId, userAuth.AuthService, userAuth.AuthData, "", false); result.Err != nil {
  1038  			return nil, result.Err
  1039  		}
  1040  	}
  1041  
  1042  	return userAuth, nil
  1043  }
  1044  
  1045  func (a *App) sendUpdatedUserEvent(user model.User) {
  1046  	adminCopyOfUser := user.DeepCopy()
  1047  	a.SanitizeProfile(adminCopyOfUser, true)
  1048  	adminMessage := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
  1049  	adminMessage.Add("user", *adminCopyOfUser)
  1050  	adminMessage.Broadcast.ContainsSensitiveData = true
  1051  	a.Publish(adminMessage)
  1052  
  1053  	a.SanitizeProfile(&user, false)
  1054  	message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil)
  1055  	message.Add("user", user)
  1056  	message.Broadcast.ContainsSanitizedData = true
  1057  	a.Publish(message)
  1058  }
  1059  
  1060  func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) {
  1061  	result := <-a.Srv.Store.User().Get(user.Id)
  1062  	if result.Err != nil {
  1063  		return nil, result.Err
  1064  	}
  1065  	prev := result.Data.(*model.User)
  1066  
  1067  	if !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) {
  1068  		if !prev.IsLDAPUser() && !prev.IsSAMLUser() && user.Email != prev.Email {
  1069  			return nil, model.NewAppError("UpdateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest)
  1070  		}
  1071  	}
  1072  
  1073  	// Don't set new eMail on user account if email verification is required, this will be done as a post-verification action
  1074  	// to avoid users being able to set non-controlled eMails as their account email
  1075  	newEmail := ""
  1076  	if *a.Config().EmailSettings.RequireEmailVerification && prev.Email != user.Email {
  1077  		newEmail = user.Email
  1078  
  1079  		_, err := a.GetUserByEmail(newEmail)
  1080  		if err == nil {
  1081  			return nil, model.NewAppError("UpdateUser", "store.sql_user.update.email_taken.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
  1082  		}
  1083  
  1084  		user.Email = prev.Email
  1085  	}
  1086  
  1087  	result = <-a.Srv.Store.User().Update(user, false)
  1088  	if result.Err != nil {
  1089  		return nil, result.Err
  1090  	}
  1091  	rusers := result.Data.([2]*model.User)
  1092  
  1093  	if sendNotifications {
  1094  		if rusers[0].Email != rusers[1].Email || newEmail != "" {
  1095  			if *a.Config().EmailSettings.RequireEmailVerification {
  1096  				a.Srv.Go(func() {
  1097  					if err := a.SendEmailVerification(rusers[0], newEmail); err != nil {
  1098  						mlog.Error(err.Error())
  1099  					}
  1100  				})
  1101  			} else {
  1102  				a.Srv.Go(func() {
  1103  					if err := a.SendEmailChangeEmail(rusers[1].Email, rusers[0].Email, rusers[0].Locale, a.GetSiteURL()); err != nil {
  1104  						mlog.Error(err.Error())
  1105  					}
  1106  				})
  1107  			}
  1108  		}
  1109  
  1110  		if rusers[0].Username != rusers[1].Username {
  1111  			a.Srv.Go(func() {
  1112  				if err := a.SendChangeUsernameEmail(rusers[1].Username, rusers[0].Username, rusers[0].Email, rusers[0].Locale, a.GetSiteURL()); err != nil {
  1113  					mlog.Error(err.Error())
  1114  				}
  1115  			})
  1116  		}
  1117  	}
  1118  
  1119  	a.InvalidateCacheForUser(user.Id)
  1120  
  1121  	return rusers[0], nil
  1122  }
  1123  
  1124  func (a *App) UpdateUserActive(userId string, active bool) *model.AppError {
  1125  	user, err := a.GetUser(userId)
  1126  
  1127  	if err != nil {
  1128  		return err
  1129  	}
  1130  	if _, err = a.UpdateActive(user, active); err != nil {
  1131  		return err
  1132  	}
  1133  
  1134  	return nil
  1135  }
  1136  
  1137  func (a *App) UpdateUserNotifyProps(userId string, props map[string]string) (*model.User, *model.AppError) {
  1138  	user, err := a.GetUser(userId)
  1139  	if err != nil {
  1140  		return nil, err
  1141  	}
  1142  
  1143  	user.NotifyProps = props
  1144  
  1145  	ruser, err := a.UpdateUser(user, true)
  1146  	if err != nil {
  1147  		return nil, err
  1148  	}
  1149  
  1150  	return ruser, nil
  1151  }
  1152  
  1153  func (a *App) UpdateMfa(activate bool, userId, token string) *model.AppError {
  1154  	if activate {
  1155  		if err := a.ActivateMfa(userId, token); err != nil {
  1156  			return err
  1157  		}
  1158  	} else {
  1159  		if err := a.DeactivateMfa(userId); err != nil {
  1160  			return err
  1161  		}
  1162  	}
  1163  
  1164  	a.Srv.Go(func() {
  1165  		user, err := a.GetUser(userId)
  1166  		if err != nil {
  1167  			mlog.Error(err.Error())
  1168  			return
  1169  		}
  1170  
  1171  		if err := a.SendMfaChangeEmail(user.Email, activate, user.Locale, a.GetSiteURL()); err != nil {
  1172  			mlog.Error(err.Error())
  1173  		}
  1174  	})
  1175  
  1176  	return nil
  1177  }
  1178  
  1179  func (a *App) UpdatePasswordByUserIdSendEmail(userId, newPassword, method string) *model.AppError {
  1180  	user, err := a.GetUser(userId)
  1181  	if err != nil {
  1182  		return err
  1183  	}
  1184  
  1185  	return a.UpdatePasswordSendEmail(user, newPassword, method)
  1186  }
  1187  
  1188  func (a *App) UpdatePassword(user *model.User, newPassword string) *model.AppError {
  1189  	if err := a.IsPasswordValid(newPassword); err != nil {
  1190  		return err
  1191  	}
  1192  
  1193  	hashedPassword := model.HashPassword(newPassword)
  1194  
  1195  	if result := <-a.Srv.Store.User().UpdatePassword(user.Id, hashedPassword); result.Err != nil {
  1196  		return model.NewAppError("UpdatePassword", "api.user.update_password.failed.app_error", nil, result.Err.Error(), http.StatusInternalServerError)
  1197  	}
  1198  
  1199  	return nil
  1200  }
  1201  
  1202  func (a *App) UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError {
  1203  	if err := a.UpdatePassword(user, newPassword); err != nil {
  1204  		return err
  1205  	}
  1206  
  1207  	a.Srv.Go(func() {
  1208  		if err := a.SendPasswordChangeEmail(user.Email, method, user.Locale, a.GetSiteURL()); err != nil {
  1209  			mlog.Error(err.Error())
  1210  		}
  1211  	})
  1212  
  1213  	return nil
  1214  }
  1215  
  1216  func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError {
  1217  	token, err := a.GetPasswordRecoveryToken(userSuppliedTokenString)
  1218  	if err != nil {
  1219  		return err
  1220  	}
  1221  	if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME {
  1222  		return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
  1223  	}
  1224  
  1225  	tokenData := struct {
  1226  		UserId string
  1227  		Email  string
  1228  	}{}
  1229  
  1230  	err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
  1231  	if err2 != nil {
  1232  		return model.NewAppError("resetPassword", "api.user.reset_password.token_parse.error", nil, "", http.StatusInternalServerError)
  1233  	}
  1234  
  1235  	user, err := a.GetUser(tokenData.UserId)
  1236  	if err != nil {
  1237  		return err
  1238  	}
  1239  
  1240  	if user.Email != tokenData.Email {
  1241  		return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest)
  1242  	}
  1243  
  1244  	if user.IsSSOUser() {
  1245  		return model.NewAppError("ResetPasswordFromCode", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
  1246  	}
  1247  
  1248  	T := utils.GetUserTranslations(user.Locale)
  1249  
  1250  	if err := a.UpdatePasswordSendEmail(user, newPassword, T("api.user.reset_password.method")); err != nil {
  1251  		return err
  1252  	}
  1253  
  1254  	if err := a.DeleteToken(token); err != nil {
  1255  		mlog.Error(err.Error())
  1256  	}
  1257  
  1258  	return nil
  1259  }
  1260  
  1261  func (a *App) SendPasswordReset(email string, siteURL string) (bool, *model.AppError) {
  1262  	user, err := a.GetUserByEmail(email)
  1263  	if err != nil {
  1264  		return false, nil
  1265  	}
  1266  
  1267  	if user.AuthData != nil && len(*user.AuthData) != 0 {
  1268  		return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest)
  1269  	}
  1270  
  1271  	token, err := a.CreatePasswordRecoveryToken(user.Id, user.Email)
  1272  	if err != nil {
  1273  		return false, err
  1274  	}
  1275  
  1276  	return a.SendPasswordResetEmail(user.Email, token, user.Locale, siteURL)
  1277  }
  1278  
  1279  func (a *App) CreatePasswordRecoveryToken(userId, email string) (*model.Token, *model.AppError) {
  1280  
  1281  	tokenExtra := struct {
  1282  		UserId string
  1283  		Email  string
  1284  	}{
  1285  		userId,
  1286  		email,
  1287  	}
  1288  	jsonData, err := json.Marshal(tokenExtra)
  1289  
  1290  	if err != nil {
  1291  		return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError)
  1292  	}
  1293  
  1294  	token := model.NewToken(TOKEN_TYPE_PASSWORD_RECOVERY, string(jsonData))
  1295  
  1296  	if result := <-a.Srv.Store.Token().Save(token); result.Err != nil {
  1297  		return nil, result.Err
  1298  	}
  1299  
  1300  	return token, nil
  1301  }
  1302  
  1303  func (a *App) GetPasswordRecoveryToken(token string) (*model.Token, *model.AppError) {
  1304  	result := <-a.Srv.Store.Token().GetByToken(token)
  1305  	if result.Err != nil {
  1306  		return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.invalid_link.app_error", nil, result.Err.Error(), http.StatusBadRequest)
  1307  	}
  1308  	rtoken := result.Data.(*model.Token)
  1309  	if rtoken.Type != TOKEN_TYPE_PASSWORD_RECOVERY {
  1310  		return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.broken_token.app_error", nil, "", http.StatusBadRequest)
  1311  	}
  1312  	return rtoken, nil
  1313  }
  1314  
  1315  func (a *App) DeleteToken(token *model.Token) *model.AppError {
  1316  	if result := <-a.Srv.Store.Token().Delete(token.Token); result.Err != nil {
  1317  		return result.Err
  1318  	}
  1319  
  1320  	return nil
  1321  }
  1322  
  1323  func (a *App) UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) {
  1324  	user, err := a.GetUser(userId)
  1325  	if err != nil {
  1326  		err.StatusCode = http.StatusBadRequest
  1327  		return nil, err
  1328  	}
  1329  
  1330  	if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil {
  1331  		return nil, err
  1332  	}
  1333  
  1334  	user.Roles = newRoles
  1335  	uchan := a.Srv.Store.User().Update(user, true)
  1336  	schan := a.Srv.Store.Session().UpdateRoles(user.Id, newRoles)
  1337  
  1338  	result := <-uchan
  1339  	if result.Err != nil {
  1340  		return nil, result.Err
  1341  	}
  1342  	ruser := result.Data.([2]*model.User)[0]
  1343  
  1344  	if result := <-schan; result.Err != nil {
  1345  		// soft error since the user roles were still updated
  1346  		mlog.Error(fmt.Sprint(result.Err))
  1347  	}
  1348  
  1349  	a.ClearSessionCacheForUser(user.Id)
  1350  
  1351  	if sendWebSocketEvent {
  1352  		message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ROLE_UPDATED, "", "", user.Id, nil)
  1353  		message.Add("user_id", user.Id)
  1354  		message.Add("roles", newRoles)
  1355  		a.Publish(message)
  1356  	}
  1357  
  1358  	return ruser, nil
  1359  }
  1360  
  1361  func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
  1362  	mlog.Warn(fmt.Sprintf("Attempting to permanently delete account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id))
  1363  	if user.IsInRole(model.SYSTEM_ADMIN_ROLE_ID) {
  1364  		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))
  1365  	}
  1366  
  1367  	if _, err := a.UpdateActive(user, false); err != nil {
  1368  		return err
  1369  	}
  1370  
  1371  	if result := <-a.Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); result.Err != nil {
  1372  		return result.Err
  1373  	}
  1374  
  1375  	if result := <-a.Srv.Store.UserAccessToken().DeleteAllForUser(user.Id); result.Err != nil {
  1376  		return result.Err
  1377  	}
  1378  
  1379  	if result := <-a.Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); result.Err != nil {
  1380  		return result.Err
  1381  	}
  1382  
  1383  	if result := <-a.Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); result.Err != nil {
  1384  		return result.Err
  1385  	}
  1386  
  1387  	if result := <-a.Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); result.Err != nil {
  1388  		return result.Err
  1389  	}
  1390  
  1391  	if result := <-a.Srv.Store.Command().PermanentDeleteByUser(user.Id); result.Err != nil {
  1392  		return result.Err
  1393  	}
  1394  
  1395  	if result := <-a.Srv.Store.Preference().PermanentDeleteByUser(user.Id); result.Err != nil {
  1396  		return result.Err
  1397  	}
  1398  
  1399  	if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); result.Err != nil {
  1400  		return result.Err
  1401  	}
  1402  
  1403  	if result := <-a.Srv.Store.Post().PermanentDeleteByUser(user.Id); result.Err != nil {
  1404  		return result.Err
  1405  	}
  1406  
  1407  	result := <-a.Srv.Store.FileInfo().GetForUser(user.Id)
  1408  	if result.Err != nil {
  1409  		mlog.Warn("Error getting file list for user from FileInfoStore")
  1410  	}
  1411  
  1412  	infos := result.Data.([]*model.FileInfo)
  1413  	for _, info := range infos {
  1414  		res, err := a.FileExists(info.Path)
  1415  		if err != nil {
  1416  			mlog.Warn(
  1417  				"Error checking existence of file",
  1418  				mlog.String("path", info.Path),
  1419  				mlog.Err(err),
  1420  			)
  1421  			continue
  1422  		}
  1423  
  1424  		if !res {
  1425  			mlog.Warn("File not found", mlog.String("path", info.Path))
  1426  			continue
  1427  		}
  1428  
  1429  		err = a.RemoveFile(info.Path)
  1430  
  1431  		if err != nil {
  1432  			mlog.Warn(
  1433  				"Unable to remove file",
  1434  				mlog.String("path", info.Path),
  1435  				mlog.Err(err),
  1436  			)
  1437  		}
  1438  	}
  1439  
  1440  	if result := <-a.Srv.Store.FileInfo().PermanentDeleteByUser(user.Id); result.Err != nil {
  1441  		return result.Err
  1442  	}
  1443  
  1444  	if result := <-a.Srv.Store.User().PermanentDelete(user.Id); result.Err != nil {
  1445  		return result.Err
  1446  	}
  1447  
  1448  	if result := <-a.Srv.Store.Audit().PermanentDeleteByUser(user.Id); result.Err != nil {
  1449  		return result.Err
  1450  	}
  1451  
  1452  	if result := <-a.Srv.Store.Team().RemoveAllMembersByUser(user.Id); result.Err != nil {
  1453  		return result.Err
  1454  	}
  1455  
  1456  	mlog.Warn(fmt.Sprintf("Permanently deleted account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id))
  1457  
  1458  	return nil
  1459  }
  1460  
  1461  func (a *App) PermanentDeleteAllUsers() *model.AppError {
  1462  	result := <-a.Srv.Store.User().GetAll()
  1463  	if result.Err != nil {
  1464  		return result.Err
  1465  	}
  1466  	users := result.Data.([]*model.User)
  1467  	for _, user := range users {
  1468  		a.PermanentDeleteUser(user)
  1469  	}
  1470  
  1471  	return nil
  1472  }
  1473  
  1474  func (a *App) SendEmailVerification(user *model.User, newEmail string) *model.AppError {
  1475  	token, err := a.CreateVerifyEmailToken(user.Id, newEmail)
  1476  	if err != nil {
  1477  		return err
  1478  	}
  1479  
  1480  	if _, err := a.GetStatus(user.Id); err != nil {
  1481  		return a.SendVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token)
  1482  	}
  1483  	return a.SendEmailChangeVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token)
  1484  }
  1485  
  1486  func (a *App) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError {
  1487  	token, err := a.GetVerifyEmailToken(userSuppliedTokenString)
  1488  	if err != nil {
  1489  		return err
  1490  	}
  1491  	if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME {
  1492  		return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.link_expired.app_error", nil, "", http.StatusBadRequest)
  1493  	}
  1494  
  1495  	tokenData := struct {
  1496  		UserId string
  1497  		Email  string
  1498  	}{}
  1499  
  1500  	err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
  1501  	if err2 != nil {
  1502  		return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.token_parse.error", nil, "", http.StatusInternalServerError)
  1503  	}
  1504  
  1505  	user, err := a.GetUser(tokenData.UserId)
  1506  	if err != nil {
  1507  		return err
  1508  	}
  1509  
  1510  	if err := a.VerifyUserEmail(tokenData.UserId, tokenData.Email); err != nil {
  1511  		return err
  1512  	}
  1513  
  1514  	if user.Email != tokenData.Email {
  1515  		a.Srv.Go(func() {
  1516  			if err := a.SendEmailChangeEmail(user.Email, tokenData.Email, user.Locale, a.GetSiteURL()); err != nil {
  1517  				mlog.Error(err.Error())
  1518  			}
  1519  		})
  1520  	}
  1521  
  1522  	if err := a.DeleteToken(token); err != nil {
  1523  		mlog.Error(err.Error())
  1524  	}
  1525  
  1526  	return nil
  1527  }
  1528  
  1529  func (a *App) CreateVerifyEmailToken(userId string, newEmail string) (*model.Token, *model.AppError) {
  1530  	tokenExtra := struct {
  1531  		UserId string
  1532  		Email  string
  1533  	}{
  1534  		userId,
  1535  		newEmail,
  1536  	}
  1537  	jsonData, err := json.Marshal(tokenExtra)
  1538  
  1539  	if err != nil {
  1540  		return nil, model.NewAppError("CreateVerifyEmailToken", "api.user.create_email_token.error", nil, "", http.StatusInternalServerError)
  1541  	}
  1542  
  1543  	token := model.NewToken(TOKEN_TYPE_VERIFY_EMAIL, string(jsonData))
  1544  
  1545  	if result := <-a.Srv.Store.Token().Save(token); result.Err != nil {
  1546  		return nil, result.Err
  1547  	}
  1548  
  1549  	return token, nil
  1550  }
  1551  
  1552  func (a *App) GetVerifyEmailToken(token string) (*model.Token, *model.AppError) {
  1553  	result := <-a.Srv.Store.Token().GetByToken(token)
  1554  	if result.Err != nil {
  1555  		return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.bad_link.app_error", nil, result.Err.Error(), http.StatusBadRequest)
  1556  	}
  1557  	rtoken := result.Data.(*model.Token)
  1558  	if rtoken.Type != TOKEN_TYPE_VERIFY_EMAIL {
  1559  		return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.broken_token.app_error", nil, "", http.StatusBadRequest)
  1560  	}
  1561  	return rtoken, nil
  1562  }
  1563  
  1564  // GetTotalUsersStats is used for the DM list total
  1565  func (a *App) GetTotalUsersStats() (*model.UsersStats, *model.AppError) {
  1566  	result := <-a.Srv.Store.User().Count(model.UserCountOptions{
  1567  		IncludeBotAccounts: true,
  1568  	})
  1569  	if result.Err != nil {
  1570  		return nil, result.Err
  1571  	}
  1572  	stats := &model.UsersStats{
  1573  		TotalUsersCount: result.Data.(int64),
  1574  	}
  1575  	return stats, nil
  1576  }
  1577  
  1578  func (a *App) VerifyUserEmail(userId, email string) *model.AppError {
  1579  	err := (<-a.Srv.Store.User().VerifyEmail(userId, email)).Err
  1580  
  1581  	if err != nil {
  1582  		return err
  1583  	}
  1584  
  1585  	user, err := a.GetUser(userId)
  1586  
  1587  	if err != nil {
  1588  		return err
  1589  	}
  1590  
  1591  	a.sendUpdatedUserEvent(*user)
  1592  
  1593  	return nil
  1594  }
  1595  
  1596  func (a *App) SearchUsers(props *model.UserSearch, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1597  	if props.WithoutTeam {
  1598  		return a.SearchUsersWithoutTeam(props.Term, options)
  1599  	}
  1600  	if props.InChannelId != "" {
  1601  		return a.SearchUsersInChannel(props.InChannelId, props.Term, options)
  1602  	}
  1603  	if props.NotInChannelId != "" {
  1604  		return a.SearchUsersNotInChannel(props.TeamId, props.NotInChannelId, props.Term, options)
  1605  	}
  1606  	if props.NotInTeamId != "" {
  1607  		return a.SearchUsersNotInTeam(props.NotInTeamId, props.Term, options)
  1608  	}
  1609  	return a.SearchUsersInTeam(props.TeamId, props.Term, options)
  1610  }
  1611  
  1612  func (a *App) SearchUsersInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1613  	result := <-a.Srv.Store.User().SearchInChannel(channelId, term, options)
  1614  	if result.Err != nil {
  1615  		return nil, result.Err
  1616  	}
  1617  	users := result.Data.([]*model.User)
  1618  
  1619  	for _, user := range users {
  1620  		a.SanitizeProfile(user, options.IsAdmin)
  1621  	}
  1622  
  1623  	return users, nil
  1624  }
  1625  
  1626  func (a *App) SearchUsersNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1627  	result := <-a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options)
  1628  	if result.Err != nil {
  1629  		return nil, result.Err
  1630  	}
  1631  	users := result.Data.([]*model.User)
  1632  
  1633  	for _, user := range users {
  1634  		a.SanitizeProfile(user, options.IsAdmin)
  1635  	}
  1636  
  1637  	return users, nil
  1638  }
  1639  
  1640  func (a *App) SearchUsersInTeam(teamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1641  	result := <-a.Srv.Store.User().Search(teamId, term, options)
  1642  
  1643  	if result.Err != nil {
  1644  		return nil, result.Err
  1645  	}
  1646  	users := result.Data.([]*model.User)
  1647  
  1648  	for _, user := range users {
  1649  		a.SanitizeProfile(user, options.IsAdmin)
  1650  	}
  1651  
  1652  	return users, nil
  1653  }
  1654  
  1655  func (a *App) SearchUsersNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1656  	result := <-a.Srv.Store.User().SearchNotInTeam(notInTeamId, term, options)
  1657  	if result.Err != nil {
  1658  		return nil, result.Err
  1659  	}
  1660  	users := result.Data.([]*model.User)
  1661  
  1662  	for _, user := range users {
  1663  		a.SanitizeProfile(user, options.IsAdmin)
  1664  	}
  1665  
  1666  	return users, nil
  1667  }
  1668  
  1669  func (a *App) SearchUsersWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1670  	result := <-a.Srv.Store.User().SearchWithoutTeam(term, options)
  1671  	if result.Err != nil {
  1672  		return nil, result.Err
  1673  	}
  1674  	users := result.Data.([]*model.User)
  1675  
  1676  	for _, user := range users {
  1677  		a.SanitizeProfile(user, options.IsAdmin)
  1678  	}
  1679  
  1680  	return users, nil
  1681  }
  1682  
  1683  func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInChannel, *model.AppError) {
  1684  	uchan := a.Srv.Store.User().SearchInChannel(channelId, term, options)
  1685  	nuchan := a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options)
  1686  
  1687  	autocomplete := &model.UserAutocompleteInChannel{}
  1688  
  1689  	result := <-uchan
  1690  	if result.Err != nil {
  1691  		return nil, result.Err
  1692  	}
  1693  	users := result.Data.([]*model.User)
  1694  
  1695  	for _, user := range users {
  1696  		a.SanitizeProfile(user, options.IsAdmin)
  1697  	}
  1698  
  1699  	autocomplete.InChannel = users
  1700  
  1701  	result = <-nuchan
  1702  	if result.Err != nil {
  1703  		return nil, result.Err
  1704  	}
  1705  	users = result.Data.([]*model.User)
  1706  
  1707  	for _, user := range users {
  1708  		a.SanitizeProfile(user, options.IsAdmin)
  1709  	}
  1710  
  1711  	autocomplete.OutOfChannel = users
  1712  
  1713  	return autocomplete, nil
  1714  }
  1715  
  1716  func (a *App) AutocompleteUsersInTeam(teamId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInTeam, *model.AppError) {
  1717  	autocomplete := &model.UserAutocompleteInTeam{}
  1718  	result := <-a.Srv.Store.User().Search(teamId, term, options)
  1719  
  1720  	if result.Err != nil {
  1721  		return nil, result.Err
  1722  	}
  1723  	users := result.Data.([]*model.User)
  1724  
  1725  	for _, user := range users {
  1726  		a.SanitizeProfile(user, options.IsAdmin)
  1727  	}
  1728  
  1729  	autocomplete.InTeam = users
  1730  
  1731  	return autocomplete, nil
  1732  }
  1733  
  1734  func (a *App) UpdateOAuthUserAttrs(userData io.Reader, user *model.User, provider einterfaces.OauthProvider, service string) *model.AppError {
  1735  	oauthUser := provider.GetUserFromJson(userData)
  1736  	if oauthUser == nil {
  1737  		return model.NewAppError("UpdateOAuthUserAttrs", "api.user.update_oauth_user_attrs.get_user.app_error", map[string]interface{}{"Service": service}, "", http.StatusBadRequest)
  1738  	}
  1739  
  1740  	userAttrsChanged := false
  1741  
  1742  	if oauthUser.Username != user.Username {
  1743  		if existingUser, _ := a.GetUserByUsername(oauthUser.Username); existingUser == nil {
  1744  			user.Username = oauthUser.Username
  1745  			userAttrsChanged = true
  1746  		}
  1747  	}
  1748  
  1749  	if oauthUser.GetFullName() != user.GetFullName() {
  1750  		user.FirstName = oauthUser.FirstName
  1751  		user.LastName = oauthUser.LastName
  1752  		userAttrsChanged = true
  1753  	}
  1754  
  1755  	if oauthUser.Email != user.Email {
  1756  		if existingUser, _ := a.GetUserByEmail(oauthUser.Email); existingUser == nil {
  1757  			user.Email = oauthUser.Email
  1758  			userAttrsChanged = true
  1759  		}
  1760  	}
  1761  
  1762  	if user.DeleteAt > 0 {
  1763  		// Make sure they are not disabled
  1764  		user.DeleteAt = 0
  1765  		userAttrsChanged = true
  1766  	}
  1767  
  1768  	if userAttrsChanged {
  1769  		result := <-a.Srv.Store.User().Update(user, true)
  1770  		if result.Err != nil {
  1771  			return result.Err
  1772  		}
  1773  
  1774  		user = result.Data.([2]*model.User)[0]
  1775  		a.InvalidateCacheForUser(user.Id)
  1776  	}
  1777  
  1778  	return nil
  1779  }