github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+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 "github.com/mattermost/mattermost-server/model/gitlab" 22 ) 23 24 func TestIsUsernameTaken(t *testing.T) { 25 th := Setup().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().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().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().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() 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 TestUpdateOAuthUserAttrs(t *testing.T) { 158 th := Setup() 159 defer th.TearDown() 160 161 id := model.NewId() 162 id2 := model.NewId() 163 gitlabProvider := einterfaces.GetOauthProvider("gitlab") 164 165 username := "user" + id 166 username2 := "user" + id2 167 168 email := "user" + id + "@nowhere.com" 169 email2 := "user" + id2 + "@nowhere.com" 170 171 var user, user2 *model.User 172 var gitlabUserObj oauthgitlab.GitLabUser 173 user, gitlabUserObj = createGitlabUser(t, th.App, username, email) 174 user2, _ = createGitlabUser(t, th.App, username2, email2) 175 176 t.Run("UpdateUsername", func(t *testing.T) { 177 t.Run("NoExistingUserWithSameUsername", func(t *testing.T) { 178 gitlabUserObj.Username = "updateduser" + model.NewId() 179 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 180 data := bytes.NewReader(gitlabUser) 181 182 user = getUserFromDB(th.App, user.Id, t) 183 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 184 user = getUserFromDB(th.App, user.Id, t) 185 186 if user.Username != gitlabUserObj.Username { 187 t.Fatal("user's username is not updated") 188 } 189 }) 190 191 t.Run("ExistinguserWithSameUsername", func(t *testing.T) { 192 gitlabUserObj.Username = user2.Username 193 194 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 195 data := bytes.NewReader(gitlabUser) 196 197 user = getUserFromDB(th.App, user.Id, t) 198 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 199 user = getUserFromDB(th.App, user.Id, t) 200 201 if user.Username == gitlabUserObj.Username { 202 t.Fatal("user's username is updated though there already exists another user with the same username") 203 } 204 }) 205 }) 206 207 t.Run("UpdateEmail", func(t *testing.T) { 208 t.Run("NoExistingUserWithSameEmail", func(t *testing.T) { 209 gitlabUserObj.Email = "newuser" + model.NewId() + "@nowhere.com" 210 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 211 data := bytes.NewReader(gitlabUser) 212 213 user = getUserFromDB(th.App, user.Id, t) 214 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 215 user = getUserFromDB(th.App, user.Id, t) 216 217 if user.Email != gitlabUserObj.Email { 218 t.Fatal("user's email is not updated") 219 } 220 221 if !user.EmailVerified { 222 t.Fatal("user's email should have been verified") 223 } 224 }) 225 226 t.Run("ExistingUserWithSameEmail", func(t *testing.T) { 227 gitlabUserObj.Email = user2.Email 228 229 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 230 data := bytes.NewReader(gitlabUser) 231 232 user = getUserFromDB(th.App, user.Id, t) 233 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 234 user = getUserFromDB(th.App, user.Id, t) 235 236 if user.Email == gitlabUserObj.Email { 237 t.Fatal("user's email is updated though there already exists another user with the same email") 238 } 239 }) 240 }) 241 242 t.Run("UpdateFirstName", func(t *testing.T) { 243 gitlabUserObj.Name = "Updated User" 244 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 245 data := bytes.NewReader(gitlabUser) 246 247 user = getUserFromDB(th.App, user.Id, t) 248 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 249 user = getUserFromDB(th.App, user.Id, t) 250 251 if user.FirstName != "Updated" { 252 t.Fatal("user's first name is not updated") 253 } 254 }) 255 256 t.Run("UpdateLastName", func(t *testing.T) { 257 gitlabUserObj.Name = "Updated Lastname" 258 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 259 data := bytes.NewReader(gitlabUser) 260 261 user = getUserFromDB(th.App, user.Id, t) 262 th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab") 263 user = getUserFromDB(th.App, user.Id, t) 264 265 if user.LastName != "Lastname" { 266 t.Fatal("user's last name is not updated") 267 } 268 }) 269 } 270 271 func getUserFromDB(a *App, id string, t *testing.T) *model.User { 272 user, err := a.GetUser(id) 273 if err != nil { 274 t.Fatal("user is not found", err) 275 return nil 276 } 277 return user 278 } 279 280 func getGitlabUserPayload(gitlabUser oauthgitlab.GitLabUser, t *testing.T) []byte { 281 var payload []byte 282 var err error 283 if payload, err = json.Marshal(gitlabUser); err != nil { 284 t.Fatal("Serialization of gitlab user to json failed", err) 285 } 286 287 return payload 288 } 289 290 func createGitlabUser(t *testing.T, a *App, username string, email string) (*model.User, oauthgitlab.GitLabUser) { 291 r := rand.New(rand.NewSource(time.Now().UnixNano())) 292 gitlabUserObj := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)) + 1, Username: username, Login: "user1", Email: email, Name: "Test User"} 293 gitlabUser := getGitlabUserPayload(gitlabUserObj, t) 294 295 var user *model.User 296 var err *model.AppError 297 298 if user, err = a.CreateOAuthUser("gitlab", bytes.NewReader(gitlabUser), ""); err != nil { 299 t.Fatal("unable to create the user", err) 300 } 301 302 return user, gitlabUserObj 303 } 304 305 func TestGetUsersByStatus(t *testing.T) { 306 th := Setup() 307 defer th.TearDown() 308 309 team := th.CreateTeam() 310 channel, err := th.App.CreateChannel(&model.Channel{ 311 DisplayName: "dn_" + model.NewId(), 312 Name: "name_" + model.NewId(), 313 Type: model.CHANNEL_OPEN, 314 TeamId: team.Id, 315 CreatorId: model.NewId(), 316 }, false) 317 if err != nil { 318 t.Fatalf("failed to create channel: %v", err) 319 } 320 321 createUserWithStatus := func(username string, status string) *model.User { 322 id := model.NewId() 323 324 user, err := th.App.CreateUser(&model.User{ 325 Email: "success+" + id + "@simulator.amazonses.com", 326 Username: "un_" + username + "_" + id, 327 Nickname: "nn_" + id, 328 Password: "Password1", 329 }) 330 if err != nil { 331 t.Fatalf("failed to create user: %v", err) 332 } 333 334 th.LinkUserToTeam(user, team) 335 th.AddUserToChannel(user, channel) 336 337 th.App.SaveAndBroadcastStatus(&model.Status{ 338 UserId: user.Id, 339 Status: status, 340 Manual: true, 341 }) 342 343 return user 344 } 345 346 // Creating these out of order in case that affects results 347 awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY) 348 awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY) 349 dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND) 350 dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND) 351 offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE) 352 offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE) 353 onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE) 354 onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE) 355 356 t.Run("sorting by status then alphabetical", func(t *testing.T) { 357 usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 8, true) 358 if err != nil { 359 t.Fatal(err) 360 } 361 362 expectedUsersByStatus := []*model.User{ 363 onlineUser1, 364 onlineUser2, 365 awayUser1, 366 awayUser2, 367 dndUser1, 368 dndUser2, 369 offlineUser1, 370 offlineUser2, 371 } 372 373 if len(usersByStatus) != len(expectedUsersByStatus) { 374 t.Fatalf("received only %v users, expected %v", len(usersByStatus), len(expectedUsersByStatus)) 375 } 376 377 for i := range usersByStatus { 378 if usersByStatus[i].Id != expectedUsersByStatus[i].Id { 379 t.Fatalf("received user %v at index %v, expected %v", usersByStatus[i].Username, i, expectedUsersByStatus[i].Username) 380 } 381 } 382 }) 383 384 t.Run("paging", func(t *testing.T) { 385 usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 3, true) 386 if err != nil { 387 t.Fatal(err) 388 } 389 390 if len(usersByStatus) != 3 { 391 t.Fatal("received too many users") 392 } 393 394 if usersByStatus[0].Id != onlineUser1.Id && usersByStatus[1].Id != onlineUser2.Id { 395 t.Fatal("expected to receive online users first") 396 } 397 398 if usersByStatus[2].Id != awayUser1.Id { 399 t.Fatal("expected to receive away users second") 400 } 401 402 usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 3, true) 403 if err != nil { 404 t.Fatal(err) 405 } 406 407 if usersByStatus[0].Id != awayUser2.Id { 408 t.Fatal("expected to receive away users second") 409 } 410 411 if usersByStatus[1].Id != dndUser1.Id && usersByStatus[2].Id != dndUser2.Id { 412 t.Fatal("expected to receive dnd users third") 413 } 414 415 usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 4, true) 416 if err != nil { 417 t.Fatal(err) 418 } 419 420 if len(usersByStatus) != 4 { 421 t.Fatal("received too many users") 422 } 423 424 if usersByStatus[0].Id != dndUser1.Id && usersByStatus[1].Id != dndUser2.Id { 425 t.Fatal("expected to receive dnd users third") 426 } 427 428 if usersByStatus[2].Id != offlineUser1.Id && usersByStatus[3].Id != offlineUser2.Id { 429 t.Fatal("expected to receive offline users last") 430 } 431 }) 432 } 433 434 func TestCreateUserWithToken(t *testing.T) { 435 th := Setup().InitBasic() 436 defer th.TearDown() 437 438 user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""} 439 440 t.Run("invalid token", func(t *testing.T) { 441 if _, err := th.App.CreateUserWithToken(&user, "123"); err == nil { 442 t.Fatal("Should fail on unexisting token") 443 } 444 }) 445 446 t.Run("invalid token type", func(t *testing.T) { 447 token := model.NewToken( 448 TOKEN_TYPE_VERIFY_EMAIL, 449 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 450 ) 451 <-th.App.Srv.Store.Token().Save(token) 452 defer th.App.DeleteToken(token) 453 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 454 t.Fatal("Should fail on bad token type") 455 } 456 }) 457 458 t.Run("expired token", func(t *testing.T) { 459 token := model.NewToken( 460 TOKEN_TYPE_TEAM_INVITATION, 461 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 462 ) 463 token.CreateAt = model.GetMillis() - TEAM_INVITATION_EXPIRY_TIME - 1 464 <-th.App.Srv.Store.Token().Save(token) 465 defer th.App.DeleteToken(token) 466 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 467 t.Fatal("Should fail on expired token") 468 } 469 }) 470 471 t.Run("invalid team id", func(t *testing.T) { 472 token := model.NewToken( 473 TOKEN_TYPE_TEAM_INVITATION, 474 model.MapToJson(map[string]string{"teamId": model.NewId(), "email": user.Email}), 475 ) 476 <-th.App.Srv.Store.Token().Save(token) 477 defer th.App.DeleteToken(token) 478 if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil { 479 t.Fatal("Should fail on bad team id") 480 } 481 }) 482 483 t.Run("valid request", func(t *testing.T) { 484 invitationEmail := model.NewId() + "other-email@test.com" 485 token := model.NewToken( 486 TOKEN_TYPE_TEAM_INVITATION, 487 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": invitationEmail}), 488 ) 489 <-th.App.Srv.Store.Token().Save(token) 490 newUser, err := th.App.CreateUserWithToken(&user, token.Token) 491 if err != nil { 492 t.Log(err) 493 t.Fatal("Should add user to the team") 494 } 495 if newUser.Email != invitationEmail { 496 t.Fatal("The user email must be the invitation one") 497 } 498 if result := <-th.App.Srv.Store.Token().GetByToken(token.Token); result.Err == nil { 499 t.Fatal("The token must be deleted after be used") 500 } 501 }) 502 } 503 504 func TestPermanentDeleteUser(t *testing.T) { 505 th := Setup().InitBasic() 506 defer th.TearDown() 507 508 b := []byte("testimage") 509 510 finfo, err := th.App.DoUploadFile(time.Now(), th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, "testfile.txt", b) 511 512 if err != nil { 513 t.Log(err) 514 t.Fatal("Unable to upload file") 515 } 516 517 err = th.App.PermanentDeleteUser(th.BasicUser) 518 if err != nil { 519 t.Log(err) 520 t.Fatal("Unable to delete user") 521 } 522 523 res, err := th.App.FileExists(finfo.Path) 524 525 if err != nil { 526 t.Log(err) 527 t.Fatal("Unable to check whether file exists") 528 } 529 530 if res { 531 t.Log(err) 532 t.Fatal("File was not deleted on FS") 533 } 534 535 finfo, err = th.App.GetFileInfo(finfo.Id) 536 537 if finfo != nil { 538 t.Log(err) 539 t.Fatal("Unable to find finfo") 540 } 541 542 if err == nil { 543 t.Log(err) 544 t.Fatal("GetFileInfo after DeleteUser is nil") 545 } 546 } 547 548 func TestRecordUserServiceTermsAction(t *testing.T) { 549 th := Setup().InitBasic() 550 defer th.TearDown() 551 552 user := &model.User{ 553 Email: strings.ToLower(model.NewId()) + "success+test@example.com", 554 Nickname: "Luke Skywalker", // trying to bring balance to the "Force", one test user at a time 555 Username: "luke" + model.NewId(), 556 Password: "passwd1", 557 AuthService: "", 558 } 559 user, err := th.App.CreateUser(user) 560 if err != nil { 561 t.Fatalf("failed to create user: %v", err) 562 } 563 564 defer th.App.PermanentDeleteUser(user) 565 566 serviceTerms, err := th.App.CreateServiceTerms("text", user.Id) 567 if err != nil { 568 t.Fatalf("failed to create service terms: %v", err) 569 } 570 571 err = th.App.RecordUserServiceTermsAction(user.Id, serviceTerms.Id, true) 572 if err != nil { 573 t.Fatalf("failed to record user action: %v", err) 574 } 575 576 nuser, err := th.App.GetUser(user.Id) 577 assert.Equal(t, serviceTerms.Id, nuser.AcceptedServiceTermsId) 578 579 err = th.App.RecordUserServiceTermsAction(user.Id, serviceTerms.Id, false) 580 if err != nil { 581 t.Fatalf("failed to record user action: %v", err) 582 } 583 584 nuser, err = th.App.GetUser(user.Id) 585 assert.Empty(t, nuser.AcceptedServiceTermsId) 586 }