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