github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/store/sqlstore/user_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package sqlstore
     5  
     6  import (
     7  	"database/sql"
     8  	"encoding/json"
     9  	"fmt"
    10  	"net/http"
    11  	"sort"
    12  	"strings"
    13  
    14  	"github.com/Masterminds/squirrel"
    15  	sq "github.com/Masterminds/squirrel"
    16  	"github.com/mattermost/gorp"
    17  
    18  	"github.com/vnforks/kid/v5/einterfaces"
    19  	"github.com/vnforks/kid/v5/model"
    20  	"github.com/vnforks/kid/v5/store"
    21  )
    22  
    23  const (
    24  	MAX_GROUP_CLASSES_FOR_PROFILES = 50
    25  )
    26  
    27  var (
    28  	USER_SEARCH_TYPE_NAMES_NO_FULL_NAME = []string{"Username", "Nickname"}
    29  	USER_SEARCH_TYPE_NAMES              = []string{"Username", "FirstName", "LastName", "Nickname"}
    30  	USER_SEARCH_TYPE_ALL_NO_FULL_NAME   = []string{"Username", "Nickname", "Email"}
    31  	USER_SEARCH_TYPE_ALL                = []string{"Username", "FirstName", "LastName", "Nickname", "Email"}
    32  )
    33  
    34  type SqlUserStore struct {
    35  	SqlStore
    36  	metrics einterfaces.MetricsInterface
    37  
    38  	// usersQuery is a starting point for all queries that return one or more Users.
    39  	usersQuery sq.SelectBuilder
    40  }
    41  
    42  func (us SqlUserStore) ClearCaches() {}
    43  
    44  func (us SqlUserStore) InvalidateProfileCacheForUser(userId string) {}
    45  
    46  func newSqlUserStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.UserStore {
    47  	us := &SqlUserStore{
    48  		SqlStore: sqlStore,
    49  		metrics:  metrics,
    50  	}
    51  
    52  	// note: we are providing field names explicitly here to maintain order of columns (needed when using raw queries)
    53  	us.usersQuery = us.getQueryBuilder().
    54  		Select("u.Id", "u.CreateAt", "u.UpdateAt", "u.DeleteAt", "u.Username", "u.Password", "u.AuthData", "u.AuthService", "u.Email", "u.EmailVerified", "u.Nickname", "u.FirstName", "u.LastName", "u.Position", "u.Roles", "u.AllowMarketing", "u.Props", "u.NotifyProps", "u.LastPasswordUpdate", "u.LastPictureUpdate", "u.FailedAttempts", "u.Locale", "u.Timezone", "u.MfaActive", "u.MfaSecret").
    55  		From("Users u")
    56  
    57  	for _, db := range sqlStore.GetAllConns() {
    58  		table := db.AddTableWithName(model.User{}, "Users").SetKeys(false, "Id")
    59  		table.ColMap("Id").SetMaxSize(26)
    60  		table.ColMap("Username").SetMaxSize(64).SetUnique(true)
    61  		table.ColMap("Password").SetMaxSize(128)
    62  		table.ColMap("AuthData").SetMaxSize(128).SetUnique(true)
    63  		table.ColMap("AuthService").SetMaxSize(32)
    64  		table.ColMap("Email").SetMaxSize(128).SetUnique(true)
    65  		table.ColMap("Nickname").SetMaxSize(64)
    66  		table.ColMap("FirstName").SetMaxSize(64)
    67  		table.ColMap("LastName").SetMaxSize(64)
    68  		table.ColMap("Roles").SetMaxSize(256)
    69  		table.ColMap("Props").SetMaxSize(4000)
    70  		table.ColMap("NotifyProps").SetMaxSize(2000)
    71  		table.ColMap("Locale").SetMaxSize(5)
    72  		table.ColMap("MfaSecret").SetMaxSize(128)
    73  		table.ColMap("Position").SetMaxSize(128)
    74  		table.ColMap("Timezone").SetMaxSize(256)
    75  	}
    76  
    77  	return us
    78  }
    79  
    80  func (us SqlUserStore) createIndexesIfNotExists() {
    81  	us.CreateIndexIfNotExists("idx_users_email", "Users", "Email")
    82  	us.CreateIndexIfNotExists("idx_users_update_at", "Users", "UpdateAt")
    83  	us.CreateIndexIfNotExists("idx_users_create_at", "Users", "CreateAt")
    84  	us.CreateIndexIfNotExists("idx_users_delete_at", "Users", "DeleteAt")
    85  
    86  	if us.DriverName() == model.DATABASE_DRIVER_POSTGRES {
    87  		us.CreateIndexIfNotExists("idx_users_email_lower_textpattern", "Users", "lower(Email) text_pattern_ops")
    88  		us.CreateIndexIfNotExists("idx_users_username_lower_textpattern", "Users", "lower(Username) text_pattern_ops")
    89  		us.CreateIndexIfNotExists("idx_users_nickname_lower_textpattern", "Users", "lower(Nickname) text_pattern_ops")
    90  		us.CreateIndexIfNotExists("idx_users_firstname_lower_textpattern", "Users", "lower(FirstName) text_pattern_ops")
    91  		us.CreateIndexIfNotExists("idx_users_lastname_lower_textpattern", "Users", "lower(LastName) text_pattern_ops")
    92  	}
    93  
    94  	us.CreateFullTextIndexIfNotExists("idx_users_all_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL, ", "))
    95  	us.CreateFullTextIndexIfNotExists("idx_users_all_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL_NO_FULL_NAME, ", "))
    96  	us.CreateFullTextIndexIfNotExists("idx_users_names_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES, ", "))
    97  	us.CreateFullTextIndexIfNotExists("idx_users_names_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES_NO_FULL_NAME, ", "))
    98  }
    99  
   100  func (us SqlUserStore) Save(user *model.User) (*model.User, *model.AppError) {
   101  	if len(user.Id) > 0 {
   102  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.existing.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   103  	}
   104  
   105  	user.PreSave()
   106  	if err := user.IsValid(); err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	if err := us.GetMaster().Insert(user); err != nil {
   111  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique"}) {
   112  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.email_exists.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   113  		}
   114  		if IsUniqueConstraintError(err, []string{"Username", "users_username_key", "idx_users_username_unique"}) {
   115  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.username_exists.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   116  		}
   117  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   118  	}
   119  
   120  	return user, nil
   121  }
   122  
   123  func (us SqlUserStore) Update(user *model.User, trustedUpdateData bool) (*model.UserUpdate, *model.AppError) {
   124  	user.PreUpdate()
   125  
   126  	if err := user.IsValid(); err != nil {
   127  		return nil, err
   128  	}
   129  
   130  	oldUserResult, err := us.GetMaster().Get(model.User{}, user.Id)
   131  	if err != nil {
   132  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.finding.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   133  	}
   134  
   135  	if oldUserResult == nil {
   136  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.find.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   137  	}
   138  
   139  	oldUser := oldUserResult.(*model.User)
   140  	user.CreateAt = oldUser.CreateAt
   141  	user.AuthData = oldUser.AuthData
   142  	user.AuthService = oldUser.AuthService
   143  	user.Password = oldUser.Password
   144  	user.LastPasswordUpdate = oldUser.LastPasswordUpdate
   145  	user.LastPictureUpdate = oldUser.LastPictureUpdate
   146  	user.EmailVerified = oldUser.EmailVerified
   147  	user.FailedAttempts = oldUser.FailedAttempts
   148  	user.MfaSecret = oldUser.MfaSecret
   149  	user.MfaActive = oldUser.MfaActive
   150  
   151  	if !trustedUpdateData {
   152  		user.Roles = oldUser.Roles
   153  		user.DeleteAt = oldUser.DeleteAt
   154  	}
   155  
   156  	if user.IsOAuthUser() {
   157  		if !trustedUpdateData {
   158  			user.Email = oldUser.Email
   159  		}
   160  	} else if user.IsLDAPUser() && !trustedUpdateData {
   161  		if user.Username != oldUser.Username || user.Email != oldUser.Email {
   162  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.can_not_change_ldap.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   163  		}
   164  	} else if user.Email != oldUser.Email {
   165  		user.EmailVerified = false
   166  	}
   167  
   168  	if user.Username != oldUser.Username {
   169  		user.UpdateMentionKeysFromUsername(oldUser.Username)
   170  	}
   171  
   172  	count, err := us.GetMaster().Update(user)
   173  	if err != nil {
   174  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique"}) {
   175  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.email_taken.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   176  		}
   177  		if IsUniqueConstraintError(err, []string{"Username", "users_username_key", "idx_users_username_unique"}) {
   178  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.username_taken.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   179  		}
   180  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.updating.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   181  	}
   182  
   183  	if count != 1 {
   184  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.app_error", nil, fmt.Sprintf("user_id=%v, count=%v", user.Id, count), http.StatusInternalServerError)
   185  	}
   186  
   187  	user.Sanitize(map[string]bool{})
   188  	oldUser.Sanitize(map[string]bool{})
   189  	return &model.UserUpdate{New: user, Old: oldUser}, nil
   190  }
   191  
   192  func (us SqlUserStore) UpdateLastPictureUpdate(userId string) *model.AppError {
   193  	curTime := model.GetMillis()
   194  
   195  	if _, err := us.GetMaster().Exec("UPDATE Users SET LastPictureUpdate = :Time, UpdateAt = :Time WHERE Id = :UserId", map[string]interface{}{"Time": curTime, "UserId": userId}); err != nil {
   196  		return model.NewAppError("SqlUserStore.UpdateLastPictureUpdate", "store.sql_user.update_last_picture_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   197  	}
   198  
   199  	return nil
   200  }
   201  
   202  func (us SqlUserStore) ResetLastPictureUpdate(userId string) *model.AppError {
   203  	curTime := model.GetMillis()
   204  
   205  	if _, err := us.GetMaster().Exec("UPDATE Users SET LastPictureUpdate = :PictureUpdateTime, UpdateAt = :UpdateTime WHERE Id = :UserId", map[string]interface{}{"PictureUpdateTime": 0, "UpdateTime": curTime, "UserId": userId}); err != nil {
   206  		return model.NewAppError("SqlUserStore.ResetLastPictureUpdate", "store.sql_user.update_last_picture_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   207  	}
   208  
   209  	return nil
   210  }
   211  
   212  func (us SqlUserStore) UpdateUpdateAt(userId string) (int64, *model.AppError) {
   213  	curTime := model.GetMillis()
   214  
   215  	if _, err := us.GetMaster().Exec("UPDATE Users SET UpdateAt = :Time WHERE Id = :UserId", map[string]interface{}{"Time": curTime, "UserId": userId}); err != nil {
   216  		return curTime, model.NewAppError("SqlUserStore.UpdateUpdateAt", "store.sql_user.update_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   217  	}
   218  
   219  	return curTime, nil
   220  }
   221  
   222  func (us SqlUserStore) UpdatePassword(userId, hashedPassword string) *model.AppError {
   223  	updateAt := model.GetMillis()
   224  
   225  	if _, err := us.GetMaster().Exec("UPDATE Users SET Password = :Password, LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt, AuthData = NULL, AuthService = '', FailedAttempts = 0 WHERE Id = :UserId", map[string]interface{}{"Password": hashedPassword, "LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId}); err != nil {
   226  		return model.NewAppError("SqlUserStore.UpdatePassword", "store.sql_user.update_password.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   227  	}
   228  
   229  	return nil
   230  }
   231  
   232  func (us SqlUserStore) UpdateFailedPasswordAttempts(userId string, attempts int) *model.AppError {
   233  	if _, err := us.GetMaster().Exec("UPDATE Users SET FailedAttempts = :FailedAttempts WHERE Id = :UserId", map[string]interface{}{"FailedAttempts": attempts, "UserId": userId}); err != nil {
   234  		return model.NewAppError("SqlUserStore.UpdateFailedPasswordAttempts", "store.sql_user.update_failed_pwd_attempts.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   235  	}
   236  
   237  	return nil
   238  }
   239  
   240  func (us SqlUserStore) UpdateAuthData(userId string, service string, authData *string, email string, resetMfa bool) (string, *model.AppError) {
   241  	email = strings.ToLower(email)
   242  
   243  	updateAt := model.GetMillis()
   244  
   245  	query := `
   246  			UPDATE
   247  			     Users
   248  			SET
   249  			     Password = '',
   250  			     LastPasswordUpdate = :LastPasswordUpdate,
   251  			     UpdateAt = :UpdateAt,
   252  			     FailedAttempts = 0,
   253  			     AuthService = :AuthService,
   254  			     AuthData = :AuthData`
   255  
   256  	if len(email) != 0 {
   257  		query += ", Email = :Email"
   258  	}
   259  
   260  	if resetMfa {
   261  		query += ", MfaActive = false, MfaSecret = ''"
   262  	}
   263  
   264  	query += " WHERE Id = :UserId"
   265  
   266  	if _, err := us.GetMaster().Exec(query, map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData, "Email": email}); err != nil {
   267  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique", "AuthData", "users_authdata_key"}) {
   268  			return "", model.NewAppError("SqlUserStore.UpdateAuthData", "store.sql_user.update_auth_data.email_exists.app_error", map[string]interface{}{"Service": service, "Email": email}, "user_id="+userId+", "+err.Error(), http.StatusBadRequest)
   269  		}
   270  		return "", model.NewAppError("SqlUserStore.UpdateAuthData", "store.sql_user.update_auth_data.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   271  	}
   272  	return userId, nil
   273  }
   274  
   275  func (us SqlUserStore) UpdateMfaSecret(userId, secret string) *model.AppError {
   276  	updateAt := model.GetMillis()
   277  
   278  	if _, err := us.GetMaster().Exec("UPDATE Users SET MfaSecret = :Secret, UpdateAt = :UpdateAt WHERE Id = :UserId", map[string]interface{}{"Secret": secret, "UpdateAt": updateAt, "UserId": userId}); err != nil {
   279  		return model.NewAppError("SqlUserStore.UpdateMfaSecret", "store.sql_user.update_mfa_secret.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   280  	}
   281  
   282  	return nil
   283  }
   284  
   285  func (us SqlUserStore) UpdateMfaActive(userId string, active bool) *model.AppError {
   286  	updateAt := model.GetMillis()
   287  
   288  	if _, err := us.GetMaster().Exec("UPDATE Users SET MfaActive = :Active, UpdateAt = :UpdateAt WHERE Id = :UserId", map[string]interface{}{"Active": active, "UpdateAt": updateAt, "UserId": userId}); err != nil {
   289  		return model.NewAppError("SqlUserStore.UpdateMfaActive", "store.sql_user.update_mfa_active.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   290  	}
   291  
   292  	return nil
   293  }
   294  
   295  func (us SqlUserStore) Get(id string) (*model.User, *model.AppError) {
   296  	query := us.usersQuery.Where("Id = ?", id)
   297  
   298  	queryString, args, err := query.ToSql()
   299  	if err != nil {
   300  		return nil, model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   301  	}
   302  
   303  	user := &model.User{}
   304  	if err := us.GetReplica().SelectOne(user, queryString, args...); err == sql.ErrNoRows {
   305  		return nil, model.NewAppError("SqlUserStore.Get", store.MISSING_ACCOUNT_ERROR, nil, "user_id="+id, http.StatusNotFound)
   306  	} else if err != nil {
   307  		return nil, model.NewAppError("SqlUserStore.Get", "store.sql_user.get.app_error", nil, "user_id="+id+", "+err.Error(), http.StatusInternalServerError)
   308  	}
   309  
   310  	return user, nil
   311  }
   312  
   313  func (us SqlUserStore) GetAll() ([]*model.User, *model.AppError) {
   314  	query := us.usersQuery.OrderBy("Username ASC")
   315  
   316  	queryString, args, err := query.ToSql()
   317  	if err != nil {
   318  		return nil, model.NewAppError("SqlUserStore.GetAll", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   319  	}
   320  
   321  	var data []*model.User
   322  	if _, err := us.GetReplica().Select(&data, queryString, args...); err != nil {
   323  		return nil, model.NewAppError("SqlUserStore.GetAll", "store.sql_user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   324  	}
   325  	return data, nil
   326  }
   327  
   328  func (us SqlUserStore) GetAllAfter(limit int, afterId string) ([]*model.User, *model.AppError) {
   329  	query := us.usersQuery.
   330  		Where("Id > ?", afterId).
   331  		OrderBy("Id ASC").
   332  		Limit(uint64(limit))
   333  
   334  	queryString, args, err := query.ToSql()
   335  	if err != nil {
   336  		return nil, model.NewAppError("SqlUserStore.GetAllAfter", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   337  	}
   338  
   339  	var users []*model.User
   340  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   341  		return nil, model.NewAppError("SqlUserStore.GetAllAfter", "store.sql_user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   342  	}
   343  
   344  	return users, nil
   345  }
   346  
   347  func (us SqlUserStore) GetEtagForAllProfiles() string {
   348  	updateAt, err := us.GetReplica().SelectInt("SELECT UpdateAt FROM Users ORDER BY UpdateAt DESC LIMIT 1")
   349  	if err != nil {
   350  		return fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
   351  	}
   352  	return fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt)
   353  }
   354  
   355  func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   356  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   357  	query := us.usersQuery.
   358  		OrderBy("u.Username ASC").
   359  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   360  
   361  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   362  
   363  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   364  
   365  	if options.Inactive {
   366  		query = query.Where("u.DeleteAt != 0")
   367  	}
   368  
   369  	queryString, args, err := query.ToSql()
   370  	if err != nil {
   371  		return nil, model.NewAppError("SqlUserStore.GetAllProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   372  	}
   373  
   374  	var users []*model.User
   375  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   376  		return nil, model.NewAppError("SqlUserStore.GetAllProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   377  	}
   378  
   379  	for _, u := range users {
   380  		u.Sanitize(map[string]bool{})
   381  	}
   382  
   383  	return users, nil
   384  }
   385  
   386  func applyRoleFilter(query sq.SelectBuilder, role string, isPostgreSQL bool) sq.SelectBuilder {
   387  	if role == "" {
   388  		return query
   389  	}
   390  
   391  	if isPostgreSQL {
   392  		roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "\\"))
   393  		return query.Where("u.Roles LIKE LOWER(?)", roleParam)
   394  	}
   395  
   396  	roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "*"))
   397  
   398  	return query.Where("u.Roles LIKE ? ESCAPE '*'", roleParam)
   399  }
   400  
   401  func (us SqlUserStore) GetEtagForProfiles(branchId string) string {
   402  	updateAt, err := us.GetReplica().SelectInt("SELECT UpdateAt FROM Users, BranchMembers WHERE BranchMembers.BranchId = :BranchId AND Users.Id = BranchMembers.UserId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"BranchId": branchId})
   403  	if err != nil {
   404  		return fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
   405  	}
   406  	return fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt)
   407  }
   408  
   409  func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   410  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   411  	query := us.usersQuery.
   412  		Join("BranchMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 )").
   413  		Where("tm.BranchId = ?", options.InBranchId).
   414  		OrderBy("u.Username ASC").
   415  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   416  
   417  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   418  
   419  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   420  
   421  	if options.Inactive {
   422  		query = query.Where("u.DeleteAt != 0")
   423  	}
   424  
   425  	queryString, args, err := query.ToSql()
   426  	if err != nil {
   427  		return nil, model.NewAppError("SqlUserStore.GetProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   428  	}
   429  
   430  	var users []*model.User
   431  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   432  		return nil, model.NewAppError("SqlUserStore.GetProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   433  	}
   434  
   435  	for _, u := range users {
   436  		u.Sanitize(map[string]bool{})
   437  	}
   438  
   439  	return users, nil
   440  }
   441  
   442  func (us SqlUserStore) InvalidateProfilesInClassCacheByUser(userId string) {}
   443  
   444  func (us SqlUserStore) InvalidateProfilesInClassCache(classId string) {}
   445  
   446  func (us SqlUserStore) GetProfilesInClass(classId string, offset int, limit int) ([]*model.User, *model.AppError) {
   447  	query := us.usersQuery.
   448  		Join("ClassMembers cm ON ( cm.UserId = u.Id )").
   449  		Where("cm.ClassId = ?", classId).
   450  		OrderBy("u.Username ASC").
   451  		Offset(uint64(offset)).Limit(uint64(limit))
   452  
   453  	queryString, args, err := query.ToSql()
   454  	if err != nil {
   455  		return nil, model.NewAppError("SqlUserStore.GetProfilesInClass", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   456  	}
   457  
   458  	var users []*model.User
   459  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   460  		return nil, model.NewAppError("SqlUserStore.GetProfilesInClass", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   461  	}
   462  
   463  	for _, u := range users {
   464  		u.Sanitize(map[string]bool{})
   465  	}
   466  
   467  	return users, nil
   468  }
   469  
   470  func (us SqlUserStore) GetProfilesInClassByStatus(classId string, offset int, limit int) ([]*model.User, *model.AppError) {
   471  	query := us.usersQuery.
   472  		Join("ClassMembers cm ON ( cm.UserId = u.Id )").
   473  		LeftJoin("Status s ON ( s.UserId = u.Id )").
   474  		Where("cm.ClassId = ?", classId).
   475  		OrderBy(`
   476  			CASE s.Status
   477  				WHEN 'online' THEN 1
   478  				WHEN 'away' THEN 2
   479  				WHEN 'dnd' THEN 3
   480  				ELSE 4
   481  			END
   482  			`).
   483  		OrderBy("u.Username ASC").
   484  		Offset(uint64(offset)).Limit(uint64(limit))
   485  
   486  	queryString, args, err := query.ToSql()
   487  	if err != nil {
   488  		return nil, model.NewAppError("SqlUserStore.GetProfilesInClassByStatus", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   489  	}
   490  
   491  	var users []*model.User
   492  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   493  		return nil, model.NewAppError("SqlUserStore.GetProfilesInClassByStatus", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   494  	}
   495  
   496  	for _, u := range users {
   497  		u.Sanitize(map[string]bool{})
   498  	}
   499  
   500  	return users, nil
   501  }
   502  
   503  func (us SqlUserStore) GetAllProfilesInClass(classId string, allowFromCache bool) (map[string]*model.User, *model.AppError) {
   504  	failure := func(e error) (map[string]*model.User, *model.AppError) {
   505  		return nil, model.NewAppError("SqlUserStore.GetAllProfilesInClass", "store.sql_user.app_error", nil, e.Error(), http.StatusInternalServerError)
   506  	}
   507  	query := us.usersQuery.
   508  		Join("ClassMembers cm ON ( cm.UserId = u.Id )").
   509  		Where("cm.ClassId = ?", classId).
   510  		Where("u.DeleteAt = 0").
   511  		OrderBy("u.Username ASC")
   512  
   513  	queryString, args, err := query.ToSql()
   514  	if err != nil {
   515  		return failure(err)
   516  	}
   517  	var users []*model.User
   518  	rows, err := us.GetReplica().Db.Query(queryString, args...)
   519  	if err != nil {
   520  		return failure(err)
   521  	}
   522  
   523  	defer rows.Close()
   524  	for rows.Next() {
   525  		var user model.User
   526  		var props, notifyProps, timezone []byte
   527  		if err = rows.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username, &user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified, &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, &notifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate); err != nil {
   528  			return failure(err)
   529  		}
   530  		if err = json.Unmarshal(props, &user.Props); err != nil {
   531  			return failure(err)
   532  		}
   533  		if err = json.Unmarshal(notifyProps, &user.NotifyProps); err != nil {
   534  			return failure(err)
   535  		}
   536  		if err = json.Unmarshal(timezone, &user.Timezone); err != nil {
   537  			return failure(err)
   538  		}
   539  		users = append(users, &user)
   540  	}
   541  	err = rows.Err()
   542  	if err != nil {
   543  		return failure(err)
   544  	}
   545  
   546  	userMap := make(map[string]*model.User)
   547  
   548  	for _, u := range users {
   549  		u.Sanitize(map[string]bool{})
   550  		userMap[u.Id] = u
   551  	}
   552  
   553  	return userMap, nil
   554  }
   555  
   556  func (us SqlUserStore) GetProfilesNotInClass(branchId string, classId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   557  	query := us.usersQuery.
   558  		Join("BranchMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.BranchId = ? )", branchId).
   559  		LeftJoin("ClassMembers cm ON ( cm.UserId = u.Id AND cm.ClassId = ? )", classId).
   560  		Where("cm.UserId IS NULL").
   561  		OrderBy("u.Username ASC").
   562  		Offset(uint64(offset)).Limit(uint64(limit))
   563  
   564  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   565  
   566  	queryString, args, err := query.ToSql()
   567  	if err != nil {
   568  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInClass", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   569  	}
   570  
   571  	var users []*model.User
   572  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   573  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInClass", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   574  	}
   575  
   576  	for _, u := range users {
   577  		u.Sanitize(map[string]bool{})
   578  	}
   579  
   580  	return users, nil
   581  }
   582  
   583  func (us SqlUserStore) GetProfilesWithoutBranch(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   584  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   585  	query := us.usersQuery.
   586  		Where(`(
   587  			SELECT
   588  				COUNT(0)
   589  			FROM
   590  				BranchMembers
   591  			WHERE
   592  				BranchMembers.UserId = u.Id
   593  				AND BranchMembers.DeleteAt = 0
   594  		) = 0`).
   595  		OrderBy("u.Username ASC").
   596  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   597  
   598  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   599  
   600  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   601  
   602  	if options.Inactive {
   603  		query = query.Where("u.DeleteAt != 0")
   604  	}
   605  
   606  	queryString, args, err := query.ToSql()
   607  	if err != nil {
   608  		return nil, model.NewAppError("SqlUserStore.GetProfilesWithoutBranch", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   609  	}
   610  
   611  	var users []*model.User
   612  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   613  		return nil, model.NewAppError("SqlUserStore.GetProfilesWithoutBranch", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   614  	}
   615  
   616  	for _, u := range users {
   617  		u.Sanitize(map[string]bool{})
   618  	}
   619  
   620  	return users, nil
   621  }
   622  
   623  func (us SqlUserStore) GetProfilesByUsernames(usernames []string, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   624  	query := us.usersQuery
   625  
   626  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   627  
   628  	query = query.
   629  		Where(map[string]interface{}{
   630  			"Username": usernames,
   631  		}).
   632  		OrderBy("u.Username ASC")
   633  
   634  	queryString, args, err := query.ToSql()
   635  	if err != nil {
   636  		return nil, model.NewAppError("SqlUserStore.GetProfilesByUsernames", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   637  	}
   638  
   639  	var users []*model.User
   640  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   641  		return nil, model.NewAppError("SqlUserStore.GetProfilesByUsernames", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   642  	}
   643  
   644  	return users, nil
   645  }
   646  
   647  type UserWithLastActivityAt struct {
   648  	model.User
   649  	LastActivityAt int64
   650  }
   651  
   652  func (us SqlUserStore) GetRecentlyActiveUsersForBranch(branchId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   653  	query := us.usersQuery.
   654  		Column("s.LastActivityAt").
   655  		Join("BranchMembers tm ON (tm.UserId = u.Id AND tm.BranchId = ?)", branchId).
   656  		Join("Status s ON (s.UserId = u.Id)").
   657  		OrderBy("s.LastActivityAt DESC").
   658  		OrderBy("u.Username ASC").
   659  		Offset(uint64(offset)).Limit(uint64(limit))
   660  
   661  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   662  
   663  	queryString, args, err := query.ToSql()
   664  	if err != nil {
   665  		return nil, model.NewAppError("SqlUserStore.GetRecentlyActiveUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   666  	}
   667  
   668  	var users []*UserWithLastActivityAt
   669  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   670  		return nil, model.NewAppError("SqlUserStore.GetRecentlyActiveUsers", "store.sql_user.get_recently_active_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   671  	}
   672  
   673  	userList := []*model.User{}
   674  
   675  	for _, userWithLastActivityAt := range users {
   676  		u := userWithLastActivityAt.User
   677  		u.Sanitize(map[string]bool{})
   678  		u.LastActivityAt = userWithLastActivityAt.LastActivityAt
   679  		userList = append(userList, &u)
   680  	}
   681  
   682  	return userList, nil
   683  }
   684  
   685  func (us SqlUserStore) GetNewUsersForBranch(branchId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   686  	query := us.usersQuery.
   687  		Join("BranchMembers tm ON (tm.UserId = u.Id AND tm.BranchId = ?)", branchId).
   688  		OrderBy("u.CreateAt DESC").
   689  		OrderBy("u.Username ASC").
   690  		Offset(uint64(offset)).Limit(uint64(limit))
   691  
   692  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   693  
   694  	queryString, args, err := query.ToSql()
   695  	if err != nil {
   696  		return nil, model.NewAppError("SqlUserStore.GetNewUsersForBranch", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   697  	}
   698  
   699  	var users []*model.User
   700  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   701  		return nil, model.NewAppError("SqlUserStore.GetNewUsersForBranch", "store.sql_user.get_new_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   702  	}
   703  
   704  	for _, u := range users {
   705  		u.Sanitize(map[string]bool{})
   706  	}
   707  
   708  	return users, nil
   709  }
   710  
   711  func (us SqlUserStore) GetProfileByIds(userIds []string, options *store.UserGetByIdsOpts, _ bool) ([]*model.User, *model.AppError) {
   712  	if options == nil {
   713  		options = &store.UserGetByIdsOpts{}
   714  	}
   715  
   716  	users := []*model.User{}
   717  	query := us.usersQuery.
   718  		Where(map[string]interface{}{
   719  			"u.Id": userIds,
   720  		}).
   721  		OrderBy("u.Username ASC")
   722  
   723  	if options.Since > 0 {
   724  		query = query.Where(squirrel.Gt(map[string]interface{}{
   725  			"u.UpdateAt": options.Since,
   726  		}))
   727  	}
   728  
   729  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   730  
   731  	queryString, args, err := query.ToSql()
   732  	if err != nil {
   733  		return nil, model.NewAppError("SqlUserStore.GetProfileByIds", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   734  	}
   735  
   736  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   737  		return nil, model.NewAppError("SqlUserStore.GetProfileByIds", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   738  	}
   739  
   740  	for _, u := range users {
   741  		u.Sanitize(map[string]bool{})
   742  	}
   743  
   744  	return users, nil
   745  }
   746  
   747  type UserWithClass struct {
   748  	model.User
   749  	ClassId string
   750  }
   751  
   752  func (us SqlUserStore) GetSystemAdminProfiles() (map[string]*model.User, *model.AppError) {
   753  	query := us.usersQuery.
   754  		Where("Roles LIKE ?", "%system_admin%").
   755  		OrderBy("u.Username ASC")
   756  
   757  	queryString, args, err := query.ToSql()
   758  	if err != nil {
   759  		return nil, model.NewAppError("SqlUserStore.GetSystemAdminProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   760  	}
   761  
   762  	var users []*model.User
   763  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   764  		return nil, model.NewAppError("SqlUserStore.GetSystemAdminProfiles", "store.sql_user.get_sysadmin_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   765  	}
   766  
   767  	userMap := make(map[string]*model.User)
   768  
   769  	for _, u := range users {
   770  		u.Sanitize(map[string]bool{})
   771  		userMap[u.Id] = u
   772  	}
   773  
   774  	return userMap, nil
   775  }
   776  
   777  func (us SqlUserStore) GetByEmail(email string) (*model.User, *model.AppError) {
   778  	email = strings.ToLower(email)
   779  
   780  	query := us.usersQuery.Where("Email = ?", email)
   781  
   782  	queryString, args, err := query.ToSql()
   783  	if err != nil {
   784  		return nil, model.NewAppError("SqlUserStore.GetByEmail", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   785  	}
   786  
   787  	user := model.User{}
   788  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err != nil {
   789  		return nil, model.NewAppError("SqlUserStore.GetByEmail", store.MISSING_ACCOUNT_ERROR, nil, "email="+email+", "+err.Error(), http.StatusInternalServerError)
   790  	}
   791  
   792  	return &user, nil
   793  }
   794  
   795  func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.User, *model.AppError) {
   796  	if authData == nil || *authData == "" {
   797  		return nil, model.NewAppError("SqlUserStore.GetByAuth", store.MISSING_AUTH_ACCOUNT_ERROR, nil, "authData='', authService="+authService, http.StatusBadRequest)
   798  	}
   799  
   800  	query := us.usersQuery.
   801  		Where("u.AuthData = ?", authData).
   802  		Where("u.AuthService = ?", authService)
   803  
   804  	queryString, args, err := query.ToSql()
   805  	if err != nil {
   806  		return nil, model.NewAppError("SqlUserStore.GetByAuth", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   807  	}
   808  
   809  	user := model.User{}
   810  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err == sql.ErrNoRows {
   811  		return nil, model.NewAppError("SqlUserStore.GetByAuth", store.MISSING_AUTH_ACCOUNT_ERROR, nil, "authData="+*authData+", authService="+authService+", "+err.Error(), http.StatusInternalServerError)
   812  	} else if err != nil {
   813  		return nil, model.NewAppError("SqlUserStore.GetByAuth", "store.sql_user.get_by_auth.other.app_error", nil, "authData="+*authData+", authService="+authService+", "+err.Error(), http.StatusInternalServerError)
   814  	}
   815  	return &user, nil
   816  }
   817  
   818  func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User, *model.AppError) {
   819  	query := us.usersQuery.
   820  		Where("u.AuthService = ?", authService).
   821  		OrderBy("u.Username ASC")
   822  
   823  	queryString, args, err := query.ToSql()
   824  	if err != nil {
   825  		return nil, model.NewAppError("SqlUserStore.GetAllUsingAuthService", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   826  	}
   827  
   828  	var users []*model.User
   829  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   830  		return nil, model.NewAppError("SqlUserStore.GetAllUsingAuthService", "store.sql_user.get_by_auth.other.app_error", nil, "authService="+authService+", "+err.Error(), http.StatusInternalServerError)
   831  	}
   832  
   833  	return users, nil
   834  }
   835  
   836  func (us SqlUserStore) GetByUsername(username string) (*model.User, *model.AppError) {
   837  	query := us.usersQuery.Where("u.Username = ?", username)
   838  
   839  	queryString, args, err := query.ToSql()
   840  	if err != nil {
   841  		return nil, model.NewAppError("SqlUserStore.GetByUsername", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   842  	}
   843  
   844  	var user *model.User
   845  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err != nil {
   846  		return nil, model.NewAppError("SqlUserStore.GetByUsername", "store.sql_user.get_by_username.app_error", nil, err.Error()+" -- "+queryString, http.StatusInternalServerError)
   847  	}
   848  
   849  	return user, nil
   850  }
   851  
   852  func (us SqlUserStore) GetForLogin(loginId string, allowSignInWithUsername, allowSignInWithEmail bool) (*model.User, *model.AppError) {
   853  	query := us.usersQuery
   854  	if allowSignInWithUsername && allowSignInWithEmail {
   855  		query = query.Where("Username = ? OR Email = ?", loginId, loginId)
   856  	} else if allowSignInWithUsername {
   857  		query = query.Where("Username = ?", loginId)
   858  	} else if allowSignInWithEmail {
   859  		query = query.Where("Email = ?", loginId)
   860  	} else {
   861  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, "", http.StatusInternalServerError)
   862  	}
   863  
   864  	queryString, args, err := query.ToSql()
   865  	if err != nil {
   866  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   867  	}
   868  
   869  	users := []*model.User{}
   870  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   871  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, err.Error(), http.StatusInternalServerError)
   872  	}
   873  
   874  	if len(users) == 0 {
   875  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, "", http.StatusInternalServerError)
   876  	}
   877  
   878  	if len(users) > 1 {
   879  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.multiple_users", nil, "", http.StatusInternalServerError)
   880  	}
   881  
   882  	return users[0], nil
   883  
   884  }
   885  
   886  func (us SqlUserStore) VerifyEmail(userId, email string) (string, *model.AppError) {
   887  	curTime := model.GetMillis()
   888  	if _, err := us.GetMaster().Exec("UPDATE Users SET Email = :email, EmailVerified = true, UpdateAt = :Time WHERE Id = :UserId", map[string]interface{}{"email": email, "Time": curTime, "UserId": userId}); err != nil {
   889  		return "", model.NewAppError("SqlUserStore.VerifyEmail", "store.sql_user.verify_email.app_error", nil, "userId="+userId+", "+err.Error(), http.StatusInternalServerError)
   890  	}
   891  
   892  	return userId, nil
   893  }
   894  
   895  func (us SqlUserStore) PermanentDelete(userId string) *model.AppError {
   896  	if _, err := us.GetMaster().Exec("DELETE FROM Users WHERE Id = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
   897  		return model.NewAppError("SqlUserStore.PermanentDelete", "store.sql_user.permanent_delete.app_error", nil, "userId="+userId+", "+err.Error(), http.StatusInternalServerError)
   898  	}
   899  	return nil
   900  }
   901  
   902  func (us SqlUserStore) Count(options model.UserCountOptions) (int64, *model.AppError) {
   903  	query := us.getQueryBuilder().Select("COUNT(DISTINCT u.Id)").From("Users AS u")
   904  
   905  	if !options.IncludeDeleted {
   906  		query = query.Where("u.DeleteAt = 0")
   907  	}
   908  
   909  	if options.BranchId != "" {
   910  		query = query.LeftJoin("BranchMembers AS tm ON u.Id = tm.UserId").Where("tm.BranchId = ? AND tm.DeleteAt = 0", options.BranchId)
   911  	}
   912  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, false)
   913  
   914  	if us.DriverName() == model.DATABASE_DRIVER_POSTGRES {
   915  		query = query.PlaceholderFormat(sq.Dollar)
   916  	}
   917  
   918  	queryString, args, err := query.ToSql()
   919  	if err != nil {
   920  		return int64(0), model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   921  	}
   922  
   923  	count, err := us.GetReplica().SelectInt(queryString, args...)
   924  	if err != nil {
   925  		return int64(0), model.NewAppError("SqlUserStore.Count", "store.sql_user.get_total_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   926  	}
   927  	return count, nil
   928  }
   929  
   930  func (us SqlUserStore) AnalyticsActiveCount(timePeriod int64, options model.UserCountOptions) (int64, *model.AppError) {
   931  
   932  	time := model.GetMillis() - timePeriod
   933  	query := us.getQueryBuilder().Select("COUNT(*)").From("Status AS s").Where("LastActivityAt > :Time", map[string]interface{}{"Time": time})
   934  
   935  	if !options.IncludeDeleted {
   936  		query = query.LeftJoin("Users ON s.UserId = Users.Id").Where("Users.DeleteAt = 0")
   937  	}
   938  
   939  	queryStr, args, err := query.ToSql()
   940  
   941  	if err != nil {
   942  		return 0, model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   943  	}
   944  
   945  	v, err := us.GetReplica().SelectInt(queryStr, args...)
   946  	if err != nil {
   947  		return 0, model.NewAppError("SqlUserStore.AnalyticsDailyActiveUsers", "store.sql_user.analytics_daily_active_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   948  	}
   949  	return v, nil
   950  }
   951  
   952  func (us SqlUserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) {
   953  	count, err := us.GetReplica().SelectInt("SELECT COUNT(Id) FROM Users WHERE DeleteAt > 0")
   954  	if err != nil {
   955  		return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetInactiveUsersCount", "store.sql_user.analytics_get_inactive_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   956  	}
   957  	return count, nil
   958  }
   959  
   960  func (us SqlUserStore) AnalyticsGetSystemAdminCount() (int64, *model.AppError) {
   961  	count, err := us.GetReplica().SelectInt("SELECT count(*) FROM Users WHERE Roles LIKE :Roles and DeleteAt = 0", map[string]interface{}{"Roles": "%system_admin%"})
   962  	if err != nil {
   963  		return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetSystemAdminCount", "store.sql_user.analytics_get_system_admin_count.app_error", nil, err.Error(), http.StatusInternalServerError)
   964  	}
   965  	return count, nil
   966  }
   967  
   968  func (us SqlUserStore) ClearAllCustomRoleAssignments() *model.AppError {
   969  	builtInRoles := model.MakeDefaultRoles()
   970  	lastUserId := strings.Repeat("0", 26)
   971  
   972  	for {
   973  		var transaction *gorp.Transaction
   974  		var err error
   975  
   976  		if transaction, err = us.GetMaster().Begin(); err != nil {
   977  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
   978  		}
   979  		defer finalizeTransaction(transaction)
   980  
   981  		var users []*model.User
   982  		if _, err := transaction.Select(&users, "SELECT * from Users WHERE Id > :Id ORDER BY Id LIMIT 1000", map[string]interface{}{"Id": lastUserId}); err != nil {
   983  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.select.app_error", nil, err.Error(), http.StatusInternalServerError)
   984  		}
   985  
   986  		if len(users) == 0 {
   987  			break
   988  		}
   989  
   990  		for _, user := range users {
   991  			lastUserId = user.Id
   992  
   993  			var newRoles []string
   994  
   995  			for _, role := range strings.Fields(user.Roles) {
   996  				for name := range builtInRoles {
   997  					if name == role {
   998  						newRoles = append(newRoles, role)
   999  						break
  1000  					}
  1001  				}
  1002  			}
  1003  
  1004  			newRolesString := strings.Join(newRoles, " ")
  1005  			if newRolesString != user.Roles {
  1006  				if _, err := transaction.Exec("UPDATE Users SET Roles = :Roles WHERE Id = :Id", map[string]interface{}{"Roles": newRolesString, "Id": user.Id}); err != nil {
  1007  					return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.update.app_error", nil, err.Error(), http.StatusInternalServerError)
  1008  				}
  1009  			}
  1010  		}
  1011  
  1012  		if err := transaction.Commit(); err != nil {
  1013  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1014  		}
  1015  	}
  1016  
  1017  	return nil
  1018  }
  1019  
  1020  func (us SqlUserStore) InferSystemInstallDate() (int64, *model.AppError) {
  1021  	createAt, err := us.GetReplica().SelectInt("SELECT CreateAt FROM Users WHERE CreateAt IS NOT NULL ORDER BY CreateAt ASC LIMIT 1")
  1022  	if err != nil {
  1023  		return 0, model.NewAppError("SqlUserStore.GetSystemInstallDate", "store.sql_user.get_system_install_date.app_error", nil, err.Error(), http.StatusInternalServerError)
  1024  	}
  1025  
  1026  	return createAt, nil
  1027  }
  1028  
  1029  func (us SqlUserStore) GetUnreadCount(userId string) (int64, *model.AppError) {
  1030  	query := `
  1031  		SELECT SUM(CASE WHEN c.Type = 'D' THEN (c.TotalMsgCount - cm.MsgCount) ELSE cm.MentionCount END)
  1032  		FROM Classes c
  1033  		INNER JOIN ClassMembers cm
  1034  			ON cm.ClassId = c.Id
  1035  			AND cm.UserId = :UserId
  1036  			AND c.DeleteAt = 0
  1037  	`
  1038  	count, err := us.GetReplica().SelectInt(query, map[string]interface{}{"UserId": userId})
  1039  	if err != nil {
  1040  		return count, model.NewAppError("SqlUserStore.GetMentionCount", "store.sql_user.get_unread_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1041  	}
  1042  
  1043  	return count, nil
  1044  }
  1045  
  1046  func (us SqlUserStore) GetUsersBatchForIndexing(startTime, endTime int64, limit int) ([]*model.UserForIndexing, *model.AppError) {
  1047  	var users []*model.User
  1048  	usersQuery, args, _ := us.usersQuery.
  1049  		Where(sq.GtOrEq{"u.CreateAt": startTime}).
  1050  		Where(sq.Lt{"u.CreateAt": endTime}).
  1051  		OrderBy("u.CreateAt").
  1052  		Limit(uint64(limit)).
  1053  		ToSql()
  1054  	_, err := us.GetSearchReplica().Select(&users, usersQuery, args...)
  1055  	if err != nil {
  1056  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_users.app_error", nil, err.Error(), http.StatusInternalServerError)
  1057  	}
  1058  
  1059  	userIds := []string{}
  1060  	for _, user := range users {
  1061  		userIds = append(userIds, user.Id)
  1062  	}
  1063  
  1064  	var classMembers []*model.ClassMember
  1065  	classMembersQuery, args, _ := us.getQueryBuilder().
  1066  		Select(`
  1067  				cm.ClassId,
  1068  				cm.UserId,
  1069  				cm.Roles,
  1070  				cm.LastViewedAt,
  1071  				cm.MsgCount,
  1072  				cm.MentionCount,
  1073  				cm.NotifyProps,
  1074  				cm.LastUpdateAt,
  1075  				cm.SchemeUser,
  1076  				cm.SchemeAdmin,
  1077  				(cm.SchemeGuest IS NOT NULL AND cm.SchemeGuest) as SchemeGuest
  1078  			`).
  1079  		From("ClassMembers cm").
  1080  		Join("Classes c ON cm.ClassId = c.Id").
  1081  		Where(sq.Eq{"c.Type": "O", "cm.UserId": userIds}).
  1082  		ToSql()
  1083  	_, err = us.GetSearchReplica().Select(&classMembers, classMembersQuery, args...)
  1084  	if err != nil {
  1085  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_class_members.app_error", nil, err.Error(), http.StatusInternalServerError)
  1086  	}
  1087  
  1088  	var branchMembers []*model.BranchMember
  1089  	branchMembersQuery, args, _ := us.getQueryBuilder().
  1090  		Select("BranchId, UserId, Roles, DeleteAt, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest, SchemeUser, SchemeAdmin").
  1091  		From("BranchMembers").
  1092  		Where(sq.Eq{"UserId": userIds, "DeleteAt": 0}).
  1093  		ToSql()
  1094  	_, err = us.GetSearchReplica().Select(&branchMembers, branchMembersQuery, args...)
  1095  	if err != nil {
  1096  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_branch_members.app_error", nil, err.Error(), http.StatusInternalServerError)
  1097  	}
  1098  
  1099  	userMap := map[string]*model.UserForIndexing{}
  1100  	for _, user := range users {
  1101  		userMap[user.Id] = &model.UserForIndexing{
  1102  			Id:          user.Id,
  1103  			Username:    user.Username,
  1104  			Nickname:    user.Nickname,
  1105  			FirstName:   user.FirstName,
  1106  			LastName:    user.LastName,
  1107  			CreateAt:    user.CreateAt,
  1108  			DeleteAt:    user.DeleteAt,
  1109  			BranchesIds: []string{},
  1110  			ClassesIds:  []string{},
  1111  		}
  1112  	}
  1113  
  1114  	for _, c := range classMembers {
  1115  		if userMap[c.UserId] != nil {
  1116  			userMap[c.UserId].ClassesIds = append(userMap[c.UserId].ClassesIds, c.ClassId)
  1117  		}
  1118  	}
  1119  	for _, t := range branchMembers {
  1120  		if userMap[t.UserId] != nil {
  1121  			userMap[t.UserId].BranchesIds = append(userMap[t.UserId].BranchesIds, t.BranchId)
  1122  		}
  1123  	}
  1124  
  1125  	usersForIndexing := []*model.UserForIndexing{}
  1126  	for _, user := range userMap {
  1127  		usersForIndexing = append(usersForIndexing, user)
  1128  	}
  1129  	sort.Slice(usersForIndexing, func(i, j int) bool {
  1130  		return usersForIndexing[i].CreateAt < usersForIndexing[j].CreateAt
  1131  	})
  1132  
  1133  	return usersForIndexing, nil
  1134  }
  1135  
  1136  func applyViewRestrictionsFilter(query sq.SelectBuilder, restrictions *model.ViewUsersRestrictions, distinct bool) sq.SelectBuilder {
  1137  	if restrictions == nil {
  1138  		return query
  1139  	}
  1140  
  1141  	// If you have no access to branches or classes, return and empty result.
  1142  	if restrictions.Branches != nil && len(restrictions.Branches) == 0 && restrictions.Classes != nil && len(restrictions.Classes) == 0 {
  1143  		return query.Where("1 = 0")
  1144  	}
  1145  
  1146  	branches := make([]interface{}, len(restrictions.Branches))
  1147  	for i, v := range restrictions.Branches {
  1148  		branches[i] = v
  1149  	}
  1150  	classes := make([]interface{}, len(restrictions.Classes))
  1151  	for i, v := range restrictions.Classes {
  1152  		classes[i] = v
  1153  	}
  1154  	resultQuery := query
  1155  	if restrictions.Branches != nil && len(restrictions.Branches) > 0 {
  1156  		resultQuery = resultQuery.Join(fmt.Sprintf("BranchMembers rtm ON ( rtm.UserId = u.Id AND rtm.DeleteAt = 0 AND rtm.BranchId IN (%s))", sq.Placeholders(len(branches))), branches...)
  1157  	}
  1158  	if restrictions.Classes != nil && len(restrictions.Classes) > 0 {
  1159  		resultQuery = resultQuery.Join(fmt.Sprintf("ClassMembers rcm ON ( rcm.UserId = u.Id AND rcm.ClassId IN (%s))", sq.Placeholders(len(classes))), classes...)
  1160  	}
  1161  
  1162  	if distinct {
  1163  		return resultQuery.Distinct()
  1164  	}
  1165  
  1166  	return resultQuery
  1167  }