github.com/mattermost/mattermost-server/v5@v5.39.3/api4/user_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package api4 5 6 import ( 7 "fmt" 8 "net/http" 9 "os" 10 "regexp" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/dgryski/dgoogauth" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/mock" 18 "github.com/stretchr/testify/require" 19 20 "github.com/mattermost/mattermost-server/v5/app" 21 "github.com/mattermost/mattermost-server/v5/einterfaces/mocks" 22 "github.com/mattermost/mattermost-server/v5/model" 23 "github.com/mattermost/mattermost-server/v5/shared/mail" 24 "github.com/mattermost/mattermost-server/v5/utils/testutils" 25 26 _ "github.com/mattermost/mattermost-server/v5/model/gitlab" 27 ) 28 29 func TestCreateUser(t *testing.T) { 30 th := Setup(t) 31 defer th.TearDown() 32 33 user := model.User{ 34 Email: th.GenerateTestEmail(), 35 Nickname: "Corey Hulen", 36 Password: "hello1", 37 Username: GenerateTestUsername(), 38 Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID, 39 EmailVerified: true, 40 } 41 42 ruser, resp := th.Client.CreateUser(&user) 43 CheckNoError(t, resp) 44 CheckCreatedStatus(t, resp) 45 // Creating a user as a regular user with verified flag should not verify the new user. 46 require.False(t, ruser.EmailVerified) 47 48 _, _ = th.Client.Login(user.Email, user.Password) 49 50 require.Equal(t, user.Nickname, ruser.Nickname, "nickname didn't match") 51 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "did not clear roles") 52 53 CheckUserSanitization(t, ruser) 54 55 _, resp = th.Client.CreateUser(ruser) 56 CheckBadRequestStatus(t, resp) 57 58 ruser.Id = "" 59 ruser.Username = GenerateTestUsername() 60 ruser.Password = "passwd1" 61 _, resp = th.Client.CreateUser(ruser) 62 CheckErrorMessage(t, resp, "app.user.save.email_exists.app_error") 63 CheckBadRequestStatus(t, resp) 64 65 ruser.Email = th.GenerateTestEmail() 66 ruser.Username = user.Username 67 _, resp = th.Client.CreateUser(ruser) 68 CheckErrorMessage(t, resp, "app.user.save.username_exists.app_error") 69 CheckBadRequestStatus(t, resp) 70 71 ruser.Email = "" 72 _, resp = th.Client.CreateUser(ruser) 73 CheckErrorMessage(t, resp, "model.user.is_valid.email.app_error") 74 CheckBadRequestStatus(t, resp) 75 76 ruser.Username = "testinvalid+++" 77 _, resp = th.Client.CreateUser(ruser) 78 CheckErrorMessage(t, resp, "model.user.is_valid.username.app_error") 79 CheckBadRequestStatus(t, resp) 80 81 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = false }) 82 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserCreation = false }) 83 84 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 85 user2 := &model.User{Email: th.GenerateTestEmail(), Password: "Password1", Username: GenerateTestUsername(), EmailVerified: true} 86 ruser2, resp := client.CreateUser(user2) 87 CheckNoError(t, resp) 88 // Creating a user as sysadmin should verify the user with the EmailVerified flag. 89 require.True(t, ruser2.EmailVerified) 90 91 r, err := client.DoApiPost("/users", "garbage") 92 require.NotNil(t, err, "should have errored") 93 assert.Equal(t, http.StatusBadRequest, r.StatusCode) 94 }) 95 96 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 97 email := th.GenerateTestEmail() 98 user2 := &model.User{Email: email, Password: "Password1", Username: GenerateTestUsername(), EmailVerified: true} 99 _, resp := client.CreateUser(user2) 100 CheckNoError(t, resp) 101 _, appErr := th.App.GetUserByUsername(user2.Username) 102 require.Nil(t, appErr) 103 104 user3 := &model.User{Email: fmt.Sprintf(" %s ", email), Password: "Password1", Username: GenerateTestUsername(), EmailVerified: true} 105 _, resp = client.CreateUser(user3) 106 CheckBadRequestStatus(t, resp) 107 _, appErr = th.App.GetUserByUsername(user3.Username) 108 require.NotNil(t, appErr) 109 }, "Should not be able to create two users with the same email but spaces in it") 110 } 111 112 func TestCreateUserInputFilter(t *testing.T) { 113 th := Setup(t) 114 defer th.TearDown() 115 116 t.Run("DomainRestriction", func(t *testing.T) { 117 118 enableAPIUserDeletion := th.App.Config().ServiceSettings.EnableAPIUserDeletion 119 th.App.UpdateConfig(func(cfg *model.Config) { 120 *cfg.TeamSettings.EnableOpenServer = true 121 *cfg.TeamSettings.EnableUserCreation = true 122 *cfg.TeamSettings.RestrictCreationToDomains = "mattermost.com" 123 *cfg.ServiceSettings.EnableAPIUserDeletion = true 124 }) 125 126 defer th.App.UpdateConfig(func(cfg *model.Config) { 127 *cfg.TeamSettings.RestrictCreationToDomains = "" 128 *cfg.ServiceSettings.EnableAPIUserDeletion = *enableAPIUserDeletion 129 }) 130 131 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 132 user := &model.User{Email: "foobar+testdomainrestriction@mattermost.com", Password: "Password1", Username: GenerateTestUsername()} 133 u, resp := client.CreateUser(user) // we need the returned created user to use its Id for deletion. 134 CheckNoError(t, resp) 135 _, resp = client.PermanentDeleteUser(u.Id) 136 CheckNoError(t, resp) 137 }, "ValidUser") 138 139 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 140 user := &model.User{Email: "foobar+testdomainrestriction@mattermost.org", Password: "Password1", Username: GenerateTestUsername()} 141 _, resp := client.CreateUser(user) 142 CheckBadRequestStatus(t, resp) 143 }, "InvalidEmail") 144 145 t.Run("ValidAuthServiceFilter", func(t *testing.T) { 146 t.Run("SystemAdminClient", func(t *testing.T) { 147 user := &model.User{ 148 Email: "foobar+testdomainrestriction@mattermost.org", 149 Username: GenerateTestUsername(), 150 AuthService: "ldap", 151 AuthData: model.NewString("999099"), 152 } 153 u, resp := th.SystemAdminClient.CreateUser(user) 154 CheckNoError(t, resp) 155 _, resp = th.SystemAdminClient.PermanentDeleteUser(u.Id) 156 CheckNoError(t, resp) 157 }) 158 t.Run("LocalClient", func(t *testing.T) { 159 user := &model.User{ 160 Email: "foobar+testdomainrestrictionlocalclient@mattermost.org", 161 Username: GenerateTestUsername(), 162 AuthService: "ldap", 163 AuthData: model.NewString("999100"), 164 } 165 u, resp := th.LocalClient.CreateUser(user) 166 CheckNoError(t, resp) 167 _, resp = th.LocalClient.PermanentDeleteUser(u.Id) 168 CheckNoError(t, resp) 169 }) 170 }) 171 172 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 173 user := &model.User{Email: "foobar+testdomainrestriction@mattermost.org", Password: "Password1", Username: GenerateTestUsername(), AuthService: "ldap"} 174 _, resp := th.Client.CreateUser(user) 175 CheckBadRequestStatus(t, resp) 176 }, "InvalidAuthServiceFilter") 177 }) 178 179 t.Run("Roles", func(t *testing.T) { 180 th.App.UpdateConfig(func(cfg *model.Config) { 181 *cfg.TeamSettings.EnableOpenServer = true 182 *cfg.TeamSettings.EnableUserCreation = true 183 *cfg.TeamSettings.RestrictCreationToDomains = "" 184 *cfg.ServiceSettings.EnableAPIUserDeletion = true 185 }) 186 187 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 188 emailAddr := "foobar+testinvalidrole@mattermost.com" 189 user := &model.User{Email: emailAddr, Password: "Password1", Username: GenerateTestUsername(), Roles: "system_user system_admin"} 190 _, resp := client.CreateUser(user) 191 CheckNoError(t, resp) 192 ruser, err := th.App.GetUserByEmail(emailAddr) 193 require.Nil(t, err) 194 assert.NotEqual(t, ruser.Roles, "system_user system_admin") 195 _, resp = client.PermanentDeleteUser(ruser.Id) 196 CheckNoError(t, resp) 197 }, "InvalidRole") 198 }) 199 200 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 201 th.App.UpdateConfig(func(cfg *model.Config) { 202 *cfg.TeamSettings.EnableOpenServer = true 203 *cfg.TeamSettings.EnableUserCreation = true 204 }) 205 user := &model.User{Id: "AAAAAAAAAAAAAAAAAAAAAAAAAA", Email: "foobar+testinvalidid@mattermost.com", Password: "Password1", Username: GenerateTestUsername(), Roles: "system_user system_admin"} 206 _, resp := client.CreateUser(user) 207 CheckBadRequestStatus(t, resp) 208 }, "InvalidId") 209 } 210 211 func TestCreateUserWithToken(t *testing.T) { 212 th := Setup(t).InitBasic() 213 defer th.TearDown() 214 215 t.Run("CreateWithTokenHappyPath", func(t *testing.T) { 216 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 217 token := model.NewToken( 218 app.TokenTypeTeamInvitation, 219 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 220 ) 221 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 222 223 ruser, resp := th.Client.CreateUserWithToken(&user, token.Token) 224 CheckNoError(t, resp) 225 CheckCreatedStatus(t, resp) 226 227 th.Client.Login(user.Email, user.Password) 228 require.Equal(t, user.Nickname, ruser.Nickname) 229 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 230 CheckUserSanitization(t, ruser) 231 _, err := th.App.Srv().Store.Token().GetByToken(token.Token) 232 require.Error(t, err, "The token must be deleted after being used") 233 234 teams, appErr := th.App.GetTeamsForUser(ruser.Id) 235 require.Nil(t, appErr) 236 require.NotEmpty(t, teams, "The user must have teams") 237 require.Equal(t, th.BasicTeam.Id, teams[0].Id, "The user joined team must be the team provided.") 238 }) 239 240 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 241 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 242 token := model.NewToken( 243 app.TokenTypeTeamInvitation, 244 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 245 ) 246 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 247 248 ruser, resp := client.CreateUserWithToken(&user, token.Token) 249 CheckNoError(t, resp) 250 CheckCreatedStatus(t, resp) 251 252 th.Client.Login(user.Email, user.Password) 253 require.Equal(t, user.Nickname, ruser.Nickname) 254 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 255 CheckUserSanitization(t, ruser) 256 _, err := th.App.Srv().Store.Token().GetByToken(token.Token) 257 require.Error(t, err, "The token must be deleted after being used") 258 259 teams, appErr := th.App.GetTeamsForUser(ruser.Id) 260 require.Nil(t, appErr) 261 require.NotEmpty(t, teams, "The user must have teams") 262 require.Equal(t, th.BasicTeam.Id, teams[0].Id, "The user joined team must be the team provided.") 263 }, "CreateWithTokenHappyPath") 264 265 t.Run("NoToken", func(t *testing.T) { 266 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 267 token := model.NewToken( 268 app.TokenTypeTeamInvitation, 269 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 270 ) 271 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 272 defer th.App.DeleteToken(token) 273 274 _, resp := th.Client.CreateUserWithToken(&user, "") 275 CheckBadRequestStatus(t, resp) 276 CheckErrorMessage(t, resp, "api.user.create_user.missing_token.app_error") 277 }) 278 279 t.Run("TokenExpired", func(t *testing.T) { 280 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 281 timeNow := time.Now() 282 past49Hours := timeNow.Add(-49*time.Hour).UnixNano() / int64(time.Millisecond) 283 token := model.NewToken( 284 app.TokenTypeTeamInvitation, 285 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 286 ) 287 token.CreateAt = past49Hours 288 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 289 defer th.App.DeleteToken(token) 290 291 _, resp := th.Client.CreateUserWithToken(&user, token.Token) 292 CheckBadRequestStatus(t, resp) 293 CheckErrorMessage(t, resp, "api.user.create_user.signup_link_expired.app_error") 294 }) 295 296 t.Run("WrongToken", func(t *testing.T) { 297 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 298 299 _, resp := th.Client.CreateUserWithToken(&user, "wrong") 300 CheckNotFoundStatus(t, resp) 301 CheckErrorMessage(t, resp, "api.user.create_user.signup_link_invalid.app_error") 302 }) 303 304 t.Run("EnableUserCreationDisable", func(t *testing.T) { 305 306 enableUserCreation := th.App.Config().TeamSettings.EnableUserCreation 307 defer func() { 308 th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserCreation = enableUserCreation }) 309 }() 310 311 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 312 313 token := model.NewToken( 314 app.TokenTypeTeamInvitation, 315 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 316 ) 317 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 318 defer th.App.DeleteToken(token) 319 320 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserCreation = false }) 321 322 _, resp := th.Client.CreateUserWithToken(&user, token.Token) 323 CheckNotImplementedStatus(t, resp) 324 CheckErrorMessage(t, resp, "api.user.create_user.signup_email_disabled.app_error") 325 326 }) 327 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 328 enableUserCreation := th.App.Config().TeamSettings.EnableUserCreation 329 defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserCreation = enableUserCreation }) 330 331 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 332 333 token := model.NewToken( 334 app.TokenTypeTeamInvitation, 335 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 336 ) 337 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 338 defer th.App.DeleteToken(token) 339 340 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserCreation = false }) 341 342 _, resp := client.CreateUserWithToken(&user, token.Token) 343 CheckNotImplementedStatus(t, resp) 344 CheckErrorMessage(t, resp, "api.user.create_user.signup_email_disabled.app_error") 345 }, "EnableUserCreationDisable") 346 347 t.Run("EnableOpenServerDisable", func(t *testing.T) { 348 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 349 350 token := model.NewToken( 351 app.TokenTypeTeamInvitation, 352 model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}), 353 ) 354 require.NoError(t, th.App.Srv().Store.Token().Save(token)) 355 356 enableOpenServer := th.App.Config().TeamSettings.EnableOpenServer 357 defer func() { 358 th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableOpenServer = enableOpenServer }) 359 }() 360 361 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = false }) 362 363 ruser, resp := th.Client.CreateUserWithToken(&user, token.Token) 364 CheckNoError(t, resp) 365 CheckCreatedStatus(t, resp) 366 367 th.Client.Login(user.Email, user.Password) 368 require.Equal(t, user.Nickname, ruser.Nickname) 369 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 370 CheckUserSanitization(t, ruser) 371 _, err := th.App.Srv().Store.Token().GetByToken(token.Token) 372 require.Error(t, err, "The token must be deleted after be used") 373 }) 374 } 375 376 func TestCreateUserWebSocketEvent(t *testing.T) { 377 th := Setup(t).InitBasic() 378 defer th.TearDown() 379 380 t.Run("guest should not received new_user event but user should", func(t *testing.T) { 381 th.App.Srv().SetLicense(model.NewTestLicense("guests")) 382 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) 383 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.AllowEmailAccounts = true }) 384 385 id := model.NewId() 386 guestPassword := "Pa$$word11" 387 guest := &model.User{ 388 Email: "success+" + id + "@simulator.amazonses.com", 389 Username: "un_" + id, 390 Nickname: "nn_" + id, 391 Password: guestPassword, 392 EmailVerified: true, 393 } 394 395 guest, err := th.App.CreateGuest(th.Context, guest) 396 require.Nil(t, err) 397 398 _, _, err = th.App.AddUserToTeam(th.Context, th.BasicTeam.Id, guest.Id, "") 399 require.Nil(t, err) 400 401 _, err = th.App.AddUserToChannel(guest, th.BasicChannel, false) 402 require.Nil(t, err) 403 404 guestClient := th.CreateClient() 405 406 _, resp := guestClient.Login(guest.Email, guestPassword) 407 require.Nil(t, resp.Error) 408 409 guestWSClient, err := th.CreateWebSocketClientWithClient(guestClient) 410 require.Nil(t, err) 411 defer guestWSClient.Close() 412 guestWSClient.Listen() 413 414 userWSClient, err := th.CreateWebSocketClient() 415 require.Nil(t, err) 416 defer userWSClient.Close() 417 userWSClient.Listen() 418 419 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 420 421 inviteId := th.BasicTeam.InviteId 422 423 _, resp = th.Client.CreateUserWithInviteId(&user, inviteId) 424 CheckNoError(t, resp) 425 CheckCreatedStatus(t, resp) 426 427 var userHasReceived bool 428 var guestHasReceived bool 429 430 func() { 431 for { 432 select { 433 case ev := <-userWSClient.EventChannel: 434 if ev.EventType() == model.WEBSOCKET_EVENT_NEW_USER { 435 userHasReceived = true 436 } 437 case ev := <-guestWSClient.EventChannel: 438 if ev.EventType() == model.WEBSOCKET_EVENT_NEW_USER { 439 guestHasReceived = true 440 } 441 case <-time.After(2 * time.Second): 442 return 443 } 444 } 445 }() 446 447 require.Truef(t, userHasReceived, "User should have received %s event", model.WEBSOCKET_EVENT_NEW_USER) 448 require.Falsef(t, guestHasReceived, "Guest should not have received %s event", model.WEBSOCKET_EVENT_NEW_USER) 449 }) 450 } 451 452 func TestCreateUserWithInviteId(t *testing.T) { 453 th := Setup(t).InitBasic() 454 defer th.TearDown() 455 456 t.Run("CreateWithInviteIdHappyPath", func(t *testing.T) { 457 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 458 459 inviteId := th.BasicTeam.InviteId 460 461 ruser, resp := th.Client.CreateUserWithInviteId(&user, inviteId) 462 CheckNoError(t, resp) 463 CheckCreatedStatus(t, resp) 464 465 th.Client.Login(user.Email, user.Password) 466 require.Equal(t, user.Nickname, ruser.Nickname) 467 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 468 CheckUserSanitization(t, ruser) 469 }) 470 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 471 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 472 473 inviteId := th.BasicTeam.InviteId 474 475 ruser, resp := client.CreateUserWithInviteId(&user, inviteId) 476 CheckNoError(t, resp) 477 CheckCreatedStatus(t, resp) 478 479 th.Client.Login(user.Email, user.Password) 480 require.Equal(t, user.Nickname, ruser.Nickname) 481 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 482 CheckUserSanitization(t, ruser) 483 }, "CreateWithInviteIdHappyPath") 484 485 t.Run("GroupConstrainedTeam", func(t *testing.T) { 486 user := model.User{Email: th.GenerateTestEmail(), Nickname: "", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 487 488 th.BasicTeam.GroupConstrained = model.NewBool(true) 489 team, err := th.App.UpdateTeam(th.BasicTeam) 490 require.Nil(t, err) 491 492 defer func() { 493 th.BasicTeam.GroupConstrained = model.NewBool(false) 494 _, err = th.App.UpdateTeam(th.BasicTeam) 495 require.Nil(t, err) 496 }() 497 498 inviteID := team.InviteId 499 500 _, resp := th.Client.CreateUserWithInviteId(&user, inviteID) 501 require.Equal(t, "app.team.invite_id.group_constrained.error", resp.Error.Id) 502 }) 503 504 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 505 user := model.User{Email: th.GenerateTestEmail(), Nickname: "", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 506 507 th.BasicTeam.GroupConstrained = model.NewBool(true) 508 team, err := th.App.UpdateTeam(th.BasicTeam) 509 require.Nil(t, err) 510 511 defer func() { 512 th.BasicTeam.GroupConstrained = model.NewBool(false) 513 _, err = th.App.UpdateTeam(th.BasicTeam) 514 require.Nil(t, err) 515 }() 516 517 inviteID := team.InviteId 518 519 _, resp := client.CreateUserWithInviteId(&user, inviteID) 520 require.Equal(t, "app.team.invite_id.group_constrained.error", resp.Error.Id) 521 }, "GroupConstrainedTeam") 522 523 t.Run("WrongInviteId", func(t *testing.T) { 524 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 525 526 inviteId := model.NewId() 527 528 _, resp := th.Client.CreateUserWithInviteId(&user, inviteId) 529 CheckNotFoundStatus(t, resp) 530 CheckErrorMessage(t, resp, "app.team.get_by_invite_id.finding.app_error") 531 }) 532 533 t.Run("NoInviteId", func(t *testing.T) { 534 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 535 536 _, resp := th.Client.CreateUserWithInviteId(&user, "") 537 CheckBadRequestStatus(t, resp) 538 CheckErrorMessage(t, resp, "api.user.create_user.missing_invite_id.app_error") 539 }) 540 541 t.Run("ExpiredInviteId", func(t *testing.T) { 542 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 543 544 inviteId := th.BasicTeam.InviteId 545 546 _, resp := th.SystemAdminClient.RegenerateTeamInviteId(th.BasicTeam.Id) 547 CheckNoError(t, resp) 548 549 _, resp = th.Client.CreateUserWithInviteId(&user, inviteId) 550 CheckNotFoundStatus(t, resp) 551 CheckErrorMessage(t, resp, "app.team.get_by_invite_id.finding.app_error") 552 }) 553 554 t.Run("EnableUserCreationDisable", func(t *testing.T) { 555 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 556 557 enableUserCreation := th.App.Config().TeamSettings.EnableUserCreation 558 defer func() { 559 th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserCreation = enableUserCreation }) 560 }() 561 562 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserCreation = false }) 563 564 inviteId := th.BasicTeam.InviteId 565 566 _, resp := th.Client.CreateUserWithInviteId(&user, inviteId) 567 CheckNotImplementedStatus(t, resp) 568 CheckErrorMessage(t, resp, "api.user.create_user.signup_email_disabled.app_error") 569 }) 570 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 571 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 572 573 enableUserCreation := th.App.Config().TeamSettings.EnableUserCreation 574 defer th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserCreation = enableUserCreation }) 575 576 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserCreation = false }) 577 578 inviteId := th.BasicTeam.InviteId 579 _, resp := client.CreateUserWithInviteId(&user, inviteId) 580 CheckNotImplementedStatus(t, resp) 581 CheckErrorMessage(t, resp, "api.user.create_user.signup_email_disabled.app_error") 582 }, "EnableUserCreationDisable") 583 584 t.Run("EnableOpenServerDisable", func(t *testing.T) { 585 user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 586 587 enableOpenServer := th.App.Config().TeamSettings.EnableOpenServer 588 defer func() { 589 th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableOpenServer = enableOpenServer }) 590 }() 591 592 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = false }) 593 594 team, res := th.SystemAdminClient.RegenerateTeamInviteId(th.BasicTeam.Id) 595 assert.Nil(t, res.Error) 596 inviteId := team.InviteId 597 598 ruser, resp := th.Client.CreateUserWithInviteId(&user, inviteId) 599 CheckNoError(t, resp) 600 CheckCreatedStatus(t, resp) 601 602 th.Client.Login(user.Email, user.Password) 603 require.Equal(t, user.Nickname, ruser.Nickname) 604 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "should clear roles") 605 CheckUserSanitization(t, ruser) 606 }) 607 } 608 609 func TestGetMe(t *testing.T) { 610 th := Setup(t).InitBasic() 611 defer th.TearDown() 612 613 ruser, resp := th.Client.GetMe("") 614 CheckNoError(t, resp) 615 616 require.Equal(t, th.BasicUser.Id, ruser.Id) 617 618 th.Client.Logout() 619 _, resp = th.Client.GetMe("") 620 CheckUnauthorizedStatus(t, resp) 621 } 622 623 func TestGetUser(t *testing.T) { 624 th := Setup(t) 625 defer th.TearDown() 626 627 user := th.CreateUser() 628 user.Props = map[string]string{"testpropkey": "testpropvalue"} 629 630 th.App.UpdateUser(user, false) 631 632 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 633 ruser, resp := client.GetUser(user.Id, "") 634 CheckNoError(t, resp) 635 CheckUserSanitization(t, ruser) 636 637 require.Equal(t, user.Email, ruser.Email) 638 639 assert.NotNil(t, ruser.Props) 640 assert.Equal(t, ruser.Props["testpropkey"], "testpropvalue") 641 require.False(t, ruser.IsBot) 642 643 ruser, resp = client.GetUser(user.Id, resp.Etag) 644 CheckEtag(t, ruser, resp) 645 646 _, resp = client.GetUser("junk", "") 647 CheckBadRequestStatus(t, resp) 648 649 _, resp = client.GetUser(model.NewId(), "") 650 CheckNotFoundStatus(t, resp) 651 }) 652 653 // Check against privacy config settings 654 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowEmailAddress = false }) 655 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 656 657 ruser, resp := th.Client.GetUser(user.Id, "") 658 CheckNoError(t, resp) 659 660 require.Empty(t, ruser.Email, "email should be blank") 661 require.Empty(t, ruser.FirstName, "first name should be blank") 662 require.Empty(t, ruser.LastName, "last name should be blank") 663 664 th.Client.Logout() 665 _, resp = th.Client.GetUser(user.Id, "") 666 CheckUnauthorizedStatus(t, resp) 667 668 // System admins should ignore privacy settings 669 ruser, _ = th.SystemAdminClient.GetUser(user.Id, resp.Etag) 670 require.NotEmpty(t, ruser.Email, "email should not be blank") 671 require.NotEmpty(t, ruser.FirstName, "first name should not be blank") 672 require.NotEmpty(t, ruser.LastName, "last name should not be blank") 673 } 674 675 func TestGetUserWithAcceptedTermsOfServiceForOtherUser(t *testing.T) { 676 th := Setup(t) 677 defer th.TearDown() 678 679 user := th.CreateUser() 680 681 tos, _ := th.App.CreateTermsOfService("Dummy TOS", user.Id) 682 683 th.App.UpdateUser(user, false) 684 685 ruser, resp := th.Client.GetUser(user.Id, "") 686 CheckNoError(t, resp) 687 CheckUserSanitization(t, ruser) 688 689 require.Equal(t, user.Email, ruser.Email) 690 691 assert.Empty(t, ruser.TermsOfServiceId) 692 693 th.App.SaveUserTermsOfService(user.Id, tos.Id, true) 694 695 ruser, resp = th.Client.GetUser(user.Id, "") 696 CheckNoError(t, resp) 697 CheckUserSanitization(t, ruser) 698 699 require.Equal(t, user.Email, ruser.Email) 700 701 // user TOS data cannot be fetched for other users by non-admin users 702 assert.Empty(t, ruser.TermsOfServiceId) 703 } 704 705 func TestGetUserWithAcceptedTermsOfService(t *testing.T) { 706 th := Setup(t).InitBasic() 707 defer th.TearDown() 708 709 user := th.BasicUser 710 711 tos, _ := th.App.CreateTermsOfService("Dummy TOS", user.Id) 712 713 ruser, resp := th.Client.GetUser(user.Id, "") 714 CheckNoError(t, resp) 715 CheckUserSanitization(t, ruser) 716 717 require.Equal(t, user.Email, ruser.Email) 718 719 assert.Empty(t, ruser.TermsOfServiceId) 720 721 th.App.SaveUserTermsOfService(user.Id, tos.Id, true) 722 723 ruser, resp = th.Client.GetUser(user.Id, "") 724 CheckNoError(t, resp) 725 CheckUserSanitization(t, ruser) 726 727 require.Equal(t, user.Email, ruser.Email) 728 729 // a user can view their own TOS details 730 assert.Equal(t, tos.Id, ruser.TermsOfServiceId) 731 } 732 733 func TestGetUserWithAcceptedTermsOfServiceWithAdminUser(t *testing.T) { 734 th := Setup(t).InitBasic() 735 th.LoginSystemAdmin() 736 defer th.TearDown() 737 738 user := th.BasicUser 739 740 tos, _ := th.App.CreateTermsOfService("Dummy TOS", user.Id) 741 742 ruser, resp := th.SystemAdminClient.GetUser(user.Id, "") 743 CheckNoError(t, resp) 744 CheckUserSanitization(t, ruser) 745 746 require.Equal(t, user.Email, ruser.Email) 747 748 assert.Empty(t, ruser.TermsOfServiceId) 749 750 th.App.SaveUserTermsOfService(user.Id, tos.Id, true) 751 752 ruser, resp = th.SystemAdminClient.GetUser(user.Id, "") 753 CheckNoError(t, resp) 754 CheckUserSanitization(t, ruser) 755 756 require.Equal(t, user.Email, ruser.Email) 757 758 // admin can view anyone's TOS details 759 assert.Equal(t, tos.Id, ruser.TermsOfServiceId) 760 } 761 762 func TestGetBotUser(t *testing.T) { 763 th := Setup(t).InitBasic() 764 defer th.TearDown() 765 766 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 767 768 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 769 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.TEAM_USER_ROLE_ID, false) 770 771 th.App.UpdateConfig(func(cfg *model.Config) { 772 *cfg.ServiceSettings.EnableBotAccountCreation = true 773 }) 774 775 bot := &model.Bot{ 776 Username: GenerateTestUsername(), 777 DisplayName: "a bot", 778 Description: "bot", 779 } 780 781 createdBot, resp := th.Client.CreateBot(bot) 782 CheckCreatedStatus(t, resp) 783 defer th.App.PermanentDeleteBot(createdBot.UserId) 784 785 botUser, resp := th.Client.GetUser(createdBot.UserId, "") 786 CheckNoError(t, resp) 787 require.Equal(t, bot.Username, botUser.Username) 788 require.True(t, botUser.IsBot) 789 } 790 791 func TestGetUserByUsername(t *testing.T) { 792 th := Setup(t).InitBasic() 793 defer th.TearDown() 794 795 user := th.BasicUser 796 797 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 798 ruser, resp := client.GetUserByUsername(user.Username, "") 799 CheckNoError(t, resp) 800 CheckUserSanitization(t, ruser) 801 802 require.Equal(t, user.Email, ruser.Email) 803 804 ruser, resp = client.GetUserByUsername(user.Username, resp.Etag) 805 CheckEtag(t, ruser, resp) 806 807 _, resp = client.GetUserByUsername(GenerateTestUsername(), "") 808 CheckNotFoundStatus(t, resp) 809 }) 810 811 // Check against privacy config settings 812 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowEmailAddress = false }) 813 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 814 815 ruser, resp := th.Client.GetUserByUsername(th.BasicUser2.Username, "") 816 CheckNoError(t, resp) 817 818 require.Empty(t, ruser.Email, "email should be blank") 819 require.Empty(t, ruser.FirstName, "first name should be blank") 820 require.Empty(t, ruser.LastName, "last name should be blank") 821 822 ruser, resp = th.Client.GetUserByUsername(th.BasicUser.Username, "") 823 CheckNoError(t, resp) 824 require.NotEmpty(t, ruser.NotifyProps, "notify props should be sent") 825 826 th.Client.Logout() 827 _, resp = th.Client.GetUserByUsername(user.Username, "") 828 CheckUnauthorizedStatus(t, resp) 829 830 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 831 // System admins should ignore privacy settings 832 ruser, _ = client.GetUserByUsername(user.Username, resp.Etag) 833 require.NotEmpty(t, ruser.Email, "email should not be blank") 834 require.NotEmpty(t, ruser.FirstName, "first name should not be blank") 835 require.NotEmpty(t, ruser.LastName, "last name should not be blank") 836 }) 837 } 838 839 func TestGetUserByUsernameWithAcceptedTermsOfService(t *testing.T) { 840 th := Setup(t).InitBasic() 841 defer th.TearDown() 842 843 user := th.BasicUser 844 845 ruser, resp := th.Client.GetUserByUsername(user.Username, "") 846 CheckNoError(t, resp) 847 CheckUserSanitization(t, ruser) 848 849 require.Equal(t, user.Email, ruser.Email) 850 851 tos, _ := th.App.CreateTermsOfService("Dummy TOS", user.Id) 852 th.App.SaveUserTermsOfService(ruser.Id, tos.Id, true) 853 854 ruser, resp = th.Client.GetUserByUsername(user.Username, "") 855 CheckNoError(t, resp) 856 CheckUserSanitization(t, ruser) 857 858 require.Equal(t, user.Email, ruser.Email) 859 860 require.Equal(t, tos.Id, ruser.TermsOfServiceId, "Terms of service ID should match") 861 } 862 863 func TestSaveUserTermsOfService(t *testing.T) { 864 th := Setup(t) 865 defer th.TearDown() 866 867 t.Run("Invalid data", func(t *testing.T) { 868 resp, err := th.Client.DoApiPost("/users/"+th.BasicUser.Id+"/terms_of_service", "{}") 869 require.NotNil(t, err) 870 assert.Equal(t, http.StatusBadRequest, resp.StatusCode) 871 }) 872 } 873 874 func TestGetUserByEmail(t *testing.T) { 875 th := Setup(t) 876 defer th.TearDown() 877 878 user := th.CreateUser() 879 userWithSlash, resp := th.SystemAdminClient.CreateUser(&model.User{ 880 Email: "email/with/slashes@example.com", 881 Username: GenerateTestUsername(), 882 Password: "Pa$$word11", 883 }) 884 require.Nil(t, resp.Error) 885 886 th.App.UpdateConfig(func(cfg *model.Config) { 887 *cfg.PrivacySettings.ShowEmailAddress = true 888 *cfg.PrivacySettings.ShowFullName = true 889 }) 890 891 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 892 t.Run("should be able to get another user by email", func(t *testing.T) { 893 ruser, resp := client.GetUserByEmail(user.Email, "") 894 CheckNoError(t, resp) 895 CheckUserSanitization(t, ruser) 896 897 require.Equal(t, user.Email, ruser.Email) 898 }) 899 900 t.Run("Get user with a / character in the email", func(t *testing.T) { 901 ruser, resp := client.GetUserByEmail(userWithSlash.Email, "") 902 require.Nil(t, resp.Error) 903 require.Equal(t, ruser.Id, userWithSlash.Id) 904 }) 905 906 t.Run("should return not modified when provided with a matching etag", func(t *testing.T) { 907 _, resp := client.GetUserByEmail(user.Email, "") 908 CheckNoError(t, resp) 909 910 ruser, resp := client.GetUserByEmail(user.Email, resp.Etag) 911 CheckEtag(t, ruser, resp) 912 }) 913 914 t.Run("should return bad request when given an invalid email", func(t *testing.T) { 915 _, resp := client.GetUserByEmail(GenerateTestUsername(), "") 916 CheckBadRequestStatus(t, resp) 917 }) 918 919 t.Run("should return 404 when given a non-existent email", func(t *testing.T) { 920 _, resp := client.GetUserByEmail(th.GenerateTestEmail(), "") 921 CheckNotFoundStatus(t, resp) 922 }) 923 }) 924 925 t.Run("should sanitize full name for non-admin based on privacy settings", func(t *testing.T) { 926 th.App.UpdateConfig(func(cfg *model.Config) { 927 *cfg.PrivacySettings.ShowEmailAddress = true 928 *cfg.PrivacySettings.ShowFullName = false 929 }) 930 931 ruser, resp := th.Client.GetUserByEmail(user.Email, "") 932 CheckNoError(t, resp) 933 assert.Equal(t, "", ruser.FirstName, "first name should be blank") 934 assert.Equal(t, "", ruser.LastName, "last name should be blank") 935 936 th.App.UpdateConfig(func(cfg *model.Config) { 937 *cfg.PrivacySettings.ShowFullName = true 938 }) 939 940 ruser, resp = th.Client.GetUserByEmail(user.Email, "") 941 CheckNoError(t, resp) 942 assert.NotEqual(t, "", ruser.FirstName, "first name should be set") 943 assert.NotEqual(t, "", ruser.LastName, "last name should be set") 944 }) 945 946 t.Run("should return forbidden for non-admin when privacy settings hide email", func(t *testing.T) { 947 th.App.UpdateConfig(func(cfg *model.Config) { 948 *cfg.PrivacySettings.ShowEmailAddress = false 949 }) 950 951 _, resp := th.Client.GetUserByEmail(user.Email, "") 952 CheckForbiddenStatus(t, resp) 953 954 th.App.UpdateConfig(func(cfg *model.Config) { 955 *cfg.PrivacySettings.ShowEmailAddress = true 956 }) 957 958 ruser, resp := th.Client.GetUserByEmail(user.Email, "") 959 CheckNoError(t, resp) 960 assert.Equal(t, user.Email, ruser.Email, "email should be set") 961 }) 962 963 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 964 t.Run("should not sanitize full name for admin, regardless of privacy settings", func(t *testing.T) { 965 th.App.UpdateConfig(func(cfg *model.Config) { 966 *cfg.PrivacySettings.ShowEmailAddress = true 967 *cfg.PrivacySettings.ShowFullName = false 968 }) 969 970 ruser, resp := client.GetUserByEmail(user.Email, "") 971 CheckNoError(t, resp) 972 assert.NotEqual(t, "", ruser.FirstName, "first name should be set") 973 assert.NotEqual(t, "", ruser.LastName, "last name should be set") 974 975 th.App.UpdateConfig(func(cfg *model.Config) { 976 *cfg.PrivacySettings.ShowFullName = true 977 }) 978 979 ruser, resp = client.GetUserByEmail(user.Email, "") 980 CheckNoError(t, resp) 981 assert.NotEqual(t, "", ruser.FirstName, "first name should be set") 982 assert.NotEqual(t, "", ruser.LastName, "last name should be set") 983 }) 984 985 t.Run("should always return email for admin, regardless of privacy settings", func(t *testing.T) { 986 th.App.UpdateConfig(func(cfg *model.Config) { 987 *cfg.PrivacySettings.ShowEmailAddress = false 988 }) 989 990 ruser, resp := client.GetUserByEmail(user.Email, "") 991 CheckNoError(t, resp) 992 assert.Equal(t, user.Email, ruser.Email, "email should be set") 993 994 th.App.UpdateConfig(func(cfg *model.Config) { 995 *cfg.PrivacySettings.ShowEmailAddress = true 996 }) 997 998 ruser, resp = client.GetUserByEmail(user.Email, "") 999 CheckNoError(t, resp) 1000 assert.Equal(t, user.Email, ruser.Email, "email should be set") 1001 }) 1002 }) 1003 } 1004 1005 func TestSearchUsers(t *testing.T) { 1006 th := Setup(t).InitBasic() 1007 defer th.TearDown() 1008 1009 search := &model.UserSearch{Term: th.BasicUser.Username} 1010 1011 users, resp := th.Client.SearchUsers(search) 1012 CheckNoError(t, resp) 1013 1014 require.True(t, findUserInList(th.BasicUser.Id, users), "should have found user") 1015 1016 _, err := th.App.UpdateActive(th.Context, th.BasicUser2, false) 1017 require.Nil(t, err) 1018 1019 search.Term = th.BasicUser2.Username 1020 search.AllowInactive = false 1021 1022 users, resp = th.Client.SearchUsers(search) 1023 CheckNoError(t, resp) 1024 1025 require.False(t, findUserInList(th.BasicUser2.Id, users), "should not have found user") 1026 1027 search.AllowInactive = true 1028 1029 users, resp = th.Client.SearchUsers(search) 1030 CheckNoError(t, resp) 1031 1032 require.True(t, findUserInList(th.BasicUser2.Id, users), "should have found user") 1033 1034 search.Term = th.BasicUser.Username 1035 search.AllowInactive = false 1036 search.TeamId = th.BasicTeam.Id 1037 1038 users, resp = th.Client.SearchUsers(search) 1039 CheckNoError(t, resp) 1040 1041 require.True(t, findUserInList(th.BasicUser.Id, users), "should have found user") 1042 1043 search.NotInChannelId = th.BasicChannel.Id 1044 1045 users, resp = th.Client.SearchUsers(search) 1046 CheckNoError(t, resp) 1047 1048 require.False(t, findUserInList(th.BasicUser.Id, users), "should not have found user") 1049 1050 search.TeamId = "" 1051 search.NotInChannelId = "" 1052 search.InChannelId = th.BasicChannel.Id 1053 1054 users, resp = th.Client.SearchUsers(search) 1055 CheckNoError(t, resp) 1056 1057 require.True(t, findUserInList(th.BasicUser.Id, users), "should have found user") 1058 1059 search.InChannelId = "" 1060 search.NotInChannelId = th.BasicChannel.Id 1061 _, resp = th.Client.SearchUsers(search) 1062 CheckBadRequestStatus(t, resp) 1063 1064 search.NotInChannelId = model.NewId() 1065 search.TeamId = model.NewId() 1066 _, resp = th.Client.SearchUsers(search) 1067 CheckForbiddenStatus(t, resp) 1068 1069 search.NotInChannelId = "" 1070 search.TeamId = model.NewId() 1071 _, resp = th.Client.SearchUsers(search) 1072 CheckForbiddenStatus(t, resp) 1073 1074 search.InChannelId = model.NewId() 1075 search.TeamId = "" 1076 _, resp = th.Client.SearchUsers(search) 1077 CheckForbiddenStatus(t, resp) 1078 1079 // Test search for users not in any team 1080 search.TeamId = "" 1081 search.NotInChannelId = "" 1082 search.InChannelId = "" 1083 search.NotInTeamId = th.BasicTeam.Id 1084 1085 users, resp = th.Client.SearchUsers(search) 1086 CheckNoError(t, resp) 1087 1088 require.False(t, findUserInList(th.BasicUser.Id, users), "should not have found user") 1089 1090 oddUser := th.CreateUser() 1091 search.Term = oddUser.Username 1092 1093 users, resp = th.Client.SearchUsers(search) 1094 CheckNoError(t, resp) 1095 1096 require.True(t, findUserInList(oddUser.Id, users), "should have found user") 1097 1098 _, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, oddUser.Id) 1099 CheckNoError(t, resp) 1100 1101 users, resp = th.Client.SearchUsers(search) 1102 CheckNoError(t, resp) 1103 1104 require.False(t, findUserInList(oddUser.Id, users), "should not have found user") 1105 1106 search.NotInTeamId = model.NewId() 1107 _, resp = th.Client.SearchUsers(search) 1108 CheckForbiddenStatus(t, resp) 1109 1110 search.Term = th.BasicUser.Username 1111 1112 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowEmailAddress = false }) 1113 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 1114 1115 _, err = th.App.UpdateActive(th.Context, th.BasicUser2, true) 1116 require.Nil(t, err) 1117 1118 search.InChannelId = "" 1119 search.NotInTeamId = "" 1120 search.Term = th.BasicUser2.Email 1121 users, resp = th.Client.SearchUsers(search) 1122 CheckNoError(t, resp) 1123 1124 require.False(t, findUserInList(th.BasicUser2.Id, users), "should not have found user") 1125 1126 search.Term = th.BasicUser2.FirstName 1127 users, resp = th.Client.SearchUsers(search) 1128 CheckNoError(t, resp) 1129 1130 require.False(t, findUserInList(th.BasicUser2.Id, users), "should not have found user") 1131 1132 search.Term = th.BasicUser2.LastName 1133 users, resp = th.Client.SearchUsers(search) 1134 CheckNoError(t, resp) 1135 1136 require.False(t, findUserInList(th.BasicUser2.Id, users), "should not have found user") 1137 1138 search.Term = th.BasicUser.FirstName 1139 search.InChannelId = th.BasicChannel.Id 1140 search.NotInChannelId = th.BasicChannel.Id 1141 search.TeamId = th.BasicTeam.Id 1142 users, resp = th.SystemAdminClient.SearchUsers(search) 1143 CheckNoError(t, resp) 1144 1145 require.True(t, findUserInList(th.BasicUser.Id, users), "should have found user") 1146 1147 id := model.NewId() 1148 group, err := th.App.CreateGroup(&model.Group{ 1149 DisplayName: "dn-foo_" + id, 1150 Name: model.NewString("name" + id), 1151 Source: model.GroupSourceLdap, 1152 Description: "description_" + id, 1153 RemoteId: model.NewId(), 1154 }) 1155 assert.Nil(t, err) 1156 1157 search = &model.UserSearch{Term: th.BasicUser.Username, InGroupId: group.Id} 1158 t.Run("Requires ldap license when searching in group", func(t *testing.T) { 1159 _, resp = th.SystemAdminClient.SearchUsers(search) 1160 CheckNotImplementedStatus(t, resp) 1161 }) 1162 1163 th.App.Srv().SetLicense(model.NewTestLicense("ldap")) 1164 1165 t.Run("Requires manage system permission when searching for users in a group", func(t *testing.T) { 1166 _, resp = th.Client.SearchUsers(search) 1167 CheckForbiddenStatus(t, resp) 1168 }) 1169 1170 t.Run("Returns empty list when no users found searching for users in a group", func(t *testing.T) { 1171 users, resp = th.SystemAdminClient.SearchUsers(search) 1172 CheckNoError(t, resp) 1173 require.Empty(t, users) 1174 }) 1175 1176 _, err = th.App.UpsertGroupMember(group.Id, th.BasicUser.Id) 1177 assert.Nil(t, err) 1178 1179 t.Run("Returns user in group user found in group", func(t *testing.T) { 1180 users, resp = th.SystemAdminClient.SearchUsers(search) 1181 CheckNoError(t, resp) 1182 require.Equal(t, users[0].Id, th.BasicUser.Id) 1183 }) 1184 } 1185 1186 func findUserInList(id string, users []*model.User) bool { 1187 for _, user := range users { 1188 if user.Id == id { 1189 return true 1190 } 1191 } 1192 return false 1193 } 1194 1195 func TestAutocompleteUsersInChannel(t *testing.T) { 1196 th := Setup(t).InitBasic() 1197 defer th.TearDown() 1198 teamId := th.BasicTeam.Id 1199 channelId := th.BasicChannel.Id 1200 username := th.BasicUser.Username 1201 newUser := th.CreateUser() 1202 1203 tt := []struct { 1204 Name string 1205 TeamId string 1206 ChannelId string 1207 Username string 1208 ExpectedResults int 1209 MoreThan bool 1210 ShouldFail bool 1211 }{ 1212 { 1213 "Autocomplete in channel for specific username", 1214 teamId, 1215 channelId, 1216 username, 1217 1, 1218 false, 1219 false, 1220 }, 1221 { 1222 "Search for not valid username", 1223 teamId, 1224 channelId, 1225 "amazonses", 1226 0, 1227 false, 1228 false, 1229 }, 1230 { 1231 "Search for all users", 1232 teamId, 1233 channelId, 1234 "", 1235 2, 1236 true, 1237 false, 1238 }, 1239 { 1240 "Fail when the teamId is not provided", 1241 "", 1242 channelId, 1243 "", 1244 2, 1245 true, 1246 true, 1247 }, 1248 } 1249 1250 for _, tc := range tt { 1251 t.Run(tc.Name, func(t *testing.T) { 1252 th.LoginBasic() 1253 rusers, resp := th.Client.AutocompleteUsersInChannel(tc.TeamId, tc.ChannelId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1254 if tc.ShouldFail { 1255 CheckErrorMessage(t, resp, "api.user.autocomplete_users.missing_team_id.app_error") 1256 } else { 1257 CheckNoError(t, resp) 1258 if tc.MoreThan { 1259 assert.True(t, len(rusers.Users) >= tc.ExpectedResults) 1260 } else { 1261 assert.Len(t, rusers.Users, tc.ExpectedResults) 1262 } 1263 } 1264 1265 th.Client.Logout() 1266 _, resp = th.Client.AutocompleteUsersInChannel(tc.TeamId, tc.ChannelId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1267 CheckUnauthorizedStatus(t, resp) 1268 1269 th.Client.Login(newUser.Email, newUser.Password) 1270 _, resp = th.Client.AutocompleteUsersInChannel(tc.TeamId, tc.ChannelId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1271 CheckForbiddenStatus(t, resp) 1272 }) 1273 } 1274 1275 t.Run("Check against privacy config settings", func(t *testing.T) { 1276 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 1277 1278 th.LoginBasic() 1279 rusers, resp := th.Client.AutocompleteUsersInChannel(teamId, channelId, username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1280 CheckNoError(t, resp) 1281 1282 assert.Equal(t, rusers.Users[0].FirstName, "", "should not show first/last name") 1283 assert.Equal(t, rusers.Users[0].LastName, "", "should not show first/last name") 1284 }) 1285 1286 t.Run("Check OutOfChannel results with/without VIEW_MEMBERS permissions", func(t *testing.T) { 1287 permissionsUser := th.CreateUser() 1288 th.SystemAdminClient.DemoteUserToGuest(permissionsUser.Id) 1289 permissionsUser.Roles = "system_guest" 1290 th.LinkUserToTeam(permissionsUser, th.BasicTeam) 1291 th.AddUserToChannel(permissionsUser, th.BasicChannel) 1292 1293 otherUser := th.CreateUser() 1294 th.LinkUserToTeam(otherUser, th.BasicTeam) 1295 1296 th.Client.Login(permissionsUser.Email, permissionsUser.Password) 1297 1298 rusers, resp := th.Client.AutocompleteUsersInChannel(teamId, channelId, "", model.USER_SEARCH_DEFAULT_LIMIT, "") 1299 CheckNoError(t, resp) 1300 assert.Len(t, rusers.OutOfChannel, 1) 1301 1302 defaultRolePermissions := th.SaveDefaultRolePermissions() 1303 defer func() { 1304 th.RestoreDefaultRolePermissions(defaultRolePermissions) 1305 }() 1306 1307 th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.SYSTEM_USER_ROLE_ID) 1308 th.RemovePermissionFromRole(model.PERMISSION_VIEW_MEMBERS.Id, model.TEAM_USER_ROLE_ID) 1309 1310 rusers, resp = th.Client.AutocompleteUsersInChannel(teamId, channelId, "", model.USER_SEARCH_DEFAULT_LIMIT, "") 1311 CheckNoError(t, resp) 1312 assert.Empty(t, rusers.OutOfChannel) 1313 1314 th.App.GetOrCreateDirectChannel(th.Context, permissionsUser.Id, otherUser.Id) 1315 1316 rusers, resp = th.Client.AutocompleteUsersInChannel(teamId, channelId, "", model.USER_SEARCH_DEFAULT_LIMIT, "") 1317 CheckNoError(t, resp) 1318 assert.Len(t, rusers.OutOfChannel, 1) 1319 }) 1320 1321 t.Run("user must have access to team id, especially when it does not match channel's team id", func(t *testing.T) { 1322 _, resp := th.Client.AutocompleteUsersInChannel("otherTeamId", channelId, username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1323 CheckErrorMessage(t, resp, "api.context.permissions.app_error") 1324 }) 1325 } 1326 1327 func TestAutocompleteUsersInTeam(t *testing.T) { 1328 th := Setup(t).InitBasic() 1329 defer th.TearDown() 1330 teamId := th.BasicTeam.Id 1331 username := th.BasicUser.Username 1332 newUser := th.CreateUser() 1333 1334 tt := []struct { 1335 Name string 1336 TeamId string 1337 Username string 1338 ExpectedResults int 1339 MoreThan bool 1340 }{ 1341 { 1342 "specific username", 1343 teamId, 1344 username, 1345 1, 1346 false, 1347 }, 1348 { 1349 "not valid username", 1350 teamId, 1351 "amazonses", 1352 0, 1353 false, 1354 }, 1355 { 1356 "all users in team", 1357 teamId, 1358 "", 1359 2, 1360 true, 1361 }, 1362 } 1363 1364 for _, tc := range tt { 1365 t.Run(tc.Name, func(t *testing.T) { 1366 th.LoginBasic() 1367 rusers, resp := th.Client.AutocompleteUsersInTeam(tc.TeamId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1368 CheckNoError(t, resp) 1369 if tc.MoreThan { 1370 assert.True(t, len(rusers.Users) >= tc.ExpectedResults) 1371 } else { 1372 assert.Len(t, rusers.Users, tc.ExpectedResults) 1373 } 1374 th.Client.Logout() 1375 _, resp = th.Client.AutocompleteUsersInTeam(tc.TeamId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1376 CheckUnauthorizedStatus(t, resp) 1377 1378 th.Client.Login(newUser.Email, newUser.Password) 1379 _, resp = th.Client.AutocompleteUsersInTeam(tc.TeamId, tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1380 CheckForbiddenStatus(t, resp) 1381 }) 1382 } 1383 1384 t.Run("Check against privacy config settings", func(t *testing.T) { 1385 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 1386 1387 th.LoginBasic() 1388 rusers, resp := th.Client.AutocompleteUsersInTeam(teamId, username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1389 CheckNoError(t, resp) 1390 1391 assert.Equal(t, rusers.Users[0].FirstName, "", "should not show first/last name") 1392 assert.Equal(t, rusers.Users[0].LastName, "", "should not show first/last name") 1393 }) 1394 } 1395 1396 func TestAutocompleteUsers(t *testing.T) { 1397 th := Setup(t).InitBasic() 1398 defer th.TearDown() 1399 username := th.BasicUser.Username 1400 newUser := th.CreateUser() 1401 1402 tt := []struct { 1403 Name string 1404 Username string 1405 ExpectedResults int 1406 MoreThan bool 1407 }{ 1408 { 1409 "specific username", 1410 username, 1411 1, 1412 false, 1413 }, 1414 { 1415 "not valid username", 1416 "amazonses", 1417 0, 1418 false, 1419 }, 1420 { 1421 "all users in team", 1422 "", 1423 2, 1424 true, 1425 }, 1426 } 1427 1428 for _, tc := range tt { 1429 t.Run(tc.Name, func(t *testing.T) { 1430 th.LoginBasic() 1431 rusers, resp := th.Client.AutocompleteUsers(tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1432 CheckNoError(t, resp) 1433 if tc.MoreThan { 1434 assert.True(t, len(rusers.Users) >= tc.ExpectedResults) 1435 } else { 1436 assert.Len(t, rusers.Users, tc.ExpectedResults) 1437 } 1438 1439 th.Client.Logout() 1440 _, resp = th.Client.AutocompleteUsers(tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1441 CheckUnauthorizedStatus(t, resp) 1442 1443 th.Client.Login(newUser.Email, newUser.Password) 1444 _, resp = th.Client.AutocompleteUsers(tc.Username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1445 CheckNoError(t, resp) 1446 }) 1447 } 1448 1449 t.Run("Check against privacy config settings", func(t *testing.T) { 1450 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowFullName = false }) 1451 1452 th.LoginBasic() 1453 rusers, resp := th.Client.AutocompleteUsers(username, model.USER_SEARCH_DEFAULT_LIMIT, "") 1454 CheckNoError(t, resp) 1455 1456 assert.Equal(t, rusers.Users[0].FirstName, "", "should not show first/last name") 1457 assert.Equal(t, rusers.Users[0].LastName, "", "should not show first/last name") 1458 }) 1459 } 1460 1461 func TestGetProfileImage(t *testing.T) { 1462 th := Setup(t).InitBasic() 1463 defer th.TearDown() 1464 1465 // recreate basic user 1466 th.BasicUser = th.CreateUser() 1467 th.LoginBasic() 1468 user := th.BasicUser 1469 1470 data, resp := th.Client.GetProfileImage(user.Id, "") 1471 CheckNoError(t, resp) 1472 require.NotEmpty(t, data, "should not be empty") 1473 1474 _, resp = th.Client.GetProfileImage(user.Id, resp.Etag) 1475 require.NotEqual(t, http.StatusNotModified, resp.StatusCode, "should not hit etag") 1476 1477 _, resp = th.Client.GetProfileImage("junk", "") 1478 CheckBadRequestStatus(t, resp) 1479 1480 _, resp = th.Client.GetProfileImage(model.NewId(), "") 1481 CheckNotFoundStatus(t, resp) 1482 1483 th.Client.Logout() 1484 _, resp = th.Client.GetProfileImage(user.Id, "") 1485 CheckUnauthorizedStatus(t, resp) 1486 1487 _, resp = th.SystemAdminClient.GetProfileImage(user.Id, "") 1488 CheckNoError(t, resp) 1489 1490 info := &model.FileInfo{Path: "/users/" + user.Id + "/profile.png"} 1491 err := th.cleanupTestFile(info) 1492 require.NoError(t, err) 1493 } 1494 1495 func TestGetUsersByIds(t *testing.T) { 1496 th := Setup(t).InitBasic() 1497 defer th.TearDown() 1498 1499 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 1500 t.Run("should return the user", func(t *testing.T) { 1501 users, resp := client.GetUsersByIds([]string{th.BasicUser.Id}) 1502 1503 CheckNoError(t, resp) 1504 1505 assert.Equal(t, th.BasicUser.Id, users[0].Id) 1506 CheckUserSanitization(t, users[0]) 1507 }) 1508 1509 t.Run("should return error when no IDs are specified", func(t *testing.T) { 1510 _, resp := client.GetUsersByIds([]string{}) 1511 1512 CheckBadRequestStatus(t, resp) 1513 }) 1514 1515 t.Run("should not return an error for invalid IDs", func(t *testing.T) { 1516 users, resp := client.GetUsersByIds([]string{"junk"}) 1517 1518 CheckNoError(t, resp) 1519 require.Empty(t, users, "no users should be returned") 1520 }) 1521 1522 t.Run("should still return users for valid IDs when invalid IDs are specified", func(t *testing.T) { 1523 users, resp := client.GetUsersByIds([]string{"junk", th.BasicUser.Id}) 1524 1525 CheckNoError(t, resp) 1526 1527 require.Len(t, users, 1, "1 user should be returned") 1528 }) 1529 }) 1530 1531 t.Run("should return error when not logged in", func(t *testing.T) { 1532 th.Client.Logout() 1533 1534 _, resp := th.Client.GetUsersByIds([]string{th.BasicUser.Id}) 1535 CheckUnauthorizedStatus(t, resp) 1536 }) 1537 } 1538 1539 func TestGetUsersByIdsWithOptions(t *testing.T) { 1540 t.Run("should only return specified users that have been updated since the given time", func(t *testing.T) { 1541 th := Setup(t) 1542 defer th.TearDown() 1543 1544 // Users before the timestamp shouldn't be returned 1545 user1, err := th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Username: model.NewId(), Password: model.NewId()}) 1546 require.Nil(t, err) 1547 1548 user2, err := th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Username: model.NewId(), Password: model.NewId()}) 1549 require.Nil(t, err) 1550 1551 // Users not in the list of IDs shouldn't be returned 1552 _, err = th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Username: model.NewId(), Password: model.NewId()}) 1553 require.Nil(t, err) 1554 1555 users, resp := th.Client.GetUsersByIdsWithOptions([]string{user1.Id, user2.Id}, &model.UserGetByIdsOptions{ 1556 Since: user2.UpdateAt - 1, 1557 }) 1558 1559 assert.Nil(t, resp.Error) 1560 assert.Len(t, users, 1) 1561 assert.Equal(t, users[0].Id, user2.Id) 1562 }) 1563 } 1564 1565 func TestGetUsersByGroupChannelIds(t *testing.T) { 1566 th := Setup(t).InitBasic() 1567 defer th.TearDown() 1568 1569 gc1, err := th.App.CreateGroupChannel([]string{th.BasicUser.Id, th.SystemAdminUser.Id, th.TeamAdminUser.Id}, th.BasicUser.Id) 1570 require.Nil(t, err) 1571 1572 usersByChannelId, resp := th.Client.GetUsersByGroupChannelIds([]string{gc1.Id}) 1573 CheckNoError(t, resp) 1574 1575 users, ok := usersByChannelId[gc1.Id] 1576 assert.True(t, ok) 1577 userIds := []string{} 1578 for _, user := range users { 1579 userIds = append(userIds, user.Id) 1580 } 1581 1582 require.ElementsMatch(t, []string{th.SystemAdminUser.Id, th.TeamAdminUser.Id}, userIds) 1583 1584 th.LoginBasic2() 1585 usersByChannelId, resp = th.Client.GetUsersByGroupChannelIds([]string{gc1.Id}) 1586 CheckNoError(t, resp) 1587 1588 _, ok = usersByChannelId[gc1.Id] 1589 require.False(t, ok) 1590 1591 th.Client.Logout() 1592 _, resp = th.Client.GetUsersByGroupChannelIds([]string{gc1.Id}) 1593 CheckUnauthorizedStatus(t, resp) 1594 } 1595 1596 func TestGetUsersByUsernames(t *testing.T) { 1597 th := Setup(t).InitBasic() 1598 defer th.TearDown() 1599 1600 users, resp := th.Client.GetUsersByUsernames([]string{th.BasicUser.Username}) 1601 CheckNoError(t, resp) 1602 1603 require.Equal(t, th.BasicUser.Id, users[0].Id) 1604 CheckUserSanitization(t, users[0]) 1605 1606 _, resp = th.Client.GetUsersByIds([]string{}) 1607 CheckBadRequestStatus(t, resp) 1608 1609 users, resp = th.Client.GetUsersByUsernames([]string{"junk"}) 1610 CheckNoError(t, resp) 1611 require.Empty(t, users, "no users should be returned") 1612 1613 users, resp = th.Client.GetUsersByUsernames([]string{"junk", th.BasicUser.Username}) 1614 CheckNoError(t, resp) 1615 require.Len(t, users, 1, "1 user should be returned") 1616 1617 th.Client.Logout() 1618 _, resp = th.Client.GetUsersByUsernames([]string{th.BasicUser.Username}) 1619 CheckUnauthorizedStatus(t, resp) 1620 } 1621 1622 func TestGetTotalUsersStat(t *testing.T) { 1623 th := Setup(t) 1624 defer th.TearDown() 1625 1626 total, _ := th.Server.Store.User().Count(model.UserCountOptions{ 1627 IncludeDeleted: false, 1628 IncludeBotAccounts: true, 1629 }) 1630 1631 rstats, resp := th.Client.GetTotalUsersStats("") 1632 CheckNoError(t, resp) 1633 1634 require.Equal(t, total, rstats.TotalUsersCount) 1635 } 1636 1637 func TestUpdateUser(t *testing.T) { 1638 th := Setup(t) 1639 defer th.TearDown() 1640 1641 user := th.CreateUser() 1642 th.Client.Login(user.Email, user.Password) 1643 1644 user.Nickname = "Joram Wilander" 1645 user.Roles = model.SYSTEM_USER_ROLE_ID 1646 user.LastPasswordUpdate = 123 1647 1648 ruser, resp := th.Client.UpdateUser(user) 1649 CheckNoError(t, resp) 1650 CheckUserSanitization(t, ruser) 1651 1652 require.Equal(t, "Joram Wilander", ruser.Nickname, "Nickname should update properly") 1653 require.Equal(t, model.SYSTEM_USER_ROLE_ID, ruser.Roles, "Roles should not update") 1654 require.NotEqual(t, 123, ruser.LastPasswordUpdate, "LastPasswordUpdate should not update") 1655 1656 ruser.Email = th.GenerateTestEmail() 1657 _, resp = th.Client.UpdateUser(ruser) 1658 CheckBadRequestStatus(t, resp) 1659 1660 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 1661 ruser.Email = th.GenerateTestEmail() 1662 _, resp = client.UpdateUser(user) 1663 CheckNoError(t, resp) 1664 }) 1665 1666 ruser.Password = user.Password 1667 ruser, resp = th.Client.UpdateUser(ruser) 1668 CheckNoError(t, resp) 1669 CheckUserSanitization(t, ruser) 1670 1671 ruser.Id = "junk" 1672 _, resp = th.Client.UpdateUser(ruser) 1673 CheckBadRequestStatus(t, resp) 1674 1675 ruser.Id = model.NewId() 1676 _, resp = th.Client.UpdateUser(ruser) 1677 CheckForbiddenStatus(t, resp) 1678 1679 r, err := th.Client.DoApiPut("/users/"+ruser.Id, "garbage") 1680 require.NotNil(t, err) 1681 require.Equal(t, http.StatusBadRequest, r.StatusCode) 1682 1683 session, _ := th.App.GetSession(th.Client.AuthToken) 1684 session.IsOAuth = true 1685 th.App.AddSessionToCache(session) 1686 1687 ruser.Id = user.Id 1688 ruser.Email = th.GenerateTestEmail() 1689 _, resp = th.Client.UpdateUser(ruser) 1690 CheckForbiddenStatus(t, resp) 1691 1692 th.Client.Logout() 1693 _, resp = th.Client.UpdateUser(user) 1694 CheckUnauthorizedStatus(t, resp) 1695 1696 th.LoginBasic() 1697 _, resp = th.Client.UpdateUser(user) 1698 CheckForbiddenStatus(t, resp) 1699 1700 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 1701 _, resp = client.UpdateUser(user) 1702 CheckNoError(t, resp) 1703 }) 1704 } 1705 1706 func TestPatchUser(t *testing.T) { 1707 th := Setup(t).InitBasic() 1708 defer th.TearDown() 1709 1710 user := th.CreateUser() 1711 th.Client.Login(user.Email, user.Password) 1712 1713 t.Run("Timezone limit error", func(t *testing.T) { 1714 patch := &model.UserPatch{} 1715 patch.Timezone = model.StringMap{} 1716 patch.Timezone["manualTimezone"] = string(make([]byte, model.USER_TIMEZONE_MAX_RUNES)) 1717 ruser, resp := th.Client.PatchUser(user.Id, patch) 1718 CheckBadRequestStatus(t, resp) 1719 require.Equal(t, "model.user.is_valid.timezone_limit.app_error", resp.Error.Id) 1720 require.Nil(t, ruser) 1721 }) 1722 1723 patch := &model.UserPatch{} 1724 patch.Password = model.NewString("testpassword") 1725 patch.Nickname = model.NewString("Joram Wilander") 1726 patch.FirstName = model.NewString("Joram") 1727 patch.LastName = model.NewString("Wilander") 1728 patch.Position = new(string) 1729 patch.NotifyProps = model.StringMap{} 1730 patch.NotifyProps["comment"] = "somethingrandom" 1731 patch.Timezone = model.StringMap{} 1732 patch.Timezone["useAutomaticTimezone"] = "true" 1733 patch.Timezone["automaticTimezone"] = "America/New_York" 1734 patch.Timezone["manualTimezone"] = "" 1735 1736 ruser, resp := th.Client.PatchUser(user.Id, patch) 1737 CheckNoError(t, resp) 1738 CheckUserSanitization(t, ruser) 1739 1740 require.Equal(t, "Joram Wilander", ruser.Nickname, "Nickname should update properly") 1741 require.Equal(t, "Joram", ruser.FirstName, "FirstName should update properly") 1742 require.Equal(t, "Wilander", ruser.LastName, "LastName should update properly") 1743 require.Empty(t, ruser.Position, "Position should update properly") 1744 require.Equal(t, user.Username, ruser.Username, "Username should not update") 1745 require.Empty(t, ruser.Password, "Password should not be returned") 1746 require.Equal(t, "somethingrandom", ruser.NotifyProps["comment"], "NotifyProps should update properly") 1747 require.Equal(t, "true", ruser.Timezone["useAutomaticTimezone"], "useAutomaticTimezone should update properly") 1748 require.Equal(t, "America/New_York", ruser.Timezone["automaticTimezone"], "automaticTimezone should update properly") 1749 require.Empty(t, ruser.Timezone["manualTimezone"], "manualTimezone should update properly") 1750 1751 err := th.App.CheckPasswordAndAllCriteria(ruser, *patch.Password, "") 1752 require.NotNil(t, err, "Password should not match") 1753 1754 currentPassword := user.Password 1755 user, err = th.App.GetUser(ruser.Id) 1756 require.Nil(t, err) 1757 1758 err = th.App.CheckPasswordAndAllCriteria(user, currentPassword, "") 1759 require.Nil(t, err, "Password should still match") 1760 1761 patch = &model.UserPatch{} 1762 patch.Email = model.NewString(th.GenerateTestEmail()) 1763 1764 _, resp = th.Client.PatchUser(user.Id, patch) 1765 CheckBadRequestStatus(t, resp) 1766 1767 patch.Password = model.NewString(currentPassword) 1768 ruser, resp = th.Client.PatchUser(user.Id, patch) 1769 CheckNoError(t, resp) 1770 1771 require.Equal(t, *patch.Email, ruser.Email, "Email should update properly") 1772 1773 patch.Username = model.NewString(th.BasicUser2.Username) 1774 _, resp = th.Client.PatchUser(user.Id, patch) 1775 CheckBadRequestStatus(t, resp) 1776 1777 patch.Username = nil 1778 1779 _, resp = th.Client.PatchUser("junk", patch) 1780 CheckBadRequestStatus(t, resp) 1781 1782 ruser.Id = model.NewId() 1783 _, resp = th.Client.PatchUser(model.NewId(), patch) 1784 CheckForbiddenStatus(t, resp) 1785 1786 r, err := th.Client.DoApiPut("/users/"+user.Id+"/patch", "garbage") 1787 require.NotNil(t, err) 1788 require.Equal(t, http.StatusBadRequest, r.StatusCode) 1789 1790 session, _ := th.App.GetSession(th.Client.AuthToken) 1791 session.IsOAuth = true 1792 th.App.AddSessionToCache(session) 1793 1794 patch.Email = model.NewString(th.GenerateTestEmail()) 1795 _, resp = th.Client.PatchUser(user.Id, patch) 1796 CheckForbiddenStatus(t, resp) 1797 1798 th.Client.Logout() 1799 _, resp = th.Client.PatchUser(user.Id, patch) 1800 CheckUnauthorizedStatus(t, resp) 1801 1802 th.LoginBasic() 1803 _, resp = th.Client.PatchUser(user.Id, patch) 1804 CheckForbiddenStatus(t, resp) 1805 1806 _, resp = th.SystemAdminClient.PatchUser(user.Id, patch) 1807 CheckNoError(t, resp) 1808 } 1809 1810 func TestUserUnicodeNames(t *testing.T) { 1811 th := Setup(t) 1812 defer th.TearDown() 1813 Client := th.Client 1814 1815 t.Run("create user unicode", func(t *testing.T) { 1816 user := model.User{ 1817 Email: th.GenerateTestEmail(), 1818 FirstName: "Andrew\u202e", 1819 LastName: "\ufeffWiggin", 1820 Nickname: "Ender\u2028 Wiggin", 1821 Password: "hello1", 1822 Username: "\ufeffwiggin77", 1823 Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 1824 1825 ruser, resp := Client.CreateUser(&user) 1826 CheckNoError(t, resp) 1827 CheckCreatedStatus(t, resp) 1828 1829 _, _ = Client.Login(user.Email, user.Password) 1830 1831 require.Equal(t, "wiggin77", ruser.Username, "Bad Unicode not filtered from username") 1832 require.Equal(t, "Andrew Wiggin", ruser.GetDisplayName(model.SHOW_FULLNAME), "Bad Unicode not filtered from displayname") 1833 require.Equal(t, "Ender Wiggin", ruser.Nickname, "Bad Unicode not filtered from nickname") 1834 }) 1835 1836 t.Run("update user unicode", func(t *testing.T) { 1837 user := th.CreateUser() 1838 Client.Login(user.Email, user.Password) 1839 1840 user.Username = "wiggin\ufff9" 1841 user.Nickname = "Ender\u0340 \ufffcWiggin" 1842 user.FirstName = "Andrew\ufff9" 1843 user.LastName = "Wig\u206fgin" 1844 1845 ruser, resp := Client.UpdateUser(user) 1846 CheckNoError(t, resp) 1847 1848 require.Equal(t, "wiggin", ruser.Username, "bad unicode should be filtered from username") 1849 require.Equal(t, "Ender Wiggin", ruser.Nickname, "bad unicode should be filtered from nickname") 1850 require.Equal(t, "Andrew Wiggin", ruser.GetDisplayName(model.SHOW_FULLNAME), "bad unicode should be filtered from display name") 1851 }) 1852 1853 t.Run("patch user unicode", func(t *testing.T) { 1854 user := th.CreateUser() 1855 Client.Login(user.Email, user.Password) 1856 1857 patch := &model.UserPatch{} 1858 patch.Nickname = model.NewString("\U000E0000Ender\u206d Wiggin\U000E007F") 1859 patch.FirstName = model.NewString("\U0001d173Andrew\U0001d17a") 1860 patch.LastName = model.NewString("\u2028Wiggin\u2029") 1861 1862 ruser, resp := Client.PatchUser(user.Id, patch) 1863 CheckNoError(t, resp) 1864 CheckUserSanitization(t, ruser) 1865 1866 require.Equal(t, "Ender Wiggin", ruser.Nickname, "Bad unicode should be filtered from nickname") 1867 require.Equal(t, "Andrew", ruser.FirstName, "Bad unicode should be filtered from first name") 1868 require.Equal(t, "Wiggin", ruser.LastName, "Bad unicode should be filtered from last name") 1869 require.Equal(t, "Andrew Wiggin", ruser.GetDisplayName(model.SHOW_FULLNAME), "Bad unicode should be filtered from display name") 1870 }) 1871 } 1872 1873 func TestUpdateUserAuth(t *testing.T) { 1874 th := Setup(t) 1875 defer th.TearDown() 1876 1877 team := th.CreateTeamWithClient(th.SystemAdminClient) 1878 1879 user := th.CreateUser() 1880 1881 th.LinkUserToTeam(user, team) 1882 _, err := th.App.Srv().Store.User().VerifyEmail(user.Id, user.Email) 1883 require.NoError(t, err) 1884 1885 userAuth := &model.UserAuth{} 1886 userAuth.AuthData = user.AuthData 1887 userAuth.AuthService = user.AuthService 1888 userAuth.Password = user.Password 1889 1890 // Regular user can not use endpoint 1891 _, respErr := th.SystemAdminClient.UpdateUserAuth(user.Id, userAuth) 1892 require.NotNil(t, respErr, "Shouldn't have permissions. Only Admins") 1893 1894 userAuth.AuthData = model.NewString("test@test.com") 1895 userAuth.AuthService = model.USER_AUTH_SERVICE_SAML 1896 userAuth.Password = "newpassword" 1897 ruser, resp := th.SystemAdminClient.UpdateUserAuth(user.Id, userAuth) 1898 CheckNoError(t, resp) 1899 1900 // AuthData and AuthService are set, password is set to empty 1901 require.Equal(t, *userAuth.AuthData, *ruser.AuthData) 1902 require.Equal(t, model.USER_AUTH_SERVICE_SAML, ruser.AuthService) 1903 require.Empty(t, ruser.Password) 1904 1905 // When AuthData or AuthService are empty, password must be valid 1906 userAuth.AuthData = user.AuthData 1907 userAuth.AuthService = "" 1908 userAuth.Password = "1" 1909 _, respErr = th.SystemAdminClient.UpdateUserAuth(user.Id, userAuth) 1910 require.NotNil(t, respErr) 1911 1912 // Regular user can not use endpoint 1913 user2 := th.CreateUser() 1914 th.LinkUserToTeam(user2, team) 1915 _, err = th.App.Srv().Store.User().VerifyEmail(user2.Id, user2.Email) 1916 require.NoError(t, err) 1917 1918 th.SystemAdminClient.Login(user2.Email, "passwd1") 1919 1920 userAuth.AuthData = user.AuthData 1921 userAuth.AuthService = user.AuthService 1922 userAuth.Password = user.Password 1923 _, respErr = th.SystemAdminClient.UpdateUserAuth(user.Id, userAuth) 1924 require.NotNil(t, respErr, "Should have errored") 1925 } 1926 1927 func TestDeleteUser(t *testing.T) { 1928 th := Setup(t).InitBasic() 1929 defer th.TearDown() 1930 1931 th.LoginBasic() 1932 _, resp := th.Client.DeleteUser(th.SystemAdminUser.Id) 1933 CheckForbiddenStatus(t, resp) 1934 1935 th.Client.Logout() 1936 _, resp = th.Client.DeleteUser(th.BasicUser.Id) 1937 CheckUnauthorizedStatus(t, resp) 1938 1939 th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { 1940 _, resp = c.DeleteUser(model.NewId()) 1941 CheckNotFoundStatus(t, resp) 1942 1943 _, resp = c.DeleteUser("junk") 1944 CheckBadRequestStatus(t, resp) 1945 1946 userToDelete := th.CreateUser() 1947 _, resp = c.DeleteUser(userToDelete.Id) 1948 CheckNoError(t, resp) 1949 }) 1950 1951 selfDeleteUser := th.CreateUser() 1952 th.LoginBasic() 1953 _, resp = th.Client.DeleteUser(selfDeleteUser.Id) 1954 CheckForbiddenStatus(t, resp) 1955 1956 th.Client.Login(selfDeleteUser.Email, selfDeleteUser.Password) 1957 th.App.UpdateConfig(func(c *model.Config) { 1958 *c.TeamSettings.EnableUserDeactivation = false 1959 }) 1960 _, resp = th.Client.DeleteUser(selfDeleteUser.Id) 1961 CheckUnauthorizedStatus(t, resp) 1962 1963 th.App.UpdateConfig(func(c *model.Config) { 1964 *c.TeamSettings.EnableUserDeactivation = true 1965 }) 1966 _, resp = th.Client.DeleteUser(selfDeleteUser.Id) 1967 CheckNoError(t, resp) 1968 } 1969 1970 func TestPermanentDeleteUser(t *testing.T) { 1971 th := Setup(t).InitBasic() 1972 defer th.TearDown() 1973 1974 enableAPIUserDeletion := *th.App.Config().ServiceSettings.EnableAPIUserDeletion 1975 defer func() { 1976 th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableAPIUserDeletion = &enableAPIUserDeletion }) 1977 }() 1978 1979 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableAPIUserDeletion = false }) 1980 1981 userToDelete := th.CreateUser() 1982 1983 t.Run("Permanent deletion not available through API if EnableAPIUserDeletion is not set", func(t *testing.T) { 1984 _, resp := th.SystemAdminClient.PermanentDeleteUser(userToDelete.Id) 1985 CheckUnauthorizedStatus(t, resp) 1986 }) 1987 1988 t.Run("Permanent deletion available through local mode even if EnableAPIUserDeletion is not set", func(t *testing.T) { 1989 ok, resp := th.LocalClient.PermanentDeleteUser(userToDelete.Id) 1990 CheckNoError(t, resp) 1991 assert.True(t, ok) 1992 }) 1993 1994 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableAPIUserDeletion = true }) 1995 th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { 1996 userToDelete = th.CreateUser() 1997 ok, resp := c.PermanentDeleteUser(userToDelete.Id) 1998 CheckNoError(t, resp) 1999 assert.True(t, ok) 2000 2001 _, err := th.App.GetTeam(userToDelete.Id) 2002 assert.NotNil(t, err) 2003 2004 ok, resp = c.PermanentDeleteUser("junk") 2005 CheckBadRequestStatus(t, resp) 2006 require.False(t, ok, "should have returned false") 2007 }, "Permanent deletion with EnableAPIUserDeletion set") 2008 } 2009 2010 func TestPermanentDeleteAllUsers(t *testing.T) { 2011 th := Setup(t).InitBasic() 2012 defer th.TearDown() 2013 2014 t.Run("The endpoint should not be available for neither normal nor sysadmin users", func(t *testing.T) { 2015 _, resp := th.Client.PermanentDeleteAllUsers() 2016 CheckNotFoundStatus(t, resp) 2017 2018 _, resp = th.SystemAdminClient.PermanentDeleteAllUsers() 2019 CheckNotFoundStatus(t, resp) 2020 }) 2021 2022 t.Run("The endpoint should permanently delete all users", func(t *testing.T) { 2023 // Basic user creates a team and a channel 2024 team, err := th.App.CreateTeamWithUser(th.Context, &model.Team{ 2025 DisplayName: "User Created Team", 2026 Name: "user-created-team", 2027 Email: "usercreatedteam@test.com", 2028 Type: model.TEAM_OPEN, 2029 }, th.BasicUser.Id) 2030 require.Nil(t, err) 2031 2032 channel, err := th.App.CreateChannelWithUser(th.Context, &model.Channel{ 2033 DisplayName: "User Created Channel", 2034 Name: "user-created-channel", 2035 Type: model.CHANNEL_OPEN, 2036 TeamId: team.Id, 2037 }, th.BasicUser.Id) 2038 require.Nil(t, err) 2039 2040 // Check that we have users and posts in the database 2041 users, nErr := th.App.Srv().Store.User().GetAll() 2042 require.NoError(t, nErr) 2043 require.Greater(t, len(users), 0) 2044 2045 postCount, nErr := th.App.Srv().Store.Post().AnalyticsPostCount("", false, false) 2046 require.NoError(t, nErr) 2047 require.Greater(t, postCount, int64(0)) 2048 2049 // Delete all users and their posts 2050 _, resp := th.LocalClient.PermanentDeleteAllUsers() 2051 require.Nil(t, resp.Error) 2052 2053 // Check that both user and post tables are empty 2054 users, nErr = th.App.Srv().Store.User().GetAll() 2055 require.NoError(t, nErr) 2056 require.Len(t, users, 0) 2057 2058 postCount, nErr = th.App.Srv().Store.Post().AnalyticsPostCount("", false, false) 2059 require.NoError(t, nErr) 2060 require.Equal(t, postCount, int64(0)) 2061 2062 // Check that the channel and team created by the user were not deleted 2063 rTeam, err := th.App.GetTeam(team.Id) 2064 require.Nil(t, err) 2065 require.NotNil(t, rTeam) 2066 2067 rChannel, err := th.App.GetChannel(channel.Id) 2068 require.Nil(t, err) 2069 require.NotNil(t, rChannel) 2070 }) 2071 } 2072 2073 func TestUpdateUserRoles(t *testing.T) { 2074 th := Setup(t).InitBasic() 2075 defer th.TearDown() 2076 2077 _, resp := th.Client.UpdateUserRoles(th.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID) 2078 CheckForbiddenStatus(t, resp) 2079 2080 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2081 _, resp = client.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID) 2082 CheckNoError(t, resp) 2083 2084 _, resp = client.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID) 2085 CheckNoError(t, resp) 2086 2087 _, resp = client.UpdateUserRoles(th.BasicUser.Id, "junk") 2088 CheckBadRequestStatus(t, resp) 2089 2090 _, resp = client.UpdateUserRoles("junk", model.SYSTEM_USER_ROLE_ID) 2091 CheckBadRequestStatus(t, resp) 2092 2093 _, resp = client.UpdateUserRoles(model.NewId(), model.SYSTEM_USER_ROLE_ID) 2094 CheckBadRequestStatus(t, resp) 2095 }) 2096 } 2097 2098 func assertExpectedWebsocketEvent(t *testing.T, client *model.WebSocketClient, event string, test func(*model.WebSocketEvent)) { 2099 for { 2100 select { 2101 case resp, ok := <-client.EventChannel: 2102 require.Truef(t, ok, "channel closed before receiving expected event %s", event) 2103 if resp.EventType() == event { 2104 test(resp) 2105 return 2106 } 2107 case <-time.After(5 * time.Second): 2108 require.Failf(t, "failed to receive expected event %s", event) 2109 } 2110 } 2111 } 2112 2113 func assertWebsocketEventUserUpdatedWithEmail(t *testing.T, client *model.WebSocketClient, email string) { 2114 assertExpectedWebsocketEvent(t, client, model.WEBSOCKET_EVENT_USER_UPDATED, func(event *model.WebSocketEvent) { 2115 eventUser, ok := event.GetData()["user"].(*model.User) 2116 require.True(t, ok, "expected user") 2117 assert.Equal(t, email, eventUser.Email) 2118 }) 2119 } 2120 2121 func TestUpdateUserActive(t *testing.T) { 2122 t.Run("not activating more users when cloud license users at limit", func(t *testing.T) { 2123 // create 5 active users 2124 th := Setup(t).InitBasic() 2125 defer th.TearDown() 2126 2127 cloudMock := &mocks.CloudInterface{} 2128 cloudMock.Mock.On( 2129 "GetSubscription", mock.Anything, 2130 ).Return(&model.Subscription{ 2131 ID: "MySubscriptionID", 2132 CustomerID: "MyCustomer", 2133 ProductID: "SomeProductId", 2134 AddOns: []string{}, 2135 StartAt: 1000000000, 2136 EndAt: 2000000000, 2137 CreateAt: 1000000000, 2138 Seats: 100, 2139 DNS: "some.dns.server", 2140 IsPaidTier: "false", 2141 }, nil) 2142 2143 th.App.Srv().SetLicense(model.NewTestLicense("cloud")) 2144 th.App.Srv().Cloud = cloudMock 2145 2146 user := th.BasicUser 2147 2148 th.App.UpdateConfig(func(cfg *model.Config) { 2149 *cfg.TeamSettings.EnableUserDeactivation = true 2150 *cfg.ExperimentalSettings.CloudUserLimit = 4 2151 }) 2152 2153 // deactivate 5th user, now we have 4 active users and are at limit 2154 pass, resp := th.SystemAdminClient.UpdateUserActive(user.Id, false) 2155 CheckNoError(t, resp) 2156 require.True(t, pass) 2157 2158 // try and reactivate 5th user, not allowed because it exceeds the set cloud user limit 2159 pass, resp = th.SystemAdminClient.UpdateUserActive(user.Id, true) 2160 CheckBadRequestStatus(t, resp) 2161 require.False(t, pass) 2162 require.Equal(t, resp.Error.Message, "Unable to activate more users as the cloud account is over capacity.") 2163 }) 2164 t.Run("basic tests", func(t *testing.T) { 2165 th := Setup(t).InitBasic() 2166 defer th.TearDown() 2167 2168 user := th.BasicUser 2169 2170 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = true }) 2171 pass, resp := th.Client.UpdateUserActive(user.Id, false) 2172 CheckNoError(t, resp) 2173 2174 require.True(t, pass) 2175 2176 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = false }) 2177 pass, resp = th.Client.UpdateUserActive(user.Id, false) 2178 CheckUnauthorizedStatus(t, resp) 2179 2180 require.False(t, pass) 2181 2182 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = true }) 2183 pass, resp = th.Client.UpdateUserActive(user.Id, false) 2184 CheckUnauthorizedStatus(t, resp) 2185 2186 require.False(t, pass) 2187 2188 th.LoginBasic2() 2189 2190 _, resp = th.Client.UpdateUserActive(user.Id, true) 2191 CheckForbiddenStatus(t, resp) 2192 2193 _, resp = th.Client.UpdateUserActive(GenerateTestId(), true) 2194 CheckForbiddenStatus(t, resp) 2195 2196 _, resp = th.Client.UpdateUserActive("junk", true) 2197 CheckBadRequestStatus(t, resp) 2198 2199 th.Client.Logout() 2200 2201 _, resp = th.Client.UpdateUserActive(user.Id, true) 2202 CheckUnauthorizedStatus(t, resp) 2203 2204 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2205 _, resp := client.UpdateUserActive(user.Id, true) 2206 CheckNoError(t, resp) 2207 2208 _, resp = client.UpdateUserActive(user.Id, false) 2209 CheckNoError(t, resp) 2210 2211 authData := model.NewId() 2212 _, err := th.App.Srv().Store.User().UpdateAuthData(user.Id, "random", &authData, "", true) 2213 require.NoError(t, err) 2214 2215 _, resp = client.UpdateUserActive(user.Id, false) 2216 CheckNoError(t, resp) 2217 }) 2218 }) 2219 2220 t.Run("websocket events", func(t *testing.T) { 2221 th := Setup(t).InitBasic() 2222 defer th.TearDown() 2223 2224 user := th.BasicUser2 2225 2226 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableUserDeactivation = true }) 2227 2228 webSocketClient, err := th.CreateWebSocketClient() 2229 assert.Nil(t, err) 2230 defer webSocketClient.Close() 2231 2232 webSocketClient.Listen() 2233 2234 time.Sleep(300 * time.Millisecond) 2235 resp := <-webSocketClient.ResponseChannel 2236 require.Equal(t, model.STATUS_OK, resp.Status) 2237 2238 adminWebSocketClient, err := th.CreateWebSocketSystemAdminClient() 2239 assert.Nil(t, err) 2240 defer adminWebSocketClient.Close() 2241 2242 adminWebSocketClient.Listen() 2243 2244 time.Sleep(300 * time.Millisecond) 2245 resp = <-adminWebSocketClient.ResponseChannel 2246 require.Equal(t, model.STATUS_OK, resp.Status) 2247 2248 // Verify that both admins and regular users see the email when privacy settings allow same, 2249 // and confirm event is fired for SystemAdmin and Local mode 2250 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowEmailAddress = true }) 2251 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2252 _, respErr := client.UpdateUserActive(user.Id, false) 2253 CheckNoError(t, respErr) 2254 2255 assertWebsocketEventUserUpdatedWithEmail(t, webSocketClient, user.Email) 2256 assertWebsocketEventUserUpdatedWithEmail(t, adminWebSocketClient, user.Email) 2257 }) 2258 2259 // Verify that only admins see the email when privacy settings hide emails, 2260 // and confirm event is fired for SystemAdmin and Local mode 2261 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2262 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PrivacySettings.ShowEmailAddress = false }) 2263 _, respErr := client.UpdateUserActive(user.Id, true) 2264 CheckNoError(t, respErr) 2265 2266 assertWebsocketEventUserUpdatedWithEmail(t, webSocketClient, "") 2267 assertWebsocketEventUserUpdatedWithEmail(t, adminWebSocketClient, user.Email) 2268 }) 2269 }) 2270 2271 t.Run("activate guest should fail when guests feature is disable", func(t *testing.T) { 2272 th := Setup(t).InitBasic() 2273 defer th.TearDown() 2274 2275 id := model.NewId() 2276 guest := &model.User{ 2277 Email: "success+" + id + "@simulator.amazonses.com", 2278 Username: "un_" + id, 2279 Nickname: "nn_" + id, 2280 Password: "Password1", 2281 EmailVerified: true, 2282 } 2283 user, err := th.App.CreateGuest(th.Context, guest) 2284 require.Nil(t, err) 2285 th.App.UpdateActive(th.Context, user, false) 2286 2287 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = false }) 2288 defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) 2289 2290 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2291 _, resp := client.UpdateUserActive(user.Id, true) 2292 CheckUnauthorizedStatus(t, resp) 2293 }) 2294 }) 2295 2296 t.Run("activate guest should work when guests feature is enabled", func(t *testing.T) { 2297 th := Setup(t).InitBasic() 2298 defer th.TearDown() 2299 2300 id := model.NewId() 2301 guest := &model.User{ 2302 Email: "success+" + id + "@simulator.amazonses.com", 2303 Username: "un_" + id, 2304 Nickname: "nn_" + id, 2305 Password: "Password1", 2306 EmailVerified: true, 2307 } 2308 user, err := th.App.CreateGuest(th.Context, guest) 2309 require.Nil(t, err) 2310 th.App.UpdateActive(th.Context, user, false) 2311 2312 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) 2313 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2314 _, resp := client.UpdateUserActive(user.Id, true) 2315 CheckNoError(t, resp) 2316 }) 2317 }) 2318 } 2319 2320 func TestGetUsers(t *testing.T) { 2321 th := Setup(t) 2322 defer th.TearDown() 2323 2324 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 2325 rusers, resp := client.GetUsers(0, 60, "") 2326 CheckNoError(t, resp) 2327 for _, u := range rusers { 2328 CheckUserSanitization(t, u) 2329 } 2330 2331 rusers, resp = client.GetUsers(0, 1, "") 2332 CheckNoError(t, resp) 2333 require.Len(t, rusers, 1, "should be 1 per page") 2334 2335 rusers, resp = client.GetUsers(1, 1, "") 2336 CheckNoError(t, resp) 2337 require.Len(t, rusers, 1, "should be 1 per page") 2338 2339 rusers, resp = client.GetUsers(10000, 100, "") 2340 CheckNoError(t, resp) 2341 require.Empty(t, rusers, "should be no users") 2342 2343 // Check default params for page and per_page 2344 _, err := client.DoApiGet("/users", "") 2345 require.Nil(t, err) 2346 }) 2347 2348 th.Client.Logout() 2349 _, resp := th.Client.GetUsers(0, 60, "") 2350 CheckUnauthorizedStatus(t, resp) 2351 } 2352 2353 func TestGetNewUsersInTeam(t *testing.T) { 2354 th := Setup(t).InitBasic() 2355 defer th.TearDown() 2356 teamId := th.BasicTeam.Id 2357 2358 rusers, resp := th.Client.GetNewUsersInTeam(teamId, 0, 60, "") 2359 CheckNoError(t, resp) 2360 2361 lastCreateAt := model.GetMillis() 2362 for _, u := range rusers { 2363 require.LessOrEqual(t, u.CreateAt, lastCreateAt, "right sorting") 2364 lastCreateAt = u.CreateAt 2365 CheckUserSanitization(t, u) 2366 } 2367 2368 rusers, resp = th.Client.GetNewUsersInTeam(teamId, 1, 1, "") 2369 CheckNoError(t, resp) 2370 require.Len(t, rusers, 1, "should be 1 per page") 2371 2372 th.Client.Logout() 2373 _, resp = th.Client.GetNewUsersInTeam(teamId, 1, 1, "") 2374 CheckUnauthorizedStatus(t, resp) 2375 } 2376 2377 func TestGetRecentlyActiveUsersInTeam(t *testing.T) { 2378 th := Setup(t).InitBasic() 2379 defer th.TearDown() 2380 teamId := th.BasicTeam.Id 2381 2382 th.App.SetStatusOnline(th.BasicUser.Id, true) 2383 2384 rusers, resp := th.Client.GetRecentlyActiveUsersInTeam(teamId, 0, 60, "") 2385 CheckNoError(t, resp) 2386 2387 for _, u := range rusers { 2388 require.NotZero(t, u.LastActivityAt, "should return last activity at") 2389 CheckUserSanitization(t, u) 2390 } 2391 2392 rusers, resp = th.Client.GetRecentlyActiveUsersInTeam(teamId, 0, 1, "") 2393 CheckNoError(t, resp) 2394 require.Len(t, rusers, 1, "should be 1 per page") 2395 2396 th.Client.Logout() 2397 _, resp = th.Client.GetRecentlyActiveUsersInTeam(teamId, 0, 1, "") 2398 CheckUnauthorizedStatus(t, resp) 2399 } 2400 2401 func TestGetActiveUsersInTeam(t *testing.T) { 2402 th := Setup(t).InitBasic() 2403 defer th.TearDown() 2404 teamId := th.BasicTeam.Id 2405 2406 th.SystemAdminClient.UpdateUserActive(th.BasicUser2.Id, false) 2407 rusers, resp := th.Client.GetActiveUsersInTeam(teamId, 0, 60, "") 2408 CheckNoError(t, resp) 2409 2410 require.NotZero(t, len(rusers)) 2411 for _, u := range rusers { 2412 require.Zero(t, u.DeleteAt, "should not be deleted") 2413 require.NotEqual(t, th.BasicUser2.Id, "should not include deactivated user") 2414 CheckUserSanitization(t, u) 2415 } 2416 2417 rusers, resp = th.Client.GetActiveUsersInTeam(teamId, 0, 1, "") 2418 CheckNoError(t, resp) 2419 require.Len(t, rusers, 1, "should be 1 per page") 2420 2421 // Check case where we have supplied both active and inactive flags 2422 _, err := th.Client.DoApiGet("/users?inactive=true&active=true", "") 2423 require.NotNil(t, err) 2424 2425 th.Client.Logout() 2426 _, resp = th.Client.GetActiveUsersInTeam(teamId, 0, 1, "") 2427 CheckUnauthorizedStatus(t, resp) 2428 } 2429 2430 func TestGetUsersWithoutTeam(t *testing.T) { 2431 th := Setup(t).InitBasic() 2432 defer th.TearDown() 2433 2434 _, resp := th.Client.GetUsersWithoutTeam(0, 100, "") 2435 require.NotNil(t, resp.Error, "should prevent non-admin user from getting users without a team") 2436 2437 // These usernames need to appear in the first 100 users for this to work 2438 2439 user, resp := th.Client.CreateUser(&model.User{ 2440 Username: "a000000000" + model.NewId(), 2441 Email: "success+" + model.NewId() + "@simulator.amazonses.com", 2442 Password: "Password1", 2443 }) 2444 CheckNoError(t, resp) 2445 th.LinkUserToTeam(user, th.BasicTeam) 2446 defer th.App.Srv().Store.User().PermanentDelete(user.Id) 2447 2448 user2, resp := th.Client.CreateUser(&model.User{ 2449 Username: "a000000001" + model.NewId(), 2450 Email: "success+" + model.NewId() + "@simulator.amazonses.com", 2451 Password: "Password1", 2452 }) 2453 CheckNoError(t, resp) 2454 defer th.App.Srv().Store.User().PermanentDelete(user2.Id) 2455 2456 rusers, resp := th.SystemAdminClient.GetUsersWithoutTeam(0, 100, "") 2457 CheckNoError(t, resp) 2458 2459 found1 := false 2460 found2 := false 2461 2462 for _, u := range rusers { 2463 if u.Id == user.Id { 2464 found1 = true 2465 } else if u.Id == user2.Id { 2466 found2 = true 2467 } 2468 } 2469 2470 require.False(t, found1, "should not return user that as a team") 2471 require.True(t, found2, "should return user that has no teams") 2472 } 2473 2474 func TestGetUsersInTeam(t *testing.T) { 2475 th := Setup(t).InitBasic() 2476 defer th.TearDown() 2477 teamId := th.BasicTeam.Id 2478 2479 rusers, resp := th.Client.GetUsersInTeam(teamId, 0, 60, "") 2480 CheckNoError(t, resp) 2481 for _, u := range rusers { 2482 CheckUserSanitization(t, u) 2483 } 2484 2485 rusers, resp = th.Client.GetUsersInTeam(teamId, 0, 60, resp.Etag) 2486 CheckEtag(t, rusers, resp) 2487 2488 rusers, resp = th.Client.GetUsersInTeam(teamId, 0, 1, "") 2489 CheckNoError(t, resp) 2490 require.Len(t, rusers, 1, "should be 1 per page") 2491 2492 rusers, resp = th.Client.GetUsersInTeam(teamId, 1, 1, "") 2493 CheckNoError(t, resp) 2494 require.Len(t, rusers, 1, "should be 1 per page") 2495 2496 rusers, resp = th.Client.GetUsersInTeam(teamId, 10000, 100, "") 2497 CheckNoError(t, resp) 2498 require.Empty(t, rusers, "should be no users") 2499 2500 th.Client.Logout() 2501 _, resp = th.Client.GetUsersInTeam(teamId, 0, 60, "") 2502 CheckUnauthorizedStatus(t, resp) 2503 2504 user := th.CreateUser() 2505 th.Client.Login(user.Email, user.Password) 2506 _, resp = th.Client.GetUsersInTeam(teamId, 0, 60, "") 2507 CheckForbiddenStatus(t, resp) 2508 2509 _, resp = th.SystemAdminClient.GetUsersInTeam(teamId, 0, 60, "") 2510 CheckNoError(t, resp) 2511 } 2512 2513 func TestGetUsersNotInTeam(t *testing.T) { 2514 th := Setup(t).InitBasic() 2515 defer th.TearDown() 2516 teamId := th.BasicTeam.Id 2517 2518 rusers, resp := th.Client.GetUsersNotInTeam(teamId, 0, 60, "") 2519 CheckNoError(t, resp) 2520 for _, u := range rusers { 2521 CheckUserSanitization(t, u) 2522 } 2523 require.Len(t, rusers, 2, "should be 2 users in total") 2524 2525 rusers, resp = th.Client.GetUsersNotInTeam(teamId, 0, 60, resp.Etag) 2526 CheckEtag(t, rusers, resp) 2527 2528 rusers, resp = th.Client.GetUsersNotInTeam(teamId, 0, 1, "") 2529 CheckNoError(t, resp) 2530 require.Len(t, rusers, 1, "should be 1 per page") 2531 2532 rusers, resp = th.Client.GetUsersNotInTeam(teamId, 2, 1, "") 2533 CheckNoError(t, resp) 2534 require.Empty(t, rusers, "should be no users") 2535 2536 rusers, resp = th.Client.GetUsersNotInTeam(teamId, 10000, 100, "") 2537 CheckNoError(t, resp) 2538 require.Empty(t, rusers, "should be no users") 2539 2540 th.Client.Logout() 2541 _, resp = th.Client.GetUsersNotInTeam(teamId, 0, 60, "") 2542 CheckUnauthorizedStatus(t, resp) 2543 2544 user := th.CreateUser() 2545 th.Client.Login(user.Email, user.Password) 2546 _, resp = th.Client.GetUsersNotInTeam(teamId, 0, 60, "") 2547 CheckForbiddenStatus(t, resp) 2548 2549 _, resp = th.SystemAdminClient.GetUsersNotInTeam(teamId, 0, 60, "") 2550 CheckNoError(t, resp) 2551 } 2552 2553 func TestGetUsersInChannel(t *testing.T) { 2554 th := Setup(t).InitBasic() 2555 defer th.TearDown() 2556 channelId := th.BasicChannel.Id 2557 2558 rusers, resp := th.Client.GetUsersInChannel(channelId, 0, 60, "") 2559 CheckNoError(t, resp) 2560 for _, u := range rusers { 2561 CheckUserSanitization(t, u) 2562 } 2563 2564 rusers, resp = th.Client.GetUsersInChannel(channelId, 0, 1, "") 2565 CheckNoError(t, resp) 2566 require.Len(t, rusers, 1, "should be 1 per page") 2567 2568 rusers, resp = th.Client.GetUsersInChannel(channelId, 1, 1, "") 2569 CheckNoError(t, resp) 2570 require.Len(t, rusers, 1, "should be 1 per page") 2571 2572 rusers, resp = th.Client.GetUsersInChannel(channelId, 10000, 100, "") 2573 CheckNoError(t, resp) 2574 require.Empty(t, rusers, "should be no users") 2575 2576 th.Client.Logout() 2577 _, resp = th.Client.GetUsersInChannel(channelId, 0, 60, "") 2578 CheckUnauthorizedStatus(t, resp) 2579 2580 user := th.CreateUser() 2581 th.Client.Login(user.Email, user.Password) 2582 _, resp = th.Client.GetUsersInChannel(channelId, 0, 60, "") 2583 CheckForbiddenStatus(t, resp) 2584 2585 _, resp = th.SystemAdminClient.GetUsersInChannel(channelId, 0, 60, "") 2586 CheckNoError(t, resp) 2587 } 2588 2589 func TestGetUsersNotInChannel(t *testing.T) { 2590 th := Setup(t).InitBasic() 2591 defer th.TearDown() 2592 teamId := th.BasicTeam.Id 2593 channelId := th.BasicChannel.Id 2594 2595 user := th.CreateUser() 2596 th.LinkUserToTeam(user, th.BasicTeam) 2597 2598 rusers, resp := th.Client.GetUsersNotInChannel(teamId, channelId, 0, 60, "") 2599 CheckNoError(t, resp) 2600 for _, u := range rusers { 2601 CheckUserSanitization(t, u) 2602 } 2603 2604 rusers, resp = th.Client.GetUsersNotInChannel(teamId, channelId, 0, 1, "") 2605 CheckNoError(t, resp) 2606 require.Len(t, rusers, 1, "should be 1 per page") 2607 2608 rusers, resp = th.Client.GetUsersNotInChannel(teamId, channelId, 10000, 100, "") 2609 CheckNoError(t, resp) 2610 require.Empty(t, rusers, "should be no users") 2611 2612 th.Client.Logout() 2613 _, resp = th.Client.GetUsersNotInChannel(teamId, channelId, 0, 60, "") 2614 CheckUnauthorizedStatus(t, resp) 2615 2616 th.Client.Login(user.Email, user.Password) 2617 _, resp = th.Client.GetUsersNotInChannel(teamId, channelId, 0, 60, "") 2618 CheckForbiddenStatus(t, resp) 2619 2620 _, resp = th.SystemAdminClient.GetUsersNotInChannel(teamId, channelId, 0, 60, "") 2621 CheckNoError(t, resp) 2622 } 2623 2624 func TestGetUsersInGroup(t *testing.T) { 2625 th := Setup(t).InitBasic() 2626 defer th.TearDown() 2627 2628 id := model.NewId() 2629 group, err := th.App.CreateGroup(&model.Group{ 2630 DisplayName: "dn-foo_" + id, 2631 Name: model.NewString("name" + id), 2632 Source: model.GroupSourceLdap, 2633 Description: "description_" + id, 2634 RemoteId: model.NewId(), 2635 }) 2636 assert.Nil(t, err) 2637 2638 var response *model.Response 2639 var users []*model.User 2640 2641 t.Run("Requires ldap license", func(t *testing.T) { 2642 _, response = th.SystemAdminClient.GetUsersInGroup(group.Id, 0, 60, "") 2643 CheckNotImplementedStatus(t, response) 2644 }) 2645 2646 th.App.Srv().SetLicense(model.NewTestLicense("ldap")) 2647 2648 t.Run("Requires manage system permission to access users in group", func(t *testing.T) { 2649 th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 2650 _, response = th.Client.GetUsersInGroup(group.Id, 0, 60, "") 2651 CheckForbiddenStatus(t, response) 2652 }) 2653 2654 user1, err := th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Nickname: "test user1", Password: "test-password-1", Username: "test-user-1", Roles: model.SYSTEM_USER_ROLE_ID}) 2655 assert.Nil(t, err) 2656 _, err = th.App.UpsertGroupMember(group.Id, user1.Id) 2657 assert.Nil(t, err) 2658 2659 t.Run("Returns users in group when called by system admin", func(t *testing.T) { 2660 users, response = th.SystemAdminClient.GetUsersInGroup(group.Id, 0, 60, "") 2661 CheckNoError(t, response) 2662 assert.Equal(t, users[0].Id, user1.Id) 2663 }) 2664 2665 t.Run("Returns no users when pagination out of range", func(t *testing.T) { 2666 users, response = th.SystemAdminClient.GetUsersInGroup(group.Id, 5, 60, "") 2667 CheckNoError(t, response) 2668 assert.Empty(t, users) 2669 }) 2670 } 2671 2672 func TestUpdateUserMfa(t *testing.T) { 2673 th := Setup(t).InitBasic() 2674 defer th.TearDown() 2675 2676 th.App.Srv().SetLicense(model.NewTestLicense("mfa")) 2677 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) 2678 2679 session, _ := th.App.GetSession(th.Client.AuthToken) 2680 session.IsOAuth = true 2681 th.App.AddSessionToCache(session) 2682 2683 _, resp := th.Client.UpdateUserMfa(th.BasicUser.Id, "12345", false) 2684 CheckForbiddenStatus(t, resp) 2685 2686 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2687 _, resp := client.UpdateUserMfa(th.BasicUser.Id, "12345", false) 2688 CheckNoError(t, resp) 2689 }) 2690 } 2691 2692 // CheckUserMfa is deprecated and should not be used anymore, it will be disabled by default in version 6.0 2693 func TestCheckUserMfa(t *testing.T) { 2694 th := Setup(t).InitBasic() 2695 defer th.TearDown() 2696 2697 th.App.UpdateConfig(func(c *model.Config) { 2698 *c.ServiceSettings.DisableLegacyMFA = false 2699 }) 2700 2701 required, resp := th.Client.CheckUserMfa(th.BasicUser.Email) 2702 CheckNoError(t, resp) 2703 2704 require.False(t, required, "mfa not active") 2705 2706 _, resp = th.Client.CheckUserMfa("") 2707 CheckBadRequestStatus(t, resp) 2708 2709 th.Client.Logout() 2710 2711 required, resp = th.Client.CheckUserMfa(th.BasicUser.Email) 2712 CheckNoError(t, resp) 2713 2714 require.False(t, required, "mfa not active") 2715 2716 th.App.Srv().SetLicense(model.NewTestLicense("mfa")) 2717 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) 2718 2719 th.LoginBasic() 2720 2721 required, resp = th.Client.CheckUserMfa(th.BasicUser.Email) 2722 CheckNoError(t, resp) 2723 2724 require.False(t, required, "mfa not active") 2725 2726 th.Client.Logout() 2727 2728 required, resp = th.Client.CheckUserMfa(th.BasicUser.Email) 2729 CheckNoError(t, resp) 2730 2731 require.False(t, required, "mfa not active") 2732 2733 th.App.UpdateConfig(func(c *model.Config) { 2734 *c.ServiceSettings.DisableLegacyMFA = true 2735 }) 2736 2737 _, resp = th.Client.CheckUserMfa(th.BasicUser.Email) 2738 CheckNotFoundStatus(t, resp) 2739 } 2740 2741 func TestUserLoginMFAFlow(t *testing.T) { 2742 th := Setup(t).InitBasic() 2743 defer th.TearDown() 2744 2745 th.App.UpdateConfig(func(c *model.Config) { 2746 *c.ServiceSettings.DisableLegacyMFA = true 2747 *c.ServiceSettings.EnableMultifactorAuthentication = true 2748 }) 2749 2750 t.Run("WithoutMFA", func(t *testing.T) { 2751 _, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 2752 CheckNoError(t, resp) 2753 }) 2754 2755 t.Run("WithInvalidMFA", func(t *testing.T) { 2756 secret, err := th.App.GenerateMfaSecret(th.BasicUser.Id) 2757 assert.Nil(t, err) 2758 2759 // Fake user has MFA enabled 2760 nErr := th.Server.Store.User().UpdateMfaActive(th.BasicUser.Id, true) 2761 require.NoError(t, nErr) 2762 2763 nErr = th.Server.Store.User().UpdateMfaActive(th.BasicUser.Id, true) 2764 require.NoError(t, nErr) 2765 2766 nErr = th.Server.Store.User().UpdateMfaSecret(th.BasicUser.Id, secret.Secret) 2767 require.NoError(t, nErr) 2768 2769 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 2770 CheckErrorMessage(t, resp, "mfa.validate_token.authenticate.app_error") 2771 assert.Nil(t, user) 2772 2773 user, resp = th.Client.LoginWithMFA(th.BasicUser.Email, th.BasicUser.Password, "") 2774 CheckErrorMessage(t, resp, "mfa.validate_token.authenticate.app_error") 2775 assert.Nil(t, user) 2776 2777 user, resp = th.Client.LoginWithMFA(th.BasicUser.Email, th.BasicUser.Password, "abcdefgh") 2778 CheckErrorMessage(t, resp, "mfa.validate_token.authenticate.app_error") 2779 assert.Nil(t, user) 2780 2781 secret2, err := th.App.GenerateMfaSecret(th.BasicUser2.Id) 2782 assert.Nil(t, err) 2783 user, resp = th.Client.LoginWithMFA(th.BasicUser.Email, th.BasicUser.Password, secret2.Secret) 2784 CheckErrorMessage(t, resp, "mfa.validate_token.authenticate.app_error") 2785 assert.Nil(t, user) 2786 }) 2787 2788 t.Run("WithCorrectMFA", func(t *testing.T) { 2789 secret, err := th.App.GenerateMfaSecret(th.BasicUser.Id) 2790 assert.Nil(t, err) 2791 2792 // Fake user has MFA enabled 2793 nErr := th.Server.Store.User().UpdateMfaActive(th.BasicUser.Id, true) 2794 require.NoError(t, nErr) 2795 2796 nErr = th.Server.Store.User().UpdateMfaSecret(th.BasicUser.Id, secret.Secret) 2797 require.NoError(t, nErr) 2798 2799 code := dgoogauth.ComputeCode(secret.Secret, time.Now().UTC().Unix()/30) 2800 2801 user, resp := th.Client.LoginWithMFA(th.BasicUser.Email, th.BasicUser.Password, fmt.Sprintf("%06d", code)) 2802 CheckNoError(t, resp) 2803 assert.NotNil(t, user) 2804 }) 2805 } 2806 2807 func TestGenerateMfaSecret(t *testing.T) { 2808 th := Setup(t).InitBasic() 2809 defer th.TearDown() 2810 2811 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = false }) 2812 2813 _, resp := th.Client.GenerateMfaSecret(th.BasicUser.Id) 2814 CheckNotImplementedStatus(t, resp) 2815 2816 _, resp = th.SystemAdminClient.GenerateMfaSecret(th.BasicUser.Id) 2817 CheckNotImplementedStatus(t, resp) 2818 2819 _, resp = th.Client.GenerateMfaSecret("junk") 2820 CheckBadRequestStatus(t, resp) 2821 2822 th.App.Srv().SetLicense(model.NewTestLicense("mfa")) 2823 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) 2824 2825 _, resp = th.Client.GenerateMfaSecret(model.NewId()) 2826 CheckForbiddenStatus(t, resp) 2827 2828 session, _ := th.App.GetSession(th.Client.AuthToken) 2829 session.IsOAuth = true 2830 th.App.AddSessionToCache(session) 2831 2832 _, resp = th.Client.GenerateMfaSecret(th.BasicUser.Id) 2833 CheckForbiddenStatus(t, resp) 2834 2835 th.Client.Logout() 2836 2837 _, resp = th.Client.GenerateMfaSecret(th.BasicUser.Id) 2838 CheckUnauthorizedStatus(t, resp) 2839 } 2840 2841 func TestUpdateUserPassword(t *testing.T) { 2842 th := Setup(t).InitBasic() 2843 defer th.TearDown() 2844 2845 password := "newpassword1" 2846 pass, resp := th.Client.UpdateUserPassword(th.BasicUser.Id, th.BasicUser.Password, password) 2847 CheckNoError(t, resp) 2848 2849 require.True(t, pass) 2850 2851 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, password, "") 2852 CheckBadRequestStatus(t, resp) 2853 2854 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, password, "junk") 2855 CheckBadRequestStatus(t, resp) 2856 2857 _, resp = th.Client.UpdateUserPassword("junk", password, password) 2858 CheckBadRequestStatus(t, resp) 2859 2860 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, "", password) 2861 CheckBadRequestStatus(t, resp) 2862 2863 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, "junk", password) 2864 CheckBadRequestStatus(t, resp) 2865 2866 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, password, th.BasicUser.Password) 2867 CheckNoError(t, resp) 2868 2869 th.Client.Logout() 2870 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, password, password) 2871 CheckUnauthorizedStatus(t, resp) 2872 2873 th.LoginBasic2() 2874 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, password, password) 2875 CheckForbiddenStatus(t, resp) 2876 2877 th.LoginBasic() 2878 2879 // Test lockout 2880 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.MaximumLoginAttempts = 2 }) 2881 2882 // Fail twice 2883 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, "badpwd", "newpwd") 2884 CheckBadRequestStatus(t, resp) 2885 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, "badpwd", "newpwd") 2886 CheckBadRequestStatus(t, resp) 2887 2888 // Should fail because account is locked out 2889 _, resp = th.Client.UpdateUserPassword(th.BasicUser.Id, th.BasicUser.Password, "newpwd") 2890 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 2891 CheckUnauthorizedStatus(t, resp) 2892 2893 // System admin can update another user's password 2894 adminSetPassword := "pwdsetbyadmin" 2895 pass, resp = th.SystemAdminClient.UpdateUserPassword(th.BasicUser.Id, "", adminSetPassword) 2896 CheckNoError(t, resp) 2897 2898 require.True(t, pass) 2899 2900 _, resp = th.Client.Login(th.BasicUser.Email, adminSetPassword) 2901 CheckNoError(t, resp) 2902 } 2903 2904 func TestUpdateUserHashedPassword(t *testing.T) { 2905 th := Setup(t).InitBasic() 2906 defer th.TearDown() 2907 client := th.Client 2908 2909 password := "SuperSecurePass23!" 2910 passwordHash := "$2a$10$CiS1iWVPUj7rQNdY6XW53.DmaPLsETIvmW2p0asp4Dqpofs10UL5W" 2911 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 2912 pass, resp := client.UpdateUserHashedPassword(th.BasicUser.Id, passwordHash) 2913 CheckNoError(t, resp) 2914 require.True(t, pass) 2915 }) 2916 2917 _, resp := client.Login(th.BasicUser.Email, password) 2918 CheckNoError(t, resp) 2919 2920 // Standard users should never be updating their passwords with already- 2921 // hashed passwords. 2922 pass, resp := client.UpdateUserHashedPassword(th.BasicUser.Id, passwordHash) 2923 CheckUnauthorizedStatus(t, resp) 2924 require.False(t, pass) 2925 } 2926 2927 func TestResetPassword(t *testing.T) { 2928 t.Skip("test disabled during old build server changes, should be investigated") 2929 2930 th := Setup(t).InitBasic() 2931 defer th.TearDown() 2932 th.Client.Logout() 2933 user := th.BasicUser 2934 // Delete all the messages before check the reset password 2935 mail.DeleteMailBox(user.Email) 2936 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 2937 success, resp := client.SendPasswordResetEmail(user.Email) 2938 CheckNoError(t, resp) 2939 require.True(t, success, "should succeed") 2940 _, resp = client.SendPasswordResetEmail("") 2941 CheckBadRequestStatus(t, resp) 2942 // Should not leak whether the email is attached to an account or not 2943 success, resp = client.SendPasswordResetEmail("notreal@example.com") 2944 CheckNoError(t, resp) 2945 require.True(t, success, "should succeed") 2946 }) 2947 // Check if the email was send to the right email address and the recovery key match 2948 var resultsMailbox mail.JSONMessageHeaderInbucket 2949 err := mail.RetryInbucket(5, func() error { 2950 var err error 2951 resultsMailbox, err = mail.GetMailBox(user.Email) 2952 return err 2953 }) 2954 if err != nil { 2955 t.Log(err) 2956 t.Log("No email was received, maybe due load on the server. Disabling this verification") 2957 } 2958 var recoveryTokenString string 2959 if err == nil && len(resultsMailbox) > 0 { 2960 require.Contains(t, resultsMailbox[0].To[0], user.Email, "Correct To recipient") 2961 resultsEmail, mailErr := mail.GetMessageFromMailbox(user.Email, resultsMailbox[0].ID) 2962 require.NoError(t, mailErr) 2963 loc := strings.Index(resultsEmail.Body.Text, "token=") 2964 require.NotEqual(t, -1, loc, "Code should be found in email") 2965 loc += 6 2966 recoveryTokenString = resultsEmail.Body.Text[loc : loc+model.TOKEN_SIZE] 2967 } 2968 recoveryToken, err := th.App.Srv().Store.Token().GetByToken(recoveryTokenString) 2969 require.NoError(t, err, "Recovery token not found (%s)", recoveryTokenString) 2970 2971 _, resp := th.Client.ResetPassword(recoveryToken.Token, "") 2972 CheckBadRequestStatus(t, resp) 2973 _, resp = th.Client.ResetPassword(recoveryToken.Token, "newp") 2974 CheckBadRequestStatus(t, resp) 2975 _, resp = th.Client.ResetPassword("", "newpwd") 2976 CheckBadRequestStatus(t, resp) 2977 _, resp = th.Client.ResetPassword("junk", "newpwd") 2978 CheckBadRequestStatus(t, resp) 2979 code := "" 2980 for i := 0; i < model.TOKEN_SIZE; i++ { 2981 code += "a" 2982 } 2983 _, resp = th.Client.ResetPassword(code, "newpwd") 2984 CheckBadRequestStatus(t, resp) 2985 success, resp := th.Client.ResetPassword(recoveryToken.Token, "newpwd") 2986 CheckNoError(t, resp) 2987 require.True(t, success) 2988 th.Client.Login(user.Email, "newpwd") 2989 th.Client.Logout() 2990 _, resp = th.Client.ResetPassword(recoveryToken.Token, "newpwd") 2991 CheckBadRequestStatus(t, resp) 2992 authData := model.NewId() 2993 _, err = th.App.Srv().Store.User().UpdateAuthData(user.Id, "random", &authData, "", true) 2994 require.NoError(t, err) 2995 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 2996 _, resp = client.SendPasswordResetEmail(user.Email) 2997 CheckBadRequestStatus(t, resp) 2998 }) 2999 } 3000 3001 func TestGetSessions(t *testing.T) { 3002 th := Setup(t).InitBasic() 3003 defer th.TearDown() 3004 3005 user := th.BasicUser 3006 3007 th.Client.Login(user.Email, user.Password) 3008 3009 sessions, resp := th.Client.GetSessions(user.Id, "") 3010 for _, session := range sessions { 3011 require.Equal(t, user.Id, session.UserId, "user id should match session user id") 3012 } 3013 CheckNoError(t, resp) 3014 3015 _, resp = th.Client.RevokeSession("junk", model.NewId()) 3016 CheckBadRequestStatus(t, resp) 3017 3018 _, resp = th.Client.GetSessions(th.BasicUser2.Id, "") 3019 CheckForbiddenStatus(t, resp) 3020 3021 _, resp = th.Client.GetSessions(model.NewId(), "") 3022 CheckForbiddenStatus(t, resp) 3023 3024 th.Client.Logout() 3025 _, resp = th.Client.GetSessions(th.BasicUser2.Id, "") 3026 CheckUnauthorizedStatus(t, resp) 3027 3028 _, resp = th.SystemAdminClient.GetSessions(user.Id, "") 3029 CheckNoError(t, resp) 3030 3031 _, resp = th.SystemAdminClient.GetSessions(th.BasicUser2.Id, "") 3032 CheckNoError(t, resp) 3033 3034 _, resp = th.SystemAdminClient.GetSessions(model.NewId(), "") 3035 CheckNoError(t, resp) 3036 } 3037 3038 func TestRevokeSessions(t *testing.T) { 3039 th := Setup(t).InitBasic() 3040 defer th.TearDown() 3041 3042 user := th.BasicUser 3043 th.Client.Login(user.Email, user.Password) 3044 sessions, _ := th.Client.GetSessions(user.Id, "") 3045 require.NotZero(t, len(sessions), "sessions should exist") 3046 for _, session := range sessions { 3047 require.Equal(t, user.Id, session.UserId, "user id does not match session user id") 3048 } 3049 session := sessions[0] 3050 3051 _, resp := th.Client.RevokeSession(user.Id, model.NewId()) 3052 CheckBadRequestStatus(t, resp) 3053 3054 _, resp = th.Client.RevokeSession(th.BasicUser2.Id, model.NewId()) 3055 CheckForbiddenStatus(t, resp) 3056 3057 _, resp = th.Client.RevokeSession("junk", model.NewId()) 3058 CheckBadRequestStatus(t, resp) 3059 3060 status, resp := th.Client.RevokeSession(user.Id, session.Id) 3061 require.True(t, status, "user session revoke successfully") 3062 CheckNoError(t, resp) 3063 3064 th.LoginBasic() 3065 3066 sessions, _ = th.App.GetSessions(th.SystemAdminUser.Id) 3067 session = sessions[0] 3068 3069 _, resp = th.Client.RevokeSession(user.Id, session.Id) 3070 CheckBadRequestStatus(t, resp) 3071 3072 th.Client.Logout() 3073 _, resp = th.Client.RevokeSession(user.Id, model.NewId()) 3074 CheckUnauthorizedStatus(t, resp) 3075 3076 _, resp = th.SystemAdminClient.RevokeSession(user.Id, model.NewId()) 3077 CheckBadRequestStatus(t, resp) 3078 3079 sessions, _ = th.SystemAdminClient.GetSessions(th.SystemAdminUser.Id, "") 3080 require.NotEmpty(t, sessions, "sessions should exist") 3081 for _, session := range sessions { 3082 require.Equal(t, th.SystemAdminUser.Id, session.UserId, "user id should match session user id") 3083 } 3084 session = sessions[0] 3085 3086 _, resp = th.SystemAdminClient.RevokeSession(th.SystemAdminUser.Id, session.Id) 3087 CheckNoError(t, resp) 3088 } 3089 3090 func TestRevokeAllSessions(t *testing.T) { 3091 th := Setup(t).InitBasic() 3092 defer th.TearDown() 3093 3094 user := th.BasicUser 3095 th.Client.Login(user.Email, user.Password) 3096 3097 _, resp := th.Client.RevokeAllSessions(th.BasicUser2.Id) 3098 CheckForbiddenStatus(t, resp) 3099 3100 _, resp = th.Client.RevokeAllSessions("junk" + user.Id) 3101 CheckBadRequestStatus(t, resp) 3102 3103 status, resp := th.Client.RevokeAllSessions(user.Id) 3104 require.True(t, status, "user all sessions revoke unsuccessful") 3105 CheckNoError(t, resp) 3106 3107 th.Client.Logout() 3108 _, resp = th.Client.RevokeAllSessions(user.Id) 3109 CheckUnauthorizedStatus(t, resp) 3110 3111 th.Client.Login(user.Email, user.Password) 3112 3113 sessions, _ := th.Client.GetSessions(user.Id, "") 3114 require.NotEmpty(t, sessions, "session should exist") 3115 3116 _, resp = th.Client.RevokeAllSessions(user.Id) 3117 CheckNoError(t, resp) 3118 3119 sessions, _ = th.SystemAdminClient.GetSessions(user.Id, "") 3120 require.Empty(t, sessions, "no sessions should exist for user") 3121 3122 _, resp = th.Client.RevokeAllSessions(user.Id) 3123 CheckUnauthorizedStatus(t, resp) 3124 } 3125 3126 func TestRevokeSessionsFromAllUsers(t *testing.T) { 3127 th := Setup(t).InitBasic() 3128 defer th.TearDown() 3129 3130 user := th.BasicUser 3131 th.Client.Login(user.Email, user.Password) 3132 _, resp := th.Client.RevokeSessionsFromAllUsers() 3133 CheckForbiddenStatus(t, resp) 3134 3135 th.Client.Logout() 3136 _, resp = th.Client.RevokeSessionsFromAllUsers() 3137 CheckUnauthorizedStatus(t, resp) 3138 3139 th.Client.Login(user.Email, user.Password) 3140 admin := th.SystemAdminUser 3141 th.Client.Login(admin.Email, admin.Password) 3142 sessions, err := th.Server.Store.Session().GetSessions(user.Id) 3143 require.NotEmpty(t, sessions) 3144 require.NoError(t, err) 3145 sessions, err = th.Server.Store.Session().GetSessions(admin.Id) 3146 require.NotEmpty(t, sessions) 3147 require.NoError(t, err) 3148 _, resp = th.Client.RevokeSessionsFromAllUsers() 3149 CheckNoError(t, resp) 3150 3151 // All sessions were revoked, so making the same call 3152 // again will fail due to lack of a session. 3153 _, resp = th.Client.RevokeSessionsFromAllUsers() 3154 CheckUnauthorizedStatus(t, resp) 3155 3156 sessions, err = th.Server.Store.Session().GetSessions(user.Id) 3157 require.Empty(t, sessions) 3158 require.NoError(t, err) 3159 3160 sessions, err = th.Server.Store.Session().GetSessions(admin.Id) 3161 require.Empty(t, sessions) 3162 require.NoError(t, err) 3163 3164 } 3165 3166 func TestAttachDeviceId(t *testing.T) { 3167 th := Setup(t).InitBasic() 3168 defer th.TearDown() 3169 3170 deviceId := model.PUSH_NOTIFY_APPLE + ":1234567890" 3171 3172 t.Run("success", func(t *testing.T) { 3173 testCases := []struct { 3174 Description string 3175 SiteURL string 3176 ExpectedSetCookieHeaderRegexp string 3177 }{ 3178 {"no subpath", "http://localhost:8065", "^MMAUTHTOKEN=[a-z0-9]+; Path=/"}, 3179 {"subpath", "http://localhost:8065/subpath", "^MMAUTHTOKEN=[a-z0-9]+; Path=/subpath"}, 3180 } 3181 3182 for _, tc := range testCases { 3183 t.Run(tc.Description, func(t *testing.T) { 3184 3185 th.App.UpdateConfig(func(cfg *model.Config) { 3186 *cfg.ServiceSettings.SiteURL = tc.SiteURL 3187 }) 3188 3189 pass, resp := th.Client.AttachDeviceId(deviceId) 3190 CheckNoError(t, resp) 3191 3192 cookies := resp.Header.Get("Set-Cookie") 3193 assert.Regexp(t, tc.ExpectedSetCookieHeaderRegexp, cookies) 3194 assert.True(t, pass) 3195 3196 sessions, err := th.App.GetSessions(th.BasicUser.Id) 3197 require.Nil(t, err) 3198 assert.Equal(t, deviceId, sessions[0].DeviceId, "Missing device Id") 3199 }) 3200 } 3201 }) 3202 3203 t.Run("invalid device id", func(t *testing.T) { 3204 _, resp := th.Client.AttachDeviceId("") 3205 CheckBadRequestStatus(t, resp) 3206 }) 3207 3208 t.Run("not logged in", func(t *testing.T) { 3209 th.Client.Logout() 3210 3211 _, resp := th.Client.AttachDeviceId("") 3212 CheckUnauthorizedStatus(t, resp) 3213 }) 3214 } 3215 3216 func TestGetUserAudits(t *testing.T) { 3217 th := Setup(t).InitBasic() 3218 defer th.TearDown() 3219 user := th.BasicUser 3220 3221 audits, resp := th.Client.GetUserAudits(user.Id, 0, 100, "") 3222 for _, audit := range audits { 3223 require.Equal(t, user.Id, audit.UserId, "user id should match audit user id") 3224 } 3225 CheckNoError(t, resp) 3226 3227 _, resp = th.Client.GetUserAudits(th.BasicUser2.Id, 0, 100, "") 3228 CheckForbiddenStatus(t, resp) 3229 3230 th.Client.Logout() 3231 _, resp = th.Client.GetUserAudits(user.Id, 0, 100, "") 3232 CheckUnauthorizedStatus(t, resp) 3233 3234 _, resp = th.SystemAdminClient.GetUserAudits(user.Id, 0, 100, "") 3235 CheckNoError(t, resp) 3236 } 3237 3238 func TestVerifyUserEmail(t *testing.T) { 3239 th := Setup(t) 3240 defer th.TearDown() 3241 3242 email := th.GenerateTestEmail() 3243 user := model.User{Email: email, Nickname: "Darth Vader", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} 3244 3245 ruser, _ := th.Client.CreateUser(&user) 3246 3247 token, err := th.App.Srv().EmailService.CreateVerifyEmailToken(ruser.Id, email) 3248 require.Nil(t, err, "Unable to create email verify token") 3249 3250 _, resp := th.Client.VerifyUserEmail(token.Token) 3251 CheckNoError(t, resp) 3252 3253 _, resp = th.Client.VerifyUserEmail(GenerateTestId()) 3254 CheckBadRequestStatus(t, resp) 3255 3256 _, resp = th.Client.VerifyUserEmail("") 3257 CheckBadRequestStatus(t, resp) 3258 } 3259 3260 func TestSendVerificationEmail(t *testing.T) { 3261 th := Setup(t).InitBasic() 3262 defer th.TearDown() 3263 3264 pass, resp := th.Client.SendVerificationEmail(th.BasicUser.Email) 3265 CheckNoError(t, resp) 3266 3267 require.True(t, pass, "should have passed") 3268 3269 _, resp = th.Client.SendVerificationEmail("") 3270 CheckBadRequestStatus(t, resp) 3271 3272 // Even non-existent emails should return 200 OK 3273 _, resp = th.Client.SendVerificationEmail(th.GenerateTestEmail()) 3274 CheckNoError(t, resp) 3275 3276 th.Client.Logout() 3277 _, resp = th.Client.SendVerificationEmail(th.BasicUser.Email) 3278 CheckNoError(t, resp) 3279 } 3280 3281 func TestSetProfileImage(t *testing.T) { 3282 th := Setup(t).InitBasic() 3283 defer th.TearDown() 3284 user := th.BasicUser 3285 3286 data, err := testutils.ReadTestFile("test.png") 3287 require.NoError(t, err) 3288 3289 ok, resp := th.Client.SetProfileImage(user.Id, data) 3290 require.Truef(t, ok, "%v", resp.Error) 3291 CheckNoError(t, resp) 3292 3293 ok, resp = th.Client.SetProfileImage(model.NewId(), data) 3294 require.False(t, ok, "Should return false, set profile image not allowed") 3295 CheckForbiddenStatus(t, resp) 3296 3297 // status code returns either forbidden or unauthorized 3298 // note: forbidden is set as default at Client4.SetProfileImage when request is terminated early by server 3299 th.Client.Logout() 3300 _, resp = th.Client.SetProfileImage(user.Id, data) 3301 if resp.StatusCode == http.StatusForbidden { 3302 CheckForbiddenStatus(t, resp) 3303 } else if resp.StatusCode == http.StatusUnauthorized { 3304 CheckUnauthorizedStatus(t, resp) 3305 } else { 3306 require.Fail(t, "Should have failed either forbidden or unauthorized") 3307 } 3308 3309 buser, appErr := th.App.GetUser(user.Id) 3310 require.Nil(t, appErr) 3311 3312 _, resp = th.SystemAdminClient.SetProfileImage(user.Id, data) 3313 CheckNoError(t, resp) 3314 3315 ruser, appErr := th.App.GetUser(user.Id) 3316 require.Nil(t, appErr) 3317 assert.True(t, buser.LastPictureUpdate < ruser.LastPictureUpdate, "Picture should have updated for user") 3318 3319 info := &model.FileInfo{Path: "users/" + user.Id + "/profile.png"} 3320 err = th.cleanupTestFile(info) 3321 require.NoError(t, err) 3322 } 3323 3324 func TestSetDefaultProfileImage(t *testing.T) { 3325 th := Setup(t).InitBasic() 3326 defer th.TearDown() 3327 user := th.BasicUser 3328 3329 ok, resp := th.Client.SetDefaultProfileImage(user.Id) 3330 require.True(t, ok) 3331 CheckNoError(t, resp) 3332 3333 ok, resp = th.Client.SetDefaultProfileImage(model.NewId()) 3334 require.False(t, ok, "Should return false, set profile image not allowed") 3335 CheckForbiddenStatus(t, resp) 3336 3337 // status code returns either forbidden or unauthorized 3338 // note: forbidden is set as default at Client4.SetDefaultProfileImage when request is terminated early by server 3339 th.Client.Logout() 3340 _, resp = th.Client.SetDefaultProfileImage(user.Id) 3341 if resp.StatusCode == http.StatusForbidden { 3342 CheckForbiddenStatus(t, resp) 3343 } else if resp.StatusCode == http.StatusUnauthorized { 3344 CheckUnauthorizedStatus(t, resp) 3345 } else { 3346 require.Fail(t, "Should have failed either forbidden or unauthorized") 3347 } 3348 3349 _, resp = th.SystemAdminClient.SetDefaultProfileImage(user.Id) 3350 CheckNoError(t, resp) 3351 3352 ruser, err := th.App.GetUser(user.Id) 3353 require.Nil(t, err) 3354 assert.Equal(t, int64(0), ruser.LastPictureUpdate, "Picture should have resetted to default") 3355 3356 info := &model.FileInfo{Path: "users/" + user.Id + "/profile.png"} 3357 cleanupErr := th.cleanupTestFile(info) 3358 require.NoError(t, cleanupErr) 3359 } 3360 3361 func TestLogin(t *testing.T) { 3362 th := Setup(t).InitBasic() 3363 defer th.TearDown() 3364 th.Client.Logout() 3365 3366 th.App.UpdateConfig(func(cfg *model.Config) { 3367 *cfg.ServiceSettings.EnableBotAccountCreation = true 3368 }) 3369 3370 t.Run("missing password", func(t *testing.T) { 3371 _, resp := th.Client.Login(th.BasicUser.Email, "") 3372 CheckErrorMessage(t, resp, "api.user.login.blank_pwd.app_error") 3373 }) 3374 3375 t.Run("unknown user", func(t *testing.T) { 3376 _, resp := th.Client.Login("unknown", th.BasicUser.Password) 3377 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email_username") 3378 }) 3379 3380 t.Run("valid login", func(t *testing.T) { 3381 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3382 CheckNoError(t, resp) 3383 assert.Equal(t, user.Id, th.BasicUser.Id) 3384 }) 3385 3386 t.Run("bot login rejected", func(t *testing.T) { 3387 bot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 3388 Username: "bot", 3389 }) 3390 CheckNoError(t, resp) 3391 3392 botUser, resp := th.SystemAdminClient.GetUser(bot.UserId, "") 3393 CheckNoError(t, resp) 3394 3395 changed, resp := th.SystemAdminClient.UpdateUserPassword(bot.UserId, "", "password") 3396 CheckNoError(t, resp) 3397 require.True(t, changed) 3398 3399 _, resp = th.Client.Login(botUser.Email, "password") 3400 CheckErrorMessage(t, resp, "api.user.login.bot_login_forbidden.app_error") 3401 }) 3402 3403 t.Run("login with terms_of_service set", func(t *testing.T) { 3404 termsOfService, err := th.App.CreateTermsOfService("terms of service", th.BasicUser.Id) 3405 require.Nil(t, err) 3406 3407 success, resp := th.Client.RegisterTermsOfServiceAction(th.BasicUser.Id, termsOfService.Id, true) 3408 CheckNoError(t, resp) 3409 assert.True(t, *success) 3410 3411 userTermsOfService, resp := th.Client.GetUserTermsOfService(th.BasicUser.Id, "") 3412 CheckNoError(t, resp) 3413 3414 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3415 CheckNoError(t, resp) 3416 assert.Equal(t, user.Id, th.BasicUser.Id) 3417 assert.Equal(t, user.TermsOfServiceId, userTermsOfService.TermsOfServiceId) 3418 assert.Equal(t, user.TermsOfServiceCreateAt, userTermsOfService.CreateAt) 3419 }) 3420 } 3421 3422 func TestLoginWithLag(t *testing.T) { 3423 th := Setup(t).InitBasic() 3424 defer th.TearDown() 3425 th.Client.Logout() 3426 3427 t.Run("with replication lag, caches cleared", func(t *testing.T) { 3428 if !replicaFlag { 3429 t.Skipf("requires test flag: -mysql-replica") 3430 } 3431 3432 if *th.App.Srv().Config().SqlSettings.DriverName != model.DATABASE_DRIVER_MYSQL { 3433 t.Skipf("requires %q database driver", model.DATABASE_DRIVER_MYSQL) 3434 } 3435 3436 mainHelper.SQLStore.UpdateLicense(model.NewTestLicense("ldap")) 3437 mainHelper.ToggleReplicasOff() 3438 3439 err := th.App.RevokeAllSessions(th.BasicUser.Id) 3440 require.Nil(t, err) 3441 3442 mainHelper.ToggleReplicasOn() 3443 defer mainHelper.ToggleReplicasOff() 3444 3445 cmdErr := mainHelper.SetReplicationLagForTesting(5) 3446 require.NoError(t, cmdErr) 3447 defer mainHelper.SetReplicationLagForTesting(0) 3448 3449 _, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3450 CheckNoError(t, resp) 3451 3452 err = th.App.Srv().InvalidateAllCaches() 3453 require.Nil(t, err) 3454 3455 session, err := th.App.GetSession(th.Client.AuthToken) 3456 require.Nil(t, err) 3457 require.NotNil(t, session) 3458 }) 3459 } 3460 3461 func TestLoginCookies(t *testing.T) { 3462 t.Run("should return cookies with X-Requested-With header", func(t *testing.T) { 3463 th := Setup(t).InitBasic() 3464 defer th.TearDown() 3465 3466 th.Client.HttpHeader[model.HEADER_REQUESTED_WITH] = model.HEADER_REQUESTED_WITH_XML 3467 3468 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3469 3470 sessionCookie := "" 3471 userCookie := "" 3472 csrfCookie := "" 3473 3474 for _, cookie := range resp.Header["Set-Cookie"] { 3475 if match := regexp.MustCompile("^" + model.SESSION_COOKIE_TOKEN + "=([a-z0-9]+)").FindStringSubmatch(cookie); match != nil { 3476 sessionCookie = match[1] 3477 } else if match := regexp.MustCompile("^" + model.SESSION_COOKIE_USER + "=([a-z0-9]+)").FindStringSubmatch(cookie); match != nil { 3478 userCookie = match[1] 3479 } else if match := regexp.MustCompile("^" + model.SESSION_COOKIE_CSRF + "=([a-z0-9]+)").FindStringSubmatch(cookie); match != nil { 3480 csrfCookie = match[1] 3481 } 3482 } 3483 3484 session, _ := th.App.GetSession(th.Client.AuthToken) 3485 3486 assert.Equal(t, th.Client.AuthToken, sessionCookie) 3487 assert.Equal(t, user.Id, userCookie) 3488 assert.Equal(t, session.GetCSRF(), csrfCookie) 3489 }) 3490 3491 t.Run("should not return cookies without X-Requested-With header", func(t *testing.T) { 3492 th := Setup(t).InitBasic() 3493 defer th.TearDown() 3494 3495 _, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3496 3497 assert.Empty(t, resp.Header.Get("Set-Cookie")) 3498 }) 3499 3500 t.Run("should include subpath in path", func(t *testing.T) { 3501 th := Setup(t).InitBasic() 3502 defer th.TearDown() 3503 3504 th.Client.HttpHeader[model.HEADER_REQUESTED_WITH] = model.HEADER_REQUESTED_WITH_XML 3505 3506 testCases := []struct { 3507 Description string 3508 SiteURL string 3509 ExpectedSetCookieHeaderRegexp string 3510 }{ 3511 {"no subpath", "http://localhost:8065", "^MMAUTHTOKEN=[a-z0-9]+; Path=/"}, 3512 {"subpath", "http://localhost:8065/subpath", "^MMAUTHTOKEN=[a-z0-9]+; Path=/subpath"}, 3513 } 3514 3515 for _, tc := range testCases { 3516 t.Run(tc.Description, func(t *testing.T) { 3517 th.App.UpdateConfig(func(cfg *model.Config) { 3518 *cfg.ServiceSettings.SiteURL = tc.SiteURL 3519 }) 3520 3521 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3522 CheckNoError(t, resp) 3523 assert.Equal(t, user.Id, th.BasicUser.Id) 3524 3525 cookies := resp.Header.Get("Set-Cookie") 3526 assert.Regexp(t, tc.ExpectedSetCookieHeaderRegexp, cookies) 3527 }) 3528 } 3529 }) 3530 } 3531 3532 func TestCBALogin(t *testing.T) { 3533 t.Run("primary", func(t *testing.T) { 3534 th := Setup(t).InitBasic() 3535 defer th.TearDown() 3536 th.App.Srv().SetLicense(model.NewTestLicense("saml")) 3537 3538 th.App.UpdateConfig(func(cfg *model.Config) { 3539 *cfg.ServiceSettings.EnableBotAccountCreation = true 3540 }) 3541 3542 th.App.UpdateConfig(func(cfg *model.Config) { 3543 *cfg.ExperimentalSettings.ClientSideCertEnable = true 3544 *cfg.ExperimentalSettings.ClientSideCertCheck = model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH 3545 }) 3546 3547 t.Run("missing cert header", func(t *testing.T) { 3548 th.Client.Logout() 3549 _, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3550 CheckBadRequestStatus(t, resp) 3551 }) 3552 3553 t.Run("missing cert subject", func(t *testing.T) { 3554 th.Client.Logout() 3555 th.Client.HttpHeader["X-SSL-Client-Cert"] = "valid_cert_fake" 3556 _, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3557 CheckBadRequestStatus(t, resp) 3558 }) 3559 3560 t.Run("emails mismatch", func(t *testing.T) { 3561 th.Client.Logout() 3562 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=mis_match" + th.BasicUser.Email 3563 _, resp := th.Client.Login(th.BasicUser.Email, "") 3564 CheckUnauthorizedStatus(t, resp) 3565 }) 3566 3567 t.Run("successful cba login", func(t *testing.T) { 3568 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=" + th.BasicUser.Email 3569 user, resp := th.Client.Login(th.BasicUser.Email, "") 3570 CheckNoError(t, resp) 3571 require.NotNil(t, user) 3572 require.Equal(t, th.BasicUser.Id, user.Id) 3573 }) 3574 3575 t.Run("bot login rejected", func(t *testing.T) { 3576 bot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 3577 Username: "bot", 3578 }) 3579 CheckNoError(t, resp) 3580 3581 botUser, resp := th.SystemAdminClient.GetUser(bot.UserId, "") 3582 CheckNoError(t, resp) 3583 3584 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=" + botUser.Email 3585 3586 _, resp = th.Client.Login(botUser.Email, "") 3587 CheckErrorMessage(t, resp, "api.user.login.bot_login_forbidden.app_error") 3588 }) 3589 }) 3590 3591 t.Run("secondary", func(t *testing.T) { 3592 th := Setup(t).InitBasic() 3593 defer th.TearDown() 3594 th.App.Srv().SetLicense(model.NewTestLicense("saml")) 3595 3596 th.App.UpdateConfig(func(cfg *model.Config) { 3597 *cfg.ServiceSettings.EnableBotAccountCreation = true 3598 }) 3599 3600 th.Client.HttpHeader["X-SSL-Client-Cert"] = "valid_cert_fake" 3601 3602 th.App.UpdateConfig(func(cfg *model.Config) { 3603 *cfg.ExperimentalSettings.ClientSideCertEnable = true 3604 *cfg.ExperimentalSettings.ClientSideCertCheck = model.CLIENT_SIDE_CERT_CHECK_SECONDARY_AUTH 3605 }) 3606 3607 t.Run("password required", func(t *testing.T) { 3608 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=" + th.BasicUser.Email 3609 _, resp := th.Client.Login(th.BasicUser.Email, "") 3610 CheckBadRequestStatus(t, resp) 3611 }) 3612 3613 t.Run("successful cba login with password", func(t *testing.T) { 3614 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=" + th.BasicUser.Email 3615 user, resp := th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3616 CheckNoError(t, resp) 3617 require.NotNil(t, user) 3618 require.Equal(t, th.BasicUser.Id, user.Id) 3619 }) 3620 3621 t.Run("bot login rejected", func(t *testing.T) { 3622 bot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 3623 Username: "bot", 3624 }) 3625 CheckNoError(t, resp) 3626 3627 botUser, resp := th.SystemAdminClient.GetUser(bot.UserId, "") 3628 CheckNoError(t, resp) 3629 3630 changed, resp := th.SystemAdminClient.UpdateUserPassword(bot.UserId, "", "password") 3631 CheckNoError(t, resp) 3632 require.True(t, changed) 3633 3634 th.Client.HttpHeader["X-SSL-Client-Cert-Subject-DN"] = "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=" + botUser.Email 3635 3636 _, resp = th.Client.Login(botUser.Email, "password") 3637 CheckErrorMessage(t, resp, "api.user.login.bot_login_forbidden.app_error") 3638 }) 3639 }) 3640 } 3641 3642 func TestSwitchAccount(t *testing.T) { 3643 th := Setup(t).InitBasic() 3644 defer th.TearDown() 3645 3646 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GitLabSettings.Enable = true }) 3647 3648 th.Client.Logout() 3649 3650 sr := &model.SwitchRequest{ 3651 CurrentService: model.USER_AUTH_SERVICE_EMAIL, 3652 NewService: model.USER_AUTH_SERVICE_GITLAB, 3653 Email: th.BasicUser.Email, 3654 Password: th.BasicUser.Password, 3655 } 3656 3657 link, resp := th.Client.SwitchAccountType(sr) 3658 CheckNoError(t, resp) 3659 3660 require.NotEmpty(t, link, "bad link") 3661 3662 th.App.Srv().SetLicense(model.NewTestLicense()) 3663 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = false }) 3664 3665 sr = &model.SwitchRequest{ 3666 CurrentService: model.USER_AUTH_SERVICE_EMAIL, 3667 NewService: model.USER_AUTH_SERVICE_GITLAB, 3668 } 3669 3670 _, resp = th.Client.SwitchAccountType(sr) 3671 CheckForbiddenStatus(t, resp) 3672 3673 th.LoginBasic() 3674 3675 sr = &model.SwitchRequest{ 3676 CurrentService: model.USER_AUTH_SERVICE_SAML, 3677 NewService: model.USER_AUTH_SERVICE_EMAIL, 3678 Email: th.BasicUser.Email, 3679 NewPassword: th.BasicUser.Password, 3680 } 3681 3682 _, resp = th.Client.SwitchAccountType(sr) 3683 CheckForbiddenStatus(t, resp) 3684 3685 sr = &model.SwitchRequest{ 3686 CurrentService: model.USER_AUTH_SERVICE_EMAIL, 3687 NewService: model.USER_AUTH_SERVICE_LDAP, 3688 } 3689 3690 _, resp = th.Client.SwitchAccountType(sr) 3691 CheckForbiddenStatus(t, resp) 3692 3693 sr = &model.SwitchRequest{ 3694 CurrentService: model.USER_AUTH_SERVICE_LDAP, 3695 NewService: model.USER_AUTH_SERVICE_EMAIL, 3696 } 3697 3698 _, resp = th.Client.SwitchAccountType(sr) 3699 CheckForbiddenStatus(t, resp) 3700 3701 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = true }) 3702 3703 th.LoginBasic() 3704 3705 fakeAuthData := model.NewId() 3706 _, err := th.App.Srv().Store.User().UpdateAuthData(th.BasicUser.Id, model.USER_AUTH_SERVICE_GITLAB, &fakeAuthData, th.BasicUser.Email, true) 3707 require.NoError(t, err) 3708 3709 sr = &model.SwitchRequest{ 3710 CurrentService: model.USER_AUTH_SERVICE_GITLAB, 3711 NewService: model.USER_AUTH_SERVICE_EMAIL, 3712 Email: th.BasicUser.Email, 3713 NewPassword: th.BasicUser.Password, 3714 } 3715 3716 link, resp = th.Client.SwitchAccountType(sr) 3717 CheckNoError(t, resp) 3718 3719 require.Equal(t, "/login?extra=signin_change", link) 3720 3721 th.Client.Logout() 3722 _, resp = th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 3723 CheckNoError(t, resp) 3724 th.Client.Logout() 3725 3726 sr = &model.SwitchRequest{ 3727 CurrentService: model.USER_AUTH_SERVICE_GITLAB, 3728 NewService: model.SERVICE_GOOGLE, 3729 } 3730 3731 _, resp = th.Client.SwitchAccountType(sr) 3732 CheckBadRequestStatus(t, resp) 3733 3734 sr = &model.SwitchRequest{ 3735 CurrentService: model.USER_AUTH_SERVICE_EMAIL, 3736 NewService: model.USER_AUTH_SERVICE_GITLAB, 3737 Password: th.BasicUser.Password, 3738 } 3739 3740 _, resp = th.Client.SwitchAccountType(sr) 3741 CheckNotFoundStatus(t, resp) 3742 3743 sr = &model.SwitchRequest{ 3744 CurrentService: model.USER_AUTH_SERVICE_EMAIL, 3745 NewService: model.USER_AUTH_SERVICE_GITLAB, 3746 Email: th.BasicUser.Email, 3747 } 3748 3749 _, resp = th.Client.SwitchAccountType(sr) 3750 CheckUnauthorizedStatus(t, resp) 3751 3752 sr = &model.SwitchRequest{ 3753 CurrentService: model.USER_AUTH_SERVICE_GITLAB, 3754 NewService: model.USER_AUTH_SERVICE_EMAIL, 3755 Email: th.BasicUser.Email, 3756 NewPassword: th.BasicUser.Password, 3757 } 3758 3759 _, resp = th.Client.SwitchAccountType(sr) 3760 CheckUnauthorizedStatus(t, resp) 3761 } 3762 3763 func assertToken(t *testing.T, th *TestHelper, token *model.UserAccessToken, expectedUserId string) { 3764 t.Helper() 3765 3766 oldSessionToken := th.Client.AuthToken 3767 defer func() { th.Client.AuthToken = oldSessionToken }() 3768 3769 th.Client.AuthToken = token.Token 3770 ruser, resp := th.Client.GetMe("") 3771 CheckNoError(t, resp) 3772 3773 assert.Equal(t, expectedUserId, ruser.Id, "returned wrong user") 3774 } 3775 3776 func assertInvalidToken(t *testing.T, th *TestHelper, token *model.UserAccessToken) { 3777 t.Helper() 3778 3779 oldSessionToken := th.Client.AuthToken 3780 defer func() { th.Client.AuthToken = oldSessionToken }() 3781 3782 th.Client.AuthToken = token.Token 3783 _, resp := th.Client.GetMe("") 3784 CheckUnauthorizedStatus(t, resp) 3785 } 3786 3787 func TestCreateUserAccessToken(t *testing.T) { 3788 t.Run("create token without permission", func(t *testing.T) { 3789 th := Setup(t).InitBasic() 3790 defer th.TearDown() 3791 3792 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3793 3794 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 3795 CheckForbiddenStatus(t, resp) 3796 }) 3797 3798 t.Run("system admin and local mode can create access token", func(t *testing.T) { 3799 th := Setup(t).InitBasic() 3800 defer th.TearDown() 3801 3802 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3803 3804 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 3805 rtoken, resp := client.CreateUserAccessToken(th.BasicUser.Id, "test token") 3806 CheckNoError(t, resp) 3807 3808 assert.Equal(t, th.BasicUser.Id, rtoken.UserId, "wrong user id") 3809 assert.NotEmpty(t, rtoken.Token, "token should not be empty") 3810 assert.NotEmpty(t, rtoken.Id, "id should not be empty") 3811 assert.Equal(t, "test token", rtoken.Description, "description did not match") 3812 assert.True(t, rtoken.IsActive, "token should be active") 3813 assertToken(t, th, rtoken, th.BasicUser.Id) 3814 }) 3815 }) 3816 3817 t.Run("create token for invalid user id", func(t *testing.T) { 3818 th := Setup(t).InitBasic() 3819 defer th.TearDown() 3820 3821 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3822 3823 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 3824 _, resp := client.CreateUserAccessToken("notarealuserid", "test token") 3825 CheckBadRequestStatus(t, resp) 3826 }) 3827 }) 3828 3829 t.Run("create token with invalid value", func(t *testing.T) { 3830 th := Setup(t).InitBasic() 3831 defer th.TearDown() 3832 3833 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3834 3835 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 3836 _, resp := client.CreateUserAccessToken(th.BasicUser.Id, "") 3837 CheckBadRequestStatus(t, resp) 3838 }) 3839 }) 3840 3841 t.Run("create token with user access tokens disabled", func(t *testing.T) { 3842 th := Setup(t).InitBasic() 3843 defer th.TearDown() 3844 3845 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = false }) 3846 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 3847 3848 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 3849 _, resp := client.CreateUserAccessToken(th.BasicUser.Id, "test token") 3850 CheckNotImplementedStatus(t, resp) 3851 }) 3852 }) 3853 3854 t.Run("create user access token", func(t *testing.T) { 3855 th := Setup(t).InitBasic() 3856 defer th.TearDown() 3857 3858 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3859 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 3860 3861 rtoken, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 3862 CheckNoError(t, resp) 3863 3864 assert.Equal(t, th.BasicUser.Id, rtoken.UserId, "wrong user id") 3865 assert.NotEmpty(t, rtoken.Token, "token should not be empty") 3866 assert.NotEmpty(t, rtoken.Id, "id should not be empty") 3867 assert.Equal(t, "test token", rtoken.Description, "description did not match") 3868 assert.True(t, rtoken.IsActive, "token should be active") 3869 3870 assertToken(t, th, rtoken, th.BasicUser.Id) 3871 }) 3872 3873 t.Run("create user access token as second user, without permission", func(t *testing.T) { 3874 th := Setup(t).InitBasic() 3875 defer th.TearDown() 3876 3877 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3878 3879 _, resp := th.Client.CreateUserAccessToken(th.BasicUser2.Id, "test token") 3880 CheckForbiddenStatus(t, resp) 3881 }) 3882 3883 t.Run("create user access token for basic user as as system admin", func(t *testing.T) { 3884 th := Setup(t).InitBasic() 3885 defer th.TearDown() 3886 3887 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3888 3889 rtoken, resp := th.SystemAdminClient.CreateUserAccessToken(th.BasicUser.Id, "test token") 3890 CheckNoError(t, resp) 3891 assert.Equal(t, th.BasicUser.Id, rtoken.UserId) 3892 3893 oldSessionToken := th.Client.AuthToken 3894 defer func() { th.Client.AuthToken = oldSessionToken }() 3895 3896 assertToken(t, th, rtoken, th.BasicUser.Id) 3897 }) 3898 3899 t.Run("create access token as oauth session", func(t *testing.T) { 3900 th := Setup(t).InitBasic() 3901 defer th.TearDown() 3902 3903 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3904 3905 session, _ := th.App.GetSession(th.Client.AuthToken) 3906 session.IsOAuth = true 3907 th.App.AddSessionToCache(session) 3908 3909 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 3910 CheckForbiddenStatus(t, resp) 3911 }) 3912 3913 t.Run("create access token for bot created by user", func(t *testing.T) { 3914 th := Setup(t).InitBasic() 3915 defer th.TearDown() 3916 3917 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3918 3919 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 3920 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 3921 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 3922 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 3923 th.App.UpdateConfig(func(cfg *model.Config) { 3924 *cfg.ServiceSettings.EnableBotAccountCreation = true 3925 }) 3926 3927 createdBot, resp := th.Client.CreateBot(&model.Bot{ 3928 Username: GenerateTestUsername(), 3929 DisplayName: "a bot", 3930 Description: "bot", 3931 }) 3932 CheckCreatedStatus(t, resp) 3933 defer th.App.PermanentDeleteBot(createdBot.UserId) 3934 3935 t.Run("without MANAGE_BOT permission", func(t *testing.T) { 3936 th.RemovePermissionFromRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 3937 3938 _, resp = th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 3939 CheckForbiddenStatus(t, resp) 3940 }) 3941 3942 t.Run("with MANAGE_BOTS permission", func(t *testing.T) { 3943 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 3944 3945 token, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 3946 CheckNoError(t, resp) 3947 assert.Equal(t, createdBot.UserId, token.UserId) 3948 assertToken(t, th, token, createdBot.UserId) 3949 }) 3950 }) 3951 3952 t.Run("create access token for bot created by another user, only having MANAGE_BOTS permission", func(t *testing.T) { 3953 th := Setup(t).InitBasic() 3954 defer th.TearDown() 3955 3956 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3957 3958 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 3959 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 3960 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 3961 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 3962 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 3963 th.App.UpdateConfig(func(cfg *model.Config) { 3964 *cfg.ServiceSettings.EnableBotAccountCreation = true 3965 }) 3966 3967 createdBot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 3968 Username: GenerateTestUsername(), 3969 DisplayName: "a bot", 3970 Description: "bot", 3971 }) 3972 CheckCreatedStatus(t, resp) 3973 defer th.App.PermanentDeleteBot(createdBot.UserId) 3974 3975 t.Run("only having MANAGE_BOTS permission", func(t *testing.T) { 3976 _, resp = th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 3977 CheckForbiddenStatus(t, resp) 3978 }) 3979 3980 t.Run("with MANAGE_OTHERS_BOTS permission", func(t *testing.T) { 3981 th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.TEAM_USER_ROLE_ID) 3982 3983 rtoken, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 3984 CheckNoError(t, resp) 3985 assert.Equal(t, createdBot.UserId, rtoken.UserId) 3986 3987 assertToken(t, th, rtoken, createdBot.UserId) 3988 }) 3989 }) 3990 } 3991 3992 func TestGetUserAccessToken(t *testing.T) { 3993 t.Run("get for invalid user id", func(t *testing.T) { 3994 th := Setup(t).InitBasic() 3995 defer th.TearDown() 3996 3997 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 3998 3999 _, resp := th.Client.GetUserAccessToken("123") 4000 CheckBadRequestStatus(t, resp) 4001 }) 4002 4003 t.Run("get for unknown user id", func(t *testing.T) { 4004 th := Setup(t).InitBasic() 4005 defer th.TearDown() 4006 4007 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4008 4009 _, resp := th.Client.GetUserAccessToken(model.NewId()) 4010 CheckForbiddenStatus(t, resp) 4011 }) 4012 4013 t.Run("get my token", func(t *testing.T) { 4014 th := Setup(t).InitBasic() 4015 defer th.TearDown() 4016 4017 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4018 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4019 4020 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4021 CheckNoError(t, resp) 4022 4023 rtoken, resp := th.Client.GetUserAccessToken(token.Id) 4024 CheckNoError(t, resp) 4025 4026 assert.Equal(t, th.BasicUser.Id, rtoken.UserId, "wrong user id") 4027 assert.Empty(t, rtoken.Token, "token should be blank") 4028 assert.NotEmpty(t, rtoken.Id, "id should not be empty") 4029 assert.Equal(t, "test token", rtoken.Description, "description did not match") 4030 }) 4031 4032 t.Run("get user token as system admin", func(t *testing.T) { 4033 th := Setup(t).InitBasic() 4034 defer th.TearDown() 4035 4036 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4037 4038 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4039 4040 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4041 CheckNoError(t, resp) 4042 4043 rtoken, resp := th.SystemAdminClient.GetUserAccessToken(token.Id) 4044 CheckNoError(t, resp) 4045 4046 assert.Equal(t, th.BasicUser.Id, rtoken.UserId, "wrong user id") 4047 assert.Empty(t, rtoken.Token, "token should be blank") 4048 assert.NotEmpty(t, rtoken.Id, "id should not be empty") 4049 assert.Equal(t, "test token", rtoken.Description, "description did not match") 4050 }) 4051 4052 t.Run("get token for bot created by user", func(t *testing.T) { 4053 th := Setup(t).InitBasic() 4054 defer th.TearDown() 4055 4056 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4057 4058 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4059 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4060 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4061 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4062 th.AddPermissionToRole(model.PERMISSION_READ_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4063 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4064 th.App.UpdateConfig(func(cfg *model.Config) { 4065 *cfg.ServiceSettings.EnableBotAccountCreation = true 4066 }) 4067 4068 createdBot, resp := th.Client.CreateBot(&model.Bot{ 4069 Username: GenerateTestUsername(), 4070 DisplayName: "a bot", 4071 Description: "bot", 4072 }) 4073 CheckCreatedStatus(t, resp) 4074 defer th.App.PermanentDeleteBot(createdBot.UserId) 4075 4076 token, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 4077 CheckNoError(t, resp) 4078 4079 t.Run("without MANAGE_BOTS permission", func(t *testing.T) { 4080 th.RemovePermissionFromRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4081 4082 _, resp := th.Client.GetUserAccessToken(token.Id) 4083 CheckForbiddenStatus(t, resp) 4084 }) 4085 4086 t.Run("with MANAGE_BOTS permission", func(t *testing.T) { 4087 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4088 4089 returnedToken, resp := th.Client.GetUserAccessToken(token.Id) 4090 CheckNoError(t, resp) 4091 4092 // Actual token won't be returned. 4093 returnedToken.Token = token.Token 4094 assert.Equal(t, token, returnedToken) 4095 }) 4096 }) 4097 4098 t.Run("get token for bot created by another user", func(t *testing.T) { 4099 th := Setup(t).InitBasic() 4100 defer th.TearDown() 4101 4102 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4103 4104 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4105 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4106 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4107 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4108 th.AddPermissionToRole(model.PERMISSION_READ_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4109 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4110 th.App.UpdateConfig(func(cfg *model.Config) { 4111 *cfg.ServiceSettings.EnableBotAccountCreation = true 4112 }) 4113 4114 createdBot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 4115 Username: GenerateTestUsername(), 4116 DisplayName: "a bot", 4117 Description: "bot", 4118 }) 4119 CheckCreatedStatus(t, resp) 4120 defer th.App.PermanentDeleteBot(createdBot.UserId) 4121 4122 token, resp := th.SystemAdminClient.CreateUserAccessToken(createdBot.UserId, "test token") 4123 CheckNoError(t, resp) 4124 4125 t.Run("only having MANAGE_BOTS permission", func(t *testing.T) { 4126 _, resp = th.Client.GetUserAccessToken(token.Id) 4127 CheckForbiddenStatus(t, resp) 4128 }) 4129 4130 t.Run("with MANAGE_OTHERS_BOTS permission", func(t *testing.T) { 4131 th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.TEAM_USER_ROLE_ID) 4132 4133 returnedToken, resp := th.Client.GetUserAccessToken(token.Id) 4134 CheckNoError(t, resp) 4135 4136 // Actual token won't be returned. 4137 returnedToken.Token = token.Token 4138 assert.Equal(t, token, returnedToken) 4139 }) 4140 }) 4141 } 4142 4143 func TestGetUserAccessTokensForUser(t *testing.T) { 4144 t.Run("multiple tokens, offset 0, limit 100", func(t *testing.T) { 4145 th := Setup(t).InitBasic() 4146 defer th.TearDown() 4147 4148 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4149 4150 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4151 4152 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4153 CheckNoError(t, resp) 4154 4155 _, resp = th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4156 CheckNoError(t, resp) 4157 4158 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 4159 rtokens, resp := client.GetUserAccessTokensForUser(th.BasicUser.Id, 0, 100) 4160 CheckNoError(t, resp) 4161 4162 assert.Len(t, rtokens, 2, "should have 2 tokens") 4163 for _, uat := range rtokens { 4164 assert.Equal(t, th.BasicUser.Id, uat.UserId, "wrong user id") 4165 } 4166 }) 4167 }) 4168 4169 t.Run("multiple tokens, offset 1, limit 1", func(t *testing.T) { 4170 th := Setup(t).InitBasic() 4171 defer th.TearDown() 4172 4173 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4174 4175 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4176 4177 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4178 CheckNoError(t, resp) 4179 4180 _, resp = th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4181 CheckNoError(t, resp) 4182 4183 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 4184 rtokens, resp := client.GetUserAccessTokensForUser(th.BasicUser.Id, 1, 1) 4185 CheckNoError(t, resp) 4186 4187 assert.Len(t, rtokens, 1, "should have 1 tokens") 4188 for _, uat := range rtokens { 4189 assert.Equal(t, th.BasicUser.Id, uat.UserId, "wrong user id") 4190 } 4191 }) 4192 }) 4193 } 4194 4195 func TestGetUserAccessTokens(t *testing.T) { 4196 t.Run("GetUserAccessTokens, not a system admin", func(t *testing.T) { 4197 th := Setup(t).InitBasic() 4198 defer th.TearDown() 4199 4200 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4201 4202 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4203 4204 _, resp := th.Client.GetUserAccessTokens(0, 100) 4205 CheckForbiddenStatus(t, resp) 4206 }) 4207 4208 t.Run("GetUserAccessTokens, as a system admin, page 1, perPage 1", func(t *testing.T) { 4209 th := Setup(t).InitBasic() 4210 defer th.TearDown() 4211 4212 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4213 4214 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4215 4216 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4217 CheckNoError(t, resp) 4218 4219 _, resp = th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4220 CheckNoError(t, resp) 4221 4222 rtokens, resp := th.SystemAdminClient.GetUserAccessTokens(1, 1) 4223 CheckNoError(t, resp) 4224 4225 assert.Len(t, rtokens, 1, "should have 1 token") 4226 }) 4227 4228 t.Run("GetUserAccessTokens, as a system admin, page 0, perPage 2", func(t *testing.T) { 4229 th := Setup(t).InitBasic() 4230 defer th.TearDown() 4231 4232 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4233 4234 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4235 4236 _, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4237 CheckNoError(t, resp) 4238 4239 _, resp = th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token 2") 4240 CheckNoError(t, resp) 4241 4242 rtokens, resp := th.SystemAdminClient.GetUserAccessTokens(0, 2) 4243 CheckNoError(t, resp) 4244 4245 assert.Len(t, rtokens, 2, "should have 2 tokens") 4246 }) 4247 } 4248 4249 func TestSearchUserAccessToken(t *testing.T) { 4250 th := Setup(t).InitBasic() 4251 defer th.TearDown() 4252 4253 testDescription := "test token" 4254 4255 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4256 4257 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4258 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) 4259 CheckNoError(t, resp) 4260 4261 _, resp = th.Client.SearchUserAccessTokens(&model.UserAccessTokenSearch{Term: token.Id}) 4262 CheckForbiddenStatus(t, resp) 4263 4264 rtokens, resp := th.SystemAdminClient.SearchUserAccessTokens(&model.UserAccessTokenSearch{Term: th.BasicUser.Id}) 4265 CheckNoError(t, resp) 4266 4267 require.Len(t, rtokens, 1, "should have 1 token") 4268 4269 rtokens, resp = th.SystemAdminClient.SearchUserAccessTokens(&model.UserAccessTokenSearch{Term: token.Id}) 4270 CheckNoError(t, resp) 4271 4272 require.Len(t, rtokens, 1, "should have 1 token") 4273 4274 rtokens, resp = th.SystemAdminClient.SearchUserAccessTokens(&model.UserAccessTokenSearch{Term: th.BasicUser.Username}) 4275 CheckNoError(t, resp) 4276 4277 require.Len(t, rtokens, 1, "should have 1 token") 4278 4279 rtokens, resp = th.SystemAdminClient.SearchUserAccessTokens(&model.UserAccessTokenSearch{Term: "not found"}) 4280 CheckNoError(t, resp) 4281 4282 require.Empty(t, rtokens, "should have 1 tokens") 4283 } 4284 4285 func TestRevokeUserAccessToken(t *testing.T) { 4286 t.Run("revoke user token", func(t *testing.T) { 4287 th := Setup(t).InitBasic() 4288 defer th.TearDown() 4289 4290 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4291 4292 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4293 th.TestForAllClients(t, func(t *testing.T, client *model.Client4) { 4294 token, resp := client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4295 CheckNoError(t, resp) 4296 assertToken(t, th, token, th.BasicUser.Id) 4297 4298 ok, resp := client.RevokeUserAccessToken(token.Id) 4299 CheckNoError(t, resp) 4300 assert.True(t, ok, "should have passed") 4301 4302 assertInvalidToken(t, th, token) 4303 }) 4304 }) 4305 4306 t.Run("revoke token belonging to another user", func(t *testing.T) { 4307 th := Setup(t).InitBasic() 4308 defer th.TearDown() 4309 4310 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4311 4312 token, resp := th.SystemAdminClient.CreateUserAccessToken(th.BasicUser2.Id, "test token") 4313 CheckNoError(t, resp) 4314 4315 ok, resp := th.Client.RevokeUserAccessToken(token.Id) 4316 CheckForbiddenStatus(t, resp) 4317 assert.False(t, ok, "should have failed") 4318 }) 4319 4320 t.Run("revoke token for bot created by user", func(t *testing.T) { 4321 th := Setup(t).InitBasic() 4322 defer th.TearDown() 4323 4324 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4325 4326 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4327 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4328 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4329 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4330 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4331 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4332 th.App.UpdateConfig(func(cfg *model.Config) { 4333 *cfg.ServiceSettings.EnableBotAccountCreation = true 4334 }) 4335 4336 createdBot, resp := th.Client.CreateBot(&model.Bot{ 4337 Username: GenerateTestUsername(), 4338 DisplayName: "a bot", 4339 Description: "bot", 4340 }) 4341 CheckCreatedStatus(t, resp) 4342 defer th.App.PermanentDeleteBot(createdBot.UserId) 4343 4344 token, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 4345 CheckNoError(t, resp) 4346 4347 t.Run("without MANAGE_BOTS permission", func(t *testing.T) { 4348 th.RemovePermissionFromRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4349 4350 _, resp := th.Client.RevokeUserAccessToken(token.Id) 4351 CheckForbiddenStatus(t, resp) 4352 }) 4353 4354 t.Run("with MANAGE_BOTS permission", func(t *testing.T) { 4355 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4356 4357 ok, resp := th.Client.RevokeUserAccessToken(token.Id) 4358 CheckNoError(t, resp) 4359 assert.True(t, ok, "should have passed") 4360 }) 4361 }) 4362 4363 t.Run("revoke token for bot created by another user", func(t *testing.T) { 4364 th := Setup(t).InitBasic() 4365 defer th.TearDown() 4366 4367 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4368 4369 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4370 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4371 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4372 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4373 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4374 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4375 th.App.UpdateConfig(func(cfg *model.Config) { 4376 *cfg.ServiceSettings.EnableBotAccountCreation = true 4377 }) 4378 4379 createdBot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 4380 Username: GenerateTestUsername(), 4381 DisplayName: "a bot", 4382 Description: "bot", 4383 }) 4384 CheckCreatedStatus(t, resp) 4385 defer th.App.PermanentDeleteBot(createdBot.UserId) 4386 4387 token, resp := th.SystemAdminClient.CreateUserAccessToken(createdBot.UserId, "test token") 4388 CheckNoError(t, resp) 4389 4390 t.Run("only having MANAGE_BOTS permission", func(t *testing.T) { 4391 _, resp = th.Client.RevokeUserAccessToken(token.Id) 4392 CheckForbiddenStatus(t, resp) 4393 }) 4394 4395 t.Run("with MANAGE_OTHERS_BOTS permission", func(t *testing.T) { 4396 th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.TEAM_USER_ROLE_ID) 4397 4398 ok, resp := th.Client.RevokeUserAccessToken(token.Id) 4399 CheckNoError(t, resp) 4400 assert.True(t, ok, "should have passed") 4401 }) 4402 }) 4403 } 4404 4405 func TestDisableUserAccessToken(t *testing.T) { 4406 t.Run("disable user token", func(t *testing.T) { 4407 th := Setup(t).InitBasic() 4408 defer th.TearDown() 4409 4410 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4411 4412 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4413 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4414 CheckNoError(t, resp) 4415 assertToken(t, th, token, th.BasicUser.Id) 4416 4417 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4418 CheckNoError(t, resp) 4419 assert.True(t, ok, "should have passed") 4420 4421 assertInvalidToken(t, th, token) 4422 }) 4423 4424 t.Run("disable token belonging to another user", func(t *testing.T) { 4425 th := Setup(t).InitBasic() 4426 defer th.TearDown() 4427 4428 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4429 4430 token, resp := th.SystemAdminClient.CreateUserAccessToken(th.BasicUser2.Id, "test token") 4431 CheckNoError(t, resp) 4432 4433 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4434 CheckForbiddenStatus(t, resp) 4435 assert.False(t, ok, "should have failed") 4436 }) 4437 4438 t.Run("disable token for bot created by user", func(t *testing.T) { 4439 th := Setup(t).InitBasic() 4440 defer th.TearDown() 4441 4442 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4443 4444 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4445 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4446 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4447 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4448 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4449 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4450 th.App.UpdateConfig(func(cfg *model.Config) { 4451 *cfg.ServiceSettings.EnableBotAccountCreation = true 4452 }) 4453 4454 createdBot, resp := th.Client.CreateBot(&model.Bot{ 4455 Username: GenerateTestUsername(), 4456 DisplayName: "a bot", 4457 Description: "bot", 4458 }) 4459 CheckCreatedStatus(t, resp) 4460 defer th.App.PermanentDeleteBot(createdBot.UserId) 4461 4462 token, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 4463 CheckNoError(t, resp) 4464 4465 t.Run("without MANAGE_BOTS permission", func(t *testing.T) { 4466 th.RemovePermissionFromRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4467 4468 _, resp := th.Client.DisableUserAccessToken(token.Id) 4469 CheckForbiddenStatus(t, resp) 4470 }) 4471 4472 t.Run("with MANAGE_BOTS permission", func(t *testing.T) { 4473 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4474 4475 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4476 CheckNoError(t, resp) 4477 assert.True(t, ok, "should have passed") 4478 }) 4479 }) 4480 4481 t.Run("disable token for bot created by another user", func(t *testing.T) { 4482 th := Setup(t).InitBasic() 4483 defer th.TearDown() 4484 4485 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4486 4487 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4488 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4489 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4490 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4491 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4492 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4493 th.App.UpdateConfig(func(cfg *model.Config) { 4494 *cfg.ServiceSettings.EnableBotAccountCreation = true 4495 }) 4496 4497 createdBot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 4498 Username: GenerateTestUsername(), 4499 DisplayName: "a bot", 4500 Description: "bot", 4501 }) 4502 CheckCreatedStatus(t, resp) 4503 defer th.App.PermanentDeleteBot(createdBot.UserId) 4504 4505 token, resp := th.SystemAdminClient.CreateUserAccessToken(createdBot.UserId, "test token") 4506 CheckNoError(t, resp) 4507 4508 t.Run("only having MANAGE_BOTS permission", func(t *testing.T) { 4509 _, resp = th.Client.DisableUserAccessToken(token.Id) 4510 CheckForbiddenStatus(t, resp) 4511 }) 4512 4513 t.Run("with MANAGE_OTHERS_BOTS permission", func(t *testing.T) { 4514 th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.TEAM_USER_ROLE_ID) 4515 4516 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4517 CheckNoError(t, resp) 4518 assert.True(t, ok, "should have passed") 4519 }) 4520 }) 4521 } 4522 4523 func TestEnableUserAccessToken(t *testing.T) { 4524 t.Run("enable user token", func(t *testing.T) { 4525 th := Setup(t).InitBasic() 4526 defer th.TearDown() 4527 4528 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4529 4530 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4531 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, "test token") 4532 CheckNoError(t, resp) 4533 assertToken(t, th, token, th.BasicUser.Id) 4534 4535 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4536 CheckNoError(t, resp) 4537 assert.True(t, ok, "should have passed") 4538 4539 assertInvalidToken(t, th, token) 4540 4541 ok, resp = th.Client.EnableUserAccessToken(token.Id) 4542 CheckNoError(t, resp) 4543 assert.True(t, ok, "should have passed") 4544 4545 assertToken(t, th, token, th.BasicUser.Id) 4546 }) 4547 4548 t.Run("enable token belonging to another user", func(t *testing.T) { 4549 th := Setup(t).InitBasic() 4550 defer th.TearDown() 4551 4552 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4553 4554 token, resp := th.SystemAdminClient.CreateUserAccessToken(th.BasicUser2.Id, "test token") 4555 CheckNoError(t, resp) 4556 4557 ok, resp := th.SystemAdminClient.DisableUserAccessToken(token.Id) 4558 CheckNoError(t, resp) 4559 assert.True(t, ok, "should have passed") 4560 4561 ok, resp = th.Client.DisableUserAccessToken(token.Id) 4562 CheckForbiddenStatus(t, resp) 4563 assert.False(t, ok, "should have failed") 4564 }) 4565 4566 t.Run("enable token for bot created by user", func(t *testing.T) { 4567 th := Setup(t).InitBasic() 4568 defer th.TearDown() 4569 4570 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4571 4572 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4573 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4574 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4575 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4576 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4577 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4578 th.App.UpdateConfig(func(cfg *model.Config) { 4579 *cfg.ServiceSettings.EnableBotAccountCreation = true 4580 }) 4581 4582 createdBot, resp := th.Client.CreateBot(&model.Bot{ 4583 Username: GenerateTestUsername(), 4584 DisplayName: "a bot", 4585 Description: "bot", 4586 }) 4587 CheckCreatedStatus(t, resp) 4588 defer th.App.PermanentDeleteBot(createdBot.UserId) 4589 4590 token, resp := th.Client.CreateUserAccessToken(createdBot.UserId, "test token") 4591 CheckNoError(t, resp) 4592 4593 ok, resp := th.Client.DisableUserAccessToken(token.Id) 4594 CheckNoError(t, resp) 4595 assert.True(t, ok, "should have passed") 4596 4597 t.Run("without MANAGE_BOTS permission", func(t *testing.T) { 4598 th.RemovePermissionFromRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4599 4600 _, resp := th.Client.EnableUserAccessToken(token.Id) 4601 CheckForbiddenStatus(t, resp) 4602 }) 4603 4604 t.Run("with MANAGE_BOTS permission", func(t *testing.T) { 4605 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4606 4607 ok, resp := th.Client.EnableUserAccessToken(token.Id) 4608 CheckNoError(t, resp) 4609 assert.True(t, ok, "should have passed") 4610 }) 4611 }) 4612 4613 t.Run("enable token for bot created by another user", func(t *testing.T) { 4614 th := Setup(t).InitBasic() 4615 defer th.TearDown() 4616 4617 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4618 4619 defer th.RestoreDefaultRolePermissions(th.SaveDefaultRolePermissions()) 4620 th.AddPermissionToRole(model.PERMISSION_CREATE_BOT.Id, model.TEAM_USER_ROLE_ID) 4621 th.AddPermissionToRole(model.PERMISSION_MANAGE_BOTS.Id, model.TEAM_USER_ROLE_ID) 4622 th.AddPermissionToRole(model.PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4623 th.AddPermissionToRole(model.PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, model.TEAM_USER_ROLE_ID) 4624 th.App.UpdateUserRoles(th.BasicUser.Id, model.TEAM_USER_ROLE_ID, false) 4625 th.App.UpdateConfig(func(cfg *model.Config) { 4626 *cfg.ServiceSettings.EnableBotAccountCreation = true 4627 }) 4628 4629 createdBot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 4630 Username: GenerateTestUsername(), 4631 DisplayName: "a bot", 4632 Description: "bot", 4633 }) 4634 CheckCreatedStatus(t, resp) 4635 defer th.App.PermanentDeleteBot(createdBot.UserId) 4636 4637 token, resp := th.SystemAdminClient.CreateUserAccessToken(createdBot.UserId, "test token") 4638 CheckNoError(t, resp) 4639 4640 ok, resp := th.SystemAdminClient.DisableUserAccessToken(token.Id) 4641 CheckNoError(t, resp) 4642 assert.True(t, ok, "should have passed") 4643 4644 t.Run("only having MANAGE_BOTS permission", func(t *testing.T) { 4645 _, resp := th.Client.EnableUserAccessToken(token.Id) 4646 CheckForbiddenStatus(t, resp) 4647 }) 4648 4649 t.Run("with MANAGE_OTHERS_BOTS permission", func(t *testing.T) { 4650 th.AddPermissionToRole(model.PERMISSION_MANAGE_OTHERS_BOTS.Id, model.TEAM_USER_ROLE_ID) 4651 4652 ok, resp := th.Client.EnableUserAccessToken(token.Id) 4653 CheckNoError(t, resp) 4654 assert.True(t, ok, "should have passed") 4655 }) 4656 }) 4657 } 4658 4659 func TestUserAccessTokenInactiveUser(t *testing.T) { 4660 th := Setup(t).InitBasic() 4661 defer th.TearDown() 4662 4663 testDescription := "test token" 4664 4665 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4666 4667 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4668 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) 4669 CheckNoError(t, resp) 4670 4671 th.Client.AuthToken = token.Token 4672 _, resp = th.Client.GetMe("") 4673 CheckNoError(t, resp) 4674 4675 th.App.UpdateActive(th.Context, th.BasicUser, false) 4676 4677 _, resp = th.Client.GetMe("") 4678 CheckUnauthorizedStatus(t, resp) 4679 } 4680 4681 func TestUserAccessTokenDisableConfig(t *testing.T) { 4682 th := Setup(t).InitBasic() 4683 defer th.TearDown() 4684 4685 testDescription := "test token" 4686 4687 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = true }) 4688 4689 th.App.UpdateUserRoles(th.BasicUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_USER_ACCESS_TOKEN_ROLE_ID, false) 4690 token, resp := th.Client.CreateUserAccessToken(th.BasicUser.Id, testDescription) 4691 CheckNoError(t, resp) 4692 4693 oldSessionToken := th.Client.AuthToken 4694 th.Client.AuthToken = token.Token 4695 _, resp = th.Client.GetMe("") 4696 CheckNoError(t, resp) 4697 4698 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableUserAccessTokens = false }) 4699 4700 _, resp = th.Client.GetMe("") 4701 CheckUnauthorizedStatus(t, resp) 4702 4703 th.Client.AuthToken = oldSessionToken 4704 _, resp = th.Client.GetMe("") 4705 CheckNoError(t, resp) 4706 } 4707 4708 func TestUserAccessTokenDisableConfigBotsExcluded(t *testing.T) { 4709 th := Setup(t) 4710 defer th.TearDown() 4711 4712 th.App.UpdateConfig(func(cfg *model.Config) { 4713 *cfg.ServiceSettings.EnableBotAccountCreation = true 4714 *cfg.ServiceSettings.EnableUserAccessTokens = false 4715 }) 4716 4717 bot, resp := th.SystemAdminClient.CreateBot(&model.Bot{ 4718 Username: GenerateTestUsername(), 4719 DisplayName: "a bot", 4720 Description: "bot", 4721 }) 4722 CheckCreatedStatus(t, resp) 4723 4724 rtoken, resp := th.SystemAdminClient.CreateUserAccessToken(bot.UserId, "test token") 4725 th.Client.AuthToken = rtoken.Token 4726 CheckNoError(t, resp) 4727 4728 _, resp = th.Client.GetMe("") 4729 CheckNoError(t, resp) 4730 } 4731 4732 func TestGetUsersByStatus(t *testing.T) { 4733 th := Setup(t) 4734 defer th.TearDown() 4735 4736 team, err := th.App.CreateTeam(th.Context, &model.Team{ 4737 DisplayName: "dn_" + model.NewId(), 4738 Name: GenerateTestTeamName(), 4739 Email: th.GenerateTestEmail(), 4740 Type: model.TEAM_OPEN, 4741 }) 4742 4743 require.Nil(t, err, "failed to create team") 4744 4745 channel, err := th.App.CreateChannel(th.Context, &model.Channel{ 4746 DisplayName: "dn_" + model.NewId(), 4747 Name: "name_" + model.NewId(), 4748 Type: model.CHANNEL_OPEN, 4749 TeamId: team.Id, 4750 CreatorId: model.NewId(), 4751 }, false) 4752 require.Nil(t, err, "failed to create channel") 4753 4754 createUserWithStatus := func(username string, status string) *model.User { 4755 id := model.NewId() 4756 4757 user, err := th.App.CreateUser(th.Context, &model.User{ 4758 Email: "success+" + id + "@simulator.amazonses.com", 4759 Username: "un_" + username + "_" + id, 4760 Nickname: "nn_" + id, 4761 Password: "Password1", 4762 }) 4763 require.Nil(t, err, "failed to create user") 4764 4765 th.LinkUserToTeam(user, team) 4766 th.AddUserToChannel(user, channel) 4767 4768 th.App.SaveAndBroadcastStatus(&model.Status{ 4769 UserId: user.Id, 4770 Status: status, 4771 Manual: true, 4772 }) 4773 4774 return user 4775 } 4776 4777 // Creating these out of order in case that affects results 4778 offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE) 4779 offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE) 4780 awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY) 4781 awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY) 4782 onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE) 4783 onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE) 4784 dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND) 4785 dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND) 4786 4787 client := th.CreateClient() 4788 _, resp := client.Login(onlineUser2.Username, "Password1") 4789 require.Nil(t, resp.Error) 4790 4791 t.Run("sorting by status then alphabetical", func(t *testing.T) { 4792 usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 8, "") 4793 require.Nil(t, resp.Error) 4794 4795 expectedUsersByStatus := []*model.User{ 4796 onlineUser1, 4797 onlineUser2, 4798 awayUser1, 4799 awayUser2, 4800 dndUser1, 4801 dndUser2, 4802 offlineUser1, 4803 offlineUser2, 4804 } 4805 require.Equal(t, len(expectedUsersByStatus), len(usersByStatus)) 4806 4807 for i := range usersByStatus { 4808 require.Equal(t, expectedUsersByStatus[i].Id, usersByStatus[i].Id) 4809 } 4810 }) 4811 4812 t.Run("paging", func(t *testing.T) { 4813 usersByStatus, resp := client.GetUsersInChannelByStatus(channel.Id, 0, 3, "") 4814 require.Nil(t, resp.Error) 4815 require.Len(t, usersByStatus, 3) 4816 require.Equal(t, onlineUser1.Id, usersByStatus[0].Id, "online users first") 4817 require.Equal(t, onlineUser2.Id, usersByStatus[1].Id, "online users first") 4818 require.Equal(t, awayUser1.Id, usersByStatus[2].Id, "expected to receive away users second") 4819 4820 usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 3, "") 4821 require.Nil(t, resp.Error) 4822 4823 require.Equal(t, awayUser2.Id, usersByStatus[0].Id, "expected to receive away users second") 4824 require.Equal(t, dndUser1.Id, usersByStatus[1].Id, "expected to receive dnd users third") 4825 require.Equal(t, dndUser2.Id, usersByStatus[2].Id, "expected to receive dnd users third") 4826 4827 usersByStatus, resp = client.GetUsersInChannelByStatus(channel.Id, 1, 4, "") 4828 require.Nil(t, resp.Error) 4829 4830 require.Len(t, usersByStatus, 4) 4831 require.Equal(t, dndUser1.Id, usersByStatus[0].Id, "expected to receive dnd users third") 4832 require.Equal(t, dndUser2.Id, usersByStatus[1].Id, "expected to receive dnd users third") 4833 4834 require.Equal(t, offlineUser1.Id, usersByStatus[2].Id, "expected to receive offline users last") 4835 require.Equal(t, offlineUser2.Id, usersByStatus[3].Id, "expected to receive offline users last") 4836 }) 4837 } 4838 4839 func TestRegisterTermsOfServiceAction(t *testing.T) { 4840 th := Setup(t).InitBasic() 4841 defer th.TearDown() 4842 4843 success, resp := th.Client.RegisterTermsOfServiceAction(th.BasicUser.Id, "st_1", true) 4844 CheckErrorMessage(t, resp, "app.terms_of_service.get.no_rows.app_error") 4845 assert.Nil(t, success) 4846 4847 termsOfService, err := th.App.CreateTermsOfService("terms of service", th.BasicUser.Id) 4848 require.Nil(t, err) 4849 4850 success, resp = th.Client.RegisterTermsOfServiceAction(th.BasicUser.Id, termsOfService.Id, true) 4851 CheckNoError(t, resp) 4852 4853 assert.True(t, *success) 4854 _, err = th.App.GetUser(th.BasicUser.Id) 4855 require.Nil(t, err) 4856 } 4857 4858 func TestGetUserTermsOfService(t *testing.T) { 4859 th := Setup(t).InitBasic() 4860 defer th.TearDown() 4861 4862 _, resp := th.Client.GetUserTermsOfService(th.BasicUser.Id, "") 4863 CheckErrorMessage(t, resp, "app.user_terms_of_service.get_by_user.no_rows.app_error") 4864 4865 termsOfService, err := th.App.CreateTermsOfService("terms of service", th.BasicUser.Id) 4866 require.Nil(t, err) 4867 4868 success, resp := th.Client.RegisterTermsOfServiceAction(th.BasicUser.Id, termsOfService.Id, true) 4869 CheckNoError(t, resp) 4870 assert.True(t, *success) 4871 4872 userTermsOfService, resp := th.Client.GetUserTermsOfService(th.BasicUser.Id, "") 4873 CheckNoError(t, resp) 4874 4875 assert.Equal(t, th.BasicUser.Id, userTermsOfService.UserId) 4876 assert.Equal(t, termsOfService.Id, userTermsOfService.TermsOfServiceId) 4877 assert.NotEmpty(t, userTermsOfService.CreateAt) 4878 } 4879 4880 func TestLoginErrorMessage(t *testing.T) { 4881 th := Setup(t).InitBasic() 4882 defer th.TearDown() 4883 4884 _, resp := th.Client.Logout() 4885 CheckNoError(t, resp) 4886 4887 // Email and Username enabled 4888 th.App.UpdateConfig(func(cfg *model.Config) { 4889 *cfg.EmailSettings.EnableSignInWithEmail = true 4890 *cfg.EmailSettings.EnableSignInWithUsername = true 4891 }) 4892 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4893 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email_username") 4894 4895 // Email enabled 4896 th.App.UpdateConfig(func(cfg *model.Config) { 4897 *cfg.EmailSettings.EnableSignInWithEmail = true 4898 *cfg.EmailSettings.EnableSignInWithUsername = false 4899 }) 4900 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4901 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email") 4902 4903 // Username enabled 4904 th.App.UpdateConfig(func(cfg *model.Config) { 4905 *cfg.EmailSettings.EnableSignInWithEmail = false 4906 *cfg.EmailSettings.EnableSignInWithUsername = true 4907 }) 4908 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4909 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_username") 4910 4911 // SAML/SSO enabled 4912 th.App.UpdateConfig(func(cfg *model.Config) { 4913 *cfg.SamlSettings.Enable = true 4914 *cfg.SamlSettings.Verify = false 4915 *cfg.SamlSettings.Encrypt = false 4916 *cfg.SamlSettings.IdpUrl = "https://localhost/adfs/ls" 4917 *cfg.SamlSettings.IdpDescriptorUrl = "https://localhost/adfs/services/trust" 4918 *cfg.SamlSettings.IdpMetadataUrl = "https://localhost/adfs/metadata" 4919 *cfg.SamlSettings.ServiceProviderIdentifier = "https://localhost/login/sso/saml" 4920 *cfg.SamlSettings.AssertionConsumerServiceURL = "https://localhost/login/sso/saml" 4921 *cfg.SamlSettings.IdpCertificateFile = app.SamlIdpCertificateName 4922 *cfg.SamlSettings.PrivateKeyFile = app.SamlPrivateKeyName 4923 *cfg.SamlSettings.PublicCertificateFile = app.SamlPublicCertificateName 4924 *cfg.SamlSettings.EmailAttribute = "Email" 4925 *cfg.SamlSettings.UsernameAttribute = "Username" 4926 *cfg.SamlSettings.FirstNameAttribute = "FirstName" 4927 *cfg.SamlSettings.LastNameAttribute = "LastName" 4928 *cfg.SamlSettings.NicknameAttribute = "" 4929 *cfg.SamlSettings.PositionAttribute = "" 4930 *cfg.SamlSettings.LocaleAttribute = "" 4931 }) 4932 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4933 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_sso") 4934 } 4935 4936 func TestLoginLockout(t *testing.T) { 4937 th := Setup(t).InitBasic() 4938 defer th.TearDown() 4939 4940 _, resp := th.Client.Logout() 4941 CheckNoError(t, resp) 4942 4943 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.MaximumLoginAttempts = 3 }) 4944 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) 4945 4946 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4947 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email_username") 4948 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4949 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email_username") 4950 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4951 CheckErrorMessage(t, resp, "api.user.login.invalid_credentials_email_username") 4952 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4953 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4954 _, resp = th.Client.Login(th.BasicUser.Email, "wrong") 4955 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4956 4957 //Check if lock is active 4958 _, resp = th.Client.Login(th.BasicUser.Email, th.BasicUser.Password) 4959 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4960 4961 // Fake user has MFA enabled 4962 err := th.Server.Store.User().UpdateMfaActive(th.BasicUser2.Id, true) 4963 require.NoError(t, err) 4964 _, resp = th.Client.LoginWithMFA(th.BasicUser2.Email, th.BasicUser2.Password, "000000") 4965 CheckErrorMessage(t, resp, "api.user.check_user_mfa.bad_code.app_error") 4966 _, resp = th.Client.LoginWithMFA(th.BasicUser2.Email, th.BasicUser2.Password, "000000") 4967 CheckErrorMessage(t, resp, "api.user.check_user_mfa.bad_code.app_error") 4968 _, resp = th.Client.LoginWithMFA(th.BasicUser2.Email, th.BasicUser2.Password, "000000") 4969 CheckErrorMessage(t, resp, "api.user.check_user_mfa.bad_code.app_error") 4970 _, resp = th.Client.LoginWithMFA(th.BasicUser2.Email, th.BasicUser2.Password, "000000") 4971 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4972 _, resp = th.Client.LoginWithMFA(th.BasicUser2.Email, th.BasicUser2.Password, "000000") 4973 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4974 4975 // Fake user has MFA disabled 4976 err = th.Server.Store.User().UpdateMfaActive(th.BasicUser2.Id, false) 4977 require.NoError(t, err) 4978 4979 //Check if lock is active 4980 _, resp = th.Client.Login(th.BasicUser2.Email, th.BasicUser2.Password) 4981 CheckErrorMessage(t, resp, "api.user.check_user_login_attempts.too_many.app_error") 4982 } 4983 4984 func TestDemoteUserToGuest(t *testing.T) { 4985 th := Setup(t).InitBasic() 4986 defer th.TearDown() 4987 4988 enableGuestAccounts := *th.App.Config().GuestAccountsSettings.Enable 4989 defer func() { 4990 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = enableGuestAccounts }) 4991 th.App.Srv().RemoveLicense() 4992 }() 4993 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) 4994 th.App.Srv().SetLicense(model.NewTestLicense()) 4995 4996 user := th.BasicUser 4997 4998 th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { 4999 _, respErr := c.GetUser(user.Id, "") 5000 CheckNoError(t, respErr) 5001 5002 _, respErr = c.DemoteUserToGuest(user.Id) 5003 CheckNoError(t, respErr) 5004 5005 defer require.Nil(t, th.App.PromoteGuestToUser(th.Context, user, "")) 5006 }, "demote a user to guest") 5007 5008 t.Run("websocket update user event", func(t *testing.T) { 5009 webSocketClient, err := th.CreateWebSocketClient() 5010 assert.Nil(t, err) 5011 defer webSocketClient.Close() 5012 5013 webSocketClient.Listen() 5014 5015 time.Sleep(300 * time.Millisecond) 5016 resp := <-webSocketClient.ResponseChannel 5017 require.Equal(t, model.STATUS_OK, resp.Status) 5018 5019 adminWebSocketClient, err := th.CreateWebSocketSystemAdminClient() 5020 assert.Nil(t, err) 5021 defer adminWebSocketClient.Close() 5022 5023 adminWebSocketClient.Listen() 5024 5025 time.Sleep(300 * time.Millisecond) 5026 resp = <-adminWebSocketClient.ResponseChannel 5027 require.Equal(t, model.STATUS_OK, resp.Status) 5028 5029 _, respErr := th.SystemAdminClient.GetUser(user.Id, "") 5030 CheckNoError(t, respErr) 5031 _, respErr = th.SystemAdminClient.DemoteUserToGuest(user.Id) 5032 CheckNoError(t, respErr) 5033 defer th.SystemAdminClient.PromoteGuestToUser(user.Id) 5034 5035 assertExpectedWebsocketEvent(t, webSocketClient, model.WEBSOCKET_EVENT_USER_UPDATED, func(event *model.WebSocketEvent) { 5036 eventUser, ok := event.GetData()["user"].(*model.User) 5037 require.True(t, ok, "expected user") 5038 assert.Equal(t, "system_guest", eventUser.Roles) 5039 }) 5040 assertExpectedWebsocketEvent(t, adminWebSocketClient, model.WEBSOCKET_EVENT_USER_UPDATED, func(event *model.WebSocketEvent) { 5041 eventUser, ok := event.GetData()["user"].(*model.User) 5042 require.True(t, ok, "expected user") 5043 assert.Equal(t, "system_guest", eventUser.Roles) 5044 }) 5045 }) 5046 } 5047 5048 func TestPromoteGuestToUser(t *testing.T) { 5049 th := Setup(t).InitBasic() 5050 defer th.TearDown() 5051 5052 enableGuestAccounts := *th.App.Config().GuestAccountsSettings.Enable 5053 defer func() { 5054 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = enableGuestAccounts }) 5055 th.App.Srv().RemoveLicense() 5056 }() 5057 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) 5058 th.App.Srv().SetLicense(model.NewTestLicense()) 5059 5060 user := th.BasicUser 5061 th.App.UpdateUserRoles(user.Id, model.SYSTEM_GUEST_ROLE_ID, false) 5062 5063 th.TestForSystemAdminAndLocal(t, func(t *testing.T, c *model.Client4) { 5064 _, respErr := c.GetUser(user.Id, "") 5065 CheckNoError(t, respErr) 5066 5067 _, respErr = c.PromoteGuestToUser(user.Id) 5068 CheckNoError(t, respErr) 5069 5070 defer require.Nil(t, th.App.DemoteUserToGuest(user)) 5071 }, "promete a guest to user") 5072 5073 t.Run("websocket update user event", func(t *testing.T) { 5074 webSocketClient, err := th.CreateWebSocketClient() 5075 assert.Nil(t, err) 5076 defer webSocketClient.Close() 5077 5078 webSocketClient.Listen() 5079 5080 time.Sleep(300 * time.Millisecond) 5081 resp := <-webSocketClient.ResponseChannel 5082 require.Equal(t, model.STATUS_OK, resp.Status) 5083 5084 adminWebSocketClient, err := th.CreateWebSocketSystemAdminClient() 5085 assert.Nil(t, err) 5086 defer adminWebSocketClient.Close() 5087 5088 adminWebSocketClient.Listen() 5089 5090 time.Sleep(300 * time.Millisecond) 5091 resp = <-adminWebSocketClient.ResponseChannel 5092 require.Equal(t, model.STATUS_OK, resp.Status) 5093 5094 _, respErr := th.SystemAdminClient.GetUser(user.Id, "") 5095 CheckNoError(t, respErr) 5096 _, respErr = th.SystemAdminClient.PromoteGuestToUser(user.Id) 5097 CheckNoError(t, respErr) 5098 defer th.SystemAdminClient.DemoteUserToGuest(user.Id) 5099 5100 assertExpectedWebsocketEvent(t, webSocketClient, model.WEBSOCKET_EVENT_USER_UPDATED, func(event *model.WebSocketEvent) { 5101 eventUser, ok := event.GetData()["user"].(*model.User) 5102 require.True(t, ok, "expected user") 5103 assert.Equal(t, "system_user", eventUser.Roles) 5104 }) 5105 assertExpectedWebsocketEvent(t, adminWebSocketClient, model.WEBSOCKET_EVENT_USER_UPDATED, func(event *model.WebSocketEvent) { 5106 eventUser, ok := event.GetData()["user"].(*model.User) 5107 require.True(t, ok, "expected user") 5108 assert.Equal(t, "system_user", eventUser.Roles) 5109 }) 5110 }) 5111 } 5112 5113 func TestVerifyUserEmailWithoutToken(t *testing.T) { 5114 th := Setup(t) 5115 defer th.TearDown() 5116 5117 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 5118 email := th.GenerateTestEmail() 5119 user := model.User{Email: email, Nickname: "Darth Vader", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_USER_ROLE_ID} 5120 ruser, _ := th.Client.CreateUser(&user) 5121 5122 vuser, resp := client.VerifyUserEmailWithoutToken(ruser.Id) 5123 require.Nil(t, resp.Error) 5124 require.Equal(t, ruser.Id, vuser.Id) 5125 }, "Should verify a new user") 5126 5127 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 5128 vuser, resp := client.VerifyUserEmailWithoutToken("randomId") 5129 require.NotNil(t, resp.Error) 5130 CheckErrorMessage(t, resp, "api.context.invalid_url_param.app_error") 5131 require.Nil(t, vuser) 5132 }, "Should not be able to find user") 5133 5134 t.Run("Should not be able to verify user due to permissions", func(t *testing.T) { 5135 user := th.CreateUser() 5136 vuser, resp := th.Client.VerifyUserEmailWithoutToken(user.Id) 5137 require.NotNil(t, resp.Error) 5138 CheckErrorMessage(t, resp, "api.context.permissions.app_error") 5139 require.Nil(t, vuser) 5140 }) 5141 } 5142 5143 func TestGetKnownUsers(t *testing.T) { 5144 th := Setup(t) 5145 defer th.TearDown() 5146 5147 t1, err := th.App.CreateTeam(th.Context, &model.Team{ 5148 DisplayName: "dn_" + model.NewId(), 5149 Name: GenerateTestTeamName(), 5150 Email: th.GenerateTestEmail(), 5151 Type: model.TEAM_OPEN, 5152 }) 5153 require.Nil(t, err, "failed to create team") 5154 5155 t2, err := th.App.CreateTeam(th.Context, &model.Team{ 5156 DisplayName: "dn_" + model.NewId(), 5157 Name: GenerateTestTeamName(), 5158 Email: th.GenerateTestEmail(), 5159 Type: model.TEAM_OPEN, 5160 }) 5161 require.Nil(t, err, "failed to create team") 5162 5163 t3, err := th.App.CreateTeam(th.Context, &model.Team{ 5164 DisplayName: "dn_" + model.NewId(), 5165 Name: GenerateTestTeamName(), 5166 Email: th.GenerateTestEmail(), 5167 Type: model.TEAM_OPEN, 5168 }) 5169 require.Nil(t, err, "failed to create team") 5170 5171 c1, err := th.App.CreateChannel(th.Context, &model.Channel{ 5172 DisplayName: "dn_" + model.NewId(), 5173 Name: "name_" + model.NewId(), 5174 Type: model.CHANNEL_OPEN, 5175 TeamId: t1.Id, 5176 CreatorId: model.NewId(), 5177 }, false) 5178 require.Nil(t, err, "failed to create channel") 5179 5180 c2, err := th.App.CreateChannel(th.Context, &model.Channel{ 5181 DisplayName: "dn_" + model.NewId(), 5182 Name: "name_" + model.NewId(), 5183 Type: model.CHANNEL_OPEN, 5184 TeamId: t2.Id, 5185 CreatorId: model.NewId(), 5186 }, false) 5187 require.Nil(t, err, "failed to create channel") 5188 5189 c3, err := th.App.CreateChannel(th.Context, &model.Channel{ 5190 DisplayName: "dn_" + model.NewId(), 5191 Name: "name_" + model.NewId(), 5192 Type: model.CHANNEL_OPEN, 5193 TeamId: t3.Id, 5194 CreatorId: model.NewId(), 5195 }, false) 5196 require.Nil(t, err, "failed to create channel") 5197 5198 u1 := th.CreateUser() 5199 defer th.App.PermanentDeleteUser(th.Context, u1) 5200 u2 := th.CreateUser() 5201 defer th.App.PermanentDeleteUser(th.Context, u2) 5202 u3 := th.CreateUser() 5203 defer th.App.PermanentDeleteUser(th.Context, u3) 5204 u4 := th.CreateUser() 5205 defer th.App.PermanentDeleteUser(th.Context, u4) 5206 5207 th.LinkUserToTeam(u1, t1) 5208 th.LinkUserToTeam(u1, t2) 5209 th.LinkUserToTeam(u2, t1) 5210 th.LinkUserToTeam(u3, t2) 5211 th.LinkUserToTeam(u4, t3) 5212 5213 th.App.AddUserToChannel(u1, c1, false) 5214 th.App.AddUserToChannel(u1, c2, false) 5215 th.App.AddUserToChannel(u2, c1, false) 5216 th.App.AddUserToChannel(u3, c2, false) 5217 th.App.AddUserToChannel(u4, c3, false) 5218 5219 t.Run("get know users sharing no channels", func(t *testing.T) { 5220 _, _ = th.Client.Login(u4.Email, u4.Password) 5221 userIds, resp := th.Client.GetKnownUsers() 5222 CheckNoError(t, resp) 5223 assert.Empty(t, userIds) 5224 }) 5225 5226 t.Run("get know users sharing one channel", func(t *testing.T) { 5227 _, _ = th.Client.Login(u3.Email, u3.Password) 5228 userIds, resp := th.Client.GetKnownUsers() 5229 CheckNoError(t, resp) 5230 assert.Len(t, userIds, 1) 5231 assert.Equal(t, userIds[0], u1.Id) 5232 }) 5233 5234 t.Run("get know users sharing multiple channels", func(t *testing.T) { 5235 _, _ = th.Client.Login(u1.Email, u1.Password) 5236 userIds, resp := th.Client.GetKnownUsers() 5237 CheckNoError(t, resp) 5238 assert.Len(t, userIds, 2) 5239 assert.ElementsMatch(t, userIds, []string{u2.Id, u3.Id}) 5240 }) 5241 } 5242 5243 func TestPublishUserTyping(t *testing.T) { 5244 th := Setup(t).InitBasic() 5245 defer th.TearDown() 5246 5247 tr := model.TypingRequest{ 5248 ChannelId: th.BasicChannel.Id, 5249 ParentId: "randomparentid", 5250 } 5251 5252 t.Run("should return ok for non-system admin when triggering typing event for own user", func(t *testing.T) { 5253 _, resp := th.Client.PublishUserTyping(th.BasicUser.Id, tr) 5254 CheckNoError(t, resp) 5255 }) 5256 5257 t.Run("should return ok for system admin when triggering typing event for own user", func(t *testing.T) { 5258 th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam) 5259 th.AddUserToChannel(th.SystemAdminUser, th.BasicChannel) 5260 5261 _, resp := th.SystemAdminClient.PublishUserTyping(th.SystemAdminUser.Id, tr) 5262 CheckNoError(t, resp) 5263 }) 5264 5265 t.Run("should return forbidden for non-system admin when triggering a typing event for a different user", func(t *testing.T) { 5266 _, resp := th.Client.PublishUserTyping(th.BasicUser2.Id, tr) 5267 CheckForbiddenStatus(t, resp) 5268 }) 5269 5270 t.Run("should return bad request when triggering a typing event for an invalid user id", func(t *testing.T) { 5271 _, resp := th.Client.PublishUserTyping("invalid", tr) 5272 CheckErrorMessage(t, resp, "api.context.invalid_url_param.app_error") 5273 CheckBadRequestStatus(t, resp) 5274 }) 5275 5276 t.Run("should send typing event via websocket when triggering a typing event for a user with a common channel", func(t *testing.T) { 5277 webSocketClient, err := th.CreateWebSocketClient() 5278 assert.Nil(t, err) 5279 defer webSocketClient.Close() 5280 5281 webSocketClient.Listen() 5282 5283 time.Sleep(300 * time.Millisecond) 5284 wsResp := <-webSocketClient.ResponseChannel 5285 require.Equal(t, model.STATUS_OK, wsResp.Status) 5286 5287 _, resp := th.SystemAdminClient.PublishUserTyping(th.BasicUser2.Id, tr) 5288 CheckNoError(t, resp) 5289 5290 assertExpectedWebsocketEvent(t, webSocketClient, model.WEBSOCKET_EVENT_TYPING, func(resp *model.WebSocketEvent) { 5291 assert.Equal(t, th.BasicChannel.Id, resp.GetBroadcast().ChannelId) 5292 5293 eventUserId, ok := resp.GetData()["user_id"].(string) 5294 require.True(t, ok, "expected user_id") 5295 assert.Equal(t, th.BasicUser2.Id, eventUserId) 5296 5297 eventParentId, ok := resp.GetData()["parent_id"].(string) 5298 require.True(t, ok, "expected parent_id") 5299 assert.Equal(t, "randomparentid", eventParentId) 5300 }) 5301 }) 5302 5303 th.Server.Busy.Set(time.Second * 10) 5304 5305 t.Run("should return service unavailable for non-system admin user when triggering a typing event and server busy", func(t *testing.T) { 5306 _, resp := th.Client.PublishUserTyping("invalid", tr) 5307 CheckErrorMessage(t, resp, "api.context.server_busy.app_error") 5308 CheckServiceUnavailableStatus(t, resp) 5309 }) 5310 5311 t.Run("should return service unavailable for system admin user when triggering a typing event and server busy", func(t *testing.T) { 5312 _, resp := th.SystemAdminClient.PublishUserTyping(th.SystemAdminUser.Id, tr) 5313 CheckErrorMessage(t, resp, "api.context.server_busy.app_error") 5314 CheckServiceUnavailableStatus(t, resp) 5315 }) 5316 } 5317 5318 func TestConvertUserToBot(t *testing.T) { 5319 th := Setup(t).InitBasic() 5320 defer th.TearDown() 5321 5322 bot, resp := th.Client.ConvertUserToBot(th.BasicUser.Id) 5323 CheckForbiddenStatus(t, resp) 5324 require.Nil(t, bot) 5325 5326 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 5327 user := model.User{Email: th.GenerateTestEmail(), Username: GenerateTestUsername(), Password: "password"} 5328 5329 ruser, resp := client.CreateUser(&user) 5330 CheckNoError(t, resp) 5331 CheckCreatedStatus(t, resp) 5332 5333 bot, resp = client.ConvertUserToBot(ruser.Id) 5334 CheckNoError(t, resp) 5335 require.NotNil(t, bot) 5336 require.Equal(t, bot.UserId, ruser.Id) 5337 5338 bot, resp = client.GetBot(bot.UserId, "") 5339 CheckNoError(t, resp) 5340 require.NotNil(t, bot) 5341 }) 5342 } 5343 5344 func TestMigrateAuthToLDAP(t *testing.T) { 5345 th := Setup(t).InitBasic() 5346 defer th.TearDown() 5347 5348 _, err := th.Client.MigrateAuthToLdap("email", "a", false) 5349 CheckForbiddenStatus(t, err) 5350 5351 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 5352 _, err = client.MigrateAuthToLdap("email", "a", false) 5353 CheckNotImplementedStatus(t, err) 5354 }) 5355 } 5356 5357 func TestMigrateAuthToSAML(t *testing.T) { 5358 th := Setup(t).InitBasic() 5359 defer th.TearDown() 5360 5361 _, err := th.Client.MigrateAuthToSaml("email", map[string]string{"1": "a"}, true) 5362 CheckForbiddenStatus(t, err) 5363 5364 th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) { 5365 _, err = client.MigrateAuthToSaml("email", map[string]string{"1": "a"}, true) 5366 CheckNotImplementedStatus(t, err) 5367 }) 5368 } 5369 func TestUpdatePassword(t *testing.T) { 5370 th := Setup(t) 5371 defer th.TearDown() 5372 5373 t.Run("Forbidden when request performed by system user on a system admin", func(t *testing.T) { 5374 res := th.Client.UpdatePassword(th.SystemAdminUser.Id, "Pa$$word11", "foobar") 5375 CheckForbiddenStatus(t, res) 5376 }) 5377 5378 t.Run("OK when request performed by system user with requisite system permission, except if requested user is system admin", func(t *testing.T) { 5379 th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS.Id, model.SYSTEM_USER_ROLE_ID) 5380 defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS.Id, model.SYSTEM_USER_ROLE_ID) 5381 5382 res := th.Client.UpdatePassword(th.TeamAdminUser.Id, "Pa$$word11", "foobar") 5383 CheckOKStatus(t, res) 5384 5385 res = th.Client.UpdatePassword(th.SystemAdminUser.Id, "Pa$$word11", "foobar") 5386 CheckForbiddenStatus(t, res) 5387 }) 5388 5389 t.Run("OK when request performed by system admin, even if requested user is system admin", func(t *testing.T) { 5390 res := th.SystemAdminClient.UpdatePassword(th.SystemAdminUser.Id, "Pa$$word11", "foobar") 5391 CheckOKStatus(t, res) 5392 }) 5393 } 5394 5395 func TestGetThreadsForUser(t *testing.T) { 5396 th := Setup(t).InitBasic() 5397 defer th.TearDown() 5398 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5399 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5400 5401 th.App.UpdateConfig(func(cfg *model.Config) { 5402 *cfg.ServiceSettings.ThreadAutoFollow = true 5403 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5404 }) 5405 t.Run("empty", func(t *testing.T) { 5406 Client := th.Client 5407 5408 _, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5409 CheckNoError(t, resp) 5410 CheckCreatedStatus(t, resp) 5411 5412 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5413 5414 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{}) 5415 require.Nil(t, resp.Error) 5416 require.Len(t, uss.Threads, 0) 5417 }) 5418 5419 t.Run("no params, 1 thread", func(t *testing.T) { 5420 Client := th.Client 5421 5422 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5423 CheckNoError(t, resp) 5424 CheckCreatedStatus(t, resp) 5425 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5426 CheckNoError(t, resp2) 5427 CheckCreatedStatus(t, resp2) 5428 5429 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5430 5431 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{}) 5432 require.Nil(t, resp.Error) 5433 require.Len(t, uss.Threads, 1) 5434 require.Equal(t, uss.Threads[0].PostId, rpost.Id) 5435 require.Equal(t, uss.Threads[0].ReplyCount, int64(1)) 5436 }) 5437 5438 t.Run("extended, 1 thread", func(t *testing.T) { 5439 Client := th.Client 5440 5441 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5442 CheckNoError(t, resp) 5443 CheckCreatedStatus(t, resp) 5444 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5445 CheckNoError(t, resp2) 5446 CheckCreatedStatus(t, resp2) 5447 5448 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5449 5450 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5451 Extended: true, 5452 }) 5453 require.Nil(t, resp.Error) 5454 require.Len(t, uss.Threads, 1) 5455 require.Equal(t, uss.Threads[0].PostId, rpost.Id) 5456 require.Equal(t, uss.Threads[0].ReplyCount, int64(1)) 5457 require.Equal(t, uss.Threads[0].Participants[0].Id, th.BasicUser.Id) 5458 }) 5459 5460 t.Run("deleted, 1 thread", func(t *testing.T) { 5461 Client := th.Client 5462 5463 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5464 CheckNoError(t, resp) 5465 CheckCreatedStatus(t, resp) 5466 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5467 CheckNoError(t, resp2) 5468 CheckCreatedStatus(t, resp2) 5469 5470 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5471 5472 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5473 Deleted: false, 5474 }) 5475 require.Nil(t, resp.Error) 5476 require.Len(t, uss.Threads, 1) 5477 require.Equal(t, uss.Threads[0].PostId, rpost.Id) 5478 require.Equal(t, uss.Threads[0].ReplyCount, int64(1)) 5479 require.Equal(t, uss.Threads[0].Participants[0].Id, th.BasicUser.Id) 5480 5481 res, resp2 := th.Client.DeletePost(rpost.Id) 5482 require.True(t, res) 5483 require.Nil(t, resp2.Error) 5484 5485 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5486 Deleted: false, 5487 }) 5488 require.Nil(t, resp.Error) 5489 require.Len(t, uss.Threads, 0) 5490 5491 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5492 Deleted: true, 5493 }) 5494 require.Nil(t, resp.Error) 5495 require.Len(t, uss.Threads, 1) 5496 require.Greater(t, uss.Threads[0].Post.DeleteAt, int64(0)) 5497 5498 }) 5499 5500 t.Run("paged, 30 threads", func(t *testing.T) { 5501 Client := th.Client 5502 5503 var rootIds []*model.Post 5504 for i := 0; i < 30; i++ { 5505 time.Sleep(1) 5506 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5507 CheckNoError(t, resp) 5508 CheckCreatedStatus(t, resp) 5509 rootIds = append(rootIds, rpost) 5510 time.Sleep(1) 5511 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5512 CheckNoError(t, resp2) 5513 CheckCreatedStatus(t, resp2) 5514 } 5515 5516 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5517 5518 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5519 Deleted: false, 5520 }) 5521 require.Nil(t, resp.Error) 5522 require.Len(t, uss.Threads, 30) 5523 require.Len(t, rootIds, 30) 5524 require.Equal(t, uss.Threads[0].PostId, rootIds[29].Id) 5525 require.Equal(t, uss.Threads[0].ReplyCount, int64(1)) 5526 require.Equal(t, uss.Threads[0].Participants[0].Id, th.BasicUser.Id) 5527 }) 5528 5529 t.Run("paged, 10 threads before/after", func(t *testing.T) { 5530 Client := th.Client 5531 5532 var rootIds []*model.Post 5533 for i := 0; i < 30; i++ { 5534 time.Sleep(1) 5535 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: fmt.Sprintf("testMsg-%d", i)}) 5536 rootIds = append(rootIds, rpost) 5537 time.Sleep(1) 5538 postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: fmt.Sprintf("testReply-%d", i), RootId: rpost.Id}) 5539 } 5540 rootId := rootIds[15].Id // middle point 5541 rootIdBefore := rootIds[14].Id 5542 rootIdAfter := rootIds[16].Id 5543 5544 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5545 5546 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5547 Deleted: false, 5548 PageSize: 10, 5549 Before: rootId, 5550 }) 5551 5552 require.Nil(t, resp.Error) 5553 require.Len(t, uss.Threads, 10) 5554 require.Equal(t, rootIdBefore, uss.Threads[0].PostId) 5555 5556 uss2, resp2 := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5557 Deleted: false, 5558 PageSize: 10, 5559 After: rootId, 5560 }) 5561 require.Nil(t, resp2.Error) 5562 require.Len(t, uss2.Threads, 10) 5563 5564 require.Equal(t, rootIdAfter, uss2.Threads[0].PostId) 5565 5566 uss3, resp3 := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5567 Deleted: false, 5568 PageSize: 10, 5569 After: rootId + "__bad", 5570 }) 5571 require.Nil(t, resp3.Error) 5572 require.NotNil(t, uss3.Threads) 5573 require.Len(t, uss3.Threads, 0) 5574 }) 5575 5576 t.Run("editing or reacting to reply post does not make thread unread", func(t *testing.T) { 5577 Client := th.Client 5578 5579 rootPost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "root post"}) 5580 replyPost, _ := postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "reply post", RootId: rootPost.Id}) 5581 uss, resp := th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5582 Deleted: false, 5583 }) 5584 CheckNoError(t, resp) 5585 require.Equal(t, uss.TotalUnreadThreads, int64(1)) 5586 require.Equal(t, uss.Threads[0].PostId, rootPost.Id) 5587 5588 _, resp = th.Client.UpdateThreadReadForUser(th.BasicUser.Id, th.BasicChannel.TeamId, rootPost.Id, model.GetMillis()) 5589 CheckNoError(t, resp) 5590 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5591 Deleted: false, 5592 }) 5593 CheckNoError(t, resp) 5594 require.Equal(t, uss.TotalUnreadThreads, int64(0)) 5595 5596 // edit post 5597 editedReplyPostMessage := "edited " + replyPost.Message 5598 _, resp = th.SystemAdminClient.PatchPost(replyPost.Id, &model.PostPatch{Message: &editedReplyPostMessage}) 5599 CheckNoError(t, resp) 5600 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5601 Deleted: false, 5602 }) 5603 CheckNoError(t, resp) 5604 require.Equal(t, uss.TotalUnreadThreads, int64(0)) 5605 5606 // react to post 5607 reaction := &model.Reaction{ 5608 UserId: th.SystemAdminUser.Id, 5609 PostId: replyPost.Id, 5610 EmojiName: "smile", 5611 } 5612 _, resp = th.SystemAdminClient.SaveReaction(reaction) 5613 CheckNoError(t, resp) 5614 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5615 Deleted: false, 5616 }) 5617 CheckNoError(t, resp) 5618 require.Equal(t, uss.TotalUnreadThreads, int64(0)) 5619 }) 5620 } 5621 5622 func TestThreadSocketEvents(t *testing.T) { 5623 th := Setup(t).InitBasic() 5624 defer th.TearDown() 5625 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5626 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5627 5628 th.ConfigStore.SetReadOnlyFF(false) 5629 defer th.ConfigStore.SetReadOnlyFF(true) 5630 5631 th.App.UpdateConfig(func(cfg *model.Config) { 5632 *cfg.ServiceSettings.ThreadAutoFollow = true 5633 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5634 }) 5635 5636 userWSClient, err := th.CreateWebSocketClient() 5637 require.Nil(t, err) 5638 defer userWSClient.Close() 5639 userWSClient.Listen() 5640 5641 Client := th.Client 5642 5643 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5644 CheckNoError(t, resp) 5645 CheckCreatedStatus(t, resp) 5646 5647 _, err = th.App.CreatePostAsUser(th.Context, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", UserId: th.BasicUser2.Id, RootId: rpost.Id}, th.Context.Session().Id, false) 5648 require.Nil(t, err) 5649 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5650 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser2.Id) 5651 5652 t.Run("Listed for update event", func(t *testing.T) { 5653 var caught bool 5654 func() { 5655 for { 5656 select { 5657 case ev := <-userWSClient.EventChannel: 5658 if ev.EventType() == model.WEBSOCKET_EVENT_THREAD_UPDATED { 5659 caught = true 5660 thread, err := model.ThreadResponseFromJson(ev.GetData()["thread"].(string)) 5661 require.NoError(t, err) 5662 for _, p := range thread.Participants { 5663 if p.Id != th.BasicUser.Id && p.Id != th.BasicUser2.Id { 5664 require.Fail(t, "invalid participants") 5665 } 5666 } 5667 } 5668 case <-time.After(1 * time.Second): 5669 return 5670 } 5671 } 5672 }() 5673 require.Truef(t, caught, "User should have received %s event", model.WEBSOCKET_EVENT_THREAD_UPDATED) 5674 }) 5675 5676 resp = th.Client.UpdateThreadFollowForUser(th.BasicUser.Id, th.BasicTeam.Id, rpost.Id, false) 5677 CheckNoError(t, resp) 5678 CheckOKStatus(t, resp) 5679 5680 t.Run("Listed for follow event", func(t *testing.T) { 5681 var caught bool 5682 func() { 5683 for { 5684 select { 5685 case ev := <-userWSClient.EventChannel: 5686 if ev.EventType() == model.WEBSOCKET_EVENT_THREAD_FOLLOW_CHANGED { 5687 caught = true 5688 require.Equal(t, ev.GetData()["state"], false) 5689 require.Equal(t, ev.GetData()["reply_count"], float64(1)) 5690 } 5691 case <-time.After(1 * time.Second): 5692 return 5693 } 5694 } 5695 }() 5696 require.Truef(t, caught, "User should have received %s event", model.WEBSOCKET_EVENT_THREAD_FOLLOW_CHANGED) 5697 }) 5698 5699 _, resp = th.Client.UpdateThreadReadForUser(th.BasicUser.Id, th.BasicTeam.Id, rpost.Id, 123) 5700 CheckNoError(t, resp) 5701 CheckOKStatus(t, resp) 5702 5703 t.Run("Listed for read event", func(t *testing.T) { 5704 var caught bool 5705 func() { 5706 for { 5707 select { 5708 case ev := <-userWSClient.EventChannel: 5709 if ev.EventType() == model.WEBSOCKET_EVENT_THREAD_READ_CHANGED { 5710 caught = true 5711 require.EqualValues(t, ev.GetData()["timestamp"], 123) 5712 } 5713 case <-time.After(1 * time.Second): 5714 return 5715 } 5716 } 5717 }() 5718 5719 require.Truef(t, caught, "User should have received %s event", model.WEBSOCKET_EVENT_THREAD_READ_CHANGED) 5720 }) 5721 5722 } 5723 5724 func TestFollowThreads(t *testing.T) { 5725 th := Setup(t).InitBasic() 5726 defer th.TearDown() 5727 5728 t.Run("1 thread", func(t *testing.T) { 5729 Client := th.Client 5730 5731 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5732 CheckNoError(t, resp) 5733 CheckCreatedStatus(t, resp) 5734 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5735 CheckNoError(t, resp2) 5736 CheckCreatedStatus(t, resp2) 5737 5738 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5739 var uss *model.Threads 5740 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5741 Deleted: false, 5742 }) 5743 CheckNoError(t, resp) 5744 require.Len(t, uss.Threads, 1) 5745 5746 resp = th.Client.UpdateThreadFollowForUser(th.BasicUser.Id, th.BasicTeam.Id, rpost.Id, false) 5747 CheckNoError(t, resp) 5748 CheckOKStatus(t, resp) 5749 5750 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5751 Deleted: false, 5752 }) 5753 CheckNoError(t, resp) 5754 require.Len(t, uss.Threads, 0) 5755 5756 resp = th.Client.UpdateThreadFollowForUser(th.BasicUser.Id, th.BasicTeam.Id, rpost.Id, true) 5757 CheckNoError(t, resp) 5758 CheckOKStatus(t, resp) 5759 5760 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5761 Deleted: false, 5762 }) 5763 CheckNoError(t, resp) 5764 require.Len(t, uss.Threads, 1) 5765 require.GreaterOrEqual(t, uss.Threads[0].LastViewedAt, uss.Threads[0].LastReplyAt) 5766 5767 }) 5768 } 5769 5770 func checkThreadListReplies(t *testing.T, th *TestHelper, client *model.Client4, userId string, expectedReplies, expectedThreads int, options *model.GetUserThreadsOpts) (*model.Threads, *model.Response) { 5771 opts := model.GetUserThreadsOpts{} 5772 if options != nil { 5773 opts = *options 5774 } 5775 u, r := client.GetUserThreads(userId, th.BasicTeam.Id, opts) 5776 CheckNoError(t, r) 5777 require.Len(t, u.Threads, expectedThreads) 5778 5779 count := int64(0) 5780 sum := int64(0) 5781 for _, thr := range u.Threads { 5782 if thr.UnreadReplies > 0 { 5783 count += 1 5784 } 5785 sum += thr.UnreadReplies 5786 } 5787 require.EqualValues(t, expectedReplies, sum, "expectedReplies don't match") 5788 require.Equal(t, count, u.TotalUnreadThreads, "TotalUnreadThreads don't match") 5789 5790 return u, r 5791 } 5792 5793 func postAndCheck(t *testing.T, client *model.Client4, post *model.Post) (*model.Post, *model.Response) { 5794 p, resp := client.CreatePost(post) 5795 CheckNoError(t, resp) 5796 CheckCreatedStatus(t, resp) 5797 return p, resp 5798 } 5799 5800 func TestMaintainUnreadRepliesInThread(t *testing.T) { 5801 th := Setup(t).InitBasic() 5802 defer th.TearDown() 5803 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5804 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5805 th.App.UpdateConfig(func(cfg *model.Config) { 5806 *cfg.ServiceSettings.ThreadAutoFollow = true 5807 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5808 }) 5809 5810 Client := th.Client 5811 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5812 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.SystemAdminUser.Id) 5813 5814 // create a post by regular user 5815 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5816 // reply with another 5817 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5818 5819 // regular user should have one thread with one reply 5820 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 1, 1, nil) 5821 5822 // add another reply by regular user 5823 postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply2", RootId: rpost.Id}) 5824 5825 // replying to the thread clears reply count, so it should be 0 5826 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 0, 1, nil) 5827 5828 // the other user should have 1 reply - the reply from the regular user 5829 checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 1, 1, nil) 5830 5831 // mark all as read for user 5832 resp := th.Client.UpdateThreadsReadForUser(th.BasicUser.Id, th.BasicTeam.Id) 5833 CheckNoError(t, resp) 5834 CheckOKStatus(t, resp) 5835 5836 // reply count should be 0 5837 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 0, 1, nil) 5838 5839 // mark other user's read state 5840 _, resp = th.SystemAdminClient.UpdateThreadReadForUser(th.SystemAdminUser.Id, th.BasicTeam.Id, rpost.Id, model.GetMillis()) 5841 CheckNoError(t, resp) 5842 CheckOKStatus(t, resp) 5843 5844 // get unread only, should return nothing 5845 checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 0, 0, &model.GetUserThreadsOpts{Unread: true}) 5846 5847 // restore unread to an old date 5848 _, resp = th.SystemAdminClient.UpdateThreadReadForUser(th.SystemAdminUser.Id, th.BasicTeam.Id, rpost.Id, 123) 5849 CheckNoError(t, resp) 5850 CheckOKStatus(t, resp) 5851 5852 // should have 2 unread replies now 5853 checkThreadListReplies(t, th, th.SystemAdminClient, th.SystemAdminUser.Id, 2, 1, &model.GetUserThreadsOpts{Unread: true}) 5854 5855 } 5856 5857 func TestThreadCounts(t *testing.T) { 5858 th := Setup(t).InitBasic() 5859 defer th.TearDown() 5860 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5861 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5862 th.App.UpdateConfig(func(cfg *model.Config) { 5863 *cfg.ServiceSettings.ThreadAutoFollow = true 5864 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5865 }) 5866 5867 Client := th.Client 5868 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5869 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.SystemAdminUser.Id) 5870 5871 // create a post by regular user 5872 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5873 // reply with another 5874 time.Sleep(1) 5875 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5876 5877 // create another post by regular user 5878 time.Sleep(1) 5879 rpost2, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testMsg1"}) 5880 // reply with another 2 times 5881 time.Sleep(1) 5882 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testReply2", RootId: rpost2.Id}) 5883 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testReply22", RootId: rpost2.Id}) 5884 5885 // regular user should have two threads with 3 replies total 5886 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 3, 2, &model.GetUserThreadsOpts{ 5887 Deleted: false, 5888 }) 5889 5890 // delete first thread 5891 th.App.Srv().Store.Post().Delete(rpost.Id, model.GetMillis(), th.BasicUser.Id) 5892 5893 // we should now have 1 thread with 2 replies 5894 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 2, 1, &model.GetUserThreadsOpts{ 5895 Deleted: false, 5896 }) 5897 // with Deleted we should get the same as before deleting 5898 checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 3, 2, &model.GetUserThreadsOpts{ 5899 Deleted: true, 5900 }) 5901 } 5902 5903 func TestSingleThreadGet(t *testing.T) { 5904 th := Setup(t).InitBasic() 5905 defer th.TearDown() 5906 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5907 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5908 th.App.UpdateConfig(func(cfg *model.Config) { 5909 *cfg.ServiceSettings.ThreadAutoFollow = true 5910 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5911 }) 5912 5913 Client := th.Client 5914 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5915 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.SystemAdminUser.Id) 5916 5917 // create a post by regular user 5918 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5919 // reply with another 5920 time.Sleep(1) 5921 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 5922 5923 // create another thread to check that we are not returning it by mistake 5924 rpost2, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testMsg2"}) 5925 time.Sleep(1) 5926 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testReply", RootId: rpost2.Id}) 5927 5928 // regular user should have two threads with 3 replies total 5929 threads, _ := checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 2, 2, nil) 5930 5931 tr, resp := th.Client.GetUserThread(th.BasicUser.Id, th.BasicTeam.Id, threads.Threads[0].PostId, false) 5932 CheckNoError(t, resp) 5933 require.NotNil(t, tr) 5934 require.Equal(t, threads.Threads[0].PostId, tr.PostId) 5935 require.Empty(t, tr.Participants[0].Username) 5936 5937 tr, resp = th.Client.GetUserThread(th.BasicUser.Id, th.BasicTeam.Id, threads.Threads[0].PostId, true) 5938 CheckNoError(t, resp) 5939 require.NotEmpty(t, tr.Participants[0].Username) 5940 } 5941 5942 func TestMaintainUnreadMentionsInThread(t *testing.T) { 5943 th := Setup(t).InitBasic() 5944 defer th.TearDown() 5945 Client := th.Client 5946 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 5947 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 5948 th.App.UpdateConfig(func(cfg *model.Config) { 5949 *cfg.ServiceSettings.ThreadAutoFollow = true 5950 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 5951 }) 5952 checkThreadList := func(client *model.Client4, userId string, expectedMentions, expectedThreads int) (*model.Threads, *model.Response) { 5953 uss, resp := client.GetUserThreads(userId, th.BasicTeam.Id, model.GetUserThreadsOpts{ 5954 Deleted: false, 5955 }) 5956 CheckNoError(t, resp) 5957 5958 require.Len(t, uss.Threads, expectedThreads) 5959 sum := int64(0) 5960 for _, thr := range uss.Threads { 5961 sum += thr.UnreadMentions 5962 } 5963 require.Equal(t, sum, uss.TotalUnreadMentions) 5964 require.EqualValues(t, expectedMentions, uss.TotalUnreadMentions) 5965 5966 return uss, resp 5967 } 5968 5969 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 5970 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.SystemAdminUser.Id) 5971 5972 // create regular post 5973 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 5974 // create reply and mention the original poster and another user 5975 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply @" + th.BasicUser.Username + " and @" + th.BasicUser2.Username, RootId: rpost.Id}) 5976 5977 // basic user 1 was mentioned 1 time 5978 checkThreadList(th.Client, th.BasicUser.Id, 1, 1) 5979 // basic user 2 was mentioned 1 time 5980 checkThreadList(th.SystemAdminClient, th.BasicUser2.Id, 1, 1) 5981 5982 // test self mention, shouldn't increase mention count 5983 postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply @" + th.BasicUser.Username, RootId: rpost.Id}) 5984 // count shouldn't increase 5985 checkThreadList(th.Client, th.BasicUser.Id, 1, 1) 5986 5987 // test DM 5988 dm := th.CreateDmChannel(th.SystemAdminUser) 5989 dm_root_post, _ := postAndCheck(t, Client, &model.Post{ChannelId: dm.Id, Message: "hi @" + th.SystemAdminUser.Username}) 5990 5991 // no changes 5992 checkThreadList(th.Client, th.BasicUser.Id, 1, 1) 5993 5994 // post reply by the same user 5995 postAndCheck(t, Client, &model.Post{ChannelId: dm.Id, Message: "how are you", RootId: dm_root_post.Id}) 5996 5997 // thread created 5998 checkThreadList(th.Client, th.BasicUser.Id, 1, 2) 5999 6000 // post two replies by another user, without mentions. mention count should still increase since this is a DM 6001 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: dm.Id, Message: "msg1", RootId: dm_root_post.Id}) 6002 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: dm.Id, Message: "msg2", RootId: dm_root_post.Id}) 6003 // expect increment by two mentions 6004 checkThreadList(th.Client, th.BasicUser.Id, 3, 2) 6005 } 6006 6007 func TestReadThreads(t *testing.T) { 6008 th := Setup(t).InitBasic() 6009 defer th.TearDown() 6010 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 6011 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 6012 th.App.UpdateConfig(func(cfg *model.Config) { 6013 *cfg.ServiceSettings.ThreadAutoFollow = true 6014 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 6015 }) 6016 Client := th.Client 6017 t.Run("all threads", func(t *testing.T) { 6018 6019 rpost, resp := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg"}) 6020 CheckNoError(t, resp) 6021 CheckCreatedStatus(t, resp) 6022 _, resp2 := Client.CreatePost(&model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply", RootId: rpost.Id}) 6023 CheckNoError(t, resp2) 6024 CheckCreatedStatus(t, resp2) 6025 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 6026 6027 var uss, uss2 *model.Threads 6028 uss, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 6029 Deleted: false, 6030 }) 6031 CheckNoError(t, resp) 6032 require.Len(t, uss.Threads, 1) 6033 6034 time.Sleep(1) 6035 resp = th.Client.UpdateThreadsReadForUser(th.BasicUser.Id, th.BasicTeam.Id) 6036 CheckNoError(t, resp) 6037 CheckOKStatus(t, resp) 6038 6039 uss2, resp = th.Client.GetUserThreads(th.BasicUser.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{ 6040 Deleted: false, 6041 }) 6042 CheckNoError(t, resp) 6043 require.Len(t, uss2.Threads, 1) 6044 require.Greater(t, uss2.Threads[0].LastViewedAt, uss.Threads[0].LastViewedAt) 6045 }) 6046 6047 t.Run("1 thread", func(t *testing.T) { 6048 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.BasicUser.Id) 6049 defer th.App.Srv().Store.Post().PermanentDeleteByUser(th.SystemAdminUser.Id) 6050 6051 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsgC1"}) 6052 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReplyC1", RootId: rpost.Id}) 6053 6054 rrpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testMsgC2"}) 6055 postAndCheck(t, th.SystemAdminClient, &model.Post{ChannelId: th.BasicChannel2.Id, Message: "testReplyC2", RootId: rrpost.Id}) 6056 6057 uss, _ := checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 2, 2, nil) 6058 6059 _, resp := th.Client.UpdateThreadReadForUser(th.BasicUser.Id, th.BasicTeam.Id, rrpost.Id, model.GetMillis()+10) 6060 CheckNoError(t, resp) 6061 CheckOKStatus(t, resp) 6062 6063 uss2, _ := checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 1, 2, nil) 6064 require.Greater(t, uss2.Threads[0].LastViewedAt, uss.Threads[0].LastViewedAt) 6065 6066 timestamp := model.GetMillis() 6067 _, resp = th.Client.UpdateThreadReadForUser(th.BasicUser.Id, th.BasicTeam.Id, rrpost.Id, timestamp) 6068 CheckNoError(t, resp) 6069 CheckOKStatus(t, resp) 6070 6071 uss3, _ := checkThreadListReplies(t, th, th.Client, th.BasicUser.Id, 1, 2, nil) 6072 require.Equal(t, uss3.Threads[0].LastViewedAt, timestamp) 6073 }) 6074 } 6075 6076 func TestMarkThreadUnreadMentionCount(t *testing.T) { 6077 th := Setup(t).InitBasic() 6078 defer th.TearDown() 6079 os.Setenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS", "true") 6080 defer os.Unsetenv("MM_FEATUREFLAGS_COLLAPSEDTHREADS") 6081 th.App.UpdateConfig(func(cfg *model.Config) { 6082 *cfg.ServiceSettings.ThreadAutoFollow = true 6083 *cfg.ServiceSettings.CollapsedThreads = model.COLLAPSED_THREADS_DEFAULT_ON 6084 }) 6085 Client := th.Client 6086 6087 channel := th.BasicChannel 6088 user := th.BasicUser 6089 user2 := th.BasicUser2 6090 appErr := th.App.JoinChannel(th.Context, channel, user.Id) 6091 require.Nil(t, appErr) 6092 appErr = th.App.JoinChannel(th.Context, channel, user2.Id) 6093 require.Nil(t, appErr) 6094 6095 rpost, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testMsg @" + th.BasicUser2.Username}) 6096 time.Sleep(1) 6097 reply, _ := postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply1", RootId: rpost.Id}) 6098 time.Sleep(1) 6099 postAndCheck(t, Client, &model.Post{ChannelId: th.BasicChannel.Id, Message: "testReply2", RootId: rpost.Id}) 6100 6101 th.SystemAdminClient.UpdateThreadReadForUser(th.BasicUser2.Id, th.BasicTeam.Id, rpost.Id, model.GetMillis()) 6102 6103 u, _ := th.SystemAdminClient.GetUserThreads(th.BasicUser2.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{}) 6104 require.EqualValues(t, 0, u.TotalUnreadMentions) 6105 6106 th.SystemAdminClient.UpdateThreadReadForUser(th.BasicUser2.Id, th.BasicTeam.Id, rpost.Id, rpost.CreateAt) 6107 6108 u, _ = th.SystemAdminClient.GetUserThreads(th.BasicUser2.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{}) 6109 require.EqualValues(t, 1, u.TotalUnreadMentions) 6110 6111 th.SystemAdminClient.UpdateThreadReadForUser(th.BasicUser2.Id, th.BasicTeam.Id, rpost.Id, reply.CreateAt) 6112 6113 u, _ = th.SystemAdminClient.GetUserThreads(th.BasicUser2.Id, th.BasicTeam.Id, model.GetUserThreadsOpts{}) 6114 require.EqualValues(t, 0, u.TotalUnreadMentions) 6115 } 6116 6117 func TestPatchAndUpdateWithProviderAttributes(t *testing.T) { 6118 t.Run("LDAP user", func(t *testing.T) { 6119 th := SetupEnterprise(t).InitBasic() 6120 defer th.TearDown() 6121 user := th.CreateUserWithAuth(model.USER_AUTH_SERVICE_LDAP) 6122 ldapMock := &mocks.LdapInterface{} 6123 ldapMock.Mock.On( 6124 "CheckProviderAttributes", 6125 mock.Anything, // app.AppIface 6126 mock.Anything, // *model.User 6127 mock.Anything, // *model.Patch 6128 ).Return("") 6129 th.App.Srv().Ldap = ldapMock 6130 // CheckProviderAttributes should be called for both Patch and Update 6131 th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{}) 6132 ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1) 6133 th.SystemAdminClient.UpdateUser(user) 6134 ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 2) 6135 }) 6136 t.Run("SAML user", func(t *testing.T) { 6137 t.Run("with LDAP sync", func(t *testing.T) { 6138 th := SetupEnterprise(t).InitBasic() 6139 defer th.TearDown() 6140 th.SetupLdapConfig() 6141 th.SetupSamlConfig() 6142 th.App.UpdateConfig(func(cfg *model.Config) { 6143 *cfg.SamlSettings.EnableSyncWithLdap = true 6144 }) 6145 user := th.CreateUserWithAuth(model.USER_AUTH_SERVICE_SAML) 6146 ldapMock := &mocks.LdapInterface{} 6147 ldapMock.Mock.On( 6148 "CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything, 6149 ).Return("") 6150 th.App.Srv().Ldap = ldapMock 6151 th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{}) 6152 ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1) 6153 th.SystemAdminClient.UpdateUser(user) 6154 ldapMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 2) 6155 }) 6156 t.Run("without LDAP sync", func(t *testing.T) { 6157 th := SetupEnterprise(t).InitBasic() 6158 defer th.TearDown() 6159 user := th.CreateUserWithAuth(model.USER_AUTH_SERVICE_SAML) 6160 samlMock := &mocks.SamlInterface{} 6161 samlMock.Mock.On( 6162 "CheckProviderAttributes", mock.Anything, mock.Anything, mock.Anything, 6163 ).Return("") 6164 th.App.Srv().Saml = samlMock 6165 th.SystemAdminClient.PatchUser(user.Id, &model.UserPatch{}) 6166 samlMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 1) 6167 th.SystemAdminClient.UpdateUser(user) 6168 samlMock.AssertNumberOfCalls(t, "CheckProviderAttributes", 2) 6169 }) 6170 }) 6171 t.Run("OpenID user", func(t *testing.T) { 6172 th := SetupEnterprise(t).InitBasic() 6173 defer th.TearDown() 6174 user := th.CreateUserWithAuth(model.SERVICE_OPENID) 6175 // OAUTH users cannot change these fields 6176 for _, fieldName := range []string{ 6177 "FirstName", 6178 "LastName", 6179 } { 6180 patch := user.ToPatch() 6181 patch.SetField(fieldName, "something new") 6182 conflictField := th.App.CheckProviderAttributes(user, patch) 6183 require.NotEqual(t, "", conflictField) 6184 } 6185 }) 6186 t.Run("Patch username", func(t *testing.T) { 6187 th := SetupEnterprise(t).InitBasic() 6188 defer th.TearDown() 6189 // For non-email users, the username must be changed through the provider 6190 for _, authService := range []string{ 6191 model.USER_AUTH_SERVICE_LDAP, 6192 model.USER_AUTH_SERVICE_SAML, 6193 model.SERVICE_OPENID, 6194 } { 6195 user := th.CreateUserWithAuth(authService) 6196 patch := &model.UserPatch{Username: model.NewString("something new")} 6197 conflictField := th.App.CheckProviderAttributes(user, patch) 6198 require.NotEqual(t, "", conflictField) 6199 } 6200 }) 6201 } 6202 6203 func TestSetProfileImageWithProviderAttributes(t *testing.T) { 6204 data, err := testutils.ReadTestFile("test.png") 6205 require.NoError(t, err) 6206 6207 type imageTestCase struct { 6208 testName string 6209 ldapAttrIsSet bool 6210 shouldPass bool 6211 } 6212 6213 doImageTest := func(t *testing.T, th *TestHelper, user *model.User, testCase imageTestCase) { 6214 client := th.SystemAdminClient 6215 t.Run(testCase.testName, func(t *testing.T) { 6216 th.App.UpdateConfig(func(cfg *model.Config) { 6217 if testCase.ldapAttrIsSet { 6218 *cfg.LdapSettings.PictureAttribute = "jpegPhoto" 6219 } else { 6220 *cfg.LdapSettings.PictureAttribute = "" 6221 } 6222 }) 6223 ok, resp := client.SetProfileImage(user.Id, data) 6224 if testCase.shouldPass { 6225 require.True(t, ok) 6226 CheckNoError(t, resp) 6227 } else { 6228 require.False(t, ok) 6229 checkHTTPStatus(t, resp, http.StatusConflict, true) 6230 } 6231 }) 6232 } 6233 doCleanup := func(t *testing.T, th *TestHelper, user *model.User) { 6234 info := &model.FileInfo{Path: "users/" + user.Id + "/profile.png"} 6235 err = th.cleanupTestFile(info) 6236 require.NoError(t, err) 6237 } 6238 6239 t.Run("LDAP user", func(t *testing.T) { 6240 testCases := []imageTestCase{ 6241 {"profile picture attribute is set", true, false}, 6242 {"profile picture attribute is not set", false, true}, 6243 } 6244 th := SetupEnterprise(t).InitBasic() 6245 defer th.TearDown() 6246 th.SetupLdapConfig() 6247 user := th.CreateUserWithAuth(model.USER_AUTH_SERVICE_LDAP) 6248 for _, testCase := range testCases { 6249 doImageTest(t, th, user, testCase) 6250 } 6251 doCleanup(t, th, user) 6252 }) 6253 6254 t.Run("SAML user", func(t *testing.T) { 6255 th := SetupEnterprise(t).InitBasic() 6256 defer th.TearDown() 6257 th.SetupLdapConfig() 6258 th.SetupSamlConfig() 6259 user := th.CreateUserWithAuth(model.USER_AUTH_SERVICE_SAML) 6260 6261 t.Run("with LDAP sync", func(t *testing.T) { 6262 th.App.UpdateConfig(func(cfg *model.Config) { 6263 *cfg.SamlSettings.EnableSyncWithLdap = true 6264 }) 6265 testCases := []imageTestCase{ 6266 {"profile picture attribute is set", true, false}, 6267 {"profile picture attribute is not set", false, true}, 6268 } 6269 for _, testCase := range testCases { 6270 doImageTest(t, th, user, testCase) 6271 } 6272 }) 6273 t.Run("without LDAP sync", func(t *testing.T) { 6274 th.App.UpdateConfig(func(cfg *model.Config) { 6275 *cfg.SamlSettings.EnableSyncWithLdap = false 6276 }) 6277 testCases := []imageTestCase{ 6278 {"profile picture attribute is set", true, true}, 6279 {"profile picture attribute is not set", false, true}, 6280 } 6281 for _, testCase := range testCases { 6282 doImageTest(t, th, user, testCase) 6283 } 6284 }) 6285 doCleanup(t, th, user) 6286 }) 6287 }