github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/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  	sq "github.com/Masterminds/squirrel"
    15  	"github.com/mattermost/gorp"
    16  
    17  	"github.com/mattermost/mattermost-server/v5/einterfaces"
    18  	"github.com/mattermost/mattermost-server/v5/model"
    19  	"github.com/mattermost/mattermost-server/v5/store"
    20  )
    21  
    22  const (
    23  	MAX_GROUP_CHANNELS_FOR_PROFILES = 50
    24  )
    25  
    26  var (
    27  	USER_SEARCH_TYPE_NAMES_NO_FULL_NAME = []string{"Username", "Nickname"}
    28  	USER_SEARCH_TYPE_NAMES              = []string{"Username", "FirstName", "LastName", "Nickname"}
    29  	USER_SEARCH_TYPE_ALL_NO_FULL_NAME   = []string{"Username", "Nickname", "Email"}
    30  	USER_SEARCH_TYPE_ALL                = []string{"Username", "FirstName", "LastName", "Nickname", "Email"}
    31  )
    32  
    33  type SqlUserStore struct {
    34  	SqlStore
    35  	metrics einterfaces.MetricsInterface
    36  
    37  	// usersQuery is a starting point for all queries that return one or more Users.
    38  	usersQuery sq.SelectBuilder
    39  }
    40  
    41  func (us SqlUserStore) ClearCaches() {}
    42  
    43  func (us SqlUserStore) InvalidateProfileCacheForUser(userId string) {}
    44  
    45  func newSqlUserStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.UserStore {
    46  	us := &SqlUserStore{
    47  		SqlStore: sqlStore,
    48  		metrics:  metrics,
    49  	}
    50  
    51  	// note: we are providing field names explicitly here to maintain order of columns (needed when using raw queries)
    52  	us.usersQuery = us.getQueryBuilder().
    53  		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",
    54  			"b.UserId IS NOT NULL AS IsBot", "COALESCE(b.Description, '') AS BotDescription", "COALESCE(b.LastIconUpdate, 0) AS BotLastIconUpdate").
    55  		From("Users u").
    56  		LeftJoin("Bots b ON ( b.UserId = u.Id )")
    57  
    58  	for _, db := range sqlStore.GetAllConns() {
    59  		table := db.AddTableWithName(model.User{}, "Users").SetKeys(false, "Id")
    60  		table.ColMap("Id").SetMaxSize(26)
    61  		table.ColMap("Username").SetMaxSize(64).SetUnique(true)
    62  		table.ColMap("Password").SetMaxSize(128)
    63  		table.ColMap("AuthData").SetMaxSize(128).SetUnique(true)
    64  		table.ColMap("AuthService").SetMaxSize(32)
    65  		table.ColMap("Email").SetMaxSize(128).SetUnique(true)
    66  		table.ColMap("Nickname").SetMaxSize(64)
    67  		table.ColMap("FirstName").SetMaxSize(64)
    68  		table.ColMap("LastName").SetMaxSize(64)
    69  		table.ColMap("Roles").SetMaxSize(256)
    70  		table.ColMap("Props").SetMaxSize(4000)
    71  		table.ColMap("NotifyProps").SetMaxSize(2000)
    72  		table.ColMap("Locale").SetMaxSize(5)
    73  		table.ColMap("MfaSecret").SetMaxSize(128)
    74  		table.ColMap("Position").SetMaxSize(128)
    75  		table.ColMap("Timezone").SetMaxSize(256)
    76  	}
    77  
    78  	return us
    79  }
    80  
    81  func (us SqlUserStore) createIndexesIfNotExists() {
    82  	us.CreateIndexIfNotExists("idx_users_email", "Users", "Email")
    83  	us.CreateIndexIfNotExists("idx_users_update_at", "Users", "UpdateAt")
    84  	us.CreateIndexIfNotExists("idx_users_create_at", "Users", "CreateAt")
    85  	us.CreateIndexIfNotExists("idx_users_delete_at", "Users", "DeleteAt")
    86  
    87  	if us.DriverName() == model.DATABASE_DRIVER_POSTGRES {
    88  		us.CreateIndexIfNotExists("idx_users_email_lower_textpattern", "Users", "lower(Email) text_pattern_ops")
    89  		us.CreateIndexIfNotExists("idx_users_username_lower_textpattern", "Users", "lower(Username) text_pattern_ops")
    90  		us.CreateIndexIfNotExists("idx_users_nickname_lower_textpattern", "Users", "lower(Nickname) text_pattern_ops")
    91  		us.CreateIndexIfNotExists("idx_users_firstname_lower_textpattern", "Users", "lower(FirstName) text_pattern_ops")
    92  		us.CreateIndexIfNotExists("idx_users_lastname_lower_textpattern", "Users", "lower(LastName) text_pattern_ops")
    93  	}
    94  
    95  	us.CreateFullTextIndexIfNotExists("idx_users_all_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL, ", "))
    96  	us.CreateFullTextIndexIfNotExists("idx_users_all_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_ALL_NO_FULL_NAME, ", "))
    97  	us.CreateFullTextIndexIfNotExists("idx_users_names_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES, ", "))
    98  	us.CreateFullTextIndexIfNotExists("idx_users_names_no_full_name_txt", "Users", strings.Join(USER_SEARCH_TYPE_NAMES_NO_FULL_NAME, ", "))
    99  }
   100  
   101  func (us SqlUserStore) Save(user *model.User) (*model.User, *model.AppError) {
   102  	if len(user.Id) > 0 {
   103  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.existing.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   104  	}
   105  
   106  	user.PreSave()
   107  	if err := user.IsValid(); err != nil {
   108  		return nil, err
   109  	}
   110  
   111  	if err := us.GetMaster().Insert(user); err != nil {
   112  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique"}) {
   113  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.email_exists.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   114  		}
   115  		if IsUniqueConstraintError(err, []string{"Username", "users_username_key", "idx_users_username_unique"}) {
   116  			return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.username_exists.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   117  		}
   118  		return nil, model.NewAppError("SqlUserStore.Save", "store.sql_user.save.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   119  	}
   120  
   121  	return user, nil
   122  }
   123  
   124  func (us SqlUserStore) DeactivateGuests() ([]string, *model.AppError) {
   125  	curTime := model.GetMillis()
   126  	updateQuery := us.getQueryBuilder().Update("Users").
   127  		Set("UpdateAt", curTime).
   128  		Set("DeleteAt", curTime).
   129  		Where(sq.Eq{"Roles": "system_guest"}).
   130  		Where(sq.Eq{"DeleteAt": 0})
   131  
   132  	queryString, args, err := updateQuery.ToSql()
   133  	if err != nil {
   134  		return nil, model.NewAppError("SqlUserStore.UpdateActiveForMultipleUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   135  	}
   136  
   137  	_, err = us.GetMaster().Exec(queryString, args...)
   138  	if err != nil {
   139  		return nil, model.NewAppError("SqlUserStore.UpdateActiveForMultipleUsers", "store.sql_user.update_active_for_multiple_users.updating.app_error", nil, err.Error(), http.StatusInternalServerError)
   140  	}
   141  
   142  	selectQuery := us.getQueryBuilder().Select("Id").From("Users").Where(sq.Eq{"DeleteAt": curTime})
   143  
   144  	queryString, args, err = selectQuery.ToSql()
   145  	if err != nil {
   146  		return nil, model.NewAppError("SqlUserStore.UpdateActiveForMultipleUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   147  	}
   148  
   149  	userIds := []string{}
   150  	_, err = us.GetMaster().Select(&userIds, queryString, args...)
   151  	if err != nil {
   152  		return nil, model.NewAppError("SqlUserStore.UpdateActiveForMultipleUsers", "store.sql_user.update_active_for_multiple_users.getting_changed_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   153  	}
   154  
   155  	return userIds, nil
   156  }
   157  
   158  func (us SqlUserStore) Update(user *model.User, trustedUpdateData bool) (*model.UserUpdate, *model.AppError) {
   159  	user.PreUpdate()
   160  
   161  	if err := user.IsValid(); err != nil {
   162  		return nil, err
   163  	}
   164  
   165  	oldUserResult, err := us.GetMaster().Get(model.User{}, user.Id)
   166  	if err != nil {
   167  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.finding.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   168  	}
   169  
   170  	if oldUserResult == nil {
   171  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.find.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   172  	}
   173  
   174  	oldUser := oldUserResult.(*model.User)
   175  	user.CreateAt = oldUser.CreateAt
   176  	user.AuthData = oldUser.AuthData
   177  	user.AuthService = oldUser.AuthService
   178  	user.Password = oldUser.Password
   179  	user.LastPasswordUpdate = oldUser.LastPasswordUpdate
   180  	user.LastPictureUpdate = oldUser.LastPictureUpdate
   181  	user.EmailVerified = oldUser.EmailVerified
   182  	user.FailedAttempts = oldUser.FailedAttempts
   183  	user.MfaSecret = oldUser.MfaSecret
   184  	user.MfaActive = oldUser.MfaActive
   185  
   186  	if !trustedUpdateData {
   187  		user.Roles = oldUser.Roles
   188  		user.DeleteAt = oldUser.DeleteAt
   189  	}
   190  
   191  	if user.IsOAuthUser() {
   192  		if !trustedUpdateData {
   193  			user.Email = oldUser.Email
   194  		}
   195  	} else if user.IsLDAPUser() && !trustedUpdateData {
   196  		if user.Username != oldUser.Username || user.Email != oldUser.Email {
   197  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.can_not_change_ldap.app_error", nil, "user_id="+user.Id, http.StatusBadRequest)
   198  		}
   199  	} else if user.Email != oldUser.Email {
   200  		user.EmailVerified = false
   201  	}
   202  
   203  	if user.Username != oldUser.Username {
   204  		user.UpdateMentionKeysFromUsername(oldUser.Username)
   205  	}
   206  
   207  	count, err := us.GetMaster().Update(user)
   208  	if err != nil {
   209  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique"}) {
   210  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.email_taken.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   211  		}
   212  		if IsUniqueConstraintError(err, []string{"Username", "users_username_key", "idx_users_username_unique"}) {
   213  			return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.username_taken.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusBadRequest)
   214  		}
   215  		return nil, model.NewAppError("SqlUserStore.Update", "store.sql_user.update.updating.app_error", nil, "user_id="+user.Id+", "+err.Error(), http.StatusInternalServerError)
   216  	}
   217  
   218  	if count != 1 {
   219  		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)
   220  	}
   221  
   222  	user.Sanitize(map[string]bool{})
   223  	oldUser.Sanitize(map[string]bool{})
   224  	return &model.UserUpdate{New: user, Old: oldUser}, nil
   225  }
   226  
   227  func (us SqlUserStore) UpdateLastPictureUpdate(userId string) *model.AppError {
   228  	curTime := model.GetMillis()
   229  
   230  	if _, err := us.GetMaster().Exec("UPDATE Users SET LastPictureUpdate = :Time, UpdateAt = :Time WHERE Id = :UserId", map[string]interface{}{"Time": curTime, "UserId": userId}); err != nil {
   231  		return model.NewAppError("SqlUserStore.UpdateLastPictureUpdate", "store.sql_user.update_last_picture_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   232  	}
   233  
   234  	return nil
   235  }
   236  
   237  func (us SqlUserStore) ResetLastPictureUpdate(userId string) *model.AppError {
   238  	curTime := model.GetMillis()
   239  
   240  	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 {
   241  		return model.NewAppError("SqlUserStore.ResetLastPictureUpdate", "store.sql_user.update_last_picture_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   242  	}
   243  
   244  	return nil
   245  }
   246  
   247  func (us SqlUserStore) UpdateUpdateAt(userId string) (int64, *model.AppError) {
   248  	curTime := model.GetMillis()
   249  
   250  	if _, err := us.GetMaster().Exec("UPDATE Users SET UpdateAt = :Time WHERE Id = :UserId", map[string]interface{}{"Time": curTime, "UserId": userId}); err != nil {
   251  		return curTime, model.NewAppError("SqlUserStore.UpdateUpdateAt", "store.sql_user.update_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   252  	}
   253  
   254  	return curTime, nil
   255  }
   256  
   257  func (us SqlUserStore) UpdatePassword(userId, hashedPassword string) *model.AppError {
   258  	updateAt := model.GetMillis()
   259  
   260  	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 {
   261  		return model.NewAppError("SqlUserStore.UpdatePassword", "store.sql_user.update_password.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   262  	}
   263  
   264  	return nil
   265  }
   266  
   267  func (us SqlUserStore) UpdateFailedPasswordAttempts(userId string, attempts int) *model.AppError {
   268  	if _, err := us.GetMaster().Exec("UPDATE Users SET FailedAttempts = :FailedAttempts WHERE Id = :UserId", map[string]interface{}{"FailedAttempts": attempts, "UserId": userId}); err != nil {
   269  		return model.NewAppError("SqlUserStore.UpdateFailedPasswordAttempts", "store.sql_user.update_failed_pwd_attempts.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
   270  	}
   271  
   272  	return nil
   273  }
   274  
   275  func (us SqlUserStore) UpdateAuthData(userId string, service string, authData *string, email string, resetMfa bool) (string, *model.AppError) {
   276  	email = strings.ToLower(email)
   277  
   278  	updateAt := model.GetMillis()
   279  
   280  	query := `
   281  			UPDATE
   282  			     Users
   283  			SET
   284  			     Password = '',
   285  			     LastPasswordUpdate = :LastPasswordUpdate,
   286  			     UpdateAt = :UpdateAt,
   287  			     FailedAttempts = 0,
   288  			     AuthService = :AuthService,
   289  			     AuthData = :AuthData`
   290  
   291  	if len(email) != 0 {
   292  		query += ", Email = :Email"
   293  	}
   294  
   295  	if resetMfa {
   296  		query += ", MfaActive = false, MfaSecret = ''"
   297  	}
   298  
   299  	query += " WHERE Id = :UserId"
   300  
   301  	if _, err := us.GetMaster().Exec(query, map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData, "Email": email}); err != nil {
   302  		if IsUniqueConstraintError(err, []string{"Email", "users_email_key", "idx_users_email_unique", "AuthData", "users_authdata_key"}) {
   303  			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)
   304  		}
   305  		return "", model.NewAppError("SqlUserStore.UpdateAuthData", "store.sql_user.update_auth_data.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   306  	}
   307  	return userId, nil
   308  }
   309  
   310  func (us SqlUserStore) UpdateMfaSecret(userId, secret string) *model.AppError {
   311  	updateAt := model.GetMillis()
   312  
   313  	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 {
   314  		return model.NewAppError("SqlUserStore.UpdateMfaSecret", "store.sql_user.update_mfa_secret.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   315  	}
   316  
   317  	return nil
   318  }
   319  
   320  func (us SqlUserStore) UpdateMfaActive(userId string, active bool) *model.AppError {
   321  	updateAt := model.GetMillis()
   322  
   323  	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 {
   324  		return model.NewAppError("SqlUserStore.UpdateMfaActive", "store.sql_user.update_mfa_active.app_error", nil, "id="+userId+", "+err.Error(), http.StatusInternalServerError)
   325  	}
   326  
   327  	return nil
   328  }
   329  
   330  func (us SqlUserStore) Get(id string) (*model.User, *model.AppError) {
   331  	failure := func(err error, id string, statusCode int) *model.AppError {
   332  		details := "user_id=" + id + ", " + err.Error()
   333  		return model.NewAppError("SqlUserStore.Get", id, nil, details, statusCode)
   334  	}
   335  
   336  	query := us.usersQuery.Where("Id = ?", id)
   337  	queryString, args, err := query.ToSql()
   338  	if err != nil {
   339  		return nil, failure(err, "store.sql_user.get.app_error", http.StatusInternalServerError)
   340  	}
   341  	row := us.GetReplica().Db.QueryRow(queryString, args...)
   342  
   343  	var user model.User
   344  	var props, notifyProps, timezone []byte
   345  	err = row.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username,
   346  		&user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified,
   347  		&user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles,
   348  		&user.AllowMarketing, &props, &notifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate,
   349  		&user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret,
   350  		&user.IsBot, &user.BotDescription, &user.BotLastIconUpdate)
   351  	if err != nil {
   352  		if err == sql.ErrNoRows {
   353  			return nil, failure(err, store.MISSING_ACCOUNT_ERROR, http.StatusNotFound)
   354  		}
   355  		return nil, failure(err, "store.sql_user.get.app_error", http.StatusInternalServerError)
   356  
   357  	}
   358  	if err = json.Unmarshal(props, &user.Props); err != nil {
   359  		return nil, failure(err, "store.sql_user.get.app_error", http.StatusInternalServerError)
   360  	}
   361  	if err = json.Unmarshal(notifyProps, &user.NotifyProps); err != nil {
   362  		return nil, failure(err, "store.sql_user.get.app_error", http.StatusInternalServerError)
   363  	}
   364  	if err = json.Unmarshal(timezone, &user.Timezone); err != nil {
   365  		return nil, failure(err, "store.sql_user.get.app_error", http.StatusInternalServerError)
   366  	}
   367  
   368  	return &user, nil
   369  }
   370  
   371  func (us SqlUserStore) GetAll() ([]*model.User, *model.AppError) {
   372  	query := us.usersQuery.OrderBy("Username ASC")
   373  
   374  	queryString, args, err := query.ToSql()
   375  	if err != nil {
   376  		return nil, model.NewAppError("SqlUserStore.GetAll", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   377  	}
   378  
   379  	var data []*model.User
   380  	if _, err := us.GetReplica().Select(&data, queryString, args...); err != nil {
   381  		return nil, model.NewAppError("SqlUserStore.GetAll", "store.sql_user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   382  	}
   383  	return data, nil
   384  }
   385  
   386  func (us SqlUserStore) GetAllAfter(limit int, afterId string) ([]*model.User, *model.AppError) {
   387  	query := us.usersQuery.
   388  		Where("Id > ?", afterId).
   389  		OrderBy("Id ASC").
   390  		Limit(uint64(limit))
   391  
   392  	queryString, args, err := query.ToSql()
   393  	if err != nil {
   394  		return nil, model.NewAppError("SqlUserStore.GetAllAfter", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   395  	}
   396  
   397  	var users []*model.User
   398  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   399  		return nil, model.NewAppError("SqlUserStore.GetAllAfter", "store.sql_user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
   400  	}
   401  
   402  	return users, nil
   403  }
   404  
   405  func (us SqlUserStore) GetEtagForAllProfiles() string {
   406  	updateAt, err := us.GetReplica().SelectInt("SELECT UpdateAt FROM Users ORDER BY UpdateAt DESC LIMIT 1")
   407  	if err != nil {
   408  		return fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
   409  	}
   410  	return fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt)
   411  }
   412  
   413  func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   414  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   415  	query := us.usersQuery.
   416  		OrderBy("u.Username ASC").
   417  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   418  
   419  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   420  
   421  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   422  
   423  	if options.Inactive {
   424  		query = query.Where("u.DeleteAt != 0")
   425  	} else if options.Active {
   426  		query = query.Where("u.DeleteAt = 0")
   427  	}
   428  
   429  	queryString, args, err := query.ToSql()
   430  	if err != nil {
   431  		return nil, model.NewAppError("SqlUserStore.GetAllProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   432  	}
   433  
   434  	var users []*model.User
   435  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   436  		return nil, model.NewAppError("SqlUserStore.GetAllProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   437  	}
   438  
   439  	for _, u := range users {
   440  		u.Sanitize(map[string]bool{})
   441  	}
   442  
   443  	return users, nil
   444  }
   445  
   446  func applyRoleFilter(query sq.SelectBuilder, role string, isPostgreSQL bool) sq.SelectBuilder {
   447  	if role == "" {
   448  		return query
   449  	}
   450  
   451  	if isPostgreSQL {
   452  		roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "\\"))
   453  		return query.Where("u.Roles LIKE LOWER(?)", roleParam)
   454  	}
   455  
   456  	roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "*"))
   457  
   458  	return query.Where("u.Roles LIKE ? ESCAPE '*'", roleParam)
   459  }
   460  
   461  func applyMultiRoleFilters(query sq.SelectBuilder, roles []string, teamRoles []string, channelRoles []string) sq.SelectBuilder {
   462  	queryString := ""
   463  	if len(roles) > 0 && roles[0] != "" {
   464  		schemeGuest := false
   465  		schemeAdmin := false
   466  		schemeUser := false
   467  
   468  		for _, role := range roles {
   469  			switch role {
   470  			case model.SYSTEM_ADMIN_ROLE_ID:
   471  				schemeAdmin = true
   472  			case model.SYSTEM_USER_ROLE_ID:
   473  				schemeUser = true
   474  			case model.SYSTEM_GUEST_ROLE_ID:
   475  				schemeGuest = true
   476  			}
   477  		}
   478  
   479  		if schemeAdmin || schemeUser || schemeGuest {
   480  			if schemeAdmin && schemeUser {
   481  				queryString += `(u.Roles LIKE '%system_user%' OR u.Roles LIKE '%system_admin%') `
   482  			} else if schemeAdmin {
   483  				queryString += `(u.Roles LIKE '%system_admin%') `
   484  			} else if schemeUser {
   485  				queryString += `(u.Roles LIKE '%system_user%' AND u.Roles NOT LIKE '%system_admin%') `
   486  			}
   487  
   488  			if schemeGuest {
   489  				if queryString != "" {
   490  					queryString += "OR "
   491  				}
   492  				queryString += `(u.Roles LIKE '%system_guest%') `
   493  			}
   494  		}
   495  	}
   496  
   497  	if len(channelRoles) > 0 && channelRoles[0] != "" {
   498  		schemeGuest := false
   499  		schemeAdmin := false
   500  		schemeUser := false
   501  		for _, channelRole := range channelRoles {
   502  			switch channelRole {
   503  			case model.CHANNEL_ADMIN_ROLE_ID:
   504  				schemeAdmin = true
   505  			case model.CHANNEL_USER_ROLE_ID:
   506  				schemeUser = true
   507  			case model.CHANNEL_GUEST_ROLE_ID:
   508  				schemeGuest = true
   509  			}
   510  		}
   511  
   512  		if schemeAdmin || schemeUser || schemeGuest {
   513  			if queryString != "" {
   514  				queryString += "OR "
   515  			}
   516  			if schemeAdmin && schemeUser {
   517  				queryString += `(cm.SchemeUser = true AND u.Roles = 'system_user')`
   518  			} else if schemeAdmin {
   519  				queryString += `(cm.SchemeAdmin = true AND u.Roles = 'system_user')`
   520  			} else if schemeUser {
   521  				queryString += `(cm.SchemeUser = true AND cm.SchemeAdmin = false AND u.Roles = 'system_user')`
   522  			}
   523  
   524  			if schemeGuest {
   525  				if queryString != "" && queryString[len(queryString)-3:] != "OR " {
   526  					queryString += "OR "
   527  				}
   528  				queryString += `(cm.SchemeGuest = true AND u.Roles = 'system_guest')`
   529  			}
   530  		}
   531  	}
   532  
   533  	if len(teamRoles) > 0 && teamRoles[0] != "" {
   534  		schemeAdmin := false
   535  		schemeUser := false
   536  		schemeGuest := false
   537  		for _, teamRole := range teamRoles {
   538  			switch teamRole {
   539  			case model.TEAM_ADMIN_ROLE_ID:
   540  				schemeAdmin = true
   541  			case model.TEAM_USER_ROLE_ID:
   542  				schemeUser = true
   543  			case model.TEAM_GUEST_ROLE_ID:
   544  				schemeGuest = true
   545  			}
   546  		}
   547  
   548  		if schemeAdmin || schemeUser || schemeGuest {
   549  			if queryString != "" {
   550  				queryString += "OR "
   551  			}
   552  			if schemeAdmin && schemeUser {
   553  				queryString += `(tm.SchemeUser = true AND u.Roles = 'system_user')`
   554  			} else if schemeAdmin {
   555  				queryString += `(tm.SchemeAdmin = true AND u.Roles = 'system_user')`
   556  			} else if schemeUser {
   557  				queryString += `(tm.SchemeUser = true AND tm.SchemeAdmin = false AND u.Roles = 'system_user')`
   558  			}
   559  
   560  			if schemeGuest {
   561  				if queryString != "" && queryString[len(queryString)-3:] != "OR " {
   562  					queryString += "OR "
   563  				}
   564  				queryString += `(tm.SchemeGuest = true AND u.Roles = 'system_guest')`
   565  			}
   566  		}
   567  	}
   568  
   569  	if queryString != "" {
   570  		query = query.Where("(" + queryString + ")")
   571  	}
   572  
   573  	return query
   574  }
   575  
   576  func applyChannelGroupConstrainedFilter(query sq.SelectBuilder, channelId string) sq.SelectBuilder {
   577  	if channelId == "" {
   578  		return query
   579  	}
   580  
   581  	return query.
   582  		Where(`u.Id IN (
   583  				SELECT
   584  					GroupMembers.UserId
   585  				FROM
   586  					Channels
   587  					JOIN GroupChannels ON GroupChannels.ChannelId = Channels.Id
   588  					JOIN UserGroups ON UserGroups.Id = GroupChannels.GroupId
   589  					JOIN GroupMembers ON GroupMembers.GroupId = UserGroups.Id
   590  				WHERE
   591  					Channels.Id = ?
   592  					AND GroupChannels.DeleteAt = 0
   593  					AND UserGroups.DeleteAt = 0
   594  					AND GroupMembers.DeleteAt = 0
   595  				GROUP BY
   596  					GroupMembers.UserId
   597  			)`, channelId)
   598  }
   599  
   600  func applyTeamGroupConstrainedFilter(query sq.SelectBuilder, teamId string) sq.SelectBuilder {
   601  	if teamId == "" {
   602  		return query
   603  	}
   604  
   605  	return query.
   606  		Where(`u.Id IN (
   607  				SELECT
   608  					GroupMembers.UserId
   609  				FROM
   610  					Teams
   611  					JOIN GroupTeams ON GroupTeams.TeamId = Teams.Id
   612  					JOIN UserGroups ON UserGroups.Id = GroupTeams.GroupId
   613  					JOIN GroupMembers ON GroupMembers.GroupId = UserGroups.Id
   614  				WHERE
   615  					Teams.Id = ?
   616  					AND GroupTeams.DeleteAt = 0
   617  					AND UserGroups.DeleteAt = 0
   618  					AND GroupMembers.DeleteAt = 0
   619  				GROUP BY
   620  					GroupMembers.UserId
   621  			)`, teamId)
   622  }
   623  
   624  func (us SqlUserStore) GetEtagForProfiles(teamId string) string {
   625  	updateAt, err := us.GetReplica().SelectInt("SELECT UpdateAt FROM Users, TeamMembers WHERE TeamMembers.TeamId = :TeamId AND Users.Id = TeamMembers.UserId ORDER BY UpdateAt DESC LIMIT 1", map[string]interface{}{"TeamId": teamId})
   626  	if err != nil {
   627  		return fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
   628  	}
   629  	return fmt.Sprintf("%v.%v", model.CurrentVersion, updateAt)
   630  }
   631  
   632  func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   633  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   634  	query := us.usersQuery.
   635  		Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 )").
   636  		Where("tm.TeamId = ?", options.InTeamId).
   637  		OrderBy("u.Username ASC").
   638  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   639  
   640  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   641  
   642  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   643  	query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles)
   644  
   645  	if options.Inactive {
   646  		query = query.Where("u.DeleteAt != 0")
   647  	} else if options.Active {
   648  		query = query.Where("u.DeleteAt = 0")
   649  	}
   650  
   651  	queryString, args, err := query.ToSql()
   652  	if err != nil {
   653  		return nil, model.NewAppError("SqlUserStore.GetProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   654  	}
   655  
   656  	var users []*model.User
   657  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   658  		return nil, model.NewAppError("SqlUserStore.GetProfiles", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   659  	}
   660  
   661  	for _, u := range users {
   662  		u.Sanitize(map[string]bool{})
   663  	}
   664  
   665  	return users, nil
   666  }
   667  
   668  func (us SqlUserStore) InvalidateProfilesInChannelCacheByUser(userId string) {}
   669  
   670  func (us SqlUserStore) InvalidateProfilesInChannelCache(channelId string) {}
   671  
   672  func (us SqlUserStore) GetProfilesInChannel(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   673  	query := us.usersQuery.
   674  		Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
   675  		Where("cm.ChannelId = ?", channelId).
   676  		OrderBy("u.Username ASC").
   677  		Offset(uint64(offset)).Limit(uint64(limit))
   678  
   679  	queryString, args, err := query.ToSql()
   680  	if err != nil {
   681  		return nil, model.NewAppError("SqlUserStore.GetProfilesInChannel", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   682  	}
   683  
   684  	var users []*model.User
   685  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   686  		return nil, model.NewAppError("SqlUserStore.GetProfilesInChannel", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   687  	}
   688  
   689  	for _, u := range users {
   690  		u.Sanitize(map[string]bool{})
   691  	}
   692  
   693  	return users, nil
   694  }
   695  
   696  func (us SqlUserStore) GetProfilesInChannelByStatus(channelId string, offset int, limit int) ([]*model.User, *model.AppError) {
   697  	query := us.usersQuery.
   698  		Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
   699  		LeftJoin("Status s ON ( s.UserId = u.Id )").
   700  		Where("cm.ChannelId = ?", channelId).
   701  		OrderBy(`
   702  			CASE s.Status
   703  				WHEN 'online' THEN 1
   704  				WHEN 'away' THEN 2
   705  				WHEN 'dnd' THEN 3
   706  				ELSE 4
   707  			END
   708  			`).
   709  		OrderBy("u.Username ASC").
   710  		Offset(uint64(offset)).Limit(uint64(limit))
   711  
   712  	queryString, args, err := query.ToSql()
   713  	if err != nil {
   714  		return nil, model.NewAppError("SqlUserStore.GetProfilesInChannelByStatus", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   715  	}
   716  
   717  	var users []*model.User
   718  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   719  		return nil, model.NewAppError("SqlUserStore.GetProfilesInChannelByStatus", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   720  	}
   721  
   722  	for _, u := range users {
   723  		u.Sanitize(map[string]bool{})
   724  	}
   725  
   726  	return users, nil
   727  }
   728  
   729  func (us SqlUserStore) GetAllProfilesInChannel(channelId string, allowFromCache bool) (map[string]*model.User, *model.AppError) {
   730  	failure := func(e error) (map[string]*model.User, *model.AppError) {
   731  		return nil, model.NewAppError("SqlUserStore.GetAllProfilesInChannel", "store.sql_user.app_error", nil, e.Error(), http.StatusInternalServerError)
   732  	}
   733  	query := us.usersQuery.
   734  		Join("ChannelMembers cm ON ( cm.UserId = u.Id )").
   735  		Where("cm.ChannelId = ?", channelId).
   736  		Where("u.DeleteAt = 0").
   737  		OrderBy("u.Username ASC")
   738  
   739  	queryString, args, err := query.ToSql()
   740  	if err != nil {
   741  		return failure(err)
   742  	}
   743  	var users []*model.User
   744  	rows, err := us.GetReplica().Db.Query(queryString, args...)
   745  	if err != nil {
   746  		return failure(err)
   747  	}
   748  
   749  	defer rows.Close()
   750  	for rows.Next() {
   751  		var user model.User
   752  		var props, notifyProps, timezone []byte
   753  		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 {
   754  			return failure(err)
   755  		}
   756  		if err = json.Unmarshal(props, &user.Props); err != nil {
   757  			return failure(err)
   758  		}
   759  		if err = json.Unmarshal(notifyProps, &user.NotifyProps); err != nil {
   760  			return failure(err)
   761  		}
   762  		if err = json.Unmarshal(timezone, &user.Timezone); err != nil {
   763  			return failure(err)
   764  		}
   765  		users = append(users, &user)
   766  	}
   767  	err = rows.Err()
   768  	if err != nil {
   769  		return failure(err)
   770  	}
   771  
   772  	userMap := make(map[string]*model.User)
   773  
   774  	for _, u := range users {
   775  		u.Sanitize(map[string]bool{})
   776  		userMap[u.Id] = u
   777  	}
   778  
   779  	return userMap, nil
   780  }
   781  
   782  func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   783  	query := us.usersQuery.
   784  		Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
   785  		LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
   786  		Where("cm.UserId IS NULL").
   787  		OrderBy("u.Username ASC").
   788  		Offset(uint64(offset)).Limit(uint64(limit))
   789  
   790  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   791  
   792  	if groupConstrained {
   793  		query = applyChannelGroupConstrainedFilter(query, channelId)
   794  	}
   795  
   796  	queryString, args, err := query.ToSql()
   797  	if err != nil {
   798  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInChannel", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   799  	}
   800  
   801  	var users []*model.User
   802  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   803  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInChannel", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   804  	}
   805  
   806  	for _, u := range users {
   807  		u.Sanitize(map[string]bool{})
   808  	}
   809  
   810  	return users, nil
   811  }
   812  
   813  func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) {
   814  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
   815  	query := us.usersQuery.
   816  		Where(`(
   817  			SELECT
   818  				COUNT(0)
   819  			FROM
   820  				TeamMembers
   821  			WHERE
   822  				TeamMembers.UserId = u.Id
   823  				AND TeamMembers.DeleteAt = 0
   824  		) = 0`).
   825  		OrderBy("u.Username ASC").
   826  		Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage))
   827  
   828  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   829  
   830  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
   831  
   832  	if options.Inactive {
   833  		query = query.Where("u.DeleteAt != 0")
   834  	} else if options.Active {
   835  		query = query.Where("u.DeleteAt = 0")
   836  	}
   837  
   838  	queryString, args, err := query.ToSql()
   839  	if err != nil {
   840  		return nil, model.NewAppError("SqlUserStore.GetProfilesWithoutTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   841  	}
   842  
   843  	var users []*model.User
   844  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   845  		return nil, model.NewAppError("SqlUserStore.GetProfilesWithoutTeam", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   846  	}
   847  
   848  	for _, u := range users {
   849  		u.Sanitize(map[string]bool{})
   850  	}
   851  
   852  	return users, nil
   853  }
   854  
   855  func (us SqlUserStore) GetProfilesByUsernames(usernames []string, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   856  	query := us.usersQuery
   857  
   858  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   859  
   860  	query = query.
   861  		Where(map[string]interface{}{
   862  			"Username": usernames,
   863  		}).
   864  		OrderBy("u.Username ASC")
   865  
   866  	queryString, args, err := query.ToSql()
   867  	if err != nil {
   868  		return nil, model.NewAppError("SqlUserStore.GetProfilesByUsernames", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   869  	}
   870  
   871  	var users []*model.User
   872  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   873  		return nil, model.NewAppError("SqlUserStore.GetProfilesByUsernames", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   874  	}
   875  
   876  	return users, nil
   877  }
   878  
   879  type UserWithLastActivityAt struct {
   880  	model.User
   881  	LastActivityAt int64
   882  }
   883  
   884  func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   885  	query := us.usersQuery.
   886  		Column("s.LastActivityAt").
   887  		Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId).
   888  		Join("Status s ON (s.UserId = u.Id)").
   889  		OrderBy("s.LastActivityAt DESC").
   890  		OrderBy("u.Username ASC").
   891  		Offset(uint64(offset)).Limit(uint64(limit))
   892  
   893  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   894  
   895  	queryString, args, err := query.ToSql()
   896  	if err != nil {
   897  		return nil, model.NewAppError("SqlUserStore.GetRecentlyActiveUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   898  	}
   899  
   900  	var users []*UserWithLastActivityAt
   901  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   902  		return nil, model.NewAppError("SqlUserStore.GetRecentlyActiveUsers", "store.sql_user.get_recently_active_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   903  	}
   904  
   905  	userList := []*model.User{}
   906  
   907  	for _, userWithLastActivityAt := range users {
   908  		u := userWithLastActivityAt.User
   909  		u.Sanitize(map[string]bool{})
   910  		u.LastActivityAt = userWithLastActivityAt.LastActivityAt
   911  		userList = append(userList, &u)
   912  	}
   913  
   914  	return userList, nil
   915  }
   916  
   917  func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
   918  	query := us.usersQuery.
   919  		Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId).
   920  		OrderBy("u.CreateAt DESC").
   921  		OrderBy("u.Username ASC").
   922  		Offset(uint64(offset)).Limit(uint64(limit))
   923  
   924  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
   925  
   926  	queryString, args, err := query.ToSql()
   927  	if err != nil {
   928  		return nil, model.NewAppError("SqlUserStore.GetNewUsersForTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   929  	}
   930  
   931  	var users []*model.User
   932  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   933  		return nil, model.NewAppError("SqlUserStore.GetNewUsersForTeam", "store.sql_user.get_new_users.app_error", nil, err.Error(), http.StatusInternalServerError)
   934  	}
   935  
   936  	for _, u := range users {
   937  		u.Sanitize(map[string]bool{})
   938  	}
   939  
   940  	return users, nil
   941  }
   942  
   943  func (us SqlUserStore) GetProfileByIds(userIds []string, options *store.UserGetByIdsOpts, _ bool) ([]*model.User, *model.AppError) {
   944  	if options == nil {
   945  		options = &store.UserGetByIdsOpts{}
   946  	}
   947  
   948  	users := []*model.User{}
   949  	query := us.usersQuery.
   950  		Where(map[string]interface{}{
   951  			"u.Id": userIds,
   952  		}).
   953  		OrderBy("u.Username ASC")
   954  
   955  	if options.Since > 0 {
   956  		query = query.Where(sq.Gt(map[string]interface{}{
   957  			"u.UpdateAt": options.Since,
   958  		}))
   959  	}
   960  
   961  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
   962  
   963  	queryString, args, err := query.ToSql()
   964  	if err != nil {
   965  		return nil, model.NewAppError("SqlUserStore.GetProfileByIds", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
   966  	}
   967  
   968  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
   969  		return nil, model.NewAppError("SqlUserStore.GetProfileByIds", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
   970  	}
   971  
   972  	return users, nil
   973  }
   974  
   975  type UserWithChannel struct {
   976  	model.User
   977  	ChannelId string
   978  }
   979  
   980  func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channelIds []string) (map[string][]*model.User, *model.AppError) {
   981  	if len(channelIds) > MAX_GROUP_CHANNELS_FOR_PROFILES {
   982  		channelIds = channelIds[0:MAX_GROUP_CHANNELS_FOR_PROFILES]
   983  	}
   984  
   985  	isMemberQuery := fmt.Sprintf(`
   986        EXISTS(
   987          SELECT
   988            1
   989          FROM
   990            ChannelMembers
   991          WHERE
   992            UserId = '%s'
   993          AND
   994            ChannelId = cm.ChannelId
   995          )`, userId)
   996  
   997  	query := us.getQueryBuilder().
   998  		Select("u.*, cm.ChannelId").
   999  		From("Users u").
  1000  		Join("ChannelMembers cm ON u.Id = cm.UserId").
  1001  		Join("Channels c ON cm.ChannelId = c.Id").
  1002  		Where(sq.Eq{"c.Type": model.CHANNEL_GROUP, "cm.ChannelId": channelIds}).
  1003  		Where(isMemberQuery).
  1004  		Where(sq.NotEq{"u.Id": userId}).
  1005  		OrderBy("u.Username ASC")
  1006  
  1007  	queryString, args, err := query.ToSql()
  1008  	if err != nil {
  1009  		return nil, model.NewAppError("SqlUserStore.GetProfileByGroupChannelIdsForUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1010  	}
  1011  
  1012  	usersWithChannel := []*UserWithChannel{}
  1013  	if _, err := us.GetReplica().Select(&usersWithChannel, queryString, args...); err != nil {
  1014  		return nil, model.NewAppError("SqlUserStore.GetProfileByGroupChannelIdsForUser", "store.sql_user.get_profile_by_group_channel_ids_for_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1015  	}
  1016  
  1017  	usersByChannelId := map[string][]*model.User{}
  1018  	for _, user := range usersWithChannel {
  1019  		if val, ok := usersByChannelId[user.ChannelId]; ok {
  1020  			usersByChannelId[user.ChannelId] = append(val, &user.User)
  1021  		} else {
  1022  			usersByChannelId[user.ChannelId] = []*model.User{&user.User}
  1023  		}
  1024  	}
  1025  
  1026  	return usersByChannelId, nil
  1027  }
  1028  
  1029  func (us SqlUserStore) GetSystemAdminProfiles() (map[string]*model.User, *model.AppError) {
  1030  	query := us.usersQuery.
  1031  		Where("Roles LIKE ?", "%system_admin%").
  1032  		OrderBy("u.Username ASC")
  1033  
  1034  	queryString, args, err := query.ToSql()
  1035  	if err != nil {
  1036  		return nil, model.NewAppError("SqlUserStore.GetSystemAdminProfiles", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1037  	}
  1038  
  1039  	var users []*model.User
  1040  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1041  		return nil, model.NewAppError("SqlUserStore.GetSystemAdminProfiles", "store.sql_user.get_sysadmin_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
  1042  	}
  1043  
  1044  	userMap := make(map[string]*model.User)
  1045  
  1046  	for _, u := range users {
  1047  		u.Sanitize(map[string]bool{})
  1048  		userMap[u.Id] = u
  1049  	}
  1050  
  1051  	return userMap, nil
  1052  }
  1053  
  1054  func (us SqlUserStore) GetByEmail(email string) (*model.User, *model.AppError) {
  1055  	email = strings.ToLower(email)
  1056  
  1057  	query := us.usersQuery.Where("Email = ?", email)
  1058  
  1059  	queryString, args, err := query.ToSql()
  1060  	if err != nil {
  1061  		return nil, model.NewAppError("SqlUserStore.GetByEmail", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1062  	}
  1063  
  1064  	user := model.User{}
  1065  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err != nil {
  1066  		return nil, model.NewAppError("SqlUserStore.GetByEmail", store.MISSING_ACCOUNT_ERROR, nil, "email="+email+", "+err.Error(), http.StatusInternalServerError)
  1067  	}
  1068  
  1069  	return &user, nil
  1070  }
  1071  
  1072  func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.User, *model.AppError) {
  1073  	if authData == nil || *authData == "" {
  1074  		return nil, model.NewAppError("SqlUserStore.GetByAuth", store.MISSING_AUTH_ACCOUNT_ERROR, nil, "authData='', authService="+authService, http.StatusBadRequest)
  1075  	}
  1076  
  1077  	query := us.usersQuery.
  1078  		Where("u.AuthData = ?", authData).
  1079  		Where("u.AuthService = ?", authService)
  1080  
  1081  	queryString, args, err := query.ToSql()
  1082  	if err != nil {
  1083  		return nil, model.NewAppError("SqlUserStore.GetByAuth", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1084  	}
  1085  
  1086  	user := model.User{}
  1087  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err == sql.ErrNoRows {
  1088  		return nil, model.NewAppError("SqlUserStore.GetByAuth", store.MISSING_AUTH_ACCOUNT_ERROR, nil, "authData="+*authData+", authService="+authService+", "+err.Error(), http.StatusInternalServerError)
  1089  	} else if err != nil {
  1090  		return nil, model.NewAppError("SqlUserStore.GetByAuth", "store.sql_user.get_by_auth.other.app_error", nil, "authData="+*authData+", authService="+authService+", "+err.Error(), http.StatusInternalServerError)
  1091  	}
  1092  	return &user, nil
  1093  }
  1094  
  1095  func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User, *model.AppError) {
  1096  	query := us.usersQuery.
  1097  		Where("u.AuthService = ?", authService).
  1098  		OrderBy("u.Username ASC")
  1099  
  1100  	queryString, args, err := query.ToSql()
  1101  	if err != nil {
  1102  		return nil, model.NewAppError("SqlUserStore.GetAllUsingAuthService", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1103  	}
  1104  
  1105  	var users []*model.User
  1106  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1107  		return nil, model.NewAppError("SqlUserStore.GetAllUsingAuthService", "store.sql_user.get_by_auth.other.app_error", nil, "authService="+authService+", "+err.Error(), http.StatusInternalServerError)
  1108  	}
  1109  
  1110  	return users, nil
  1111  }
  1112  
  1113  func (us SqlUserStore) GetAllNotInAuthService(authServices []string) ([]*model.User, *model.AppError) {
  1114  	query := us.usersQuery.
  1115  		Where(sq.NotEq{"u.AuthService": authServices}).
  1116  		OrderBy("u.Username ASC")
  1117  
  1118  	queryString, args, err := query.ToSql()
  1119  	if err != nil {
  1120  		return nil, model.NewAppError("SqlUserStore.GetAllNotInAuthService", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1121  	}
  1122  
  1123  	var users []*model.User
  1124  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1125  		return nil, model.NewAppError("SqlUserStore.GetAllNotInAuthService", "store.sql_user.get_by_auth.other.app_error", nil, "", http.StatusInternalServerError)
  1126  	}
  1127  
  1128  	return users, nil
  1129  }
  1130  
  1131  func (us SqlUserStore) GetByUsername(username string) (*model.User, *model.AppError) {
  1132  	query := us.usersQuery.Where("u.Username = ?", username)
  1133  
  1134  	queryString, args, err := query.ToSql()
  1135  	if err != nil {
  1136  		return nil, model.NewAppError("SqlUserStore.GetByUsername", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1137  	}
  1138  
  1139  	var user *model.User
  1140  	if err := us.GetReplica().SelectOne(&user, queryString, args...); err != nil {
  1141  		return nil, model.NewAppError("SqlUserStore.GetByUsername", "store.sql_user.get_by_username.app_error", nil, err.Error()+" -- "+queryString, http.StatusInternalServerError)
  1142  	}
  1143  
  1144  	return user, nil
  1145  }
  1146  
  1147  func (us SqlUserStore) GetForLogin(loginId string, allowSignInWithUsername, allowSignInWithEmail bool) (*model.User, *model.AppError) {
  1148  	query := us.usersQuery
  1149  	if allowSignInWithUsername && allowSignInWithEmail {
  1150  		query = query.Where("Username = ? OR Email = ?", loginId, loginId)
  1151  	} else if allowSignInWithUsername {
  1152  		query = query.Where("Username = ?", loginId)
  1153  	} else if allowSignInWithEmail {
  1154  		query = query.Where("Email = ?", loginId)
  1155  	} else {
  1156  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, "", http.StatusInternalServerError)
  1157  	}
  1158  
  1159  	queryString, args, err := query.ToSql()
  1160  	if err != nil {
  1161  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1162  	}
  1163  
  1164  	users := []*model.User{}
  1165  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1166  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, err.Error(), http.StatusInternalServerError)
  1167  	}
  1168  
  1169  	if len(users) == 0 {
  1170  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.app_error", nil, "", http.StatusInternalServerError)
  1171  	}
  1172  
  1173  	if len(users) > 1 {
  1174  		return nil, model.NewAppError("SqlUserStore.GetForLogin", "store.sql_user.get_for_login.multiple_users", nil, "", http.StatusInternalServerError)
  1175  	}
  1176  
  1177  	return users[0], nil
  1178  
  1179  }
  1180  
  1181  func (us SqlUserStore) VerifyEmail(userId, email string) (string, *model.AppError) {
  1182  	curTime := model.GetMillis()
  1183  	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 {
  1184  		return "", model.NewAppError("SqlUserStore.VerifyEmail", "store.sql_user.verify_email.app_error", nil, "userId="+userId+", "+err.Error(), http.StatusInternalServerError)
  1185  	}
  1186  
  1187  	return userId, nil
  1188  }
  1189  
  1190  func (us SqlUserStore) PermanentDelete(userId string) *model.AppError {
  1191  	if _, err := us.GetMaster().Exec("DELETE FROM Users WHERE Id = :UserId", map[string]interface{}{"UserId": userId}); err != nil {
  1192  		return model.NewAppError("SqlUserStore.PermanentDelete", "store.sql_user.permanent_delete.app_error", nil, "userId="+userId+", "+err.Error(), http.StatusInternalServerError)
  1193  	}
  1194  	return nil
  1195  }
  1196  
  1197  func (us SqlUserStore) Count(options model.UserCountOptions) (int64, *model.AppError) {
  1198  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
  1199  	query := us.getQueryBuilder().Select("COUNT(DISTINCT u.Id)").From("Users AS u")
  1200  
  1201  	if !options.IncludeDeleted {
  1202  		query = query.Where("u.DeleteAt = 0")
  1203  	}
  1204  
  1205  	if options.IncludeBotAccounts {
  1206  		if options.ExcludeRegularUsers {
  1207  			query = query.Join("Bots ON u.Id = Bots.UserId")
  1208  		}
  1209  	} else {
  1210  		query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL")
  1211  		if options.ExcludeRegularUsers {
  1212  			// Currently this doesn't make sense because it will always return 0
  1213  			return int64(0), model.NewAppError("SqlUserStore.Count", "store.sql_user.count.app_error", nil, "", http.StatusInternalServerError)
  1214  		}
  1215  	}
  1216  
  1217  	if options.TeamId != "" {
  1218  		query = query.LeftJoin("TeamMembers AS tm ON u.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId)
  1219  	} else if options.ChannelId != "" {
  1220  		query = query.LeftJoin("ChannelMembers AS cm ON u.Id = cm.UserId").Where("cm.ChannelId = ?", options.ChannelId)
  1221  	}
  1222  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, false)
  1223  	query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles)
  1224  
  1225  	if isPostgreSQL {
  1226  		query = query.PlaceholderFormat(sq.Dollar)
  1227  	}
  1228  
  1229  	queryString, args, err := query.ToSql()
  1230  	if err != nil {
  1231  		return int64(0), model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1232  	}
  1233  
  1234  	count, err := us.GetReplica().SelectInt(queryString, args...)
  1235  	if err != nil {
  1236  		return int64(0), model.NewAppError("SqlUserStore.Count", "store.sql_user.get_total_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1237  	}
  1238  	return count, nil
  1239  }
  1240  
  1241  func (us SqlUserStore) AnalyticsActiveCount(timePeriod int64, options model.UserCountOptions) (int64, *model.AppError) {
  1242  
  1243  	time := model.GetMillis() - timePeriod
  1244  	query := us.getQueryBuilder().Select("COUNT(*)").From("Status AS s").Where("LastActivityAt > :Time", map[string]interface{}{"Time": time})
  1245  
  1246  	if !options.IncludeBotAccounts {
  1247  		query = query.LeftJoin("Bots ON s.UserId = Bots.UserId").Where("Bots.UserId IS NULL")
  1248  	}
  1249  
  1250  	if !options.IncludeDeleted {
  1251  		query = query.LeftJoin("Users ON s.UserId = Users.Id").Where("Users.DeleteAt = 0")
  1252  	}
  1253  
  1254  	queryStr, args, err := query.ToSql()
  1255  
  1256  	if err != nil {
  1257  		return 0, model.NewAppError("SqlUserStore.Get", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1258  	}
  1259  
  1260  	v, err := us.GetReplica().SelectInt(queryStr, args...)
  1261  	if err != nil {
  1262  		return 0, model.NewAppError("SqlUserStore.AnalyticsDailyActiveUsers", "store.sql_user.analytics_daily_active_users.app_error", nil, err.Error(), http.StatusInternalServerError)
  1263  	}
  1264  	return v, nil
  1265  }
  1266  
  1267  func (us SqlUserStore) GetUnreadCount(userId string) (int64, *model.AppError) {
  1268  	query := `
  1269  		SELECT SUM(CASE WHEN c.Type = 'D' THEN (c.TotalMsgCount - cm.MsgCount) ELSE cm.MentionCount END)
  1270  		FROM Channels c
  1271  		INNER JOIN ChannelMembers cm
  1272  			ON cm.ChannelId = c.Id
  1273  			AND cm.UserId = :UserId
  1274  			AND c.DeleteAt = 0
  1275  	`
  1276  	count, err := us.GetReplica().SelectInt(query, map[string]interface{}{"UserId": userId})
  1277  	if err != nil {
  1278  		return count, model.NewAppError("SqlUserStore.GetMentionCount", "store.sql_user.get_unread_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1279  	}
  1280  
  1281  	return count, nil
  1282  }
  1283  
  1284  func (us SqlUserStore) GetUnreadCountForChannel(userId string, channelId string) (int64, *model.AppError) {
  1285  	count, err := us.GetReplica().SelectInt("SELECT SUM(CASE WHEN c.Type = 'D' THEN (c.TotalMsgCount - cm.MsgCount) ELSE cm.MentionCount END) FROM Channels c INNER JOIN ChannelMembers cm ON c.Id = cm.ChannelId AND cm.ChannelId = :ChannelId AND cm.UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId})
  1286  	if err != nil {
  1287  		return 0, model.NewAppError("SqlUserStore.GetMentionCountForChannel", "store.sql_user.get_unread_count_for_channel.app_error", nil, err.Error(), http.StatusInternalServerError)
  1288  	}
  1289  	return count, nil
  1290  }
  1291  
  1292  func (us SqlUserStore) GetAnyUnreadPostCountForChannel(userId string, channelId string) (int64, *model.AppError) {
  1293  	count, err := us.GetReplica().SelectInt("SELECT SUM(c.TotalMsgCount - cm.MsgCount) FROM Channels c INNER JOIN ChannelMembers cm ON c.Id = cm.ChannelId AND cm.ChannelId = :ChannelId AND cm.UserId = :UserId", map[string]interface{}{"ChannelId": channelId, "UserId": userId})
  1294  	if err != nil {
  1295  		return count, model.NewAppError("SqlUserStore.GetMentionCountForChannel", "store.sql_user.get_unread_count_for_channel.app_error", nil, err.Error(), http.StatusInternalServerError)
  1296  	}
  1297  	return count, nil
  1298  }
  1299  
  1300  func (us SqlUserStore) Search(teamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1301  	query := us.usersQuery.
  1302  		OrderBy("Username ASC").
  1303  		Limit(uint64(options.Limit))
  1304  
  1305  	if teamId != "" {
  1306  		query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
  1307  	}
  1308  	return us.performSearch(query, term, options)
  1309  }
  1310  
  1311  func (us SqlUserStore) SearchWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1312  	query := us.usersQuery.
  1313  		Where(`(
  1314  				SELECT
  1315  					COUNT(0)
  1316  				FROM
  1317  					TeamMembers
  1318  				WHERE
  1319  					TeamMembers.UserId = u.Id
  1320  					AND TeamMembers.DeleteAt = 0
  1321  			) = 0`).
  1322  		OrderBy("u.Username ASC").
  1323  		Limit(uint64(options.Limit))
  1324  
  1325  	return us.performSearch(query, term, options)
  1326  }
  1327  
  1328  func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1329  	query := us.usersQuery.
  1330  		LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", notInTeamId).
  1331  		Where("tm.UserId IS NULL").
  1332  		OrderBy("u.Username ASC").
  1333  		Limit(uint64(options.Limit))
  1334  
  1335  	if options.GroupConstrained {
  1336  		query = applyTeamGroupConstrainedFilter(query, notInTeamId)
  1337  	}
  1338  
  1339  	return us.performSearch(query, term, options)
  1340  }
  1341  
  1342  func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1343  	query := us.usersQuery.
  1344  		LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
  1345  		Where("cm.UserId IS NULL").
  1346  		OrderBy("Username ASC").
  1347  		Limit(uint64(options.Limit))
  1348  
  1349  	if teamId != "" {
  1350  		query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId)
  1351  	}
  1352  
  1353  	if options.GroupConstrained {
  1354  		query = applyChannelGroupConstrainedFilter(query, channelId)
  1355  	}
  1356  
  1357  	return us.performSearch(query, term, options)
  1358  }
  1359  
  1360  func (us SqlUserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1361  	query := us.usersQuery.
  1362  		Join("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId).
  1363  		OrderBy("Username ASC").
  1364  		Limit(uint64(options.Limit))
  1365  
  1366  	return us.performSearch(query, term, options)
  1367  }
  1368  
  1369  func (us SqlUserStore) SearchInGroup(groupID string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1370  	query := us.usersQuery.
  1371  		Join("GroupMembers gm ON ( gm.UserId = u.Id AND gm.GroupId = ? )", groupID).
  1372  		OrderBy("Username ASC").
  1373  		Limit(uint64(options.Limit))
  1374  
  1375  	return us.performSearch(query, term, options)
  1376  }
  1377  
  1378  var spaceFulltextSearchChar = []string{
  1379  	"<",
  1380  	">",
  1381  	"+",
  1382  	"-",
  1383  	"(",
  1384  	")",
  1385  	"~",
  1386  	":",
  1387  	"*",
  1388  	"\"",
  1389  	"!",
  1390  	"@",
  1391  }
  1392  
  1393  func generateSearchQuery(query sq.SelectBuilder, terms []string, fields []string, isPostgreSQL bool) sq.SelectBuilder {
  1394  	for _, term := range terms {
  1395  		searchFields := []string{}
  1396  		termArgs := []interface{}{}
  1397  		for _, field := range fields {
  1398  			if isPostgreSQL {
  1399  				searchFields = append(searchFields, fmt.Sprintf("lower(%s) LIKE lower(?) escape '*' ", field))
  1400  			} else {
  1401  				searchFields = append(searchFields, fmt.Sprintf("%s LIKE ? escape '*' ", field))
  1402  			}
  1403  			termArgs = append(termArgs, fmt.Sprintf("%s%%", strings.TrimLeft(term, "@")))
  1404  		}
  1405  		query = query.Where(fmt.Sprintf("(%s)", strings.Join(searchFields, " OR ")), termArgs...)
  1406  	}
  1407  
  1408  	return query
  1409  }
  1410  
  1411  func (us SqlUserStore) performSearch(query sq.SelectBuilder, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) {
  1412  	term = sanitizeSearchTerm(term, "*")
  1413  
  1414  	var searchType []string
  1415  	if options.AllowEmails {
  1416  		if options.AllowFullNames {
  1417  			searchType = USER_SEARCH_TYPE_ALL
  1418  		} else {
  1419  			searchType = USER_SEARCH_TYPE_ALL_NO_FULL_NAME
  1420  		}
  1421  	} else {
  1422  		if options.AllowFullNames {
  1423  			searchType = USER_SEARCH_TYPE_NAMES
  1424  		} else {
  1425  			searchType = USER_SEARCH_TYPE_NAMES_NO_FULL_NAME
  1426  		}
  1427  	}
  1428  
  1429  	isPostgreSQL := us.DriverName() == model.DATABASE_DRIVER_POSTGRES
  1430  
  1431  	query = applyRoleFilter(query, options.Role, isPostgreSQL)
  1432  	query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles)
  1433  
  1434  	if !options.AllowInactive {
  1435  		query = query.Where("u.DeleteAt = 0")
  1436  	}
  1437  
  1438  	if strings.TrimSpace(term) != "" {
  1439  		query = generateSearchQuery(query, strings.Fields(term), searchType, isPostgreSQL)
  1440  	}
  1441  
  1442  	query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true)
  1443  
  1444  	queryString, args, err := query.ToSql()
  1445  	if err != nil {
  1446  		return nil, model.NewAppError("SqlUserStore.Search", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1447  	}
  1448  
  1449  	var users []*model.User
  1450  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1451  		return nil, model.NewAppError("SqlUserStore.Search", "store.sql_user.search.app_error", nil,
  1452  			fmt.Sprintf("term=%v, search_type=%v, %v", term, searchType, err.Error()), http.StatusInternalServerError)
  1453  	}
  1454  	for _, u := range users {
  1455  		u.Sanitize(map[string]bool{})
  1456  	}
  1457  
  1458  	return users, nil
  1459  }
  1460  
  1461  func (us SqlUserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) {
  1462  	count, err := us.GetReplica().SelectInt("SELECT COUNT(Id) FROM Users WHERE DeleteAt > 0")
  1463  	if err != nil {
  1464  		return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetInactiveUsersCount", "store.sql_user.analytics_get_inactive_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1465  	}
  1466  	return count, nil
  1467  }
  1468  
  1469  func (us SqlUserStore) AnalyticsGetGuestCount() (int64, *model.AppError) {
  1470  	count, err := us.GetReplica().SelectInt("SELECT count(*) FROM Users WHERE Roles LIKE :Roles and DeleteAt = 0", map[string]interface{}{"Roles": "%system_guest%"})
  1471  	if err != nil {
  1472  		return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetSystemAdminCount", "store.sql_user.analytics_get_system_admin_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1473  	}
  1474  	return count, nil
  1475  }
  1476  
  1477  func (us SqlUserStore) AnalyticsGetSystemAdminCount() (int64, *model.AppError) {
  1478  	count, err := us.GetReplica().SelectInt("SELECT count(*) FROM Users WHERE Roles LIKE :Roles and DeleteAt = 0", map[string]interface{}{"Roles": "%system_admin%"})
  1479  	if err != nil {
  1480  		return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetSystemAdminCount", "store.sql_user.analytics_get_system_admin_count.app_error", nil, err.Error(), http.StatusInternalServerError)
  1481  	}
  1482  	return count, nil
  1483  }
  1484  
  1485  func (us SqlUserStore) GetProfilesNotInTeam(teamId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) {
  1486  	var users []*model.User
  1487  	query := us.usersQuery.
  1488  		LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId).
  1489  		Where("tm.UserId IS NULL").
  1490  		OrderBy("u.Username ASC").
  1491  		Offset(uint64(offset)).Limit(uint64(limit))
  1492  
  1493  	query = applyViewRestrictionsFilter(query, viewRestrictions, true)
  1494  
  1495  	if groupConstrained {
  1496  		query = applyTeamGroupConstrainedFilter(query, teamId)
  1497  	}
  1498  
  1499  	queryString, args, err := query.ToSql()
  1500  	if err != nil {
  1501  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1502  	}
  1503  
  1504  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1505  		return nil, model.NewAppError("SqlUserStore.GetProfilesNotInTeam", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
  1506  	}
  1507  
  1508  	for _, u := range users {
  1509  		u.Sanitize(map[string]bool{})
  1510  	}
  1511  	return users, nil
  1512  }
  1513  
  1514  func (us SqlUserStore) GetEtagForProfilesNotInTeam(teamId string) string {
  1515  	querystr := `
  1516  		SELECT
  1517  			CONCAT(MAX(UpdateAt), '.', COUNT(Id)) as etag
  1518  		FROM
  1519  			Users as u
  1520  		LEFT JOIN TeamMembers tm
  1521  			ON tm.UserId = u.Id
  1522  			AND tm.TeamId = :TeamId
  1523  			AND tm.DeleteAt = 0
  1524  		WHERE
  1525  			tm.UserId IS NULL
  1526  	`
  1527  	etag, err := us.GetReplica().SelectStr(querystr, map[string]interface{}{"TeamId": teamId})
  1528  	if err != nil {
  1529  		return fmt.Sprintf("%v.%v", model.CurrentVersion, model.GetMillis())
  1530  	}
  1531  
  1532  	return fmt.Sprintf("%v.%v", model.CurrentVersion, etag)
  1533  }
  1534  
  1535  func (us SqlUserStore) ClearAllCustomRoleAssignments() *model.AppError {
  1536  	builtInRoles := model.MakeDefaultRoles()
  1537  	lastUserId := strings.Repeat("0", 26)
  1538  
  1539  	for {
  1540  		var transaction *gorp.Transaction
  1541  		var err error
  1542  
  1543  		if transaction, err = us.GetMaster().Begin(); err != nil {
  1544  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1545  		}
  1546  		defer finalizeTransaction(transaction)
  1547  
  1548  		var users []*model.User
  1549  		if _, err := transaction.Select(&users, "SELECT * from Users WHERE Id > :Id ORDER BY Id LIMIT 1000", map[string]interface{}{"Id": lastUserId}); err != nil {
  1550  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.select.app_error", nil, err.Error(), http.StatusInternalServerError)
  1551  		}
  1552  
  1553  		if len(users) == 0 {
  1554  			break
  1555  		}
  1556  
  1557  		for _, user := range users {
  1558  			lastUserId = user.Id
  1559  
  1560  			var newRoles []string
  1561  
  1562  			for _, role := range strings.Fields(user.Roles) {
  1563  				for name := range builtInRoles {
  1564  					if name == role {
  1565  						newRoles = append(newRoles, role)
  1566  						break
  1567  					}
  1568  				}
  1569  			}
  1570  
  1571  			newRolesString := strings.Join(newRoles, " ")
  1572  			if newRolesString != user.Roles {
  1573  				if _, err := transaction.Exec("UPDATE Users SET Roles = :Roles WHERE Id = :Id", map[string]interface{}{"Roles": newRolesString, "Id": user.Id}); err != nil {
  1574  					return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.update.app_error", nil, err.Error(), http.StatusInternalServerError)
  1575  				}
  1576  			}
  1577  		}
  1578  
  1579  		if err := transaction.Commit(); err != nil {
  1580  			return model.NewAppError("SqlUserStore.ClearAllCustomRoleAssignments", "store.sql_user.clear_all_custom_role_assignments.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1581  		}
  1582  	}
  1583  
  1584  	return nil
  1585  }
  1586  
  1587  func (us SqlUserStore) InferSystemInstallDate() (int64, *model.AppError) {
  1588  	createAt, err := us.GetReplica().SelectInt("SELECT CreateAt FROM Users WHERE CreateAt IS NOT NULL ORDER BY CreateAt ASC LIMIT 1")
  1589  	if err != nil {
  1590  		return 0, model.NewAppError("SqlUserStore.GetSystemInstallDate", "store.sql_user.get_system_install_date.app_error", nil, err.Error(), http.StatusInternalServerError)
  1591  	}
  1592  
  1593  	return createAt, nil
  1594  }
  1595  
  1596  func (us SqlUserStore) GetUsersBatchForIndexing(startTime, endTime int64, limit int) ([]*model.UserForIndexing, *model.AppError) {
  1597  	var users []*model.User
  1598  	usersQuery, args, _ := us.usersQuery.
  1599  		Where(sq.GtOrEq{"u.CreateAt": startTime}).
  1600  		Where(sq.Lt{"u.CreateAt": endTime}).
  1601  		OrderBy("u.CreateAt").
  1602  		Limit(uint64(limit)).
  1603  		ToSql()
  1604  	_, err := us.GetSearchReplica().Select(&users, usersQuery, args...)
  1605  	if err != nil {
  1606  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_users.app_error", nil, err.Error(), http.StatusInternalServerError)
  1607  	}
  1608  
  1609  	userIds := []string{}
  1610  	for _, user := range users {
  1611  		userIds = append(userIds, user.Id)
  1612  	}
  1613  
  1614  	var channelMembers []*model.ChannelMember
  1615  	channelMembersQuery, args, _ := us.getQueryBuilder().
  1616  		Select(`
  1617  				cm.ChannelId,
  1618  				cm.UserId,
  1619  				cm.Roles,
  1620  				cm.LastViewedAt,
  1621  				cm.MsgCount,
  1622  				cm.MentionCount,
  1623  				cm.NotifyProps,
  1624  				cm.LastUpdateAt,
  1625  				cm.SchemeUser,
  1626  				cm.SchemeAdmin,
  1627  				(cm.SchemeGuest IS NOT NULL AND cm.SchemeGuest) as SchemeGuest
  1628  			`).
  1629  		From("ChannelMembers cm").
  1630  		Join("Channels c ON cm.ChannelId = c.Id").
  1631  		Where(sq.Eq{"c.Type": "O", "cm.UserId": userIds}).
  1632  		ToSql()
  1633  	_, err = us.GetSearchReplica().Select(&channelMembers, channelMembersQuery, args...)
  1634  	if err != nil {
  1635  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_channel_members.app_error", nil, err.Error(), http.StatusInternalServerError)
  1636  	}
  1637  
  1638  	var teamMembers []*model.TeamMember
  1639  	teamMembersQuery, args, _ := us.getQueryBuilder().
  1640  		Select("TeamId, UserId, Roles, DeleteAt, (SchemeGuest IS NOT NULL AND SchemeGuest) as SchemeGuest, SchemeUser, SchemeAdmin").
  1641  		From("TeamMembers").
  1642  		Where(sq.Eq{"UserId": userIds, "DeleteAt": 0}).
  1643  		ToSql()
  1644  	_, err = us.GetSearchReplica().Select(&teamMembers, teamMembersQuery, args...)
  1645  	if err != nil {
  1646  		return nil, model.NewAppError("SqlUserStore.GetUsersBatchForIndexing", "store.sql_user.get_users_batch_for_indexing.get_team_members.app_error", nil, err.Error(), http.StatusInternalServerError)
  1647  	}
  1648  
  1649  	userMap := map[string]*model.UserForIndexing{}
  1650  	for _, user := range users {
  1651  		userMap[user.Id] = &model.UserForIndexing{
  1652  			Id:          user.Id,
  1653  			Username:    user.Username,
  1654  			Nickname:    user.Nickname,
  1655  			FirstName:   user.FirstName,
  1656  			LastName:    user.LastName,
  1657  			Roles:       user.Roles,
  1658  			CreateAt:    user.CreateAt,
  1659  			DeleteAt:    user.DeleteAt,
  1660  			TeamsIds:    []string{},
  1661  			ChannelsIds: []string{},
  1662  		}
  1663  	}
  1664  
  1665  	for _, c := range channelMembers {
  1666  		if userMap[c.UserId] != nil {
  1667  			userMap[c.UserId].ChannelsIds = append(userMap[c.UserId].ChannelsIds, c.ChannelId)
  1668  		}
  1669  	}
  1670  	for _, t := range teamMembers {
  1671  		if userMap[t.UserId] != nil {
  1672  			userMap[t.UserId].TeamsIds = append(userMap[t.UserId].TeamsIds, t.TeamId)
  1673  		}
  1674  	}
  1675  
  1676  	usersForIndexing := []*model.UserForIndexing{}
  1677  	for _, user := range userMap {
  1678  		usersForIndexing = append(usersForIndexing, user)
  1679  	}
  1680  	sort.Slice(usersForIndexing, func(i, j int) bool {
  1681  		return usersForIndexing[i].CreateAt < usersForIndexing[j].CreateAt
  1682  	})
  1683  
  1684  	return usersForIndexing, nil
  1685  }
  1686  
  1687  func (us SqlUserStore) GetTeamGroupUsers(teamID string) ([]*model.User, *model.AppError) {
  1688  	query := applyTeamGroupConstrainedFilter(us.usersQuery, teamID)
  1689  
  1690  	queryString, args, err := query.ToSql()
  1691  	if err != nil {
  1692  		return nil, model.NewAppError("SqlUserStore.UsersPermittedToTeam", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1693  	}
  1694  
  1695  	var users []*model.User
  1696  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1697  		return nil, model.NewAppError("SqlUserStore.UsersPermittedToTeam", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
  1698  	}
  1699  
  1700  	for _, u := range users {
  1701  		u.Sanitize(map[string]bool{})
  1702  	}
  1703  
  1704  	return users, nil
  1705  }
  1706  
  1707  func (us SqlUserStore) GetChannelGroupUsers(channelID string) ([]*model.User, *model.AppError) {
  1708  	query := applyChannelGroupConstrainedFilter(us.usersQuery, channelID)
  1709  
  1710  	queryString, args, err := query.ToSql()
  1711  	if err != nil {
  1712  		return nil, model.NewAppError("SqlUserStore.GetChannelGroupUsers", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1713  	}
  1714  
  1715  	var users []*model.User
  1716  	if _, err := us.GetReplica().Select(&users, queryString, args...); err != nil {
  1717  		return nil, model.NewAppError("SqlUserStore.GetChannelGroupUsers", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
  1718  	}
  1719  
  1720  	for _, u := range users {
  1721  		u.Sanitize(map[string]bool{})
  1722  	}
  1723  
  1724  	return users, nil
  1725  }
  1726  
  1727  func applyViewRestrictionsFilter(query sq.SelectBuilder, restrictions *model.ViewUsersRestrictions, distinct bool) sq.SelectBuilder {
  1728  	if restrictions == nil {
  1729  		return query
  1730  	}
  1731  
  1732  	// If you have no access to teams or channels, return and empty result.
  1733  	if restrictions.Teams != nil && len(restrictions.Teams) == 0 && restrictions.Channels != nil && len(restrictions.Channels) == 0 {
  1734  		return query.Where("1 = 0")
  1735  	}
  1736  
  1737  	teams := make([]interface{}, len(restrictions.Teams))
  1738  	for i, v := range restrictions.Teams {
  1739  		teams[i] = v
  1740  	}
  1741  	channels := make([]interface{}, len(restrictions.Channels))
  1742  	for i, v := range restrictions.Channels {
  1743  		channels[i] = v
  1744  	}
  1745  	resultQuery := query
  1746  	if restrictions.Teams != nil && len(restrictions.Teams) > 0 {
  1747  		resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = u.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...)
  1748  	}
  1749  	if restrictions.Channels != nil && len(restrictions.Channels) > 0 {
  1750  		resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = u.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...)
  1751  	}
  1752  
  1753  	if distinct {
  1754  		return resultQuery.Distinct()
  1755  	}
  1756  
  1757  	return resultQuery
  1758  }
  1759  
  1760  func (us SqlUserStore) PromoteGuestToUser(userId string) *model.AppError {
  1761  	transaction, err := us.GetMaster().Begin()
  1762  	if err != nil {
  1763  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.promote_guest.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1764  	}
  1765  	defer finalizeTransaction(transaction)
  1766  
  1767  	user, appErr := us.Get(userId)
  1768  	if appErr != nil {
  1769  		return appErr
  1770  	}
  1771  
  1772  	roles := user.GetRoles()
  1773  
  1774  	for idx, role := range roles {
  1775  		if role == "system_guest" {
  1776  			roles[idx] = "system_user"
  1777  		}
  1778  	}
  1779  
  1780  	curTime := model.GetMillis()
  1781  	query := us.getQueryBuilder().Update("Users").
  1782  		Set("Roles", strings.Join(roles, " ")).
  1783  		Set("UpdateAt", curTime).
  1784  		Where(sq.Eq{"Id": userId})
  1785  
  1786  	queryString, args, err := query.ToSql()
  1787  	if err != nil {
  1788  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1789  	}
  1790  
  1791  	if _, err = transaction.Exec(queryString, args...); err != nil {
  1792  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.promote_guest.user_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1793  	}
  1794  
  1795  	query = us.getQueryBuilder().Update("ChannelMembers").
  1796  		Set("SchemeUser", true).
  1797  		Set("SchemeGuest", false).
  1798  		Where(sq.Eq{"UserId": userId})
  1799  
  1800  	queryString, args, err = query.ToSql()
  1801  	if err != nil {
  1802  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1803  	}
  1804  
  1805  	if _, err = transaction.Exec(queryString, args...); err != nil {
  1806  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.promote_guest.channel_members_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1807  	}
  1808  
  1809  	query = us.getQueryBuilder().Update("TeamMembers").
  1810  		Set("SchemeUser", true).
  1811  		Set("SchemeGuest", false).
  1812  		Where(sq.Eq{"UserId": userId})
  1813  
  1814  	queryString, args, err = query.ToSql()
  1815  	if err != nil {
  1816  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1817  	}
  1818  
  1819  	if _, err := transaction.Exec(queryString, args...); err != nil {
  1820  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.promote_guest.team_members_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1821  	}
  1822  
  1823  	if err := transaction.Commit(); err != nil {
  1824  		return model.NewAppError("SqlUserStore.PromoteGuestToUser", "store.sql_user.promote_guest.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1825  	}
  1826  	return nil
  1827  }
  1828  
  1829  func (us SqlUserStore) DemoteUserToGuest(userId string) *model.AppError {
  1830  	transaction, err := us.GetMaster().Begin()
  1831  	if err != nil {
  1832  		return model.NewAppError("SqlUserStore.DemoteUserToGuest", "store.sql_user.demote_user_to_guest.open_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1833  	}
  1834  	defer finalizeTransaction(transaction)
  1835  
  1836  	user, appErr := us.Get(userId)
  1837  	if appErr != nil {
  1838  		return appErr
  1839  	}
  1840  
  1841  	roles := user.GetRoles()
  1842  
  1843  	newRoles := []string{}
  1844  	for _, role := range roles {
  1845  		if role == "system_user" {
  1846  			newRoles = append(newRoles, "system_guest")
  1847  		} else if role != "system_admin" {
  1848  			newRoles = append(newRoles, role)
  1849  		}
  1850  	}
  1851  
  1852  	curTime := model.GetMillis()
  1853  	query := us.getQueryBuilder().Update("Users").
  1854  		Set("Roles", strings.Join(newRoles, " ")).
  1855  		Set("UpdateAt", curTime).
  1856  		Where(sq.Eq{"Id": userId})
  1857  
  1858  	queryString, args, err := query.ToSql()
  1859  	if err != nil {
  1860  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1861  	}
  1862  
  1863  	if _, err = transaction.Exec(queryString, args...); err != nil {
  1864  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.demote_user_to_guest.user_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1865  	}
  1866  
  1867  	query = us.getQueryBuilder().Update("ChannelMembers").
  1868  		Set("SchemeUser", false).
  1869  		Set("SchemeGuest", true).
  1870  		Where(sq.Eq{"UserId": userId})
  1871  
  1872  	queryString, args, err = query.ToSql()
  1873  	if err != nil {
  1874  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1875  	}
  1876  
  1877  	if _, err = transaction.Exec(queryString, args...); err != nil {
  1878  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.demote_user_to_guest.channel_members_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1879  	}
  1880  
  1881  	query = us.getQueryBuilder().Update("TeamMembers").
  1882  		Set("SchemeUser", false).
  1883  		Set("SchemeGuest", true).
  1884  		Where(sq.Eq{"UserId": userId})
  1885  
  1886  	queryString, args, err = query.ToSql()
  1887  	if err != nil {
  1888  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.app_error", nil, err.Error(), http.StatusInternalServerError)
  1889  	}
  1890  
  1891  	if _, err := transaction.Exec(queryString, args...); err != nil {
  1892  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.demote_user_to_guest.team_members_update.app_error", nil, "user_id="+userId, http.StatusInternalServerError)
  1893  	}
  1894  
  1895  	if err := transaction.Commit(); err != nil {
  1896  		return model.NewAppError("SqlUserStore.DemoteGuestToUser", "store.sql_user.demote_user_to_guest.commit_transaction.app_error", nil, err.Error(), http.StatusInternalServerError)
  1897  	}
  1898  	return nil
  1899  }
  1900  
  1901  func (us SqlUserStore) AutocompleteUsersInChannel(teamId, channelId, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInChannel, *model.AppError) {
  1902  	autocomplete := &model.UserAutocompleteInChannel{}
  1903  	uchan := make(chan store.StoreResult, 1)
  1904  	go func() {
  1905  		users, err := us.SearchInChannel(channelId, term, options)
  1906  		uchan <- store.StoreResult{Data: users, Err: err}
  1907  		close(uchan)
  1908  	}()
  1909  
  1910  	nuchan := make(chan store.StoreResult, 1)
  1911  	go func() {
  1912  		users, err := us.SearchNotInChannel(teamId, channelId, term, options)
  1913  		nuchan <- store.StoreResult{Data: users, Err: err}
  1914  		close(nuchan)
  1915  	}()
  1916  
  1917  	result := <-uchan
  1918  	if result.Err != nil {
  1919  		return nil, result.Err
  1920  	}
  1921  	users := result.Data.([]*model.User)
  1922  	autocomplete.InChannel = users
  1923  
  1924  	result = <-nuchan
  1925  	if result.Err != nil {
  1926  		return nil, result.Err
  1927  	}
  1928  	users = result.Data.([]*model.User)
  1929  	autocomplete.OutOfChannel = users
  1930  	return autocomplete, nil
  1931  }
  1932  
  1933  // GetKnownUsers returns the list of user ids of users with any direct
  1934  // relationship with a user. That means any user sharing any channel, including
  1935  // direct and group channels.
  1936  func (us SqlUserStore) GetKnownUsers(userId string) ([]string, *model.AppError) {
  1937  	var userIds []string
  1938  	usersQuery, args, _ := us.getQueryBuilder().
  1939  		Select("DISTINCT ocm.UserId").
  1940  		From("ChannelMembers AS cm").
  1941  		Join("ChannelMembers AS ocm ON ocm.ChannelId = cm.ChannelId").
  1942  		Where(sq.NotEq{"ocm.UserId": userId}).
  1943  		Where(sq.Eq{"cm.UserId": userId}).
  1944  		ToSql()
  1945  	_, err := us.GetSearchReplica().Select(&userIds, usersQuery, args...)
  1946  	if err != nil {
  1947  		return nil, model.NewAppError("SqlUserStore.GetKnownUsers", "store.sql_user.get_known_users.get_users.app_error", nil, err.Error(), http.StatusInternalServerError)
  1948  	}
  1949  
  1950  	return userIds, nil
  1951  }