github.com/crspeller/mattermost-server@v0.0.0-20190328001957-a200beb3d111/app/user.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "bytes" 8 b64 "encoding/base64" 9 "encoding/json" 10 "fmt" 11 "hash/fnv" 12 "image" 13 "image/color" 14 "image/draw" 15 _ "image/gif" 16 _ "image/jpeg" 17 "image/png" 18 "io" 19 "io/ioutil" 20 "mime/multipart" 21 "net/http" 22 "path/filepath" 23 "strconv" 24 "strings" 25 26 "github.com/disintegration/imaging" 27 "github.com/golang/freetype" 28 "github.com/golang/freetype/truetype" 29 "github.com/crspeller/mattermost-server/einterfaces" 30 "github.com/crspeller/mattermost-server/mlog" 31 "github.com/crspeller/mattermost-server/model" 32 "github.com/crspeller/mattermost-server/plugin" 33 "github.com/crspeller/mattermost-server/services/mfa" 34 "github.com/crspeller/mattermost-server/store" 35 "github.com/crspeller/mattermost-server/utils" 36 "github.com/crspeller/mattermost-server/utils/fileutils" 37 ) 38 39 const ( 40 TOKEN_TYPE_PASSWORD_RECOVERY = "password_recovery" 41 TOKEN_TYPE_VERIFY_EMAIL = "verify_email" 42 TOKEN_TYPE_TEAM_INVITATION = "team_invitation" 43 PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour 44 TEAM_INVITATION_EXPIRY_TIME = 1000 * 60 * 60 * 48 // 48 hours 45 IMAGE_PROFILE_PIXEL_DIMENSION = 128 46 ) 47 48 func (a *App) CreateUserWithToken(user *model.User, tokenId string) (*model.User, *model.AppError) { 49 if err := a.IsUserSignUpAllowed(); err != nil { 50 return nil, err 51 } 52 53 result := <-a.Srv.Store.Token().GetByToken(tokenId) 54 if result.Err != nil { 55 return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, result.Err.Error(), http.StatusBadRequest) 56 } 57 58 token := result.Data.(*model.Token) 59 if token.Type != TOKEN_TYPE_TEAM_INVITATION { 60 return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_invalid.app_error", nil, "", http.StatusBadRequest) 61 } 62 63 if model.GetMillis()-token.CreateAt >= TEAM_INVITATION_EXPIRY_TIME { 64 a.DeleteToken(token) 65 return nil, model.NewAppError("CreateUserWithToken", "api.user.create_user.signup_link_expired.app_error", nil, "", http.StatusBadRequest) 66 } 67 68 tokenData := model.MapFromJson(strings.NewReader(token.Extra)) 69 70 result = <-a.Srv.Store.Team().Get(tokenData["teamId"]) 71 if result.Err != nil { 72 return nil, result.Err 73 } 74 team := result.Data.(*model.Team) 75 76 user.Email = tokenData["email"] 77 user.EmailVerified = true 78 79 ruser, err := a.CreateUser(user) 80 if err != nil { 81 return nil, err 82 } 83 84 if err := a.JoinUserToTeam(team, ruser, ""); err != nil { 85 return nil, err 86 } 87 88 a.AddDirectChannels(team.Id, ruser) 89 90 if err := a.DeleteToken(token); err != nil { 91 return nil, err 92 } 93 94 return ruser, nil 95 } 96 97 func (a *App) CreateUserWithInviteId(user *model.User, inviteId string) (*model.User, *model.AppError) { 98 if err := a.IsUserSignUpAllowed(); err != nil { 99 return nil, err 100 } 101 102 result := <-a.Srv.Store.Team().GetByInviteId(inviteId) 103 if result.Err != nil { 104 return nil, result.Err 105 } 106 team := result.Data.(*model.Team) 107 108 user.EmailVerified = false 109 110 ruser, err := a.CreateUser(user) 111 if err != nil { 112 return nil, err 113 } 114 115 if err := a.JoinUserToTeam(team, ruser, ""); err != nil { 116 return nil, err 117 } 118 119 a.AddDirectChannels(team.Id, ruser) 120 121 if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil { 122 mlog.Error(err.Error()) 123 } 124 125 return ruser, nil 126 } 127 128 func (a *App) CreateUserAsAdmin(user *model.User) (*model.User, *model.AppError) { 129 ruser, err := a.CreateUser(user) 130 if err != nil { 131 return nil, err 132 } 133 134 if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil { 135 mlog.Error(err.Error()) 136 } 137 138 return ruser, nil 139 } 140 141 func (a *App) CreateUserFromSignup(user *model.User) (*model.User, *model.AppError) { 142 if err := a.IsUserSignUpAllowed(); err != nil { 143 return nil, err 144 } 145 146 if !a.IsFirstUserAccount() && !*a.Config().TeamSettings.EnableOpenServer { 147 err := model.NewAppError("CreateUserFromSignup", "api.user.create_user.no_open_server", nil, "email="+user.Email, http.StatusForbidden) 148 return nil, err 149 } 150 151 user.EmailVerified = false 152 153 ruser, err := a.CreateUser(user) 154 if err != nil { 155 return nil, err 156 } 157 158 if err := a.SendWelcomeEmail(ruser.Id, ruser.Email, ruser.EmailVerified, ruser.Locale, a.GetSiteURL()); err != nil { 159 mlog.Error(err.Error()) 160 } 161 162 return ruser, nil 163 } 164 165 func (a *App) IsUserSignUpAllowed() *model.AppError { 166 if !*a.Config().EmailSettings.EnableSignUpWithEmail || !*a.Config().TeamSettings.EnableUserCreation { 167 err := model.NewAppError("IsUserSignUpAllowed", "api.user.create_user.signup_email_disabled.app_error", nil, "", http.StatusNotImplemented) 168 return err 169 } 170 return nil 171 } 172 173 func (a *App) IsFirstUserAccount() bool { 174 if a.SessionCacheLength() == 0 { 175 cr := <-a.Srv.Store.User().Count(model.UserCountOptions{ 176 IncludeDeleted: true, 177 }) 178 if cr.Err != nil { 179 mlog.Error(fmt.Sprint(cr.Err)) 180 return false 181 } 182 if cr.Data.(int64) <= 0 { 183 return true 184 } 185 } 186 187 return false 188 } 189 190 // indexUser fetches the required information to index a user from the database and 191 // calls the elasticsearch interface method 192 func (a *App) indexUser(user *model.User) *model.AppError { 193 userTeams := <-a.Srv.Store.Team().GetTeamsByUserId(user.Id) 194 if userTeams.Err != nil { 195 return userTeams.Err 196 } 197 198 userTeamsIds := []string{} 199 for _, team := range userTeams.Data.([]*model.Team) { 200 userTeamsIds = append(userTeamsIds, team.Id) 201 } 202 203 userChannelMembers := <-a.Srv.Store.Channel().GetAllChannelMembersForUser(user.Id, false, true) 204 if userChannelMembers.Err != nil { 205 return userChannelMembers.Err 206 } 207 208 userChannelsIds := []string{} 209 for channelId := range userChannelMembers.Data.(map[string]string) { 210 userChannelsIds = append(userChannelsIds, channelId) 211 } 212 213 return a.Elasticsearch.IndexUser(user, userTeamsIds, userChannelsIds) 214 } 215 216 func (a *App) indexUserFromId(userId string) *model.AppError { 217 user, err := a.GetUser(userId) 218 if err != nil { 219 return err 220 } 221 return a.indexUser(user) 222 } 223 224 // CreateUser creates a user and sets several fields of the returned User struct to 225 // their zero values. 226 func (a *App) CreateUser(user *model.User) (*model.User, *model.AppError) { 227 if !user.IsLDAPUser() && !user.IsSAMLUser() && !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) { 228 return nil, model.NewAppError("CreateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest) 229 } 230 231 user.Roles = model.SYSTEM_USER_ROLE_ID 232 233 // Below is a special case where the first user in the entire 234 // system is granted the system_admin role 235 result := <-a.Srv.Store.User().Count(model.UserCountOptions{ 236 IncludeDeleted: true, 237 }) 238 if result.Err != nil { 239 return nil, result.Err 240 } 241 if result.Data.(int64) <= 0 { 242 user.Roles = model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID 243 } 244 245 if _, ok := utils.GetSupportedLocales()[user.Locale]; !ok { 246 user.Locale = *a.Config().LocalizationSettings.DefaultClientLocale 247 } 248 249 ruser, err := a.createUser(user) 250 if err != nil { 251 return nil, err 252 } 253 // This message goes to everyone, so the teamId, channelId and userId are irrelevant 254 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_NEW_USER, "", "", "", nil) 255 message.Add("user_id", ruser.Id) 256 a.Publish(message) 257 258 if pluginsEnvironment := a.GetPluginsEnvironment(); pluginsEnvironment != nil { 259 a.Srv.Go(func() { 260 pluginContext := a.PluginContext() 261 pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool { 262 hooks.UserHasBeenCreated(pluginContext, user) 263 return true 264 }, plugin.UserHasBeenCreatedId) 265 }) 266 } 267 268 esInterface := a.Elasticsearch 269 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableIndexing { 270 a.Srv.Go(func() { 271 if err := a.indexUser(user); err != nil { 272 mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err)) 273 } 274 }) 275 } 276 277 return ruser, nil 278 } 279 280 func (a *App) createUser(user *model.User) (*model.User, *model.AppError) { 281 user.MakeNonNil() 282 283 if err := a.IsPasswordValid(user.Password); user.AuthService == "" && err != nil { 284 return nil, err 285 } 286 287 result := <-a.Srv.Store.User().Save(user) 288 if result.Err != nil { 289 mlog.Error(fmt.Sprintf("Couldn't save the user err=%v", result.Err)) 290 return nil, result.Err 291 } 292 ruser := result.Data.(*model.User) 293 294 if user.EmailVerified { 295 if err := a.VerifyUserEmail(ruser.Id, user.Email); err != nil { 296 mlog.Error(fmt.Sprintf("Failed to set email verified err=%v", err)) 297 } 298 } 299 300 pref := model.Preference{UserId: ruser.Id, Category: model.PREFERENCE_CATEGORY_TUTORIAL_STEPS, Name: ruser.Id, Value: "0"} 301 if presult := <-a.Srv.Store.Preference().Save(&model.Preferences{pref}); presult.Err != nil { 302 mlog.Error(fmt.Sprintf("Encountered error saving tutorial preference, err=%v", presult.Err.Message)) 303 } 304 305 ruser.Sanitize(map[string]bool{}) 306 return ruser, nil 307 } 308 309 func (a *App) CreateOAuthUser(service string, userData io.Reader, teamId string) (*model.User, *model.AppError) { 310 if !*a.Config().TeamSettings.EnableUserCreation { 311 return nil, model.NewAppError("CreateOAuthUser", "api.user.create_user.disabled.app_error", nil, "", http.StatusNotImplemented) 312 } 313 314 provider := einterfaces.GetOauthProvider(service) 315 if provider == nil { 316 return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.not_available.app_error", map[string]interface{}{"Service": strings.Title(service)}, "", http.StatusNotImplemented) 317 } 318 user := provider.GetUserFromJson(userData) 319 320 if user == nil { 321 return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.create.app_error", map[string]interface{}{"Service": service}, "", http.StatusInternalServerError) 322 } 323 324 suchan := a.Srv.Store.User().GetByAuth(user.AuthData, service) 325 euchan := a.Srv.Store.User().GetByEmail(user.Email) 326 327 found := true 328 count := 0 329 for found { 330 if found = a.IsUsernameTaken(user.Username); found { 331 user.Username = user.Username + strconv.Itoa(count) 332 count++ 333 } 334 } 335 336 if result := <-suchan; result.Err == nil { 337 return result.Data.(*model.User), nil 338 } 339 340 if result := <-euchan; result.Err == nil { 341 authService := result.Data.(*model.User).AuthService 342 if authService == "" { 343 return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.already_attached.app_error", map[string]interface{}{"Service": service, "Auth": model.USER_AUTH_SERVICE_EMAIL}, "email="+user.Email, http.StatusBadRequest) 344 } 345 return nil, model.NewAppError("CreateOAuthUser", "api.user.create_oauth_user.already_attached.app_error", map[string]interface{}{"Service": service, "Auth": authService}, "email="+user.Email, http.StatusBadRequest) 346 } 347 348 user.EmailVerified = true 349 350 ruser, err := a.CreateUser(user) 351 if err != nil { 352 return nil, err 353 } 354 355 if len(teamId) > 0 { 356 err = a.AddUserToTeamByTeamId(teamId, user) 357 if err != nil { 358 return nil, err 359 } 360 361 err = a.AddDirectChannels(teamId, user) 362 if err != nil { 363 mlog.Error(err.Error()) 364 } 365 } 366 367 return ruser, nil 368 } 369 370 // CheckUserDomain checks that a user's email domain matches a list of space-delimited domains as a string. 371 func CheckUserDomain(user *model.User, domains string) bool { 372 if len(domains) == 0 { 373 return true 374 } 375 376 domainArray := strings.Fields(strings.TrimSpace(strings.ToLower(strings.Replace(strings.Replace(domains, "@", " ", -1), ",", " ", -1)))) 377 378 for _, d := range domainArray { 379 if strings.HasSuffix(strings.ToLower(user.Email), "@"+d) { 380 return true 381 } 382 } 383 384 return false 385 } 386 387 // IsUsernameTaken checks if the username is already used by another user. Return false if the username is invalid. 388 func (a *App) IsUsernameTaken(name string) bool { 389 if !model.IsValidUsername(name) { 390 return false 391 } 392 393 if result := <-a.Srv.Store.User().GetByUsername(name); result.Err != nil { 394 return false 395 } 396 397 return true 398 } 399 400 func (a *App) GetUser(userId string) (*model.User, *model.AppError) { 401 result := <-a.Srv.Store.User().Get(userId) 402 if result.Err != nil { 403 return nil, result.Err 404 } 405 return result.Data.(*model.User), nil 406 } 407 408 func (a *App) GetUserByUsername(username string) (*model.User, *model.AppError) { 409 result := <-a.Srv.Store.User().GetByUsername(username) 410 if result.Err != nil && result.Err.Id == "store.sql_user.get_by_username.app_error" { 411 result.Err.StatusCode = http.StatusNotFound 412 return nil, result.Err 413 } 414 return result.Data.(*model.User), nil 415 } 416 417 func (a *App) GetUserByEmail(email string) (*model.User, *model.AppError) { 418 result := <-a.Srv.Store.User().GetByEmail(email) 419 if result.Err != nil { 420 if result.Err.Id == "store.sql_user.missing_account.const" { 421 result.Err.StatusCode = http.StatusNotFound 422 return nil, result.Err 423 } 424 result.Err.StatusCode = http.StatusBadRequest 425 return nil, result.Err 426 } 427 return result.Data.(*model.User), nil 428 } 429 430 func (a *App) GetUserByAuth(authData *string, authService string) (*model.User, *model.AppError) { 431 result := <-a.Srv.Store.User().GetByAuth(authData, authService) 432 if result.Err != nil { 433 return nil, result.Err 434 } 435 return result.Data.(*model.User), nil 436 } 437 438 func (a *App) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError) { 439 result := <-a.Srv.Store.User().GetAllProfiles(options) 440 if result.Err != nil { 441 return nil, result.Err 442 } 443 return result.Data.([]*model.User), nil 444 } 445 446 func (a *App) GetUsersPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) { 447 users, err := a.GetUsers(options) 448 if err != nil { 449 return nil, err 450 } 451 452 return a.sanitizeProfiles(users, asAdmin), nil 453 } 454 455 func (a *App) GetUsersEtag() string { 456 return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForAllProfiles()).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress) 457 } 458 459 func (a *App) GetUsersInTeam(options *model.UserGetOptions) ([]*model.User, *model.AppError) { 460 result := <-a.Srv.Store.User().GetProfiles(options) 461 if result.Err != nil { 462 return nil, result.Err 463 } 464 return result.Data.([]*model.User), nil 465 } 466 467 func (a *App) GetUsersNotInTeam(teamId string, offset int, limit int) ([]*model.User, *model.AppError) { 468 result := <-a.Srv.Store.User().GetProfilesNotInTeam(teamId, offset, limit) 469 if result.Err != nil { 470 return nil, result.Err 471 } 472 return result.Data.([]*model.User), nil 473 } 474 475 func (a *App) GetUsersInTeamPage(options *model.UserGetOptions, asAdmin bool) ([]*model.User, *model.AppError) { 476 users, err := a.GetUsersInTeam(options) 477 if err != nil { 478 return nil, err 479 } 480 481 return a.sanitizeProfiles(users, asAdmin), nil 482 } 483 484 func (a *App) GetUsersNotInTeamPage(teamId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 485 users, err := a.GetUsersNotInTeam(teamId, page*perPage, perPage) 486 if err != nil { 487 return nil, err 488 } 489 490 return a.sanitizeProfiles(users, asAdmin), nil 491 } 492 493 func (a *App) GetUsersInTeamEtag(teamId string) string { 494 return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfiles(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress) 495 } 496 497 func (a *App) GetUsersNotInTeamEtag(teamId string) string { 498 return fmt.Sprintf("%v.%v.%v", (<-a.Srv.Store.User().GetEtagForProfilesNotInTeam(teamId)).Data.(string), a.Config().PrivacySettings.ShowFullName, a.Config().PrivacySettings.ShowEmailAddress) 499 } 500 501 func (a *App) GetUsersInChannel(channelId string, offset int, limit int) ([]*model.User, *model.AppError) { 502 result := <-a.Srv.Store.User().GetProfilesInChannel(channelId, offset, limit) 503 if result.Err != nil { 504 return nil, result.Err 505 } 506 return result.Data.([]*model.User), nil 507 } 508 509 func (a *App) GetUsersInChannelByStatus(channelId string, offset int, limit int) ([]*model.User, *model.AppError) { 510 result := <-a.Srv.Store.User().GetProfilesInChannelByStatus(channelId, offset, limit) 511 if result.Err != nil { 512 return nil, result.Err 513 } 514 return result.Data.([]*model.User), nil 515 } 516 517 func (a *App) GetUsersInChannelMap(channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) { 518 users, err := a.GetUsersInChannel(channelId, offset, limit) 519 if err != nil { 520 return nil, err 521 } 522 523 userMap := make(map[string]*model.User, len(users)) 524 525 for _, user := range users { 526 a.SanitizeProfile(user, asAdmin) 527 userMap[user.Id] = user 528 } 529 530 return userMap, nil 531 } 532 533 func (a *App) GetUsersInChannelPage(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 534 users, err := a.GetUsersInChannel(channelId, page*perPage, perPage) 535 if err != nil { 536 return nil, err 537 } 538 return a.sanitizeProfiles(users, asAdmin), nil 539 } 540 541 func (a *App) GetUsersInChannelPageByStatus(channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 542 users, err := a.GetUsersInChannelByStatus(channelId, page*perPage, perPage) 543 if err != nil { 544 return nil, err 545 } 546 return a.sanitizeProfiles(users, asAdmin), nil 547 } 548 549 func (a *App) GetUsersNotInChannel(teamId string, channelId string, offset int, limit int) ([]*model.User, *model.AppError) { 550 result := <-a.Srv.Store.User().GetProfilesNotInChannel(teamId, channelId, offset, limit) 551 if result.Err != nil { 552 return nil, result.Err 553 } 554 return result.Data.([]*model.User), nil 555 } 556 557 func (a *App) GetUsersNotInChannelMap(teamId string, channelId string, offset int, limit int, asAdmin bool) (map[string]*model.User, *model.AppError) { 558 users, err := a.GetUsersNotInChannel(teamId, channelId, offset, limit) 559 if err != nil { 560 return nil, err 561 } 562 563 userMap := make(map[string]*model.User, len(users)) 564 565 for _, user := range users { 566 a.SanitizeProfile(user, asAdmin) 567 userMap[user.Id] = user 568 } 569 570 return userMap, nil 571 } 572 573 func (a *App) GetUsersNotInChannelPage(teamId string, channelId string, page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 574 users, err := a.GetUsersNotInChannel(teamId, channelId, page*perPage, perPage) 575 if err != nil { 576 return nil, err 577 } 578 579 return a.sanitizeProfiles(users, asAdmin), nil 580 } 581 582 func (a *App) GetUsersWithoutTeamPage(page int, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 583 users, err := a.GetUsersWithoutTeam(page*perPage, perPage) 584 if err != nil { 585 return nil, err 586 } 587 588 return a.sanitizeProfiles(users, asAdmin), nil 589 } 590 591 func (a *App) GetUsersWithoutTeam(offset int, limit int) ([]*model.User, *model.AppError) { 592 result := <-a.Srv.Store.User().GetProfilesWithoutTeam(offset, limit) 593 if result.Err != nil { 594 return nil, result.Err 595 } 596 return result.Data.([]*model.User), nil 597 } 598 599 func (a *App) GetUsersByIds(userIds []string, asAdmin bool) ([]*model.User, *model.AppError) { 600 result := <-a.Srv.Store.User().GetProfileByIds(userIds, true) 601 if result.Err != nil { 602 return nil, result.Err 603 } 604 return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil 605 } 606 607 func (a *App) GetUsersByUsernames(usernames []string, asAdmin bool) ([]*model.User, *model.AppError) { 608 result := <-a.Srv.Store.User().GetProfilesByUsernames(usernames, "") 609 if result.Err != nil { 610 return nil, result.Err 611 } 612 return a.sanitizeProfiles(result.Data.([]*model.User), asAdmin), nil 613 } 614 615 func (a *App) sanitizeProfiles(users []*model.User, asAdmin bool) []*model.User { 616 for _, u := range users { 617 a.SanitizeProfile(u, asAdmin) 618 } 619 620 return users 621 } 622 623 func (a *App) GenerateMfaSecret(userId string) (*model.MfaSecret, *model.AppError) { 624 user, err := a.GetUser(userId) 625 if err != nil { 626 return nil, err 627 } 628 629 mfaService := mfa.New(a, a.Srv.Store) 630 secret, img, err := mfaService.GenerateSecret(user) 631 if err != nil { 632 return nil, err 633 } 634 635 mfaSecret := &model.MfaSecret{Secret: secret, QRCode: b64.StdEncoding.EncodeToString(img)} 636 return mfaSecret, nil 637 } 638 639 func (a *App) ActivateMfa(userId, token string) *model.AppError { 640 result := <-a.Srv.Store.User().Get(userId) 641 if result.Err != nil { 642 return result.Err 643 } 644 user := result.Data.(*model.User) 645 646 if len(user.AuthService) > 0 && user.AuthService != model.USER_AUTH_SERVICE_LDAP { 647 return model.NewAppError("ActivateMfa", "api.user.activate_mfa.email_and_ldap_only.app_error", nil, "", http.StatusBadRequest) 648 } 649 650 mfaService := mfa.New(a, a.Srv.Store) 651 if err := mfaService.Activate(user, token); err != nil { 652 return err 653 } 654 655 return nil 656 } 657 658 func (a *App) DeactivateMfa(userId string) *model.AppError { 659 mfaService := mfa.New(a, a.Srv.Store) 660 if err := mfaService.Deactivate(userId); err != nil { 661 return err 662 } 663 664 return nil 665 } 666 667 func CreateProfileImage(username string, userId string, initialFont string) ([]byte, *model.AppError) { 668 colors := []color.NRGBA{ 669 {197, 8, 126, 255}, 670 {227, 207, 18, 255}, 671 {28, 181, 105, 255}, 672 {35, 188, 224, 255}, 673 {116, 49, 196, 255}, 674 {197, 8, 126, 255}, 675 {197, 19, 19, 255}, 676 {250, 134, 6, 255}, 677 {227, 207, 18, 255}, 678 {123, 201, 71, 255}, 679 {28, 181, 105, 255}, 680 {35, 188, 224, 255}, 681 {116, 49, 196, 255}, 682 {197, 8, 126, 255}, 683 {197, 19, 19, 255}, 684 {250, 134, 6, 255}, 685 {227, 207, 18, 255}, 686 {123, 201, 71, 255}, 687 {28, 181, 105, 255}, 688 {35, 188, 224, 255}, 689 {116, 49, 196, 255}, 690 {197, 8, 126, 255}, 691 {197, 19, 19, 255}, 692 {250, 134, 6, 255}, 693 {227, 207, 18, 255}, 694 {123, 201, 71, 255}, 695 } 696 697 h := fnv.New32a() 698 h.Write([]byte(userId)) 699 seed := h.Sum32() 700 701 initial := string(strings.ToUpper(username)[0]) 702 703 font, err := getFont(initialFont) 704 if err != nil { 705 return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error(), http.StatusInternalServerError) 706 } 707 708 color := colors[int64(seed)%int64(len(colors))] 709 dstImg := image.NewRGBA(image.Rect(0, 0, IMAGE_PROFILE_PIXEL_DIMENSION, IMAGE_PROFILE_PIXEL_DIMENSION)) 710 srcImg := image.White 711 draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.ZP, draw.Src) 712 size := float64(IMAGE_PROFILE_PIXEL_DIMENSION / 2) 713 714 c := freetype.NewContext() 715 c.SetFont(font) 716 c.SetFontSize(size) 717 c.SetClip(dstImg.Bounds()) 718 c.SetDst(dstImg) 719 c.SetSrc(srcImg) 720 721 pt := freetype.Pt(IMAGE_PROFILE_PIXEL_DIMENSION/5, IMAGE_PROFILE_PIXEL_DIMENSION*2/3) 722 _, err = c.DrawString(initial, pt) 723 if err != nil { 724 return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.initial.app_error", nil, err.Error(), http.StatusInternalServerError) 725 } 726 727 buf := new(bytes.Buffer) 728 729 if imgErr := png.Encode(buf, dstImg); imgErr != nil { 730 return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.encode.app_error", nil, imgErr.Error(), http.StatusInternalServerError) 731 } 732 return buf.Bytes(), nil 733 } 734 735 func getFont(initialFont string) (*truetype.Font, error) { 736 // Some people have the old default font still set, so just treat that as if they're using the new default 737 if initialFont == "luximbi.ttf" { 738 initialFont = "nunito-bold.ttf" 739 } 740 741 fontDir, _ := fileutils.FindDir("fonts") 742 fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont)) 743 if err != nil { 744 return nil, err 745 } 746 747 return freetype.ParseFont(fontBytes) 748 } 749 750 func (a *App) GetProfileImage(user *model.User) ([]byte, bool, *model.AppError) { 751 if len(*a.Config().FileSettings.DriverName) == 0 { 752 img, appErr := a.GetDefaultProfileImage(user) 753 if appErr != nil { 754 return nil, false, appErr 755 } 756 return img, false, nil 757 } 758 759 path := "users/" + user.Id + "/profile.png" 760 761 data, err := a.ReadFile(path) 762 if err != nil { 763 img, appErr := a.GetDefaultProfileImage(user) 764 if appErr != nil { 765 return nil, false, appErr 766 } 767 768 if user.LastPictureUpdate == 0 { 769 if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil { 770 return nil, false, err 771 } 772 } 773 return img, true, nil 774 } 775 776 return data, false, nil 777 } 778 779 func (a *App) GetDefaultProfileImage(user *model.User) ([]byte, *model.AppError) { 780 var img []byte 781 var appErr *model.AppError 782 783 if user.IsBot { 784 img = model.BotDefaultImage 785 appErr = nil 786 } else { 787 img, appErr = CreateProfileImage(user.Username, user.Id, *a.Config().FileSettings.InitialFont) 788 } 789 if appErr != nil { 790 return nil, appErr 791 } 792 return img, nil 793 } 794 795 func (a *App) SetDefaultProfileImage(user *model.User) *model.AppError { 796 img, appErr := a.GetDefaultProfileImage(user) 797 if appErr != nil { 798 return appErr 799 } 800 801 path := "users/" + user.Id + "/profile.png" 802 803 if _, err := a.WriteFile(bytes.NewReader(img), path); err != nil { 804 return err 805 } 806 807 <-a.Srv.Store.User().ResetLastPictureUpdate(user.Id) 808 809 a.InvalidateCacheForUser(user.Id) 810 811 updatedUser, appErr := a.GetUser(user.Id) 812 if appErr != nil { 813 mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", user.Id), mlog.String("user_id", user.Id)) 814 return nil 815 } 816 817 options := a.Config().GetSanitizeOptions() 818 updatedUser.SanitizeProfile(options) 819 820 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil) 821 message.Add("user", updatedUser) 822 a.Publish(message) 823 824 return nil 825 } 826 827 func (a *App) SetProfileImage(userId string, imageData *multipart.FileHeader) *model.AppError { 828 file, err := imageData.Open() 829 if err != nil { 830 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.open.app_error", nil, err.Error(), http.StatusBadRequest) 831 } 832 defer file.Close() 833 return a.SetProfileImageFromMultiPartFile(userId, file) 834 } 835 836 func (a *App) SetProfileImageFromMultiPartFile(userId string, file multipart.File) *model.AppError { 837 // Decode image config first to check dimensions before loading the whole thing into memory later on 838 config, _, err := image.DecodeConfig(file) 839 if err != nil { 840 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode_config.app_error", nil, err.Error(), http.StatusBadRequest) 841 } 842 if config.Width*config.Height > model.MaxImageSize { 843 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.too_large.app_error", nil, err.Error(), http.StatusBadRequest) 844 } 845 846 file.Seek(0, 0) 847 848 return a.SetProfileImageFromFile(userId, file) 849 } 850 851 func (a *App) SetProfileImageFromFile(userId string, file io.Reader) *model.AppError { 852 853 // Decode image into Image object 854 img, _, err := image.Decode(file) 855 if err != nil { 856 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.decode.app_error", nil, err.Error(), http.StatusBadRequest) 857 } 858 859 orientation, _ := getImageOrientation(file) 860 img = makeImageUpright(img, orientation) 861 862 // Scale profile image 863 profileWidthAndHeight := 128 864 img = imaging.Fill(img, profileWidthAndHeight, profileWidthAndHeight, imaging.Center, imaging.Lanczos) 865 866 buf := new(bytes.Buffer) 867 err = png.Encode(buf, img) 868 if err != nil { 869 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.encode.app_error", nil, err.Error(), http.StatusInternalServerError) 870 } 871 872 path := "users/" + userId + "/profile.png" 873 874 if _, err := a.WriteFile(buf, path); err != nil { 875 return model.NewAppError("SetProfileImage", "api.user.upload_profile_user.upload_profile.app_error", nil, "", http.StatusInternalServerError) 876 } 877 878 <-a.Srv.Store.User().UpdateLastPictureUpdate(userId) 879 880 a.InvalidateCacheForUser(userId) 881 882 user, userErr := a.GetUser(userId) 883 if userErr != nil { 884 mlog.Error(fmt.Sprintf("Error in getting users profile for id=%v forcing logout", userId), mlog.String("user_id", userId)) 885 return nil 886 } 887 888 options := a.Config().GetSanitizeOptions() 889 user.SanitizeProfile(options) 890 891 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil) 892 message.Add("user", user) 893 a.Publish(message) 894 895 return nil 896 } 897 898 func (a *App) UpdatePasswordAsUser(userId, currentPassword, newPassword string) *model.AppError { 899 user, err := a.GetUser(userId) 900 if err != nil { 901 return err 902 } 903 904 if user == nil { 905 err = model.NewAppError("updatePassword", "api.user.update_password.valid_account.app_error", nil, "", http.StatusBadRequest) 906 return err 907 } 908 909 if user.AuthData != nil && *user.AuthData != "" { 910 err = model.NewAppError("updatePassword", "api.user.update_password.oauth.app_error", nil, "auth_service="+user.AuthService, http.StatusBadRequest) 911 return err 912 } 913 914 if err := a.DoubleCheckPassword(user, currentPassword); err != nil { 915 if err.Id == "api.user.check_user_password.invalid.app_error" { 916 err = model.NewAppError("updatePassword", "api.user.update_password.incorrect.app_error", nil, "", http.StatusBadRequest) 917 } 918 return err 919 } 920 921 T := utils.GetUserTranslations(user.Locale) 922 923 return a.UpdatePasswordSendEmail(user, newPassword, T("api.user.update_password.menu")) 924 } 925 926 func (a *App) userDeactivated(user *model.User) *model.AppError { 927 if err := a.RevokeAllSessions(user.Id); err != nil { 928 return err 929 } 930 931 a.SetStatusOffline(user.Id, false) 932 933 if *a.Config().ServiceSettings.DisableBotsWhenOwnerIsDeactivated { 934 a.disableUserBots(user.Id) 935 } 936 937 return nil 938 } 939 940 func (a *App) invalidateUserChannelMembersCaches(user *model.User) *model.AppError { 941 teamsForUser, err := a.GetTeamsForUser(user.Id) 942 if err != nil { 943 return err 944 } 945 946 for _, team := range teamsForUser { 947 channelsForUser, err := a.GetChannelsForUser(team.Id, user.Id, false) 948 if err != nil { 949 return err 950 } 951 952 for _, channel := range *channelsForUser { 953 a.InvalidateCacheForChannelMembers(channel.Id) 954 } 955 } 956 957 return nil 958 } 959 960 func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.AppError) { 961 if active { 962 user.DeleteAt = 0 963 } else { 964 user.DeleteAt = model.GetMillis() 965 } 966 967 result := <-a.Srv.Store.User().Update(user, true) 968 if result.Err != nil { 969 return nil, result.Err 970 } 971 ruser := result.Data.([2]*model.User)[0] 972 973 if !active { 974 if err := a.userDeactivated(ruser); err != nil { 975 return nil, err 976 } 977 } 978 979 a.invalidateUserChannelMembersCaches(user) 980 981 a.sendUpdatedUserEvent(*ruser) 982 983 return ruser, nil 984 } 985 986 func (a *App) GetSanitizeOptions(asAdmin bool) map[string]bool { 987 options := a.Config().GetSanitizeOptions() 988 if asAdmin { 989 options["email"] = true 990 options["fullname"] = true 991 options["authservice"] = true 992 } 993 return options 994 } 995 996 func (a *App) SanitizeProfile(user *model.User, asAdmin bool) { 997 options := a.GetSanitizeOptions(asAdmin) 998 999 user.SanitizeProfile(options) 1000 } 1001 1002 func (a *App) UpdateUserAsUser(user *model.User, asAdmin bool) (*model.User, *model.AppError) { 1003 updatedUser, err := a.UpdateUser(user, true) 1004 if err != nil { 1005 return nil, err 1006 } 1007 1008 a.sendUpdatedUserEvent(*updatedUser) 1009 1010 return updatedUser, nil 1011 } 1012 1013 func (a *App) PatchUser(userId string, patch *model.UserPatch, asAdmin bool) (*model.User, *model.AppError) { 1014 user, err := a.GetUser(userId) 1015 if err != nil { 1016 return nil, err 1017 } 1018 1019 user.Patch(patch) 1020 1021 updatedUser, err := a.UpdateUser(user, true) 1022 if err != nil { 1023 return nil, err 1024 } 1025 1026 a.sendUpdatedUserEvent(*updatedUser) 1027 1028 return updatedUser, nil 1029 } 1030 1031 func (a *App) UpdateUserAuth(userId string, userAuth *model.UserAuth) (*model.UserAuth, *model.AppError) { 1032 if userAuth.AuthData == nil || *userAuth.AuthData == "" || userAuth.AuthService == "" { 1033 userAuth.AuthData = nil 1034 userAuth.AuthService = "" 1035 1036 if err := a.IsPasswordValid(userAuth.Password); err != nil { 1037 return nil, err 1038 } 1039 password := model.HashPassword(userAuth.Password) 1040 1041 if result := <-a.Srv.Store.User().UpdatePassword(userId, password); result.Err != nil { 1042 return nil, result.Err 1043 } 1044 } else { 1045 userAuth.Password = "" 1046 1047 if result := <-a.Srv.Store.User().UpdateAuthData(userId, userAuth.AuthService, userAuth.AuthData, "", false); result.Err != nil { 1048 return nil, result.Err 1049 } 1050 } 1051 1052 return userAuth, nil 1053 } 1054 1055 func (a *App) sendUpdatedUserEvent(user model.User) { 1056 adminCopyOfUser := user.DeepCopy() 1057 a.SanitizeProfile(adminCopyOfUser, true) 1058 adminMessage := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil) 1059 adminMessage.Add("user", *adminCopyOfUser) 1060 adminMessage.Broadcast.ContainsSensitiveData = true 1061 a.Publish(adminMessage) 1062 1063 a.SanitizeProfile(&user, false) 1064 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_UPDATED, "", "", "", nil) 1065 message.Add("user", user) 1066 message.Broadcast.ContainsSanitizedData = true 1067 a.Publish(message) 1068 } 1069 1070 func (a *App) UpdateUser(user *model.User, sendNotifications bool) (*model.User, *model.AppError) { 1071 result := <-a.Srv.Store.User().Get(user.Id) 1072 if result.Err != nil { 1073 return nil, result.Err 1074 } 1075 prev := result.Data.(*model.User) 1076 1077 if !CheckUserDomain(user, *a.Config().TeamSettings.RestrictCreationToDomains) { 1078 if !prev.IsLDAPUser() && !prev.IsSAMLUser() && user.Email != prev.Email { 1079 return nil, model.NewAppError("UpdateUser", "api.user.create_user.accepted_domain.app_error", nil, "", http.StatusBadRequest) 1080 } 1081 } 1082 1083 // Don't set new eMail on user account if email verification is required, this will be done as a post-verification action 1084 // to avoid users being able to set non-controlled eMails as their account email 1085 newEmail := "" 1086 if *a.Config().EmailSettings.RequireEmailVerification && prev.Email != user.Email { 1087 newEmail = user.Email 1088 1089 _, err := a.GetUserByEmail(newEmail) 1090 if err == nil { 1091 return nil, model.NewAppError("UpdateUser", "store.sql_user.update.email_taken.app_error", nil, "user_id="+user.Id, http.StatusBadRequest) 1092 } 1093 1094 user.Email = prev.Email 1095 } 1096 1097 result = <-a.Srv.Store.User().Update(user, false) 1098 if result.Err != nil { 1099 return nil, result.Err 1100 } 1101 rusers := result.Data.([2]*model.User) 1102 1103 if sendNotifications { 1104 if rusers[0].Email != rusers[1].Email || newEmail != "" { 1105 if *a.Config().EmailSettings.RequireEmailVerification { 1106 a.Srv.Go(func() { 1107 if err := a.SendEmailVerification(rusers[0], newEmail); err != nil { 1108 mlog.Error(err.Error()) 1109 } 1110 }) 1111 } else { 1112 a.Srv.Go(func() { 1113 if err := a.SendEmailChangeEmail(rusers[1].Email, rusers[0].Email, rusers[0].Locale, a.GetSiteURL()); err != nil { 1114 mlog.Error(err.Error()) 1115 } 1116 }) 1117 } 1118 } 1119 1120 if rusers[0].Username != rusers[1].Username { 1121 a.Srv.Go(func() { 1122 if err := a.SendChangeUsernameEmail(rusers[1].Username, rusers[0].Username, rusers[0].Email, rusers[0].Locale, a.GetSiteURL()); err != nil { 1123 mlog.Error(err.Error()) 1124 } 1125 }) 1126 } 1127 } 1128 1129 a.InvalidateCacheForUser(user.Id) 1130 1131 esInterface := a.Elasticsearch 1132 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableIndexing { 1133 a.Srv.Go(func() { 1134 if err := a.indexUser(user); err != nil { 1135 mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err)) 1136 } 1137 }) 1138 } 1139 1140 return rusers[0], nil 1141 } 1142 1143 func (a *App) UpdateUserActive(userId string, active bool) *model.AppError { 1144 user, err := a.GetUser(userId) 1145 1146 if err != nil { 1147 return err 1148 } 1149 if _, err = a.UpdateActive(user, active); err != nil { 1150 return err 1151 } 1152 1153 return nil 1154 } 1155 1156 func (a *App) UpdateUserNotifyProps(userId string, props map[string]string) (*model.User, *model.AppError) { 1157 user, err := a.GetUser(userId) 1158 if err != nil { 1159 return nil, err 1160 } 1161 1162 user.NotifyProps = props 1163 1164 ruser, err := a.UpdateUser(user, true) 1165 if err != nil { 1166 return nil, err 1167 } 1168 1169 return ruser, nil 1170 } 1171 1172 func (a *App) UpdateMfa(activate bool, userId, token string) *model.AppError { 1173 if activate { 1174 if err := a.ActivateMfa(userId, token); err != nil { 1175 return err 1176 } 1177 } else { 1178 if err := a.DeactivateMfa(userId); err != nil { 1179 return err 1180 } 1181 } 1182 1183 a.Srv.Go(func() { 1184 user, err := a.GetUser(userId) 1185 if err != nil { 1186 mlog.Error(err.Error()) 1187 return 1188 } 1189 1190 if err := a.SendMfaChangeEmail(user.Email, activate, user.Locale, a.GetSiteURL()); err != nil { 1191 mlog.Error(err.Error()) 1192 } 1193 }) 1194 1195 return nil 1196 } 1197 1198 func (a *App) UpdatePasswordByUserIdSendEmail(userId, newPassword, method string) *model.AppError { 1199 user, err := a.GetUser(userId) 1200 if err != nil { 1201 return err 1202 } 1203 1204 return a.UpdatePasswordSendEmail(user, newPassword, method) 1205 } 1206 1207 func (a *App) UpdatePassword(user *model.User, newPassword string) *model.AppError { 1208 if err := a.IsPasswordValid(newPassword); err != nil { 1209 return err 1210 } 1211 1212 hashedPassword := model.HashPassword(newPassword) 1213 1214 if result := <-a.Srv.Store.User().UpdatePassword(user.Id, hashedPassword); result.Err != nil { 1215 return model.NewAppError("UpdatePassword", "api.user.update_password.failed.app_error", nil, result.Err.Error(), http.StatusInternalServerError) 1216 } 1217 1218 return nil 1219 } 1220 1221 func (a *App) UpdatePasswordSendEmail(user *model.User, newPassword, method string) *model.AppError { 1222 if err := a.UpdatePassword(user, newPassword); err != nil { 1223 return err 1224 } 1225 1226 a.Srv.Go(func() { 1227 if err := a.SendPasswordChangeEmail(user.Email, method, user.Locale, a.GetSiteURL()); err != nil { 1228 mlog.Error(err.Error()) 1229 } 1230 }) 1231 1232 return nil 1233 } 1234 1235 func (a *App) ResetPasswordFromToken(userSuppliedTokenString, newPassword string) *model.AppError { 1236 token, err := a.GetPasswordRecoveryToken(userSuppliedTokenString) 1237 if err != nil { 1238 return err 1239 } 1240 if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME { 1241 return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest) 1242 } 1243 1244 tokenData := struct { 1245 UserId string 1246 Email string 1247 }{} 1248 1249 err2 := json.Unmarshal([]byte(token.Extra), &tokenData) 1250 if err2 != nil { 1251 return model.NewAppError("resetPassword", "api.user.reset_password.token_parse.error", nil, "", http.StatusInternalServerError) 1252 } 1253 1254 user, err := a.GetUser(tokenData.UserId) 1255 if err != nil { 1256 return err 1257 } 1258 1259 if user.Email != tokenData.Email { 1260 return model.NewAppError("resetPassword", "api.user.reset_password.link_expired.app_error", nil, "", http.StatusBadRequest) 1261 } 1262 1263 if user.IsSSOUser() { 1264 return model.NewAppError("ResetPasswordFromCode", "api.user.reset_password.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 1265 } 1266 1267 T := utils.GetUserTranslations(user.Locale) 1268 1269 if err := a.UpdatePasswordSendEmail(user, newPassword, T("api.user.reset_password.method")); err != nil { 1270 return err 1271 } 1272 1273 if err := a.DeleteToken(token); err != nil { 1274 mlog.Error(err.Error()) 1275 } 1276 1277 return nil 1278 } 1279 1280 func (a *App) SendPasswordReset(email string, siteURL string) (bool, *model.AppError) { 1281 user, err := a.GetUserByEmail(email) 1282 if err != nil { 1283 return false, nil 1284 } 1285 1286 if user.AuthData != nil && len(*user.AuthData) != 0 { 1287 return false, model.NewAppError("SendPasswordReset", "api.user.send_password_reset.sso.app_error", nil, "userId="+user.Id, http.StatusBadRequest) 1288 } 1289 1290 token, err := a.CreatePasswordRecoveryToken(user.Id, user.Email) 1291 if err != nil { 1292 return false, err 1293 } 1294 1295 return a.SendPasswordResetEmail(user.Email, token, user.Locale, siteURL) 1296 } 1297 1298 func (a *App) CreatePasswordRecoveryToken(userId, email string) (*model.Token, *model.AppError) { 1299 1300 tokenExtra := struct { 1301 UserId string 1302 Email string 1303 }{ 1304 userId, 1305 email, 1306 } 1307 jsonData, err := json.Marshal(tokenExtra) 1308 1309 if err != nil { 1310 return nil, model.NewAppError("CreatePasswordRecoveryToken", "api.user.create_password_token.error", nil, "", http.StatusInternalServerError) 1311 } 1312 1313 token := model.NewToken(TOKEN_TYPE_PASSWORD_RECOVERY, string(jsonData)) 1314 1315 if result := <-a.Srv.Store.Token().Save(token); result.Err != nil { 1316 return nil, result.Err 1317 } 1318 1319 return token, nil 1320 } 1321 1322 func (a *App) GetPasswordRecoveryToken(token string) (*model.Token, *model.AppError) { 1323 result := <-a.Srv.Store.Token().GetByToken(token) 1324 if result.Err != nil { 1325 return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.invalid_link.app_error", nil, result.Err.Error(), http.StatusBadRequest) 1326 } 1327 rtoken := result.Data.(*model.Token) 1328 if rtoken.Type != TOKEN_TYPE_PASSWORD_RECOVERY { 1329 return nil, model.NewAppError("GetPasswordRecoveryToken", "api.user.reset_password.broken_token.app_error", nil, "", http.StatusBadRequest) 1330 } 1331 return rtoken, nil 1332 } 1333 1334 func (a *App) DeleteToken(token *model.Token) *model.AppError { 1335 if result := <-a.Srv.Store.Token().Delete(token.Token); result.Err != nil { 1336 return result.Err 1337 } 1338 1339 return nil 1340 } 1341 1342 func (a *App) UpdateUserRoles(userId string, newRoles string, sendWebSocketEvent bool) (*model.User, *model.AppError) { 1343 user, err := a.GetUser(userId) 1344 if err != nil { 1345 err.StatusCode = http.StatusBadRequest 1346 return nil, err 1347 } 1348 1349 if err := a.CheckRolesExist(strings.Fields(newRoles)); err != nil { 1350 return nil, err 1351 } 1352 1353 user.Roles = newRoles 1354 uchan := a.Srv.Store.User().Update(user, true) 1355 schan := a.Srv.Store.Session().UpdateRoles(user.Id, newRoles) 1356 1357 result := <-uchan 1358 if result.Err != nil { 1359 return nil, result.Err 1360 } 1361 ruser := result.Data.([2]*model.User)[0] 1362 1363 if result := <-schan; result.Err != nil { 1364 // soft error since the user roles were still updated 1365 mlog.Error(fmt.Sprint(result.Err)) 1366 } 1367 1368 a.ClearSessionCacheForUser(user.Id) 1369 1370 if sendWebSocketEvent { 1371 message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_USER_ROLE_UPDATED, "", "", user.Id, nil) 1372 message.Add("user_id", user.Id) 1373 message.Add("roles", newRoles) 1374 a.Publish(message) 1375 } 1376 1377 return ruser, nil 1378 } 1379 1380 func (a *App) PermanentDeleteUser(user *model.User) *model.AppError { 1381 mlog.Warn(fmt.Sprintf("Attempting to permanently delete account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id)) 1382 if user.IsInRole(model.SYSTEM_ADMIN_ROLE_ID) { 1383 mlog.Warn(fmt.Sprintf("You are deleting %v that is a system administrator. You may need to set another account as the system administrator using the command line tools.", user.Email)) 1384 } 1385 1386 if _, err := a.UpdateActive(user, false); err != nil { 1387 return err 1388 } 1389 1390 if result := <-a.Srv.Store.Session().PermanentDeleteSessionsByUser(user.Id); result.Err != nil { 1391 return result.Err 1392 } 1393 1394 if result := <-a.Srv.Store.UserAccessToken().DeleteAllForUser(user.Id); result.Err != nil { 1395 return result.Err 1396 } 1397 1398 if result := <-a.Srv.Store.OAuth().PermanentDeleteAuthDataByUser(user.Id); result.Err != nil { 1399 return result.Err 1400 } 1401 1402 if result := <-a.Srv.Store.Webhook().PermanentDeleteIncomingByUser(user.Id); result.Err != nil { 1403 return result.Err 1404 } 1405 1406 if result := <-a.Srv.Store.Webhook().PermanentDeleteOutgoingByUser(user.Id); result.Err != nil { 1407 return result.Err 1408 } 1409 1410 if result := <-a.Srv.Store.Command().PermanentDeleteByUser(user.Id); result.Err != nil { 1411 return result.Err 1412 } 1413 1414 if result := <-a.Srv.Store.Preference().PermanentDeleteByUser(user.Id); result.Err != nil { 1415 return result.Err 1416 } 1417 1418 if result := <-a.Srv.Store.Channel().PermanentDeleteMembersByUser(user.Id); result.Err != nil { 1419 return result.Err 1420 } 1421 1422 if result := <-a.Srv.Store.Post().PermanentDeleteByUser(user.Id); result.Err != nil { 1423 return result.Err 1424 } 1425 1426 result := <-a.Srv.Store.FileInfo().GetForUser(user.Id) 1427 if result.Err != nil { 1428 mlog.Warn("Error getting file list for user from FileInfoStore") 1429 } 1430 1431 infos := result.Data.([]*model.FileInfo) 1432 for _, info := range infos { 1433 res, err := a.FileExists(info.Path) 1434 if err != nil { 1435 mlog.Warn( 1436 "Error checking existence of file", 1437 mlog.String("path", info.Path), 1438 mlog.Err(err), 1439 ) 1440 continue 1441 } 1442 1443 if !res { 1444 mlog.Warn("File not found", mlog.String("path", info.Path)) 1445 continue 1446 } 1447 1448 err = a.RemoveFile(info.Path) 1449 1450 if err != nil { 1451 mlog.Warn( 1452 "Unable to remove file", 1453 mlog.String("path", info.Path), 1454 mlog.Err(err), 1455 ) 1456 } 1457 } 1458 1459 if result := <-a.Srv.Store.FileInfo().PermanentDeleteByUser(user.Id); result.Err != nil { 1460 return result.Err 1461 } 1462 1463 if result := <-a.Srv.Store.User().PermanentDelete(user.Id); result.Err != nil { 1464 return result.Err 1465 } 1466 1467 if result := <-a.Srv.Store.Audit().PermanentDeleteByUser(user.Id); result.Err != nil { 1468 return result.Err 1469 } 1470 1471 if result := <-a.Srv.Store.Team().RemoveAllMembersByUser(user.Id); result.Err != nil { 1472 return result.Err 1473 } 1474 1475 mlog.Warn(fmt.Sprintf("Permanently deleted account %v id=%v", user.Email, user.Id), mlog.String("user_id", user.Id)) 1476 1477 esInterface := a.Elasticsearch 1478 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableIndexing { 1479 a.Srv.Go(func() { 1480 if err := a.Elasticsearch.DeleteUser(user); err != nil { 1481 mlog.Error("Encountered error deleting user", mlog.String("user_id", user.Id), mlog.Err(err)) 1482 } 1483 }) 1484 } 1485 1486 return nil 1487 } 1488 1489 func (a *App) PermanentDeleteAllUsers() *model.AppError { 1490 result := <-a.Srv.Store.User().GetAll() 1491 if result.Err != nil { 1492 return result.Err 1493 } 1494 users := result.Data.([]*model.User) 1495 for _, user := range users { 1496 a.PermanentDeleteUser(user) 1497 } 1498 1499 return nil 1500 } 1501 1502 func (a *App) SendEmailVerification(user *model.User, newEmail string) *model.AppError { 1503 token, err := a.CreateVerifyEmailToken(user.Id, newEmail) 1504 if err != nil { 1505 return err 1506 } 1507 1508 if _, err := a.GetStatus(user.Id); err != nil { 1509 return a.SendVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token) 1510 } 1511 return a.SendEmailChangeVerifyEmail(newEmail, user.Locale, a.GetSiteURL(), token.Token) 1512 } 1513 1514 func (a *App) VerifyEmailFromToken(userSuppliedTokenString string) *model.AppError { 1515 token, err := a.GetVerifyEmailToken(userSuppliedTokenString) 1516 if err != nil { 1517 return err 1518 } 1519 if model.GetMillis()-token.CreateAt >= PASSWORD_RECOVER_EXPIRY_TIME { 1520 return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.link_expired.app_error", nil, "", http.StatusBadRequest) 1521 } 1522 1523 tokenData := struct { 1524 UserId string 1525 Email string 1526 }{} 1527 1528 err2 := json.Unmarshal([]byte(token.Extra), &tokenData) 1529 if err2 != nil { 1530 return model.NewAppError("VerifyEmailFromToken", "api.user.verify_email.token_parse.error", nil, "", http.StatusInternalServerError) 1531 } 1532 1533 user, err := a.GetUser(tokenData.UserId) 1534 if err != nil { 1535 return err 1536 } 1537 1538 if err := a.VerifyUserEmail(tokenData.UserId, tokenData.Email); err != nil { 1539 return err 1540 } 1541 1542 if user.Email != tokenData.Email { 1543 a.Srv.Go(func() { 1544 if err := a.SendEmailChangeEmail(user.Email, tokenData.Email, user.Locale, a.GetSiteURL()); err != nil { 1545 mlog.Error(err.Error()) 1546 } 1547 }) 1548 } 1549 1550 if err := a.DeleteToken(token); err != nil { 1551 mlog.Error(err.Error()) 1552 } 1553 1554 return nil 1555 } 1556 1557 func (a *App) CreateVerifyEmailToken(userId string, newEmail string) (*model.Token, *model.AppError) { 1558 tokenExtra := struct { 1559 UserId string 1560 Email string 1561 }{ 1562 userId, 1563 newEmail, 1564 } 1565 jsonData, err := json.Marshal(tokenExtra) 1566 1567 if err != nil { 1568 return nil, model.NewAppError("CreateVerifyEmailToken", "api.user.create_email_token.error", nil, "", http.StatusInternalServerError) 1569 } 1570 1571 token := model.NewToken(TOKEN_TYPE_VERIFY_EMAIL, string(jsonData)) 1572 1573 if result := <-a.Srv.Store.Token().Save(token); result.Err != nil { 1574 return nil, result.Err 1575 } 1576 1577 return token, nil 1578 } 1579 1580 func (a *App) GetVerifyEmailToken(token string) (*model.Token, *model.AppError) { 1581 result := <-a.Srv.Store.Token().GetByToken(token) 1582 if result.Err != nil { 1583 return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.bad_link.app_error", nil, result.Err.Error(), http.StatusBadRequest) 1584 } 1585 rtoken := result.Data.(*model.Token) 1586 if rtoken.Type != TOKEN_TYPE_VERIFY_EMAIL { 1587 return nil, model.NewAppError("GetVerifyEmailToken", "api.user.verify_email.broken_token.app_error", nil, "", http.StatusBadRequest) 1588 } 1589 return rtoken, nil 1590 } 1591 1592 // GetTotalUsersStats is used for the DM list total 1593 func (a *App) GetTotalUsersStats() (*model.UsersStats, *model.AppError) { 1594 result := <-a.Srv.Store.User().Count(model.UserCountOptions{ 1595 IncludeBotAccounts: true, 1596 }) 1597 if result.Err != nil { 1598 return nil, result.Err 1599 } 1600 stats := &model.UsersStats{ 1601 TotalUsersCount: result.Data.(int64), 1602 } 1603 return stats, nil 1604 } 1605 1606 func (a *App) VerifyUserEmail(userId, email string) *model.AppError { 1607 err := (<-a.Srv.Store.User().VerifyEmail(userId, email)).Err 1608 1609 if err != nil { 1610 return err 1611 } 1612 1613 user, err := a.GetUser(userId) 1614 1615 if err != nil { 1616 return err 1617 } 1618 1619 a.sendUpdatedUserEvent(*user) 1620 1621 return nil 1622 } 1623 1624 func (a *App) SearchUsers(props *model.UserSearch, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1625 if props.WithoutTeam { 1626 return a.SearchUsersWithoutTeam(props.Term, options) 1627 } 1628 if props.InChannelId != "" { 1629 return a.SearchUsersInChannel(props.InChannelId, props.Term, options) 1630 } 1631 if props.NotInChannelId != "" { 1632 return a.SearchUsersNotInChannel(props.TeamId, props.NotInChannelId, props.Term, options) 1633 } 1634 if props.NotInTeamId != "" { 1635 return a.SearchUsersNotInTeam(props.NotInTeamId, props.Term, options) 1636 } 1637 return a.SearchUsersInTeam(props.TeamId, props.Term, options) 1638 } 1639 1640 func (a *App) SearchUsersInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1641 result := <-a.Srv.Store.User().SearchInChannel(channelId, term, options) 1642 if result.Err != nil { 1643 return nil, result.Err 1644 } 1645 users := result.Data.([]*model.User) 1646 1647 for _, user := range users { 1648 a.SanitizeProfile(user, options.IsAdmin) 1649 } 1650 1651 return users, nil 1652 } 1653 1654 func (a *App) SearchUsersNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1655 result := <-a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options) 1656 if result.Err != nil { 1657 return nil, result.Err 1658 } 1659 users := result.Data.([]*model.User) 1660 1661 for _, user := range users { 1662 a.SanitizeProfile(user, options.IsAdmin) 1663 } 1664 1665 return users, nil 1666 } 1667 1668 func (a *App) SearchUsersInTeam(teamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1669 var result store.StoreResult 1670 1671 esInterface := a.Elasticsearch 1672 license := a.License() 1673 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch { 1674 usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, term, options) 1675 if err != nil { 1676 return nil, err 1677 } 1678 1679 result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false) 1680 } else { 1681 result = <-a.Srv.Store.User().Search(teamId, term, options) 1682 } 1683 1684 if result.Err != nil { 1685 return nil, result.Err 1686 } 1687 users := result.Data.([]*model.User) 1688 1689 for _, user := range users { 1690 a.SanitizeProfile(user, options.IsAdmin) 1691 } 1692 1693 return users, nil 1694 } 1695 1696 func (a *App) SearchUsersNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1697 result := <-a.Srv.Store.User().SearchNotInTeam(notInTeamId, term, options) 1698 if result.Err != nil { 1699 return nil, result.Err 1700 } 1701 users := result.Data.([]*model.User) 1702 1703 for _, user := range users { 1704 a.SanitizeProfile(user, options.IsAdmin) 1705 } 1706 1707 return users, nil 1708 } 1709 1710 func (a *App) SearchUsersWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) { 1711 result := <-a.Srv.Store.User().SearchWithoutTeam(term, options) 1712 if result.Err != nil { 1713 return nil, result.Err 1714 } 1715 users := result.Data.([]*model.User) 1716 1717 for _, user := range users { 1718 a.SanitizeProfile(user, options.IsAdmin) 1719 } 1720 1721 return users, nil 1722 } 1723 1724 func (a *App) AutocompleteUsersInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInChannel, *model.AppError) { 1725 var uchan, nuchan store.StoreChannel 1726 1727 esInterface := a.Elasticsearch 1728 license := a.License() 1729 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch { 1730 uchanIds, nuchanIds, err := a.Elasticsearch.SearchUsersInChannel(teamId, channelId, term, options) 1731 if err != nil { 1732 return nil, err 1733 } 1734 uchan = a.Srv.Store.User().GetProfileByIds(uchanIds, false) 1735 nuchan = a.Srv.Store.User().GetProfileByIds(nuchanIds, false) 1736 } else { 1737 uchan = a.Srv.Store.User().SearchInChannel(channelId, term, options) 1738 nuchan = a.Srv.Store.User().SearchNotInChannel(teamId, channelId, term, options) 1739 } 1740 1741 autocomplete := &model.UserAutocompleteInChannel{} 1742 1743 result := <-uchan 1744 if result.Err != nil { 1745 return nil, result.Err 1746 } 1747 users := result.Data.([]*model.User) 1748 1749 for _, user := range users { 1750 a.SanitizeProfile(user, options.IsAdmin) 1751 } 1752 1753 autocomplete.InChannel = users 1754 1755 result = <-nuchan 1756 if result.Err != nil { 1757 return nil, result.Err 1758 } 1759 users = result.Data.([]*model.User) 1760 1761 for _, user := range users { 1762 a.SanitizeProfile(user, options.IsAdmin) 1763 } 1764 1765 autocomplete.OutOfChannel = users 1766 1767 return autocomplete, nil 1768 } 1769 1770 func (a *App) AutocompleteUsersInTeam(teamId string, term string, options *model.UserSearchOptions) (*model.UserAutocompleteInTeam, *model.AppError) { 1771 autocomplete := &model.UserAutocompleteInTeam{} 1772 var result store.StoreResult 1773 1774 esInterface := a.Elasticsearch 1775 license := a.License() 1776 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableAutocomplete && license != nil && *license.Features.Elasticsearch { 1777 usersIds, err := a.Elasticsearch.SearchUsersInTeam(teamId, term, options) 1778 if err != nil { 1779 return nil, err 1780 } 1781 1782 result = <-a.Srv.Store.User().GetProfileByIds(usersIds, false) 1783 } else { 1784 result = <-a.Srv.Store.User().Search(teamId, term, options) 1785 } 1786 1787 if result.Err != nil { 1788 return nil, result.Err 1789 } 1790 users := result.Data.([]*model.User) 1791 1792 for _, user := range users { 1793 a.SanitizeProfile(user, options.IsAdmin) 1794 } 1795 1796 autocomplete.InTeam = users 1797 1798 return autocomplete, nil 1799 } 1800 1801 func (a *App) UpdateOAuthUserAttrs(userData io.Reader, user *model.User, provider einterfaces.OauthProvider, service string) *model.AppError { 1802 oauthUser := provider.GetUserFromJson(userData) 1803 if oauthUser == nil { 1804 return model.NewAppError("UpdateOAuthUserAttrs", "api.user.update_oauth_user_attrs.get_user.app_error", map[string]interface{}{"Service": service}, "", http.StatusBadRequest) 1805 } 1806 1807 userAttrsChanged := false 1808 1809 if oauthUser.Username != user.Username { 1810 if existingUser, _ := a.GetUserByUsername(oauthUser.Username); existingUser == nil { 1811 user.Username = oauthUser.Username 1812 userAttrsChanged = true 1813 } 1814 } 1815 1816 if oauthUser.GetFullName() != user.GetFullName() { 1817 user.FirstName = oauthUser.FirstName 1818 user.LastName = oauthUser.LastName 1819 userAttrsChanged = true 1820 } 1821 1822 if oauthUser.Email != user.Email { 1823 if existingUser, _ := a.GetUserByEmail(oauthUser.Email); existingUser == nil { 1824 user.Email = oauthUser.Email 1825 userAttrsChanged = true 1826 } 1827 } 1828 1829 if user.DeleteAt > 0 { 1830 // Make sure they are not disabled 1831 user.DeleteAt = 0 1832 userAttrsChanged = true 1833 } 1834 1835 if userAttrsChanged { 1836 result := <-a.Srv.Store.User().Update(user, true) 1837 if result.Err != nil { 1838 return result.Err 1839 } 1840 1841 user = result.Data.([2]*model.User)[0] 1842 a.InvalidateCacheForUser(user.Id) 1843 1844 esInterface := a.Elasticsearch 1845 if esInterface != nil && *a.Config().ElasticsearchSettings.EnableIndexing { 1846 a.Srv.Go(func() { 1847 if err := a.indexUser(user); err != nil { 1848 mlog.Error("Encountered error indexing user", mlog.String("user_id", user.Id), mlog.Err(err)) 1849 } 1850 }) 1851 } 1852 } 1853 1854 return nil 1855 }