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