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