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