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