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