github.com/nhannv/mattermost-server@v5.11.1+incompatible/app/user_test.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 "encoding/json" 9 "image" 10 "image/color" 11 "math/rand" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 19 "github.com/mattermost/mattermost-server/einterfaces" 20 "github.com/mattermost/mattermost-server/model" 21 oauthgitlab "github.com/mattermost/mattermost-server/model/gitlab" 22 ) 23 24 func TestIsUsernameTaken(t *testing.T) { 25 th := Setup(t).InitBasic() 26 defer th.TearDown() 27 28 user := th.BasicUser 29 taken := th.App.IsUsernameTaken(user.Username) 30 31 if !taken { 32 t.Logf("the username '%v' should be taken", user.Username) 33 t.FailNow() 34 } 35 36 newUsername := "randomUsername" 37 taken = th.App.IsUsernameTaken(newUsername) 38 39 if taken { 40 t.Logf("the username '%v' should not be taken", newUsername) 41 t.FailNow() 42 } 43 } 44 45 func TestCheckUserDomain(t *testing.T) { 46 th := Setup(t).InitBasic() 47 defer th.TearDown() 48 49 user := th.BasicUser 50 51 cases := []struct { 52 domains string 53 matched bool 54 }{ 55 {"simulator.amazonses.com", true}, 56 {"gmail.com", false}, 57 {"", true}, 58 {"gmail.com simulator.amazonses.com", true}, 59 } 60 for _, c := range cases { 61 matched := CheckUserDomain(user, c.domains) 62 if matched != c.matched { 63 if c.matched { 64 t.Logf("'%v' should have matched '%v'", user.Email, c.domains) 65 } else { 66 t.Logf("'%v' should not have matched '%v'", user.Email, c.domains) 67 } 68 t.FailNow() 69 } 70 } 71 } 72 73 func TestCreateOAuthUser(t *testing.T) { 74 th := Setup(t).InitBasic() 75 defer th.TearDown() 76 77 r := rand.New(rand.NewSource(time.Now().UnixNano())) 78 glUser := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)) + 1, Username: "o" + model.NewId(), Email: model.NewId() + "@simulator.amazonses.com", Name: "Joram Wilander"} 79 80 json := glUser.ToJson() 81 user, err := th.App.CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id) 82 if err != nil { 83 t.Fatal(err) 84 } 85 86 if user.Username != glUser.Username { 87 t.Fatal("usernames didn't match") 88 } 89 90 th.App.PermanentDeleteUser(user) 91 92 *th.App.Config().TeamSettings.EnableUserCreation = false 93 94 _, err = th.App.CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id) 95 if err == nil { 96 t.Fatal("should have failed - user creation disabled") 97 } 98 } 99 100 func TestCreateProfileImage(t *testing.T) { 101 b, err := CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba", "nunito-bold.ttf") 102 if err != nil { 103 t.Fatal(err) 104 } 105 106 rdr := bytes.NewReader(b) 107 img, _, err2 := image.Decode(rdr) 108 if err2 != nil { 109 t.Fatal(err) 110 } 111 112 colorful := color.RGBA{116, 49, 196, 255} 113 114 if img.At(1, 1) != colorful { 115 t.Fatal("Failed to create correct color") 116 } 117 } 118 119 func TestSetDefaultProfileImage(t *testing.T) { 120 th := Setup(t).InitBasic() 121 defer th.TearDown() 122 123 err := th.App.SetDefaultProfileImage(&model.User{ 124 Id: model.NewId(), 125 Username: "notvaliduser", 126 }) 127 require.Error(t, err) 128 129 user := th.BasicUser 130 131 err = th.App.SetDefaultProfileImage(user) 132 require.Nil(t, err) 133 134 user = getUserFromDB(th.App, user.Id, t) 135 assert.Equal(t, int64(0), user.LastPictureUpdate) 136 } 137 138 func TestUpdateUserToRestrictedDomain(t *testing.T) { 139 th := Setup(t) 140 defer th.TearDown() 141 142 user := th.CreateUser() 143 defer th.App.PermanentDeleteUser(user) 144 145 th.App.UpdateConfig(func(cfg *model.Config) { 146 *cfg.TeamSettings.RestrictCreationToDomains = "foo.com" 147 }) 148 149 _, err := th.App.UpdateUser(user, false) 150 assert.True(t, err == nil) 151 152 user.Email = "asdf@ghjk.l" 153 _, err = th.App.UpdateUser(user, false) 154 assert.False(t, err == nil) 155 } 156 157 func TestUpdateUserActive(t *testing.T) { 158 th := Setup(t) 159 defer th.TearDown() 160 161 user := th.CreateUser() 162 163 EnableUserDeactivation := th.App.Config().TeamSettings.EnableUserDeactivation 164 defer func() { 165 th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserDeactivation = EnableUserDeactivation }) 166 }() 167 168 th.App.UpdateConfig(func(cfg *model.Config) { 169 *cfg.TeamSettings.EnableUserDeactivation = true 170 }) 171 err := th.App.UpdateUserActive(user.Id, false) 172 assert.Nil(t, err) 173 } 174 175 func TestUpdateActiveBotsSideEffect(t *testing.T) { 176 th := Setup(t).InitBasic() 177 defer th.TearDown() 178 179 bot, err := th.App.CreateBot(&model.Bot{ 180 Username: "username", 181 Description: "a bot", 182 OwnerId: th.BasicUser.Id, 183 }) 184 require.Nil(t, err) 185 defer th.App.PermanentDeleteBot(bot.UserId) 186 187 // Automatic deactivation disabled 188 th.App.UpdateConfig(func(cfg *model.Config) { 189 *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false 190 }) 191 192 th.App.UpdateActive(th.BasicUser, false) 193 194 retbot1, err := th.App.GetBot(bot.UserId, true) 195 require.Nil(t, err) 196 require.Zero(t, retbot1.DeleteAt) 197 user1, err := th.App.GetUser(bot.UserId) 198 require.Nil(t, err) 199 require.Zero(t, user1.DeleteAt) 200 201 th.App.UpdateActive(th.BasicUser, true) 202 203 // Automatic deactivation enabled 204 th.App.UpdateConfig(func(cfg *model.Config) { 205 *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true 206 }) 207 208 th.App.UpdateActive(th.BasicUser, false) 209 210 retbot2, err := th.App.GetBot(bot.UserId, true) 211 require.Nil(t, err) 212 require.NotZero(t, retbot2.DeleteAt) 213 user2, err := th.App.GetUser(bot.UserId) 214 require.Nil(t, err) 215 require.NotZero(t, user2.DeleteAt) 216 217 th.App.UpdateActive(th.BasicUser, true) 218 } 219 220 func TestUpdateOAuthUserAttrs(t *testing.T) { 221 th := Setup(t) 222 defer th.TearDown() 223 224 id := model.NewId() 225 id2 := model.NewId() 226 gitlabProvider := einterfaces.GetOauthProvider("gitlab") 227 228 username := "user" + id 229 username2 := "user" + id2 230 231 email := "user" + id + "@nowhere.com" 232 email2 := "user" + id2 + "@nowhere.com" 233 234 var user, user2 *model.User 235 var gitlabUserObj oauthgitlab.GitLabUser 236 user, gitlabUserObj = createGitlabUser(t, th.App, username, email) 237 user2, _ = createGitlabUser(t, th.App, username2, email2) 238 239 t.Run("UpdateUsername", func(t *testing.T) { 240 t.Run("NoExistingUserWithSameUsername", func(t *testing.T) { 241 gitlabUserObj.Username = "updateduser" + model.NewId() 242 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 243 data := bytes.NewReader(gitlabUser) 244 245 user = getUserFromDB(th.App, user.Id, t) 246 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 247 user = getUserFromDB(th.App, user.Id, t) 248 249 if user.Username != gitlabUserObj.Username { 250 t.Fatal("user's username is not updated") 251 } 252 }) 253 254 t.Run("ExistinguserWithSameUsername", func(t *testing.T) { 255 gitlabUserObj.Username = user2.Username 256 257 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 258 data := bytes.NewReader(gitlabUser) 259 260 user = getUserFromDB(th.App, user.Id, t) 261 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 262 user = getUserFromDB(th.App, user.Id, t) 263 264 if user.Username == gitlabUserObj.Username { 265 t.Fatal("user's username is updated though there already exists another user with the same username") 266 } 267 }) 268 }) 269 270 t.Run("UpdateEmail", func(t *testing.T) { 271 t.Run("NoExistingUserWithSameEmail", func(t *testing.T) { 272 gitlabUserObj.Email = "newuser" + model.NewId() + "@nowhere.com" 273 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 274 data := bytes.NewReader(gitlabUser) 275 276 user = getUserFromDB(th.App, user.Id, t) 277 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 278 user = getUserFromDB(th.App, user.Id, t) 279 280 if user.Email != gitlabUserObj.Email { 281 t.Fatal("user's email is not updated") 282 } 283 284 if !user.EmailVerified { 285 t.Fatal("user's email should have been verified") 286 } 287 }) 288 289 t.Run("ExistingUserWithSameEmail", func(t *testing.T) { 290 gitlabUserObj.Email = user2.Email 291 292 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 293 data := bytes.NewReader(gitlabUser) 294 295 user = getUserFromDB(th.App, user.Id, t) 296 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 297 user = getUserFromDB(th.App, user.Id, t) 298 299 if user.Email == gitlabUserObj.Email { 300 t.Fatal("user's email is updated though there already exists another user with the same email") 301 } 302 }) 303 }) 304 305 t.Run("UpdateFirstName", func(t *testing.T) { 306 gitlabUserObj.Name = "Updated User" 307 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 308 data := bytes.NewReader(gitlabUser) 309 310 user = getUserFromDB(th.App, user.Id, t) 311 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 312 user = getUserFromDB(th.App, user.Id, t) 313 314 if user.FirstName != "Updated" { 315 t.Fatal("user's first name is not updated") 316 } 317 }) 318 319 t.Run("UpdateLastName", func(t *testing.T) { 320 gitlabUserObj.Name = "Updated Lastname" 321 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 322 data := bytes.NewReader(gitlabUser) 323 324 user = getUserFromDB(th.App, user.Id, t) 325 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 326 user = getUserFromDB(th.App, user.Id, t) 327 328 if user.LastName != "Lastname" { 329 t.Fatal("user's last name is not updated") 330 } 331 }) 332 } 333 334 func TestUpdateUserEmail(t *testing.T) { 335 th := Setup(t) 336 defer th.TearDown() 337 338 user := th.CreateUser() 339 340 t.Run("RequireVerification", func(t *testing.T) { 341 th.App.UpdateConfig(func(cfg *model.Config) { 342 *cfg.EmailSettings.RequireEmailVerification = true 343 }) 344 345 currentEmail := user.Email 346 newEmail := th.MakeEmail() 347 348 user.Email = newEmail 349 user2, err := th.App.UpdateUser(user, false) 350 assert.Nil(t, err) 351 assert.Equal(t, currentEmail, user2.Email) 352 assert.True(t, user2.EmailVerified) 353 354 token, err := th.App.CreateVerifyEmailToken(user2.Id, newEmail) 355 assert.Nil(t, err) 356 357 err = th.App.VerifyEmailFromToken(token.Token) 358 assert.Nil(t, err) 359 360 user2, err = th.App.GetUser(user2.Id) 361 assert.Nil(t, err) 362 assert.Equal(t, newEmail, user2.Email) 363 assert.True(t, user2.EmailVerified) 364 }) 365 366 t.Run("RequireVerificationAlreadyUsedEmail", func(t *testing.T) { 367 th.App.UpdateConfig(func(cfg *model.Config) { 368 *cfg.EmailSettings.RequireEmailVerification = true 369 }) 370 371 user2 := th.CreateUser() 372 newEmail := user2.Email 373 374 user.Email = newEmail 375 user3, err := th.App.UpdateUser(user, false) 376 assert.NotNil(t, err) 377 assert.Nil(t, user3) 378 }) 379 380 t.Run("NoVerification", func(t *testing.T) { 381 th.App.UpdateConfig(func(cfg *model.Config) { 382 *cfg.EmailSettings.RequireEmailVerification = false 383 }) 384 385 newEmail := th.MakeEmail() 386 387 user.Email = newEmail 388 user2, err := th.App.UpdateUser(user, false) 389 assert.Nil(t, err) 390 assert.Equal(t, newEmail, user2.Email) 391 }) 392 } 393 394 func getUserFromDB(a *App, id string, t *testing.T) *model.User { 395 user, err := a.GetUser(id) 396 if err != nil { 397 t.Fatal("user is not found", err) 398 return nil 399 } 400 return user 401 } 402 403 func getGitlabUserPayload(gitlabUser oauthgitlab.GitLabUser, t *testing.T) []byte { 404 var payload []byte 405 var err error 406 if payload, err = json.Marshal(gitlabUser); err != nil { 407 t.Fatal("Serialization of gitlab user to json failed", err) 408 } 409 410 return payload 411 } 412 413 func createGitlabUser(t *testing.T, a *App, username string, email string) (*model.User, oauthgitlab.GitLabUser) { 414 r := rand.New(rand.NewSource(time.Now().UnixNano())) 415 gitlabUserObj := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)) + 1, Username: username, Login: "user1", Email: email, Name: "Test User"} 416 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 417 418 var user *model.User 419 var err *model.AppError 420 421 if user, err = a.CreateOAuthUser("gitlab", bytes.NewReader(gitlabUser), ""); err != nil { 422 t.Fatal("unable to create the user", err) 423 } 424 425 return user, gitlabUserObj 426 } 427 428 func TestGetUsersByStatus(t *testing.T) { 429 th := Setup(t) 430 defer th.TearDown() 431 432 team := th.CreateTeam() 433 channel, err := th.App.CreateChannel(&model.Channel{ 434 DisplayName: "dn_" + model.NewId(), 435 Name: "name_" + model.NewId(), 436 Type: model.CHANNEL_OPEN, 437 TeamId: team.Id, 438 CreatorId: model.NewId(), 439 }, false) 440 if err != nil { 441 t.Fatalf("failed to create channel: %v", err) 442 } 443 444 createUserWithStatus := func(username string, status string) *model.User { 445 id := model.NewId() 446 447 user, err := th.App.CreateUser(&model.User{ 448 Email: "success+" + id + "@simulator.amazonses.com", 449 Username: "un_" + username + "_" + id, 450 Nickname: "nn_" + id, 451 Password: "Password1", 452 }) 453 if err != nil { 454 t.Fatalf("failed to create user: %v", err) 455 } 456 457 th.LinkUserToTeam(user, team) 458 th.AddUserToChannel(user, channel) 459 460 th.App.SaveAndBroadcastStatus(&model.Status{ 461 UserId: user.Id, 462 Status: status, 463 Manual: true, 464 }) 465 466 return user 467 } 468 469 // Creating these out of order in case that affects results 470 awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY) 471 awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY) 472 dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND) 473 dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND) 474 offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE) 475 offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE) 476 onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE) 477 onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE) 478 479 t.Run("sorting by status then alphabetical", func(t *testing.T) { 480 usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 8, true) 481 if err != nil { 482 t.Fatal(err) 483 } 484 485 expectedUsersByStatus := []*model.User{ 486 onlineUser1, 487 onlineUser2, 488 awayUser1, 489 awayUser2, 490 dndUser1, 491 dndUser2, 492 offlineUser1, 493 offlineUser2, 494 } 495 496 if len(usersByStatus) != len(expectedUsersByStatus) { 497 t.Fatalf("received only %v users, expected %v", len(usersByStatus), len(expectedUsersByStatus)) 498 } 499 500 for i := range usersByStatus { 501 if usersByStatus[i].Id != expectedUsersByStatus[i].Id { 502 t.Fatalf("received user %v at index %v, expected %v", usersByStatus[i].Username, i, expectedUsersByStatus[i].Username) 503 } 504 } 505 }) 506 507 t.Run("paging", func(t *testing.T) { 508 usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 3, true) 509 if err != nil { 510 t.Fatal(err) 511 } 512 513 if len(usersByStatus) != 3 { 514 t.Fatal("received too many users") 515 } 516 517 if usersByStatus[0].Id != onlineUser1.Id && usersByStatus[1].Id != onlineUser2.Id { 518 t.Fatal("expected to receive online users first") 519 } 520 521 if usersByStatus[2].Id != awayUser1.Id { 522 t.Fatal("expected to receive away users second") 523 } 524 525 usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 3, true) 526 if err != nil { 527 t.Fatal(err) 528 } 529 530 if usersByStatus[0].Id != awayUser2.Id { 531 t.Fatal("expected to receive away users second") 532 } 533 534 if usersByStatus[1].Id != dndUser1.Id && usersByStatus[2].Id != dndUser2.Id { 535 t.Fatal("expected to receive dnd users third") 536 } 537 538 usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 4, true) 539 if err != nil { 540 t.Fatal(err) 541 } 542 543 if len(usersByStatus) != 4 { 544 t.Fatal("received too many users") 545 } 546 547 if usersByStatus[0].Id != dndUser1.Id && usersByStatus[1].Id != dndUser2.Id { 548 t.Fatal("expected to receive dnd users third") 549 } 550 551 if usersByStatus[2].Id != offlineUser1.Id && usersByStatus[3].Id != offlineUser2.Id { 552 t.Fatal("expected to receive offline users last") 553 } 554 }) 555 } 556 557 func TestCreateUserWithToken(t *testing.T) { 558 th := Setup(t).InitBasic() 559 defer th.TearDown() 560 561 user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""} 562 563 t.Run("invalid token", func(t *testing.T) { 564 if _, err := th.App.CreateUserWithToken(&user, "123"); err == nil { 565 t.Fatal("Should fail on unexisting token") 566 } 567 }) 568 569 t.Run("invalid token type", func(t *testing.T) { 570 token := model.NewToken( 571 TOKEN_TYPE_VERIFY_EMAIL, 572 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 573 ) 574 <-th.App.Srv.Store.Token().Save(token) 575 defer th.App.DeleteToken(token) 576 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 577 t.Fatal("Should fail on bad token type") 578 } 579 }) 580 581 t.Run("expired token", func(t *testing.T) { 582 token := model.NewToken( 583 TOKEN_TYPE_TEAM_INVITATION, 584 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 585 ) 586 token.CreateAt = model.GetMillis() - TEAM_INVITATION_EXPIRY_TIME - 1 587 <-th.App.Srv.Store.Token().Save(token) 588 defer th.App.DeleteToken(token) 589 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 590 t.Fatal("Should fail on expired token") 591 } 592 }) 593 594 t.Run("invalid team id", func(t *testing.T) { 595 token := model.NewToken( 596 TOKEN_TYPE_TEAM_INVITATION, 597 model.MapToJson(map[string]string{"teamId": model.NewId(), "email": user.Email}), 598 ) 599 <-th.App.Srv.Store.Token().Save(token) 600 defer th.App.DeleteToken(token) 601 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 602 t.Fatal("Should fail on bad team id") 603 } 604 }) 605 606 t.Run("valid request", func(t *testing.T) { 607 invitationEmail := model.NewId() + "other-email@test.com" 608 token := model.NewToken( 609 TOKEN_TYPE_TEAM_INVITATION, 610 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": invitationEmail}), 611 ) 612 <-th.App.Srv.Store.Token().Save(token) 613 newUser, err := th.App.CreateUserWithToken(&user, token.Token) 614 if err != nil { 615 t.Log(err) 616 t.Fatal("Should add user to the team") 617 } 618 if newUser.Email != invitationEmail { 619 t.Fatal("The user email must be the invitation one") 620 } 621 if result := <-th.App.Srv.Store.Token().GetByToken(token.Token); result.Err == nil { 622 t.Fatal("The token must be deleted after be used") 623 } 624 }) 625 } 626 627 func TestPermanentDeleteUser(t *testing.T) { 628 th := Setup(t).InitBasic() 629 defer th.TearDown() 630 631 b := []byte("testimage") 632 633 finfo, err := th.App.DoUploadFile(time.Now(), th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, "testfile.txt", b) 634 635 if err != nil { 636 t.Log(err) 637 t.Fatal("Unable to upload file") 638 } 639 640 err = th.App.PermanentDeleteUser(th.BasicUser) 641 if err != nil { 642 t.Log(err) 643 t.Fatal("Unable to delete user") 644 } 645 646 res, err := th.App.FileExists(finfo.Path) 647 648 if err != nil { 649 t.Log(err) 650 t.Fatal("Unable to check whether file exists") 651 } 652 653 if res { 654 t.Log(err) 655 t.Fatal("File was not deleted on FS") 656 } 657 658 finfo, err = th.App.GetFileInfo(finfo.Id) 659 660 if finfo != nil { 661 t.Log(err) 662 t.Fatal("Unable to find finfo") 663 } 664 665 if err == nil { 666 t.Log(err) 667 t.Fatal("GetFileInfo after DeleteUser is nil") 668 } 669 } 670 671 func TestPasswordRecovery(t *testing.T) { 672 th := Setup(t).InitBasic() 673 defer th.TearDown() 674 675 token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) 676 assert.Nil(t, err) 677 678 tokenData := struct { 679 UserId string 680 Email string 681 }{} 682 683 err2 := json.Unmarshal([]byte(token.Extra), &tokenData) 684 assert.Nil(t, err2) 685 assert.Equal(t, th.BasicUser.Id, tokenData.UserId) 686 assert.Equal(t, th.BasicUser.Email, tokenData.Email) 687 688 // Password token with same eMail as during creation 689 err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") 690 assert.Nil(t, err) 691 692 // Password token with modified eMail after creation 693 token, err = th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email) 694 assert.Nil(t, err) 695 696 th.App.UpdateConfig(func(c *model.Config) { 697 *c.EmailSettings.RequireEmailVerification = false 698 }) 699 700 th.BasicUser.Email = th.MakeEmail() 701 _, err = th.App.UpdateUser(th.BasicUser, false) 702 assert.Nil(t, err) 703 704 err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh") 705 assert.NotNil(t, err) 706 }