github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/team_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  	"encoding/base64"
     8  	"encoding/binary"
     9  	"fmt"
    10  	"net/http"
    11  	"strconv"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  
    18  	"github.com/masterhung0112/hk_server/v5/app"
    19  	"github.com/masterhung0112/hk_server/v5/model"
    20  	"github.com/masterhung0112/hk_server/v5/shared/i18n"
    21  	"github.com/masterhung0112/hk_server/v5/shared/mail"
    22  	"github.com/masterhung0112/hk_server/v5/utils/testutils"
    23  )
    24  
    25  func TestCreateTeam(t *testing.T) {
    26  	th := Setup(t)
    27  	defer th.TearDown()
    28  
    29  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
    30  		team := &model.Team{Name: GenerateTestUsername(), DisplayName: "Some Team", Type: model.TEAM_OPEN}
    31  		rteam, resp := client.CreateTeam(team)
    32  		CheckNoError(t, resp)
    33  		CheckCreatedStatus(t, resp)
    34  
    35  		require.Equal(t, rteam.Name, team.Name, "names did not match")
    36  
    37  		require.Equal(t, rteam.DisplayName, team.DisplayName, "display names did not match")
    38  
    39  		require.Equal(t, rteam.Type, team.Type, "types did not match")
    40  
    41  		_, resp = client.CreateTeam(rteam)
    42  		CheckBadRequestStatus(t, resp)
    43  
    44  		rteam.Id = ""
    45  		_, resp = client.CreateTeam(rteam)
    46  		CheckErrorMessage(t, resp, "app.team.save.existing.app_error")
    47  		CheckBadRequestStatus(t, resp)
    48  
    49  		rteam.Name = ""
    50  		_, resp = client.CreateTeam(rteam)
    51  		CheckErrorMessage(t, resp, "model.team.is_valid.characters.app_error")
    52  		CheckBadRequestStatus(t, resp)
    53  
    54  		r, err := client.DoApiPost("/teams", "garbage")
    55  		require.NotNil(t, err, "should have errored")
    56  
    57  		require.Equalf(t, r.StatusCode, http.StatusBadRequest, "wrong status code, actual: %s, expected: %s", strconv.Itoa(r.StatusCode), strconv.Itoa(http.StatusBadRequest))
    58  
    59  		// Test GroupConstrained flag
    60  		groupConstrainedTeam := &model.Team{Name: GenerateTestUsername(), DisplayName: "Some Team", Type: model.TEAM_OPEN, GroupConstrained: model.NewBool(true)}
    61  		rteam, resp = client.CreateTeam(groupConstrainedTeam)
    62  		CheckNoError(t, resp)
    63  		CheckCreatedStatus(t, resp)
    64  
    65  		assert.Equal(t, *rteam.GroupConstrained, *groupConstrainedTeam.GroupConstrained, "GroupConstrained flags do not match")
    66  	})
    67  
    68  	th.Client.Logout()
    69  
    70  	team := &model.Team{Name: GenerateTestUsername(), DisplayName: "Some Team", Type: model.TEAM_OPEN}
    71  	_, resp := th.Client.CreateTeam(team)
    72  	CheckUnauthorizedStatus(t, resp)
    73  
    74  	th.LoginBasic()
    75  
    76  	// Check the appropriate permissions are enforced.
    77  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    78  	defer func() {
    79  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    80  	}()
    81  
    82  	th.RemovePermissionFromRole(model.PERMISSION_CREATE_TEAM.Id, model.SYSTEM_USER_ROLE_ID)
    83  	th.AddPermissionToRole(model.PERMISSION_CREATE_TEAM.Id, model.SYSTEM_ADMIN_ROLE_ID)
    84  
    85  	_, resp = th.Client.CreateTeam(team)
    86  	CheckForbiddenStatus(t, resp)
    87  }
    88  
    89  func TestCreateTeamSanitization(t *testing.T) {
    90  	th := Setup(t)
    91  	defer th.TearDown()
    92  
    93  	// Non-admin users can create a team, but they become a team admin by doing so
    94  
    95  	t.Run("team admin", func(t *testing.T) {
    96  		team := &model.Team{
    97  			DisplayName:    t.Name() + "_1",
    98  			Name:           GenerateTestTeamName(),
    99  			Email:          th.GenerateTestEmail(),
   100  			Type:           model.TEAM_OPEN,
   101  			AllowedDomains: "simulator.amazonses.com,localhost",
   102  		}
   103  
   104  		rteam, resp := th.Client.CreateTeam(team)
   105  		CheckNoError(t, resp)
   106  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
   107  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   108  	})
   109  
   110  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   111  		team := &model.Team{
   112  			DisplayName:    t.Name() + "_2",
   113  			Name:           GenerateTestTeamName(),
   114  			Email:          th.GenerateTestEmail(),
   115  			Type:           model.TEAM_OPEN,
   116  			AllowedDomains: "simulator.amazonses.com,localhost",
   117  		}
   118  
   119  		rteam, resp := client.CreateTeam(team)
   120  		CheckNoError(t, resp)
   121  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
   122  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   123  	}, "system admin")
   124  }
   125  
   126  func TestGetTeam(t *testing.T) {
   127  	th := Setup(t).InitBasic()
   128  	defer th.TearDown()
   129  	Client := th.Client
   130  	team := th.BasicTeam
   131  
   132  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   133  		rteam, resp := client.GetTeam(team.Id, "")
   134  		CheckNoError(t, resp)
   135  
   136  		require.Equal(t, rteam.Id, team.Id, "wrong team")
   137  
   138  		_, resp = client.GetTeam("junk", "")
   139  		CheckBadRequestStatus(t, resp)
   140  
   141  		_, resp = client.GetTeam("", "")
   142  		CheckNotFoundStatus(t, resp)
   143  
   144  		_, resp = client.GetTeam(model.NewId(), "")
   145  		CheckNotFoundStatus(t, resp)
   146  	})
   147  
   148  	th.LoginTeamAdmin()
   149  
   150  	team2 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false}
   151  	rteam2, _ := Client.CreateTeam(team2)
   152  
   153  	team3 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_INVITE, AllowOpenInvite: true}
   154  	rteam3, _ := Client.CreateTeam(team3)
   155  
   156  	th.LoginBasic()
   157  	// AllowInviteOpen is false and team is open, and user is not on team
   158  	_, resp := Client.GetTeam(rteam2.Id, "")
   159  	CheckForbiddenStatus(t, resp)
   160  
   161  	// AllowInviteOpen is true and team is invite, and user is not on team
   162  	_, resp = Client.GetTeam(rteam3.Id, "")
   163  	CheckForbiddenStatus(t, resp)
   164  
   165  	Client.Logout()
   166  	_, resp = Client.GetTeam(team.Id, "")
   167  	CheckUnauthorizedStatus(t, resp)
   168  
   169  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   170  		_, resp = client.GetTeam(rteam2.Id, "")
   171  		CheckNoError(t, resp)
   172  	})
   173  }
   174  
   175  func TestGetTeamSanitization(t *testing.T) {
   176  	th := Setup(t).InitBasic()
   177  	defer th.TearDown()
   178  
   179  	team, resp := th.Client.CreateTeam(&model.Team{
   180  		DisplayName:    t.Name() + "_1",
   181  		Name:           GenerateTestTeamName(),
   182  		Email:          th.GenerateTestEmail(),
   183  		Type:           model.TEAM_OPEN,
   184  		AllowedDomains: "simulator.amazonses.com,localhost",
   185  	})
   186  	CheckNoError(t, resp)
   187  
   188  	t.Run("team user", func(t *testing.T) {
   189  		th.LinkUserToTeam(th.BasicUser2, team)
   190  
   191  		client := th.CreateClient()
   192  		th.LoginBasic2WithClient(client)
   193  
   194  		rteam, resp := client.GetTeam(team.Id, "")
   195  		CheckNoError(t, resp)
   196  
   197  		require.Empty(t, rteam.Email, "should have sanitized email")
   198  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   199  	})
   200  
   201  	t.Run("team user without invite permissions", func(t *testing.T) {
   202  		th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
   203  		th.LinkUserToTeam(th.BasicUser2, team)
   204  
   205  		client := th.CreateClient()
   206  		th.LoginBasic2WithClient(client)
   207  
   208  		rteam, resp := client.GetTeam(team.Id, "")
   209  		CheckNoError(t, resp)
   210  
   211  		require.Empty(t, rteam.Email, "should have sanitized email")
   212  		require.Empty(t, rteam.InviteId, "should have sanitized inviteid")
   213  	})
   214  
   215  	t.Run("team admin", func(t *testing.T) {
   216  		rteam, resp := th.Client.GetTeam(team.Id, "")
   217  		CheckNoError(t, resp)
   218  
   219  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
   220  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   221  	})
   222  
   223  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   224  		rteam, resp := client.GetTeam(team.Id, "")
   225  		CheckNoError(t, resp)
   226  
   227  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
   228  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   229  	}, "system admin")
   230  }
   231  
   232  func TestGetTeamUnread(t *testing.T) {
   233  	th := Setup(t).InitBasic()
   234  	defer th.TearDown()
   235  	Client := th.Client
   236  
   237  	teamUnread, resp := Client.GetTeamUnread(th.BasicTeam.Id, th.BasicUser.Id)
   238  	CheckNoError(t, resp)
   239  	require.Equal(t, teamUnread.TeamId, th.BasicTeam.Id, "wrong team id returned for regular user call")
   240  
   241  	_, resp = Client.GetTeamUnread("junk", th.BasicUser.Id)
   242  	CheckBadRequestStatus(t, resp)
   243  
   244  	_, resp = Client.GetTeamUnread(th.BasicTeam.Id, "junk")
   245  	CheckBadRequestStatus(t, resp)
   246  
   247  	_, resp = Client.GetTeamUnread(model.NewId(), th.BasicUser.Id)
   248  	CheckForbiddenStatus(t, resp)
   249  
   250  	_, resp = Client.GetTeamUnread(th.BasicTeam.Id, model.NewId())
   251  	CheckForbiddenStatus(t, resp)
   252  
   253  	Client.Logout()
   254  	_, resp = Client.GetTeamUnread(th.BasicTeam.Id, th.BasicUser.Id)
   255  	CheckUnauthorizedStatus(t, resp)
   256  
   257  	teamUnread, resp = th.SystemAdminClient.GetTeamUnread(th.BasicTeam.Id, th.BasicUser.Id)
   258  	CheckNoError(t, resp)
   259  	require.Equal(t, teamUnread.TeamId, th.BasicTeam.Id, "wrong team id returned")
   260  }
   261  
   262  func TestUpdateTeam(t *testing.T) {
   263  	th := Setup(t)
   264  	defer th.TearDown()
   265  
   266  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   267  		team := &model.Team{DisplayName: "Name", Description: "Some description", AllowOpenInvite: false, InviteId: "inviteid0", Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   268  		var resp *model.Response
   269  		team, resp = th.Client.CreateTeam(team)
   270  		CheckNoError(t, resp)
   271  
   272  		team.Description = "updated description"
   273  		uteam, resp := client.UpdateTeam(team)
   274  		CheckNoError(t, resp)
   275  
   276  		require.Equal(t, uteam.Description, "updated description", "Update failed")
   277  
   278  		team.DisplayName = "Updated Name"
   279  		uteam, resp = client.UpdateTeam(team)
   280  		CheckNoError(t, resp)
   281  
   282  		require.Equal(t, uteam.DisplayName, "Updated Name", "Update failed")
   283  
   284  		// Test GroupConstrained flag
   285  		team.GroupConstrained = model.NewBool(true)
   286  		rteam, resp := client.UpdateTeam(team)
   287  		CheckNoError(t, resp)
   288  		CheckOKStatus(t, resp)
   289  
   290  		require.Equal(t, *rteam.GroupConstrained, *team.GroupConstrained, "GroupConstrained flags do not match")
   291  
   292  		team.GroupConstrained = nil
   293  
   294  		team.AllowOpenInvite = true
   295  		uteam, resp = client.UpdateTeam(team)
   296  		CheckNoError(t, resp)
   297  
   298  		require.True(t, uteam.AllowOpenInvite, "Update failed")
   299  
   300  		team.InviteId = "inviteid1"
   301  		uteam, resp = client.UpdateTeam(team)
   302  		CheckNoError(t, resp)
   303  
   304  		require.NotEqual(t, uteam.InviteId, "inviteid1", "InviteID should not be updated")
   305  
   306  		team.AllowedDomains = "domain"
   307  		uteam, resp = client.UpdateTeam(team)
   308  		CheckNoError(t, resp)
   309  
   310  		require.Equal(t, uteam.AllowedDomains, "domain", "Update failed")
   311  
   312  		team.Name = "Updated name"
   313  		uteam, resp = client.UpdateTeam(team)
   314  		CheckNoError(t, resp)
   315  
   316  		require.NotEqual(t, uteam.Name, "Updated name", "Should not update name")
   317  
   318  		team.Email = "test@domain.com"
   319  		uteam, resp = client.UpdateTeam(team)
   320  		CheckNoError(t, resp)
   321  
   322  		require.NotEqual(t, uteam.Email, "test@domain.com", "Should not update email")
   323  
   324  		team.Type = model.TEAM_INVITE
   325  		uteam, resp = client.UpdateTeam(team)
   326  		CheckNoError(t, resp)
   327  
   328  		require.NotEqual(t, uteam.Type, model.TEAM_INVITE, "Should not update type")
   329  
   330  		originalTeamId := team.Id
   331  		team.Id = model.NewId()
   332  
   333  		r, _ := client.DoApiPut(client.GetTeamRoute(originalTeamId), team.ToJson())
   334  		assert.Equal(t, http.StatusBadRequest, r.StatusCode)
   335  
   336  		require.Equal(t, uteam.Id, originalTeamId, "wrong team id")
   337  
   338  		team.Id = "fake"
   339  		_, resp = client.UpdateTeam(team)
   340  		CheckBadRequestStatus(t, resp)
   341  
   342  		th.Client.Logout() // for non-local clients
   343  		_, resp = th.Client.UpdateTeam(team)
   344  		CheckUnauthorizedStatus(t, resp)
   345  		th.LoginBasic()
   346  	})
   347  
   348  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   349  		team := &model.Team{DisplayName: "New", Description: "Some description", AllowOpenInvite: false, InviteId: "inviteid0", Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   350  		var resp *model.Response
   351  		team, resp = client.CreateTeam(team)
   352  		CheckNoError(t, resp)
   353  
   354  		team.Name = "new-name"
   355  		_, resp = client.UpdateTeam(team)
   356  		CheckNoError(t, resp)
   357  	})
   358  }
   359  
   360  func TestUpdateTeamSanitization(t *testing.T) {
   361  	th := Setup(t)
   362  	defer th.TearDown()
   363  
   364  	team, resp := th.Client.CreateTeam(&model.Team{
   365  		DisplayName:    t.Name() + "_1",
   366  		Name:           GenerateTestTeamName(),
   367  		Email:          th.GenerateTestEmail(),
   368  		Type:           model.TEAM_OPEN,
   369  		AllowedDomains: "simulator.amazonses.com,localhost",
   370  	})
   371  	CheckNoError(t, resp)
   372  
   373  	// Non-admin users cannot update the team
   374  
   375  	t.Run("team admin", func(t *testing.T) {
   376  		rteam, resp := th.Client.UpdateTeam(team)
   377  		CheckNoError(t, resp)
   378  
   379  		require.NotEmpty(t, rteam.Email, "should not have sanitized email for admin")
   380  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   381  	})
   382  
   383  	t.Run("system admin", func(t *testing.T) {
   384  		rteam, resp := th.SystemAdminClient.UpdateTeam(team)
   385  		CheckNoError(t, resp)
   386  
   387  		require.NotEmpty(t, rteam.Email, "should not have sanitized email for admin")
   388  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   389  	})
   390  }
   391  
   392  func TestPatchTeam(t *testing.T) {
   393  	th := Setup(t).InitBasic()
   394  	defer th.TearDown()
   395  
   396  	team := &model.Team{DisplayName: "Name", Description: "Some description", CompanyName: "Some company name", AllowOpenInvite: false, InviteId: "inviteid0", Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   397  	team, _ = th.Client.CreateTeam(team)
   398  
   399  	patch := &model.TeamPatch{}
   400  	patch.DisplayName = model.NewString("Other name")
   401  	patch.Description = model.NewString("Other description")
   402  	patch.CompanyName = model.NewString("Other company name")
   403  	patch.AllowOpenInvite = model.NewBool(true)
   404  
   405  	_, resp := th.Client.PatchTeam(GenerateTestId(), patch)
   406  	CheckForbiddenStatus(t, resp)
   407  
   408  	th.Client.Logout()
   409  	_, resp = th.Client.PatchTeam(team.Id, patch)
   410  	CheckUnauthorizedStatus(t, resp)
   411  
   412  	th.LoginBasic2()
   413  	_, resp = th.Client.PatchTeam(team.Id, patch)
   414  	CheckForbiddenStatus(t, resp)
   415  	th.LoginBasic()
   416  
   417  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   418  		rteam, resp := client.PatchTeam(team.Id, patch)
   419  		CheckNoError(t, resp)
   420  
   421  		require.Equal(t, rteam.DisplayName, "Other name", "DisplayName did not update properly")
   422  		require.Equal(t, rteam.Description, "Other description", "Description did not update properly")
   423  		require.Equal(t, rteam.CompanyName, "Other company name", "CompanyName did not update properly")
   424  		require.NotEqual(t, rteam.InviteId, "inviteid1", "InviteId should not update")
   425  		require.True(t, rteam.AllowOpenInvite, "AllowOpenInvite did not update properly")
   426  
   427  		t.Run("Changing AllowOpenInvite to false regenerates InviteID", func(t *testing.T) {
   428  			team2 := &model.Team{DisplayName: "Name2", Description: "Some description", CompanyName: "Some company name", AllowOpenInvite: true, InviteId: model.NewId(), Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   429  			team2, _ = client.CreateTeam(team2)
   430  
   431  			patch2 := &model.TeamPatch{
   432  				AllowOpenInvite: model.NewBool(false),
   433  			}
   434  
   435  			rteam2, resp2 := client.PatchTeam(team2.Id, patch2)
   436  			CheckNoError(t, resp2)
   437  			require.Equal(t, team2.Id, rteam2.Id)
   438  			require.False(t, rteam2.AllowOpenInvite)
   439  			require.NotEqual(t, team2.InviteId, rteam2.InviteId)
   440  		})
   441  
   442  		t.Run("Changing AllowOpenInvite to true doesn't regenerate InviteID", func(t *testing.T) {
   443  			team2 := &model.Team{DisplayName: "Name3", Description: "Some description", CompanyName: "Some company name", AllowOpenInvite: false, InviteId: model.NewId(), Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   444  			team2, _ = client.CreateTeam(team2)
   445  
   446  			patch2 := &model.TeamPatch{
   447  				AllowOpenInvite: model.NewBool(true),
   448  			}
   449  
   450  			rteam2, resp2 := client.PatchTeam(team2.Id, patch2)
   451  			CheckNoError(t, resp2)
   452  			require.Equal(t, team2.Id, rteam2.Id)
   453  			require.True(t, rteam2.AllowOpenInvite)
   454  			require.Equal(t, team2.InviteId, rteam2.InviteId)
   455  		})
   456  
   457  		// Test GroupConstrained flag
   458  		patch.GroupConstrained = model.NewBool(true)
   459  		rteam, resp = client.PatchTeam(team.Id, patch)
   460  		CheckNoError(t, resp)
   461  		CheckOKStatus(t, resp)
   462  		require.Equal(t, *rteam.GroupConstrained, *patch.GroupConstrained, "GroupConstrained flags do not match")
   463  
   464  		patch.GroupConstrained = nil
   465  		_, resp = client.PatchTeam("junk", patch)
   466  		CheckBadRequestStatus(t, resp)
   467  
   468  		r, err := client.DoApiPut("/teams/"+team.Id+"/patch", "garbage")
   469  		require.NotNil(t, err, "should have errored")
   470  		require.Equalf(t, r.StatusCode, http.StatusBadRequest, "wrong status code, actual: %s, expected: %s", strconv.Itoa(r.StatusCode), strconv.Itoa(http.StatusBadRequest))
   471  	})
   472  
   473  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   474  		_, resp := client.PatchTeam(th.BasicTeam.Id, patch)
   475  		CheckNoError(t, resp)
   476  	})
   477  }
   478  
   479  func TestRestoreTeam(t *testing.T) {
   480  	th := Setup(t)
   481  	defer th.TearDown()
   482  	Client := th.Client
   483  
   484  	createTeam := func(t *testing.T, deleted bool, teamType string) *model.Team {
   485  		t.Helper()
   486  		team := &model.Team{
   487  			DisplayName:     "Some Team",
   488  			Description:     "Some description",
   489  			CompanyName:     "Some company name",
   490  			AllowOpenInvite: (teamType == model.TEAM_OPEN),
   491  			InviteId:        model.NewId(),
   492  			Name:            "aa-" + model.NewRandomTeamName() + "zz",
   493  			Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   494  			Type:            teamType,
   495  		}
   496  		team, _ = Client.CreateTeam(team)
   497  		require.NotNil(t, team)
   498  		if deleted {
   499  			_, resp := th.SystemAdminClient.SoftDeleteTeam(team.Id)
   500  			CheckOKStatus(t, resp)
   501  		}
   502  		return team
   503  	}
   504  	teamPublic := createTeam(t, true, model.TEAM_OPEN)
   505  
   506  	t.Run("invalid team", func(t *testing.T) {
   507  		_, resp := Client.RestoreTeam(model.NewId())
   508  		CheckForbiddenStatus(t, resp)
   509  	})
   510  
   511  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   512  		team := createTeam(t, true, model.TEAM_OPEN)
   513  		team, resp := client.RestoreTeam(team.Id)
   514  		CheckOKStatus(t, resp)
   515  		require.Zero(t, team.DeleteAt)
   516  		require.Equal(t, model.TEAM_OPEN, team.Type)
   517  	}, "restore archived public team")
   518  
   519  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   520  		team := createTeam(t, true, model.TEAM_INVITE)
   521  		team, resp := client.RestoreTeam(team.Id)
   522  		CheckOKStatus(t, resp)
   523  		require.Zero(t, team.DeleteAt)
   524  		require.Equal(t, model.TEAM_INVITE, team.Type)
   525  	}, "restore archived private team")
   526  
   527  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   528  		team := createTeam(t, false, model.TEAM_OPEN)
   529  		team, resp := client.RestoreTeam(team.Id)
   530  		CheckOKStatus(t, resp)
   531  		require.Zero(t, team.DeleteAt)
   532  		require.Equal(t, model.TEAM_OPEN, team.Type)
   533  	}, "restore active public team")
   534  
   535  	t.Run("not logged in", func(t *testing.T) {
   536  		Client.Logout()
   537  		_, resp := Client.RestoreTeam(teamPublic.Id)
   538  		CheckUnauthorizedStatus(t, resp)
   539  	})
   540  
   541  	t.Run("no permission to manage team", func(t *testing.T) {
   542  		th.LoginBasic2()
   543  		_, resp := Client.RestoreTeam(teamPublic.Id)
   544  		CheckForbiddenStatus(t, resp)
   545  	})
   546  
   547  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   548  		_, resp := client.RestoreTeam(teamPublic.Id)
   549  		CheckOKStatus(t, resp)
   550  	})
   551  }
   552  
   553  func TestPatchTeamSanitization(t *testing.T) {
   554  	th := Setup(t)
   555  	defer th.TearDown()
   556  
   557  	team, resp := th.Client.CreateTeam(&model.Team{
   558  		DisplayName:    t.Name() + "_1",
   559  		Name:           GenerateTestTeamName(),
   560  		Email:          th.GenerateTestEmail(),
   561  		Type:           model.TEAM_OPEN,
   562  		AllowedDomains: "simulator.amazonses.com,localhost",
   563  	})
   564  	CheckNoError(t, resp)
   565  
   566  	// Non-admin users cannot update the team
   567  
   568  	t.Run("team admin", func(t *testing.T) {
   569  		rteam, resp := th.Client.PatchTeam(team.Id, &model.TeamPatch{})
   570  		CheckNoError(t, resp)
   571  
   572  		require.NotEmpty(t, rteam.Email, "should not have sanitized email for admin")
   573  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   574  	})
   575  
   576  	t.Run("system admin", func(t *testing.T) {
   577  		rteam, resp := th.SystemAdminClient.PatchTeam(team.Id, &model.TeamPatch{})
   578  		CheckNoError(t, resp)
   579  
   580  		require.NotEmpty(t, rteam.Email, "should not have sanitized email for admin")
   581  		require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
   582  	})
   583  }
   584  
   585  func TestUpdateTeamPrivacy(t *testing.T) {
   586  	th := Setup(t)
   587  	defer th.TearDown()
   588  	Client := th.Client
   589  
   590  	createTeam := func(teamType string, allowOpenInvite bool) *model.Team {
   591  		team := &model.Team{
   592  			DisplayName:     teamType + " Team",
   593  			Description:     "Some description",
   594  			CompanyName:     "Some company name",
   595  			AllowOpenInvite: allowOpenInvite,
   596  			InviteId:        model.NewId(),
   597  			Name:            "aa-" + model.NewRandomTeamName() + "zz",
   598  			Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   599  			Type:            teamType,
   600  		}
   601  		team, _ = Client.CreateTeam(team)
   602  		return team
   603  	}
   604  
   605  	teamPublic := createTeam(model.TEAM_OPEN, true)
   606  	teamPrivate := createTeam(model.TEAM_INVITE, false)
   607  
   608  	teamPublic2 := createTeam(model.TEAM_OPEN, true)
   609  	teamPrivate2 := createTeam(model.TEAM_INVITE, false)
   610  
   611  	tests := []struct {
   612  		name                string
   613  		team                *model.Team
   614  		privacy             string
   615  		errChecker          func(t *testing.T, resp *model.Response)
   616  		wantType            string
   617  		wantOpenInvite      bool
   618  		wantInviteIdChanged bool
   619  		originalInviteId    string
   620  	}{
   621  		{name: "bad privacy", team: teamPublic, privacy: "blap", errChecker: CheckBadRequestStatus, wantType: model.TEAM_OPEN, wantOpenInvite: true},
   622  		{name: "public to private", team: teamPublic, privacy: model.TEAM_INVITE, errChecker: nil, wantType: model.TEAM_INVITE, wantOpenInvite: false, originalInviteId: teamPublic.InviteId, wantInviteIdChanged: true},
   623  		{name: "private to public", team: teamPrivate, privacy: model.TEAM_OPEN, errChecker: nil, wantType: model.TEAM_OPEN, wantOpenInvite: true, originalInviteId: teamPrivate.InviteId, wantInviteIdChanged: false},
   624  		{name: "public to public", team: teamPublic2, privacy: model.TEAM_OPEN, errChecker: nil, wantType: model.TEAM_OPEN, wantOpenInvite: true, originalInviteId: teamPublic2.InviteId, wantInviteIdChanged: false},
   625  		{name: "private to private", team: teamPrivate2, privacy: model.TEAM_INVITE, errChecker: nil, wantType: model.TEAM_INVITE, wantOpenInvite: false, originalInviteId: teamPrivate2.InviteId, wantInviteIdChanged: false},
   626  	}
   627  
   628  	for _, test := range tests {
   629  		t.Run(test.name, func(t *testing.T) {
   630  			th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   631  				team, resp := client.UpdateTeamPrivacy(test.team.Id, test.privacy)
   632  				if test.errChecker != nil {
   633  					test.errChecker(t, resp)
   634  					return
   635  				}
   636  				CheckNoError(t, resp)
   637  				CheckOKStatus(t, resp)
   638  				require.Equal(t, test.wantType, team.Type)
   639  				require.Equal(t, test.wantOpenInvite, team.AllowOpenInvite)
   640  				if test.wantInviteIdChanged {
   641  					require.NotEqual(t, test.originalInviteId, team.InviteId)
   642  				} else {
   643  					require.Equal(t, test.originalInviteId, team.InviteId)
   644  				}
   645  			})
   646  		})
   647  	}
   648  
   649  	t.Run("non-existent team", func(t *testing.T) {
   650  		_, resp := Client.UpdateTeamPrivacy(model.NewId(), model.TEAM_INVITE)
   651  		CheckForbiddenStatus(t, resp)
   652  	})
   653  
   654  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   655  		_, resp := client.UpdateTeamPrivacy(model.NewId(), model.TEAM_INVITE)
   656  		CheckNotFoundStatus(t, resp)
   657  	}, "non-existent team for admins")
   658  
   659  	t.Run("not logged in", func(t *testing.T) {
   660  		Client.Logout()
   661  		_, resp := Client.UpdateTeamPrivacy(teamPublic.Id, model.TEAM_INVITE)
   662  		CheckUnauthorizedStatus(t, resp)
   663  	})
   664  
   665  	t.Run("no permission to manage team", func(t *testing.T) {
   666  		th.LoginBasic2()
   667  		_, resp := Client.UpdateTeamPrivacy(teamPublic.Id, model.TEAM_INVITE)
   668  		CheckForbiddenStatus(t, resp)
   669  	})
   670  }
   671  
   672  func TestTeamUnicodeNames(t *testing.T) {
   673  	th := Setup(t)
   674  	defer th.TearDown()
   675  	Client := th.Client
   676  
   677  	t.Run("create team unicode", func(t *testing.T) {
   678  		team := &model.Team{
   679  			Name:        GenerateTestUsername(),
   680  			DisplayName: "Some\u206c Team",
   681  			Description: "A \ufffatest\ufffb channel.",
   682  			CompanyName: "\ufeffAcme Inc\ufffc",
   683  			Type:        model.TEAM_OPEN}
   684  		rteam, resp := Client.CreateTeam(team)
   685  		CheckNoError(t, resp)
   686  		CheckCreatedStatus(t, resp)
   687  
   688  		require.Equal(t, "Some Team", rteam.DisplayName, "bad unicode should be filtered from display name")
   689  		require.Equal(t, "A test channel.", rteam.Description, "bad unicode should be filtered from description")
   690  		require.Equal(t, "Acme Inc", rteam.CompanyName, "bad unicode should be filtered from company name")
   691  	})
   692  
   693  	t.Run("update team unicode", func(t *testing.T) {
   694  		team := &model.Team{
   695  			DisplayName: "Name",
   696  			Description: "Some description",
   697  			CompanyName: "Bad Company",
   698  			Name:        model.NewRandomTeamName(),
   699  			Email:       "success+" + model.NewId() + "@simulator.amazonses.com",
   700  			Type:        model.TEAM_OPEN}
   701  		team, _ = Client.CreateTeam(team)
   702  
   703  		team.DisplayName = "\u206eThe Team\u206f"
   704  		team.Description = "A \u17a3great\u17d3 team."
   705  		team.CompanyName = "\u206aAcme Inc"
   706  		uteam, resp := Client.UpdateTeam(team)
   707  		CheckNoError(t, resp)
   708  
   709  		require.Equal(t, "The Team", uteam.DisplayName, "bad unicode should be filtered from display name")
   710  		require.Equal(t, "A great team.", uteam.Description, "bad unicode should be filtered from description")
   711  		require.Equal(t, "Acme Inc", uteam.CompanyName, "bad unicode should be filtered from company name")
   712  	})
   713  
   714  	t.Run("patch team unicode", func(t *testing.T) {
   715  		team := &model.Team{
   716  			DisplayName: "Name",
   717  			Description: "Some description",
   718  			CompanyName: "Some company name",
   719  			Name:        model.NewRandomTeamName(),
   720  			Email:       "success+" + model.NewId() + "@simulator.amazonses.com",
   721  			Type:        model.TEAM_OPEN}
   722  		team, _ = Client.CreateTeam(team)
   723  
   724  		patch := &model.TeamPatch{}
   725  
   726  		patch.DisplayName = model.NewString("Goat\u206e Team")
   727  		patch.Description = model.NewString("\ufffaGreat team.")
   728  		patch.CompanyName = model.NewString("\u202bAcme Inc\u202c")
   729  
   730  		rteam, resp := Client.PatchTeam(team.Id, patch)
   731  		CheckNoError(t, resp)
   732  
   733  		require.Equal(t, "Goat Team", rteam.DisplayName, "bad unicode should be filtered from display name")
   734  		require.Equal(t, "Great team.", rteam.Description, "bad unicode should be filtered from description")
   735  		require.Equal(t, "Acme Inc", rteam.CompanyName, "bad unicode should be filtered from company name")
   736  	})
   737  }
   738  
   739  func TestRegenerateTeamInviteId(t *testing.T) {
   740  	th := Setup(t)
   741  	defer th.TearDown()
   742  	Client := th.Client
   743  
   744  	team := &model.Team{DisplayName: "Name", Description: "Some description", CompanyName: "Some company name", AllowOpenInvite: false, InviteId: "inviteid0", Name: "z-z-" + model.NewRandomTeamName() + "a", Email: "success+" + model.NewId() + "@simulator.amazonses.com", Type: model.TEAM_OPEN}
   745  	team, _ = Client.CreateTeam(team)
   746  
   747  	assert.NotEqual(t, team.InviteId, "")
   748  	assert.NotEqual(t, team.InviteId, "inviteid0")
   749  
   750  	rteam, resp := Client.RegenerateTeamInviteId(team.Id)
   751  	CheckNoError(t, resp)
   752  
   753  	assert.NotEqual(t, team.InviteId, rteam.InviteId)
   754  	assert.NotEqual(t, team.InviteId, "")
   755  }
   756  
   757  func TestSoftDeleteTeam(t *testing.T) {
   758  	th := Setup(t).InitBasic()
   759  	defer th.TearDown()
   760  
   761  	_, resp := th.Client.SoftDeleteTeam(th.BasicTeam.Id)
   762  	CheckForbiddenStatus(t, resp)
   763  
   764  	th.Client.Logout()
   765  	_, resp = th.Client.SoftDeleteTeam(th.BasicTeam.Id)
   766  	CheckUnauthorizedStatus(t, resp)
   767  
   768  	th.LoginBasic()
   769  	team := &model.Team{DisplayName: "DisplayName", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN}
   770  	team, _ = th.Client.CreateTeam(team)
   771  
   772  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   773  		ok, resp := client.SoftDeleteTeam(team.Id)
   774  		CheckNoError(t, resp)
   775  
   776  		require.True(t, ok, "should have returned true")
   777  
   778  		rteam, err := th.App.GetTeam(team.Id)
   779  		require.Nil(t, err, "should have returned archived team")
   780  		require.NotEqual(t, rteam.DeleteAt, 0, "should have not set to zero")
   781  
   782  		ok, resp = client.SoftDeleteTeam("junk")
   783  		CheckBadRequestStatus(t, resp)
   784  
   785  		require.False(t, ok, "should have returned false")
   786  	})
   787  
   788  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   789  		_, resp := client.SoftDeleteTeam(th.BasicTeam.Id)
   790  		CheckNoError(t, resp)
   791  	})
   792  }
   793  
   794  func TestPermanentDeleteTeam(t *testing.T) {
   795  	th := Setup(t)
   796  	defer th.TearDown()
   797  
   798  	enableAPITeamDeletion := *th.App.Config().ServiceSettings.EnableAPITeamDeletion
   799  	defer func() {
   800  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableAPITeamDeletion = &enableAPITeamDeletion })
   801  	}()
   802  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableAPITeamDeletion = false })
   803  
   804  	t.Run("Permanent deletion not available through API if EnableAPITeamDeletion is not set", func(t *testing.T) {
   805  		team := &model.Team{DisplayName: "DisplayName", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN}
   806  		team, _ = th.Client.CreateTeam(team)
   807  
   808  		_, resp := th.Client.PermanentDeleteTeam(team.Id)
   809  		CheckUnauthorizedStatus(t, resp)
   810  
   811  		_, resp = th.SystemAdminClient.PermanentDeleteTeam(team.Id)
   812  		CheckUnauthorizedStatus(t, resp)
   813  	})
   814  
   815  	t.Run("Permanent deletion available through local mode even if EnableAPITeamDeletion is not set", func(t *testing.T) {
   816  		team := &model.Team{DisplayName: "DisplayName", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN}
   817  		team, _ = th.Client.CreateTeam(team)
   818  
   819  		ok, resp := th.LocalClient.PermanentDeleteTeam(team.Id)
   820  		CheckNoError(t, resp)
   821  		assert.True(t, ok)
   822  	})
   823  
   824  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
   825  		defer func() {
   826  			th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableAPITeamDeletion = &enableAPITeamDeletion })
   827  		}()
   828  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableAPITeamDeletion = true })
   829  
   830  		team := &model.Team{DisplayName: "DisplayName", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN}
   831  		team, _ = client.CreateTeam(team)
   832  		ok, resp := client.PermanentDeleteTeam(team.Id)
   833  		CheckNoError(t, resp)
   834  		assert.True(t, ok)
   835  
   836  		_, err := th.App.GetTeam(team.Id)
   837  		assert.NotNil(t, err)
   838  
   839  		ok, resp = client.PermanentDeleteTeam("junk")
   840  		CheckBadRequestStatus(t, resp)
   841  
   842  		require.False(t, ok, "should have returned false")
   843  	}, "Permanent deletion with EnableAPITeamDeletion set")
   844  }
   845  
   846  func TestGetAllTeams(t *testing.T) {
   847  	th := Setup(t).InitBasic()
   848  	defer th.TearDown()
   849  	Client := th.Client
   850  
   851  	team1 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
   852  	team1, resp := Client.CreateTeam(team1)
   853  	CheckNoError(t, resp)
   854  
   855  	team2 := &model.Team{DisplayName: "Name2", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: true}
   856  	team2, resp = Client.CreateTeam(team2)
   857  	CheckNoError(t, resp)
   858  
   859  	team3 := &model.Team{DisplayName: "Name3", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false}
   860  	team3, resp = Client.CreateTeam(team3)
   861  	CheckNoError(t, resp)
   862  
   863  	team4 := &model.Team{DisplayName: "Name4", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false}
   864  	team4, resp = Client.CreateTeam(team4)
   865  	CheckNoError(t, resp)
   866  
   867  	testCases := []struct {
   868  		Name               string
   869  		Page               int
   870  		PerPage            int
   871  		Permissions        []string
   872  		ExpectedTeams      []string
   873  		WithCount          bool
   874  		ExpectedCount      int64
   875  		ExpectedError      bool
   876  		ErrorId            string
   877  		ExpectedStatusCode int
   878  	}{
   879  		{
   880  			Name:          "Get 1 team per page",
   881  			Page:          0,
   882  			PerPage:       1,
   883  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
   884  			ExpectedTeams: []string{team1.Id},
   885  		},
   886  		{
   887  			Name:          "Get second page with 1 team per page",
   888  			Page:          1,
   889  			PerPage:       1,
   890  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
   891  			ExpectedTeams: []string{team2.Id},
   892  		},
   893  		{
   894  			Name:          "Get no items per page",
   895  			Page:          1,
   896  			PerPage:       0,
   897  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
   898  			ExpectedTeams: []string{},
   899  		},
   900  		{
   901  			Name:          "Get all open teams",
   902  			Page:          0,
   903  			PerPage:       10,
   904  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
   905  			ExpectedTeams: []string{team1.Id, team2.Id},
   906  		},
   907  		{
   908  			Name:          "Get all private teams",
   909  			Page:          0,
   910  			PerPage:       10,
   911  			Permissions:   []string{model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
   912  			ExpectedTeams: []string{th.BasicTeam.Id, team3.Id, team4.Id},
   913  		},
   914  		{
   915  			Name:          "Get all teams",
   916  			Page:          0,
   917  			PerPage:       10,
   918  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
   919  			ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id, team4.Id},
   920  		},
   921  		{
   922  			Name:               "Get no teams because permissions",
   923  			Page:               0,
   924  			PerPage:            10,
   925  			Permissions:        []string{},
   926  			ExpectedError:      true,
   927  			ExpectedStatusCode: http.StatusForbidden,
   928  			ErrorId:            "api.team.get_all_teams.insufficient_permissions",
   929  		},
   930  		{
   931  			Name:               "Get no teams because permissions with count",
   932  			Page:               0,
   933  			PerPage:            10,
   934  			Permissions:        []string{},
   935  			WithCount:          true,
   936  			ExpectedError:      true,
   937  			ExpectedStatusCode: http.StatusForbidden,
   938  			ErrorId:            "api.team.get_all_teams.insufficient_permissions",
   939  		},
   940  		{
   941  			Name:          "Get all teams with count",
   942  			Page:          0,
   943  			PerPage:       10,
   944  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
   945  			ExpectedTeams: []string{th.BasicTeam.Id, team1.Id, team2.Id, team3.Id, team4.Id},
   946  			WithCount:     true,
   947  			ExpectedCount: 5,
   948  		},
   949  		{
   950  			Name:          "Get all public teams with count",
   951  			Page:          0,
   952  			PerPage:       10,
   953  			Permissions:   []string{model.PERMISSION_LIST_PUBLIC_TEAMS.Id},
   954  			ExpectedTeams: []string{team1.Id, team2.Id},
   955  			WithCount:     true,
   956  			ExpectedCount: 2,
   957  		},
   958  		{
   959  			Name:          "Get all private teams with count",
   960  			Page:          0,
   961  			PerPage:       10,
   962  			Permissions:   []string{model.PERMISSION_LIST_PRIVATE_TEAMS.Id},
   963  			ExpectedTeams: []string{th.BasicTeam.Id, team3.Id, team4.Id},
   964  			WithCount:     true,
   965  			ExpectedCount: 3,
   966  		},
   967  	}
   968  
   969  	for _, tc := range testCases {
   970  		t.Run(tc.Name, func(t *testing.T) {
   971  			defaultRolePermissions := th.SaveDefaultRolePermissions()
   972  			defer func() {
   973  				th.RestoreDefaultRolePermissions(defaultRolePermissions)
   974  			}()
   975  			th.RemovePermissionFromRole(model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
   976  			th.RemovePermissionFromRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
   977  			th.RemovePermissionFromRole(model.PERMISSION_LIST_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
   978  			th.RemovePermissionFromRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
   979  			for _, permission := range tc.Permissions {
   980  				th.AddPermissionToRole(permission, model.SYSTEM_USER_ROLE_ID)
   981  			}
   982  
   983  			var teams []*model.Team
   984  			var count int64
   985  			if tc.WithCount {
   986  				teams, count, resp = Client.GetAllTeamsWithTotalCount("", tc.Page, tc.PerPage)
   987  			} else {
   988  				teams, resp = Client.GetAllTeams("", tc.Page, tc.PerPage)
   989  			}
   990  			if tc.ExpectedError {
   991  				CheckErrorMessage(t, resp, tc.ErrorId)
   992  				checkHTTPStatus(t, resp, tc.ExpectedStatusCode, true)
   993  				return
   994  			}
   995  			CheckNoError(t, resp)
   996  			require.Equal(t, len(tc.ExpectedTeams), len(teams))
   997  			for idx, team := range teams {
   998  				assert.Equal(t, tc.ExpectedTeams[idx], team.Id)
   999  			}
  1000  			require.Equal(t, tc.ExpectedCount, count)
  1001  		})
  1002  	}
  1003  
  1004  	t.Run("Local mode", func(t *testing.T) {
  1005  		teams, res := th.LocalClient.GetAllTeams("", 0, 10)
  1006  		CheckNoError(t, res)
  1007  		require.Len(t, teams, 5)
  1008  	})
  1009  
  1010  	// Choose a team which the system manager can access
  1011  	sysManagerTeams, resp := th.SystemManagerClient.GetAllTeams("", 0, 10000)
  1012  	CheckOKStatus(t, resp)
  1013  	policyTeam := sysManagerTeams[0]
  1014  	// If no policies exist, GetAllTeamsExcludePolicyConstrained should return everything
  1015  	t.Run("exclude policy constrained, without policy", func(t *testing.T) {
  1016  		_, excludeConstrainedResp := Client.GetAllTeamsExcludePolicyConstrained("", 0, 100)
  1017  		CheckForbiddenStatus(t, excludeConstrainedResp)
  1018  		teams, excludeConstrainedResp := th.SystemAdminClient.GetAllTeamsExcludePolicyConstrained("", 0, 100)
  1019  		CheckOKStatus(t, excludeConstrainedResp)
  1020  		found := false
  1021  		for _, team := range teams {
  1022  			if team.Id == policyTeam.Id {
  1023  				found = true
  1024  				break
  1025  			}
  1026  		}
  1027  		require.True(t, found)
  1028  	})
  1029  	// Now actually create the policy and assign the team to it
  1030  	policy, savePolicyErr := th.App.Srv().Store.RetentionPolicy().Save(&model.RetentionPolicyWithTeamAndChannelIDs{
  1031  		RetentionPolicy: model.RetentionPolicy{
  1032  			DisplayName:  "Policy 1",
  1033  			PostDuration: model.NewInt64(30),
  1034  		},
  1035  		TeamIDs: []string{policyTeam.Id},
  1036  	})
  1037  	require.NoError(t, savePolicyErr)
  1038  	// This time, the team shouldn't be returned
  1039  	t.Run("exclude policy constrained, with policy", func(t *testing.T) {
  1040  		teams, excludeConstrainedResp := th.SystemAdminClient.GetAllTeamsExcludePolicyConstrained("", 0, 100)
  1041  		CheckOKStatus(t, excludeConstrainedResp)
  1042  		found := false
  1043  		for _, team := range teams {
  1044  			if team.Id == policyTeam.Id {
  1045  				found = true
  1046  				break
  1047  			}
  1048  		}
  1049  		require.False(t, found)
  1050  	})
  1051  
  1052  	t.Run("does not return policy ID", func(t *testing.T) {
  1053  		teams, sysManagerResp := th.SystemManagerClient.GetAllTeams("", 0, 100)
  1054  		CheckOKStatus(t, sysManagerResp)
  1055  		found := false
  1056  		for _, team := range teams {
  1057  			if team.Id == policyTeam.Id {
  1058  				found = true
  1059  				require.Nil(t, team.PolicyID)
  1060  				break
  1061  			}
  1062  		}
  1063  		require.True(t, found)
  1064  	})
  1065  
  1066  	t.Run("returns policy ID", func(t *testing.T) {
  1067  		teams, sysAdminResp := th.SystemAdminClient.GetAllTeams("", 0, 100)
  1068  		CheckOKStatus(t, sysAdminResp)
  1069  		found := false
  1070  		for _, team := range teams {
  1071  			if team.Id == policyTeam.Id {
  1072  				found = true
  1073  				require.Equal(t, *team.PolicyID, policy.ID)
  1074  				break
  1075  			}
  1076  		}
  1077  		require.True(t, found)
  1078  	})
  1079  
  1080  	t.Run("Unauthorized", func(t *testing.T) {
  1081  		Client.Logout()
  1082  		_, resp = Client.GetAllTeams("", 1, 10)
  1083  		CheckUnauthorizedStatus(t, resp)
  1084  	})
  1085  }
  1086  
  1087  func TestGetAllTeamsSanitization(t *testing.T) {
  1088  	th := Setup(t)
  1089  	defer th.TearDown()
  1090  
  1091  	team, resp := th.Client.CreateTeam(&model.Team{
  1092  		DisplayName:     t.Name() + "_1",
  1093  		Name:            GenerateTestTeamName(),
  1094  		Email:           th.GenerateTestEmail(),
  1095  		Type:            model.TEAM_OPEN,
  1096  		AllowedDomains:  "simulator.amazonses.com,localhost",
  1097  		AllowOpenInvite: true,
  1098  	})
  1099  	CheckNoError(t, resp)
  1100  	team2, resp := th.SystemAdminClient.CreateTeam(&model.Team{
  1101  		DisplayName:     t.Name() + "_2",
  1102  		Name:            GenerateTestTeamName(),
  1103  		Email:           th.GenerateTestEmail(),
  1104  		Type:            model.TEAM_OPEN,
  1105  		AllowedDomains:  "simulator.amazonses.com,localhost",
  1106  		AllowOpenInvite: true,
  1107  	})
  1108  	CheckNoError(t, resp)
  1109  
  1110  	// This may not work if the server has over 1000 open teams on it
  1111  
  1112  	t.Run("team admin/non-admin", func(t *testing.T) {
  1113  		teamFound := false
  1114  		team2Found := false
  1115  
  1116  		rteams, resp := th.Client.GetAllTeams("", 0, 1000)
  1117  		CheckNoError(t, resp)
  1118  		for _, rteam := range rteams {
  1119  			if rteam.Id == team.Id {
  1120  				teamFound = true
  1121  				require.NotEmpty(t, rteam.Email, "should not have sanitized email for team admin")
  1122  				require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
  1123  			} else if rteam.Id == team2.Id {
  1124  				team2Found = true
  1125  				require.Empty(t, rteam.Email, "should have sanitized email for team admin")
  1126  				require.Empty(t, rteam.InviteId, "should have sanitized inviteid")
  1127  			}
  1128  		}
  1129  
  1130  		require.True(t, teamFound, "wasn't returned the expected teams so the test wasn't run correctly")
  1131  		require.True(t, team2Found, "wasn't returned the expected teams so the test wasn't run correctly")
  1132  	})
  1133  
  1134  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1135  		rteams, resp := client.GetAllTeams("", 0, 1000)
  1136  		CheckNoError(t, resp)
  1137  		for _, rteam := range rteams {
  1138  			if rteam.Id != team.Id && rteam.Id != team2.Id {
  1139  				continue
  1140  			}
  1141  
  1142  			require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1143  			require.NotEmpty(t, rteam.InviteId, "should not have sanitized inviteid")
  1144  		}
  1145  	}, "system admin")
  1146  }
  1147  
  1148  func TestGetTeamByName(t *testing.T) {
  1149  	th := Setup(t).InitBasic()
  1150  	defer th.TearDown()
  1151  	team := th.BasicTeam
  1152  
  1153  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  1154  		rteam, resp := client.GetTeamByName(team.Name, "")
  1155  		CheckNoError(t, resp)
  1156  
  1157  		require.Equal(t, rteam.Name, team.Name, "wrong team")
  1158  
  1159  		_, resp = client.GetTeamByName("junk", "")
  1160  		CheckNotFoundStatus(t, resp)
  1161  
  1162  		_, resp = client.GetTeamByName("", "")
  1163  		CheckNotFoundStatus(t, resp)
  1164  
  1165  	})
  1166  
  1167  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1168  		_, resp := client.GetTeamByName(strings.ToUpper(team.Name), "")
  1169  		CheckNoError(t, resp)
  1170  	})
  1171  
  1172  	th.Client.Logout()
  1173  	_, resp := th.Client.GetTeamByName(team.Name, "")
  1174  	CheckUnauthorizedStatus(t, resp)
  1175  
  1176  	_, resp = th.SystemAdminClient.GetTeamByName(team.Name, "")
  1177  	CheckNoError(t, resp)
  1178  
  1179  	th.LoginTeamAdmin()
  1180  
  1181  	team2 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_OPEN, AllowOpenInvite: false}
  1182  	rteam2, _ := th.Client.CreateTeam(team2)
  1183  
  1184  	team3 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_INVITE, AllowOpenInvite: true}
  1185  	rteam3, _ := th.Client.CreateTeam(team3)
  1186  
  1187  	th.LoginBasic()
  1188  	// AllowInviteOpen is false and team is open, and user is not on team
  1189  	_, resp = th.Client.GetTeamByName(rteam2.Name, "")
  1190  	CheckForbiddenStatus(t, resp)
  1191  
  1192  	// AllowInviteOpen is true and team is invite only, and user is not on team
  1193  	_, resp = th.Client.GetTeamByName(rteam3.Name, "")
  1194  	CheckForbiddenStatus(t, resp)
  1195  }
  1196  
  1197  func TestGetTeamByNameSanitization(t *testing.T) {
  1198  	th := Setup(t).InitBasic()
  1199  	defer th.TearDown()
  1200  
  1201  	team, resp := th.Client.CreateTeam(&model.Team{
  1202  		DisplayName:    t.Name() + "_1",
  1203  		Name:           GenerateTestTeamName(),
  1204  		Email:          th.GenerateTestEmail(),
  1205  		Type:           model.TEAM_OPEN,
  1206  		AllowedDomains: "simulator.amazonses.com,localhost",
  1207  	})
  1208  	CheckNoError(t, resp)
  1209  
  1210  	t.Run("team user", func(t *testing.T) {
  1211  		th.LinkUserToTeam(th.BasicUser2, team)
  1212  
  1213  		client := th.CreateClient()
  1214  		th.LoginBasic2WithClient(client)
  1215  
  1216  		rteam, resp := client.GetTeamByName(team.Name, "")
  1217  		CheckNoError(t, resp)
  1218  
  1219  		require.Empty(t, rteam.Email, "should've sanitized email")
  1220  		require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1221  	})
  1222  
  1223  	t.Run("team user without invite permissions", func(t *testing.T) {
  1224  		th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  1225  		th.LinkUserToTeam(th.BasicUser2, team)
  1226  
  1227  		client := th.CreateClient()
  1228  
  1229  		th.LoginBasic2WithClient(client)
  1230  
  1231  		rteam, resp := client.GetTeam(team.Id, "")
  1232  		CheckNoError(t, resp)
  1233  
  1234  		require.Empty(t, rteam.Email, "should have sanitized email")
  1235  		require.Empty(t, rteam.InviteId, "should have sanitized inviteid")
  1236  	})
  1237  
  1238  	t.Run("team admin/non-admin", func(t *testing.T) {
  1239  		rteam, resp := th.Client.GetTeamByName(team.Name, "")
  1240  		CheckNoError(t, resp)
  1241  
  1242  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1243  		require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1244  	})
  1245  
  1246  	t.Run("system admin", func(t *testing.T) {
  1247  		rteam, resp := th.SystemAdminClient.GetTeamByName(team.Name, "")
  1248  		CheckNoError(t, resp)
  1249  
  1250  		require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1251  		require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1252  	})
  1253  }
  1254  
  1255  func TestSearchAllTeams(t *testing.T) {
  1256  	th := Setup(t).InitBasic()
  1257  	defer th.TearDown()
  1258  
  1259  	oTeam := th.BasicTeam
  1260  	oTeam.AllowOpenInvite = true
  1261  
  1262  	updatedTeam, err := th.App.UpdateTeam(oTeam)
  1263  	require.Nil(t, err, err)
  1264  	oTeam.UpdateAt = updatedTeam.UpdateAt
  1265  
  1266  	pTeam := &model.Team{DisplayName: "PName", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_INVITE}
  1267  	th.Client.CreateTeam(pTeam)
  1268  
  1269  	rteams, resp := th.Client.SearchTeams(&model.TeamSearch{Term: pTeam.Name})
  1270  	CheckNoError(t, resp)
  1271  	require.Empty(t, rteams, "should have not returned team")
  1272  
  1273  	rteams, resp = th.Client.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
  1274  	CheckNoError(t, resp)
  1275  	require.Empty(t, rteams, "should have not returned team")
  1276  
  1277  	th.Client.Logout()
  1278  
  1279  	_, resp = th.Client.SearchTeams(&model.TeamSearch{Term: pTeam.Name})
  1280  	CheckUnauthorizedStatus(t, resp)
  1281  
  1282  	_, resp = th.Client.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
  1283  	CheckUnauthorizedStatus(t, resp)
  1284  
  1285  	th.LoginBasic()
  1286  
  1287  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  1288  		rteams, resp = client.SearchTeams(&model.TeamSearch{Term: oTeam.Name})
  1289  		CheckNoError(t, resp)
  1290  		require.Len(t, rteams, 1, "should have returned 1 team")
  1291  		require.Equal(t, oTeam.Id, rteams[0].Id, "invalid team")
  1292  
  1293  		rteams, resp = client.SearchTeams(&model.TeamSearch{Term: oTeam.DisplayName})
  1294  		CheckNoError(t, resp)
  1295  		require.Len(t, rteams, 1, "should have returned 1 team")
  1296  		require.Equal(t, oTeam.Id, rteams[0].Id, "invalid team")
  1297  
  1298  		rteams, resp = client.SearchTeams(&model.TeamSearch{Term: "junk"})
  1299  		CheckNoError(t, resp)
  1300  		require.Empty(t, rteams, "should have not returned team")
  1301  	})
  1302  
  1303  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1304  		rteams, resp = client.SearchTeams(&model.TeamSearch{Term: oTeam.Name})
  1305  		CheckNoError(t, resp)
  1306  		require.Len(t, rteams, 1, "should have returned 1 team")
  1307  
  1308  		rteams, resp = client.SearchTeams(&model.TeamSearch{Term: pTeam.DisplayName})
  1309  		CheckNoError(t, resp)
  1310  		require.Len(t, rteams, 1, "should have returned 1 team")
  1311  	})
  1312  
  1313  	// Choose a team which the system manager can access
  1314  	sysManagerTeams, resp := th.SystemManagerClient.GetAllTeams("", 0, 10000)
  1315  	CheckOKStatus(t, resp)
  1316  	policyTeam := sysManagerTeams[0]
  1317  	// Now actually create the policy and assign the team to it
  1318  	policy, savePolicyErr := th.App.Srv().Store.RetentionPolicy().Save(&model.RetentionPolicyWithTeamAndChannelIDs{
  1319  		RetentionPolicy: model.RetentionPolicy{
  1320  			DisplayName:  "Policy 1",
  1321  			PostDuration: model.NewInt64(30),
  1322  		},
  1323  		TeamIDs: []string{policyTeam.Id},
  1324  	})
  1325  	require.NoError(t, savePolicyErr)
  1326  	t.Run("does not return policy ID", func(t *testing.T) {
  1327  		teams, sysManagerResp := th.SystemManagerClient.SearchTeams(&model.TeamSearch{Term: policyTeam.Name})
  1328  		CheckOKStatus(t, sysManagerResp)
  1329  		found := false
  1330  		for _, team := range teams {
  1331  			if team.Id == policyTeam.Id {
  1332  				found = true
  1333  				require.Nil(t, team.PolicyID)
  1334  				break
  1335  			}
  1336  		}
  1337  		require.True(t, found)
  1338  	})
  1339  	t.Run("returns policy ID", func(t *testing.T) {
  1340  		teams, sysAdminResp := th.SystemAdminClient.SearchTeams(&model.TeamSearch{Term: policyTeam.Name})
  1341  		CheckOKStatus(t, sysAdminResp)
  1342  		found := false
  1343  		for _, team := range teams {
  1344  			if team.Id == policyTeam.Id {
  1345  				found = true
  1346  				require.Equal(t, *team.PolicyID, policy.ID)
  1347  				break
  1348  			}
  1349  		}
  1350  		require.True(t, found)
  1351  	})
  1352  }
  1353  
  1354  func TestSearchAllTeamsPaged(t *testing.T) {
  1355  	th := Setup(t)
  1356  	defer th.TearDown()
  1357  	commonRandom := model.NewId()
  1358  	teams := [3]*model.Team{}
  1359  
  1360  	for i := 0; i < 3; i++ {
  1361  		uid := model.NewId()
  1362  		newTeam, err := th.App.CreateTeam(th.Context, &model.Team{
  1363  			DisplayName: fmt.Sprintf("%s %d %s", commonRandom, i, uid),
  1364  			Name:        fmt.Sprintf("%s-%d-%s", commonRandom, i, uid),
  1365  			Type:        model.TEAM_OPEN,
  1366  			Email:       th.GenerateTestEmail(),
  1367  		})
  1368  		require.Nil(t, err)
  1369  		teams[i] = newTeam
  1370  	}
  1371  
  1372  	foobarTeam, err := th.App.CreateTeam(th.Context, &model.Team{
  1373  		DisplayName: "FOOBARDISPLAYNAME",
  1374  		Name:        "whatever",
  1375  		Type:        model.TEAM_OPEN,
  1376  		Email:       th.GenerateTestEmail(),
  1377  	})
  1378  	require.Nil(t, err)
  1379  
  1380  	testCases := []struct {
  1381  		Name               string
  1382  		Search             *model.TeamSearch
  1383  		ExpectedTeams      []string
  1384  		ExpectedTotalCount int64
  1385  	}{
  1386  		{
  1387  			Name:               "Retrieve foobar team using partial term search",
  1388  			Search:             &model.TeamSearch{Term: "oobardisplay", Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1389  			ExpectedTeams:      []string{foobarTeam.Id},
  1390  			ExpectedTotalCount: 1,
  1391  		},
  1392  		{
  1393  			Name:               "Retrieve foobar team using the beginning of the display name as search text",
  1394  			Search:             &model.TeamSearch{Term: "foobar", Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1395  			ExpectedTeams:      []string{foobarTeam.Id},
  1396  			ExpectedTotalCount: 1,
  1397  		},
  1398  		{
  1399  			Name:               "Retrieve foobar team using the ending of the term of the display name",
  1400  			Search:             &model.TeamSearch{Term: "bardisplayname", Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1401  			ExpectedTeams:      []string{foobarTeam.Id},
  1402  			ExpectedTotalCount: 1,
  1403  		},
  1404  		{
  1405  			Name:               "Retrieve foobar team using partial term search on the name property of team",
  1406  			Search:             &model.TeamSearch{Term: "what", Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1407  			ExpectedTeams:      []string{foobarTeam.Id},
  1408  			ExpectedTotalCount: 1,
  1409  		},
  1410  		{
  1411  			Name:               "Retrieve foobar team using partial term search on the name property of team #2",
  1412  			Search:             &model.TeamSearch{Term: "ever", Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1413  			ExpectedTeams:      []string{foobarTeam.Id},
  1414  			ExpectedTotalCount: 1,
  1415  		},
  1416  		{
  1417  			Name:               "Get all teams on one page",
  1418  			Search:             &model.TeamSearch{Term: commonRandom, Page: model.NewInt(0), PerPage: model.NewInt(100)},
  1419  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id, teams[2].Id},
  1420  			ExpectedTotalCount: 3,
  1421  		},
  1422  		{
  1423  			Name:               "Get all teams on one page with partial word",
  1424  			Search:             &model.TeamSearch{Term: commonRandom[11:18]},
  1425  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id, teams[2].Id},
  1426  			ExpectedTotalCount: 3,
  1427  		},
  1428  		{
  1429  			Name:               "Get all teams on one page with term upper cased",
  1430  			Search:             &model.TeamSearch{Term: strings.ToUpper(commonRandom)},
  1431  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id, teams[2].Id},
  1432  			ExpectedTotalCount: 3,
  1433  		},
  1434  		{
  1435  			Name:               "Get all teams on one page with some of term upper and some lower",
  1436  			Search:             &model.TeamSearch{Term: commonRandom[0:11] + strings.ToUpper(commonRandom[11:18]+commonRandom[18:])},
  1437  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id, teams[2].Id},
  1438  			ExpectedTotalCount: 3,
  1439  		},
  1440  		{
  1441  			Name:               "Get 2 teams on the first page",
  1442  			Search:             &model.TeamSearch{Term: commonRandom, Page: model.NewInt(0), PerPage: model.NewInt(2)},
  1443  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id},
  1444  			ExpectedTotalCount: 3,
  1445  		},
  1446  		{
  1447  			Name:               "Get 1 team on the second page",
  1448  			Search:             &model.TeamSearch{Term: commonRandom, Page: model.NewInt(1), PerPage: model.NewInt(2)},
  1449  			ExpectedTeams:      []string{teams[2].Id},
  1450  			ExpectedTotalCount: 3,
  1451  		},
  1452  		{
  1453  			Name:               "SearchTeamsPaged paginates results by default",
  1454  			Search:             &model.TeamSearch{Term: commonRandom},
  1455  			ExpectedTeams:      []string{teams[0].Id, teams[1].Id, teams[2].Id},
  1456  			ExpectedTotalCount: 3,
  1457  		},
  1458  		{
  1459  			Name:               "No results",
  1460  			Search:             &model.TeamSearch{Term: model.NewId()},
  1461  			ExpectedTeams:      []string{},
  1462  			ExpectedTotalCount: 0,
  1463  		},
  1464  	}
  1465  
  1466  	for _, tc := range testCases {
  1467  		t.Run(tc.Name, func(t *testing.T) {
  1468  			teams, count, resp := th.SystemAdminClient.SearchTeamsPaged(tc.Search)
  1469  			require.Nil(t, resp.Error)
  1470  			require.Equal(t, tc.ExpectedTotalCount, count)
  1471  			require.Equal(t, len(tc.ExpectedTeams), len(teams))
  1472  			for i, team := range teams {
  1473  				require.Equal(t, tc.ExpectedTeams[i], team.Id)
  1474  			}
  1475  		})
  1476  	}
  1477  
  1478  	_, _, resp := th.Client.SearchTeamsPaged(&model.TeamSearch{Term: commonRandom, PerPage: model.NewInt(100)})
  1479  	require.Equal(t, "api.team.search_teams.pagination_not_implemented.public_team_search", resp.Error.Id)
  1480  	require.Equal(t, http.StatusNotImplemented, resp.StatusCode)
  1481  }
  1482  
  1483  func TestSearchAllTeamsSanitization(t *testing.T) {
  1484  	th := Setup(t).InitBasic()
  1485  	defer th.TearDown()
  1486  
  1487  	team, resp := th.Client.CreateTeam(&model.Team{
  1488  		DisplayName:    t.Name() + "_1",
  1489  		Name:           GenerateTestTeamName(),
  1490  		Email:          th.GenerateTestEmail(),
  1491  		Type:           model.TEAM_OPEN,
  1492  		AllowedDomains: "simulator.amazonses.com,localhost",
  1493  	})
  1494  	CheckNoError(t, resp)
  1495  	team2, resp := th.Client.CreateTeam(&model.Team{
  1496  		DisplayName:    t.Name() + "_2",
  1497  		Name:           GenerateTestTeamName(),
  1498  		Email:          th.GenerateTestEmail(),
  1499  		Type:           model.TEAM_OPEN,
  1500  		AllowedDomains: "simulator.amazonses.com,localhost",
  1501  	})
  1502  	CheckNoError(t, resp)
  1503  
  1504  	t.Run("non-team user", func(t *testing.T) {
  1505  		client := th.CreateClient()
  1506  		th.LoginBasic2WithClient(client)
  1507  
  1508  		rteams, resp := client.SearchTeams(&model.TeamSearch{Term: t.Name()})
  1509  		CheckNoError(t, resp)
  1510  		for _, rteam := range rteams {
  1511  			require.Empty(t, rteam.Email, "should've sanitized email")
  1512  			require.Empty(t, rteam.AllowedDomains, "should've sanitized allowed domains")
  1513  			require.Empty(t, rteam.InviteId, "should have sanitized inviteid")
  1514  		}
  1515  	})
  1516  
  1517  	t.Run("team user", func(t *testing.T) {
  1518  		th.LinkUserToTeam(th.BasicUser2, team)
  1519  
  1520  		client := th.CreateClient()
  1521  		th.LoginBasic2WithClient(client)
  1522  
  1523  		rteams, resp := client.SearchTeams(&model.TeamSearch{Term: t.Name()})
  1524  		CheckNoError(t, resp)
  1525  		for _, rteam := range rteams {
  1526  			require.Empty(t, rteam.Email, "should've sanitized email")
  1527  			require.Empty(t, rteam.AllowedDomains, "should've sanitized allowed domains")
  1528  			require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1529  		}
  1530  	})
  1531  
  1532  	t.Run("team admin", func(t *testing.T) {
  1533  		rteams, resp := th.Client.SearchTeams(&model.TeamSearch{Term: t.Name()})
  1534  		CheckNoError(t, resp)
  1535  		for _, rteam := range rteams {
  1536  			if rteam.Id == team.Id || rteam.Id == team2.Id || rteam.Id == th.BasicTeam.Id {
  1537  				require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1538  				require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1539  			}
  1540  		}
  1541  	})
  1542  
  1543  	t.Run("system admin", func(t *testing.T) {
  1544  		rteams, resp := th.SystemAdminClient.SearchTeams(&model.TeamSearch{Term: t.Name()})
  1545  		CheckNoError(t, resp)
  1546  		for _, rteam := range rteams {
  1547  			require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1548  			require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1549  		}
  1550  	})
  1551  }
  1552  
  1553  func TestGetTeamsForUser(t *testing.T) {
  1554  	th := Setup(t).InitBasic()
  1555  	defer th.TearDown()
  1556  	Client := th.Client
  1557  
  1558  	team2 := &model.Team{DisplayName: "Name", Name: GenerateTestTeamName(), Email: th.GenerateTestEmail(), Type: model.TEAM_INVITE}
  1559  	rteam2, _ := Client.CreateTeam(team2)
  1560  
  1561  	teams, resp := Client.GetTeamsForUser(th.BasicUser.Id, "")
  1562  	CheckNoError(t, resp)
  1563  
  1564  	require.Len(t, teams, 2, "wrong number of teams")
  1565  
  1566  	found1 := false
  1567  	found2 := false
  1568  	for _, t := range teams {
  1569  		if t.Id == th.BasicTeam.Id {
  1570  			found1 = true
  1571  		} else if t.Id == rteam2.Id {
  1572  			found2 = true
  1573  		}
  1574  	}
  1575  
  1576  	require.True(t, found1, "missing team")
  1577  	require.True(t, found2, "missing team")
  1578  
  1579  	_, resp = Client.GetTeamsForUser("junk", "")
  1580  	CheckBadRequestStatus(t, resp)
  1581  
  1582  	_, resp = Client.GetTeamsForUser(model.NewId(), "")
  1583  	CheckForbiddenStatus(t, resp)
  1584  
  1585  	_, resp = Client.GetTeamsForUser(th.BasicUser2.Id, "")
  1586  	CheckForbiddenStatus(t, resp)
  1587  
  1588  	_, resp = th.SystemAdminClient.GetTeamsForUser(th.BasicUser2.Id, "")
  1589  	CheckNoError(t, resp)
  1590  }
  1591  
  1592  func TestGetTeamsForUserSanitization(t *testing.T) {
  1593  	th := Setup(t).InitBasic()
  1594  	defer th.TearDown()
  1595  
  1596  	team, resp := th.Client.CreateTeam(&model.Team{
  1597  		DisplayName:    t.Name() + "_1",
  1598  		Name:           GenerateTestTeamName(),
  1599  		Email:          th.GenerateTestEmail(),
  1600  		Type:           model.TEAM_OPEN,
  1601  		AllowedDomains: "simulator.amazonses.com,localhost",
  1602  	})
  1603  	CheckNoError(t, resp)
  1604  	team2, resp := th.Client.CreateTeam(&model.Team{
  1605  		DisplayName:    t.Name() + "_2",
  1606  		Name:           GenerateTestTeamName(),
  1607  		Email:          th.GenerateTestEmail(),
  1608  		Type:           model.TEAM_OPEN,
  1609  		AllowedDomains: "simulator.amazonses.com,localhost",
  1610  	})
  1611  	CheckNoError(t, resp)
  1612  
  1613  	t.Run("team user", func(t *testing.T) {
  1614  		th.LinkUserToTeam(th.BasicUser2, team)
  1615  		th.LinkUserToTeam(th.BasicUser2, team2)
  1616  
  1617  		client := th.CreateClient()
  1618  		th.LoginBasic2WithClient(client)
  1619  
  1620  		rteams, resp := client.GetTeamsForUser(th.BasicUser2.Id, "")
  1621  		CheckNoError(t, resp)
  1622  		for _, rteam := range rteams {
  1623  			if rteam.Id != team.Id && rteam.Id != team2.Id {
  1624  				continue
  1625  			}
  1626  
  1627  			require.Empty(t, rteam.Email, "should've sanitized email")
  1628  			require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1629  		}
  1630  	})
  1631  
  1632  	t.Run("team user without invite permissions", func(t *testing.T) {
  1633  		th.LinkUserToTeam(th.BasicUser2, team)
  1634  		th.LinkUserToTeam(th.BasicUser2, team2)
  1635  
  1636  		client := th.CreateClient()
  1637  		th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  1638  		th.LoginBasic2WithClient(client)
  1639  
  1640  		rteams, resp := client.GetTeamsForUser(th.BasicUser2.Id, "")
  1641  		CheckNoError(t, resp)
  1642  		for _, rteam := range rteams {
  1643  			if rteam.Id != team.Id && rteam.Id != team2.Id {
  1644  				continue
  1645  			}
  1646  
  1647  			require.Empty(t, rteam.Email, "should have sanitized email")
  1648  			require.Empty(t, rteam.InviteId, "should have sanitized inviteid")
  1649  		}
  1650  	})
  1651  
  1652  	t.Run("team admin", func(t *testing.T) {
  1653  		rteams, resp := th.Client.GetTeamsForUser(th.BasicUser.Id, "")
  1654  		CheckNoError(t, resp)
  1655  		for _, rteam := range rteams {
  1656  			if rteam.Id != team.Id && rteam.Id != team2.Id {
  1657  				continue
  1658  			}
  1659  
  1660  			require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1661  			require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1662  		}
  1663  	})
  1664  
  1665  	t.Run("system admin", func(t *testing.T) {
  1666  		rteams, resp := th.SystemAdminClient.GetTeamsForUser(th.BasicUser.Id, "")
  1667  		CheckNoError(t, resp)
  1668  		for _, rteam := range rteams {
  1669  			if rteam.Id != team.Id && rteam.Id != team2.Id {
  1670  				continue
  1671  			}
  1672  
  1673  			require.NotEmpty(t, rteam.Email, "should not have sanitized email")
  1674  			require.NotEmpty(t, rteam.InviteId, "should have not sanitized inviteid")
  1675  		}
  1676  	})
  1677  }
  1678  
  1679  func TestGetTeamMember(t *testing.T) {
  1680  	th := Setup(t).InitBasic()
  1681  	defer th.TearDown()
  1682  	Client := th.Client
  1683  	team := th.BasicTeam
  1684  	user := th.BasicUser
  1685  
  1686  	rmember, resp := Client.GetTeamMember(team.Id, user.Id, "")
  1687  	CheckNoError(t, resp)
  1688  
  1689  	require.Equal(t, rmember.TeamId, team.Id, "wrong team id")
  1690  
  1691  	require.Equal(t, rmember.UserId, user.Id, "wrong user id")
  1692  
  1693  	_, resp = Client.GetTeamMember("junk", user.Id, "")
  1694  	CheckBadRequestStatus(t, resp)
  1695  
  1696  	_, resp = Client.GetTeamMember(team.Id, "junk", "")
  1697  	CheckBadRequestStatus(t, resp)
  1698  
  1699  	_, resp = Client.GetTeamMember("junk", "junk", "")
  1700  	CheckBadRequestStatus(t, resp)
  1701  
  1702  	_, resp = Client.GetTeamMember(team.Id, model.NewId(), "")
  1703  	CheckNotFoundStatus(t, resp)
  1704  
  1705  	_, resp = Client.GetTeamMember(model.NewId(), user.Id, "")
  1706  	CheckForbiddenStatus(t, resp)
  1707  
  1708  	_, resp = th.SystemAdminClient.GetTeamMember(team.Id, user.Id, "")
  1709  	CheckNoError(t, resp)
  1710  }
  1711  
  1712  func TestGetTeamMembers(t *testing.T) {
  1713  	th := Setup(t).InitBasic()
  1714  	defer th.TearDown()
  1715  	Client := th.Client
  1716  	team := th.BasicTeam
  1717  	userNotMember := th.CreateUser()
  1718  
  1719  	rmembers, resp := Client.GetTeamMembers(team.Id, 0, 100, "")
  1720  	CheckNoError(t, resp)
  1721  
  1722  	t.Logf("rmembers count %v\n", len(rmembers))
  1723  
  1724  	require.NotEqual(t, len(rmembers), 0, "should have results")
  1725  
  1726  	for _, rmember := range rmembers {
  1727  		require.Equal(t, rmember.TeamId, team.Id, "user should be a member of team")
  1728  		require.NotEqual(t, rmember.UserId, userNotMember.Id, "user should be a member of team")
  1729  	}
  1730  
  1731  	rmembers, resp = Client.GetTeamMembers(team.Id, 0, 1, "")
  1732  	CheckNoError(t, resp)
  1733  	require.Len(t, rmembers, 1, "should be 1 per page")
  1734  
  1735  	rmembers, resp = Client.GetTeamMembers(team.Id, 1, 1, "")
  1736  	CheckNoError(t, resp)
  1737  	require.Len(t, rmembers, 1, "should be 1 per page")
  1738  
  1739  	rmembers, resp = Client.GetTeamMembers(team.Id, 10000, 100, "")
  1740  	CheckNoError(t, resp)
  1741  	require.Empty(t, rmembers, "should be no member")
  1742  
  1743  	rmembers, resp = Client.GetTeamMembers(team.Id, 0, 2, "")
  1744  	CheckNoError(t, resp)
  1745  	rmembers2, resp := Client.GetTeamMembers(team.Id, 1, 2, "")
  1746  	CheckNoError(t, resp)
  1747  
  1748  	for _, tm1 := range rmembers {
  1749  		for _, tm2 := range rmembers2 {
  1750  			assert.NotEqual(t, tm1.UserId+tm1.TeamId, tm2.UserId+tm2.TeamId, "different pages should not have the same members")
  1751  		}
  1752  	}
  1753  
  1754  	_, resp = Client.GetTeamMembers("junk", 0, 100, "")
  1755  	CheckBadRequestStatus(t, resp)
  1756  
  1757  	_, resp = Client.GetTeamMembers(model.NewId(), 0, 100, "")
  1758  	CheckForbiddenStatus(t, resp)
  1759  
  1760  	Client.Logout()
  1761  	_, resp = Client.GetTeamMembers(team.Id, 0, 1, "")
  1762  	CheckUnauthorizedStatus(t, resp)
  1763  
  1764  	_, resp = th.SystemAdminClient.GetTeamMembersSortAndWithoutDeletedUsers(team.Id, 0, 100, "", false, "")
  1765  	CheckNoError(t, resp)
  1766  
  1767  	_, resp = th.SystemAdminClient.GetTeamMembersSortAndWithoutDeletedUsers(team.Id, 0, 100, model.USERNAME, false, "")
  1768  	CheckNoError(t, resp)
  1769  
  1770  	_, resp = th.SystemAdminClient.GetTeamMembersSortAndWithoutDeletedUsers(team.Id, 0, 100, model.USERNAME, true, "")
  1771  	CheckNoError(t, resp)
  1772  
  1773  	_, resp = th.SystemAdminClient.GetTeamMembersSortAndWithoutDeletedUsers(team.Id, 0, 100, "", true, "")
  1774  	CheckNoError(t, resp)
  1775  
  1776  	_, resp = th.SystemAdminClient.GetTeamMembersSortAndWithoutDeletedUsers(team.Id, 0, 100, model.USERNAME, false, "")
  1777  	CheckNoError(t, resp)
  1778  }
  1779  
  1780  func TestGetTeamMembersForUser(t *testing.T) {
  1781  	th := Setup(t).InitBasic()
  1782  	defer th.TearDown()
  1783  	Client := th.Client
  1784  
  1785  	members, resp := Client.GetTeamMembersForUser(th.BasicUser.Id, "")
  1786  	CheckNoError(t, resp)
  1787  
  1788  	found := false
  1789  	for _, m := range members {
  1790  		if m.TeamId == th.BasicTeam.Id {
  1791  			found = true
  1792  		}
  1793  	}
  1794  
  1795  	require.True(t, found, "missing team member")
  1796  
  1797  	_, resp = Client.GetTeamMembersForUser("junk", "")
  1798  	CheckBadRequestStatus(t, resp)
  1799  
  1800  	_, resp = Client.GetTeamMembersForUser(model.NewId(), "")
  1801  	CheckForbiddenStatus(t, resp)
  1802  
  1803  	Client.Logout()
  1804  	_, resp = Client.GetTeamMembersForUser(th.BasicUser.Id, "")
  1805  	CheckUnauthorizedStatus(t, resp)
  1806  
  1807  	user := th.CreateUser()
  1808  	Client.Login(user.Email, user.Password)
  1809  	_, resp = Client.GetTeamMembersForUser(th.BasicUser.Id, "")
  1810  	CheckForbiddenStatus(t, resp)
  1811  
  1812  	_, resp = th.SystemAdminClient.GetTeamMembersForUser(th.BasicUser.Id, "")
  1813  	CheckNoError(t, resp)
  1814  }
  1815  
  1816  func TestGetTeamMembersByIds(t *testing.T) {
  1817  	th := Setup(t).InitBasic()
  1818  	defer th.TearDown()
  1819  	Client := th.Client
  1820  
  1821  	tm, resp := Client.GetTeamMembersByIds(th.BasicTeam.Id, []string{th.BasicUser.Id})
  1822  	CheckNoError(t, resp)
  1823  
  1824  	require.Equal(t, tm[0].UserId, th.BasicUser.Id, "returned wrong user")
  1825  
  1826  	_, resp = Client.GetTeamMembersByIds(th.BasicTeam.Id, []string{})
  1827  	CheckBadRequestStatus(t, resp)
  1828  
  1829  	tm1, resp := Client.GetTeamMembersByIds(th.BasicTeam.Id, []string{"junk"})
  1830  	CheckNoError(t, resp)
  1831  	require.False(t, len(tm1) > 0, "no users should be returned")
  1832  
  1833  	tm1, resp = Client.GetTeamMembersByIds(th.BasicTeam.Id, []string{"junk", th.BasicUser.Id})
  1834  	CheckNoError(t, resp)
  1835  	require.Len(t, tm1, 1, "1 user should be returned")
  1836  
  1837  	_, resp = Client.GetTeamMembersByIds("junk", []string{th.BasicUser.Id})
  1838  	CheckBadRequestStatus(t, resp)
  1839  
  1840  	_, resp = Client.GetTeamMembersByIds(model.NewId(), []string{th.BasicUser.Id})
  1841  	CheckForbiddenStatus(t, resp)
  1842  
  1843  	Client.Logout()
  1844  	_, resp = Client.GetTeamMembersByIds(th.BasicTeam.Id, []string{th.BasicUser.Id})
  1845  	CheckUnauthorizedStatus(t, resp)
  1846  }
  1847  
  1848  func TestAddTeamMember(t *testing.T) {
  1849  	th := Setup(t).InitBasic()
  1850  	defer th.TearDown()
  1851  	Client := th.Client
  1852  	team := th.BasicTeam
  1853  	otherUser := th.CreateUser()
  1854  
  1855  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  1856  	defer th.App.Srv().SetLicense(nil)
  1857  
  1858  	enableGuestAccounts := *th.App.Config().GuestAccountsSettings.Enable
  1859  	defer func() {
  1860  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GuestAccountsSettings.Enable = &enableGuestAccounts })
  1861  	}()
  1862  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true })
  1863  
  1864  	guest := th.CreateUser()
  1865  	_, resp := th.SystemAdminClient.DemoteUserToGuest(guest.Id)
  1866  	CheckNoError(t, resp)
  1867  
  1868  	err := th.App.RemoveUserFromTeam(th.Context, th.BasicTeam.Id, th.BasicUser2.Id, "")
  1869  	if err != nil {
  1870  		require.FailNow(t, err.Error())
  1871  	}
  1872  
  1873  	// Regular user can't add a member to a team they don't belong to.
  1874  	th.LoginBasic2()
  1875  	_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
  1876  	CheckForbiddenStatus(t, resp)
  1877  	require.NotNil(t, resp.Error, "Error is nil")
  1878  	Client.Logout()
  1879  
  1880  	// SystemAdmin and mode can add member to a team
  1881  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1882  		tm, r := client.AddTeamMember(team.Id, otherUser.Id)
  1883  		CheckNoError(t, r)
  1884  		CheckCreatedStatus(t, r)
  1885  		require.Equal(t, tm.UserId, otherUser.Id, "user ids should have matched")
  1886  		require.Equal(t, tm.TeamId, team.Id, "team ids should have matched")
  1887  	})
  1888  
  1889  	// Regular user can add a member to a team they belong to.
  1890  	th.LoginBasic()
  1891  	tm, resp := Client.AddTeamMember(team.Id, otherUser.Id)
  1892  	CheckNoError(t, resp)
  1893  	CheckCreatedStatus(t, resp)
  1894  
  1895  	// Check all the returned data.
  1896  	require.NotNil(t, tm, "should have returned team member")
  1897  
  1898  	require.Equal(t, tm.UserId, otherUser.Id, "user ids should have matched")
  1899  
  1900  	require.Equal(t, tm.TeamId, team.Id, "team ids should have matched")
  1901  
  1902  	// Check with various invalid requests.
  1903  	tm, resp = Client.AddTeamMember(team.Id, "junk")
  1904  	CheckBadRequestStatus(t, resp)
  1905  
  1906  	require.Nil(t, tm, "should have not returned team member")
  1907  
  1908  	_, resp = Client.AddTeamMember("junk", otherUser.Id)
  1909  	CheckBadRequestStatus(t, resp)
  1910  
  1911  	_, resp = Client.AddTeamMember(GenerateTestId(), otherUser.Id)
  1912  	CheckForbiddenStatus(t, resp)
  1913  
  1914  	_, resp = Client.AddTeamMember(team.Id, GenerateTestId())
  1915  	CheckNotFoundStatus(t, resp)
  1916  
  1917  	Client.Logout()
  1918  
  1919  	// Check the appropriate permissions are enforced.
  1920  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  1921  	defer func() {
  1922  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
  1923  	}()
  1924  
  1925  	// Set the config so that only team admins can add a user to a team.
  1926  	th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
  1927  	th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
  1928  	th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  1929  	th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
  1930  
  1931  	th.LoginBasic()
  1932  
  1933  	// Check that a regular user can't add someone to the team.
  1934  	_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
  1935  	CheckForbiddenStatus(t, resp)
  1936  
  1937  	// Update user to team admin
  1938  	th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
  1939  	th.App.Srv().InvalidateAllCaches()
  1940  	th.LoginBasic()
  1941  
  1942  	// Should work as a team admin.
  1943  	_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
  1944  	CheckNoError(t, resp)
  1945  
  1946  	// Change permission level to team user
  1947  	th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  1948  	th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
  1949  	th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
  1950  	th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
  1951  
  1952  	th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
  1953  	th.App.Srv().InvalidateAllCaches()
  1954  	th.LoginBasic()
  1955  
  1956  	// Should work as a regular user.
  1957  	_, resp = Client.AddTeamMember(team.Id, otherUser.Id)
  1958  	CheckNoError(t, resp)
  1959  
  1960  	// Should return error with invalid JSON in body.
  1961  	_, err = Client.DoApiPost("/teams/"+team.Id+"/members", "invalid")
  1962  	require.NotNil(t, err)
  1963  	require.Equal(t, "api.team.add_team_member.invalid_body.app_error", err.Id)
  1964  
  1965  	// by token
  1966  	Client.Login(otherUser.Email, otherUser.Password)
  1967  
  1968  	token := model.NewToken(
  1969  		app.TokenTypeTeamInvitation,
  1970  		model.MapToJson(map[string]string{"teamId": team.Id}),
  1971  	)
  1972  	require.NoError(t, th.App.Srv().Store.Token().Save(token))
  1973  
  1974  	tm, resp = Client.AddTeamMemberFromInvite(token.Token, "")
  1975  	CheckNoError(t, resp)
  1976  
  1977  	require.NotNil(t, tm, "should have returned team member")
  1978  
  1979  	require.Equal(t, tm.UserId, otherUser.Id, "user ids should have matched")
  1980  
  1981  	require.Equal(t, tm.TeamId, team.Id, "team ids should have matched")
  1982  
  1983  	_, nErr := th.App.Srv().Store.Token().GetByToken(token.Token)
  1984  	require.Error(t, nErr, "The token must be deleted after be used")
  1985  
  1986  	tm, resp = Client.AddTeamMemberFromInvite("junk", "")
  1987  	CheckBadRequestStatus(t, resp)
  1988  
  1989  	require.Nil(t, tm, "should have not returned team member")
  1990  
  1991  	// expired token of more than 50 hours
  1992  	token = model.NewToken(app.TokenTypeTeamInvitation, "")
  1993  	token.CreateAt = model.GetMillis() - 1000*60*60*50
  1994  	require.NoError(t, th.App.Srv().Store.Token().Save(token))
  1995  
  1996  	_, resp = Client.AddTeamMemberFromInvite(token.Token, "")
  1997  	CheckBadRequestStatus(t, resp)
  1998  	th.App.DeleteToken(token)
  1999  
  2000  	// invalid team id
  2001  	testId := GenerateTestId()
  2002  	token = model.NewToken(
  2003  		app.TokenTypeTeamInvitation,
  2004  		model.MapToJson(map[string]string{"teamId": testId}),
  2005  	)
  2006  	require.NoError(t, th.App.Srv().Store.Token().Save(token))
  2007  
  2008  	_, resp = Client.AddTeamMemberFromInvite(token.Token, "")
  2009  	CheckNotFoundStatus(t, resp)
  2010  	th.App.DeleteToken(token)
  2011  
  2012  	// by invite_id
  2013  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  2014  	defer th.App.Srv().SetLicense(nil)
  2015  	_, resp = Client.Login(guest.Email, guest.Password)
  2016  	CheckNoError(t, resp)
  2017  
  2018  	tm, resp = Client.AddTeamMemberFromInvite("", team.InviteId)
  2019  	CheckForbiddenStatus(t, resp)
  2020  
  2021  	// by invite_id
  2022  	Client.Login(otherUser.Email, otherUser.Password)
  2023  
  2024  	tm, resp = Client.AddTeamMemberFromInvite("", team.InviteId)
  2025  	CheckNoError(t, resp)
  2026  
  2027  	require.NotNil(t, tm, "should have returned team member")
  2028  
  2029  	require.Equal(t, tm.UserId, otherUser.Id, "user ids should have matched")
  2030  
  2031  	require.Equal(t, tm.TeamId, team.Id, "team ids should have matched")
  2032  
  2033  	tm, resp = Client.AddTeamMemberFromInvite("", "junk")
  2034  	CheckNotFoundStatus(t, resp)
  2035  
  2036  	require.Nil(t, tm, "should have not returned team member")
  2037  
  2038  	// Set a team to group-constrained
  2039  	team.GroupConstrained = model.NewBool(true)
  2040  	_, err = th.App.UpdateTeam(team)
  2041  	require.Nil(t, err)
  2042  
  2043  	// Attempt to use a token on a group-constrained team
  2044  	token = model.NewToken(
  2045  		app.TokenTypeTeamInvitation,
  2046  		model.MapToJson(map[string]string{"teamId": team.Id}),
  2047  	)
  2048  	require.NoError(t, th.App.Srv().Store.Token().Save(token))
  2049  	tm, resp = Client.AddTeamMemberFromInvite(token.Token, "")
  2050  	require.Equal(t, "app.team.invite_token.group_constrained.error", resp.Error.Id)
  2051  
  2052  	// Attempt to use an invite id
  2053  	tm, resp = Client.AddTeamMemberFromInvite("", team.InviteId)
  2054  	require.Equal(t, "app.team.invite_id.group_constrained.error", resp.Error.Id)
  2055  
  2056  	// User is not in associated groups so shouldn't be allowed
  2057  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  2058  		_, resp = client.AddTeamMember(team.Id, otherUser.Id)
  2059  		CheckErrorMessage(t, resp, "api.team.add_members.user_denied")
  2060  	})
  2061  
  2062  	// Associate group to team
  2063  	_, err = th.App.UpsertGroupSyncable(&model.GroupSyncable{
  2064  		GroupId:    th.Group.Id,
  2065  		SyncableId: team.Id,
  2066  		Type:       model.GroupSyncableTypeTeam,
  2067  	})
  2068  	require.Nil(t, err)
  2069  
  2070  	// Add user to group
  2071  	_, err = th.App.UpsertGroupMember(th.Group.Id, otherUser.Id)
  2072  	require.Nil(t, err)
  2073  
  2074  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  2075  		_, resp = client.AddTeamMember(team.Id, otherUser.Id)
  2076  		CheckNoError(t, resp)
  2077  	})
  2078  }
  2079  
  2080  func TestAddTeamMemberMyself(t *testing.T) {
  2081  	th := Setup(t).InitBasic()
  2082  	defer th.TearDown()
  2083  	Client := th.Client
  2084  
  2085  	// Check the appropriate permissions are enforced.
  2086  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  2087  	defer func() {
  2088  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
  2089  	}()
  2090  
  2091  	th.LoginBasic()
  2092  
  2093  	testCases := []struct {
  2094  		Name              string
  2095  		Public            bool
  2096  		PublicPermission  bool
  2097  		PrivatePermission bool
  2098  		ExpectedSuccess   bool
  2099  	}{
  2100  		{
  2101  			Name:              "Try to join an open team without the permissions",
  2102  			Public:            true,
  2103  			PublicPermission:  false,
  2104  			PrivatePermission: false,
  2105  			ExpectedSuccess:   false,
  2106  		},
  2107  		{
  2108  			Name:              "Try to join a private team without the permissions",
  2109  			Public:            false,
  2110  			PublicPermission:  false,
  2111  			PrivatePermission: false,
  2112  			ExpectedSuccess:   false,
  2113  		},
  2114  		{
  2115  			Name:              "Try to join an open team without public permission but with private permissions",
  2116  			Public:            true,
  2117  			PublicPermission:  false,
  2118  			PrivatePermission: true,
  2119  			ExpectedSuccess:   false,
  2120  		},
  2121  		{
  2122  			Name:              "Try to join a private team without private permission but with public permission",
  2123  			Public:            false,
  2124  			PublicPermission:  true,
  2125  			PrivatePermission: false,
  2126  			ExpectedSuccess:   false,
  2127  		},
  2128  		{
  2129  			Name:              "Join an open team with the permissions",
  2130  			Public:            true,
  2131  			PublicPermission:  true,
  2132  			PrivatePermission: false,
  2133  			ExpectedSuccess:   true,
  2134  		},
  2135  		{
  2136  			Name:              "Join a private team with the permissions",
  2137  			Public:            false,
  2138  			PublicPermission:  false,
  2139  			PrivatePermission: true,
  2140  			ExpectedSuccess:   true,
  2141  		},
  2142  	}
  2143  
  2144  	for _, tc := range testCases {
  2145  		t.Run(tc.Name, func(t *testing.T) {
  2146  			team := th.CreateTeam()
  2147  			team.AllowOpenInvite = tc.Public
  2148  			th.App.UpdateTeam(team)
  2149  			if tc.PublicPermission {
  2150  				th.AddPermissionToRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2151  			} else {
  2152  				th.RemovePermissionFromRole(model.PERMISSION_JOIN_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2153  			}
  2154  			if tc.PrivatePermission {
  2155  				th.AddPermissionToRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2156  			} else {
  2157  				th.RemovePermissionFromRole(model.PERMISSION_JOIN_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2158  			}
  2159  			_, resp := Client.AddTeamMember(team.Id, th.BasicUser.Id)
  2160  			if tc.ExpectedSuccess {
  2161  				CheckNoError(t, resp)
  2162  			} else {
  2163  				CheckForbiddenStatus(t, resp)
  2164  			}
  2165  		})
  2166  	}
  2167  
  2168  }
  2169  
  2170  func TestAddTeamMembersDomainConstrained(t *testing.T) {
  2171  	th := Setup(t).InitBasic()
  2172  	defer th.TearDown()
  2173  	client := th.SystemAdminClient
  2174  	team := th.BasicTeam
  2175  	team.AllowedDomains = "domain1.com, domain2.com"
  2176  	_, response := client.UpdateTeam(team)
  2177  	require.Nil(t, response.Error)
  2178  
  2179  	// create two users on allowed domains
  2180  	user1, response := client.CreateUser(&model.User{
  2181  		Email:    "user@domain1.com",
  2182  		Password: "Pa$$word11",
  2183  		Username: GenerateTestUsername(),
  2184  	})
  2185  	require.Nil(t, response.Error)
  2186  	user2, response := client.CreateUser(&model.User{
  2187  		Email:    "user@domain2.com",
  2188  		Password: "Pa$$word11",
  2189  		Username: GenerateTestUsername(),
  2190  	})
  2191  	require.Nil(t, response.Error)
  2192  
  2193  	userList := []string{
  2194  		user1.Id,
  2195  		user2.Id,
  2196  	}
  2197  
  2198  	// validate that they can be added
  2199  	tm, response := client.AddTeamMembers(team.Id, userList)
  2200  	require.Nil(t, response.Error)
  2201  	require.Len(t, tm, 2)
  2202  
  2203  	// cleanup
  2204  	_, response = client.RemoveTeamMember(team.Id, user1.Id)
  2205  	require.Nil(t, response.Error)
  2206  	_, response = client.RemoveTeamMember(team.Id, user2.Id)
  2207  	require.Nil(t, response.Error)
  2208  
  2209  	// disable one of the allowed domains
  2210  	team.AllowedDomains = "domain1.com"
  2211  	_, response = client.UpdateTeam(team)
  2212  	require.Nil(t, response.Error)
  2213  
  2214  	// validate that they cannot be added
  2215  	_, response = client.AddTeamMembers(team.Id, userList)
  2216  	require.NotNil(t, response.Error)
  2217  
  2218  	// validate that one user can be added gracefully
  2219  	members, response := client.AddTeamMembersGracefully(team.Id, userList)
  2220  	require.Nil(t, response.Error)
  2221  	require.Len(t, members, 2)
  2222  	require.NotNil(t, members[0].Member)
  2223  	require.NotNil(t, members[1].Error)
  2224  	require.Equal(t, members[0].UserId, user1.Id)
  2225  	require.Equal(t, members[1].UserId, user2.Id)
  2226  	require.Nil(t, members[0].Error)
  2227  	require.Nil(t, members[1].Member)
  2228  }
  2229  
  2230  func TestAddTeamMembers(t *testing.T) {
  2231  	th := Setup(t).InitBasic()
  2232  	defer th.TearDown()
  2233  	Client := th.Client
  2234  	team := th.BasicTeam
  2235  	otherUser := th.CreateUser()
  2236  	userList := []string{
  2237  		otherUser.Id,
  2238  	}
  2239  
  2240  	th.App.UpdateConfig(func(cfg *model.Config) {
  2241  		*cfg.ServiceSettings.EnableBotAccountCreation = true
  2242  	})
  2243  	bot := th.CreateBotWithSystemAdminClient()
  2244  
  2245  	err := th.App.RemoveUserFromTeam(th.Context, th.BasicTeam.Id, th.BasicUser2.Id, "")
  2246  	require.Nil(t, err)
  2247  
  2248  	// Regular user can't add a member to a team they don't belong to.
  2249  	th.LoginBasic2()
  2250  	_, resp := Client.AddTeamMembers(team.Id, userList)
  2251  	CheckForbiddenStatus(t, resp)
  2252  	Client.Logout()
  2253  
  2254  	// Regular user can add a member to a team they belong to.
  2255  	th.LoginBasic()
  2256  	tm, resp := Client.AddTeamMembers(team.Id, userList)
  2257  	CheckNoError(t, resp)
  2258  	CheckCreatedStatus(t, resp)
  2259  
  2260  	// Check all the returned data.
  2261  	require.NotNil(t, tm[0], "should have returned team member")
  2262  
  2263  	require.Equal(t, tm[0].UserId, otherUser.Id, "user ids should have matched")
  2264  
  2265  	require.Equal(t, tm[0].TeamId, team.Id, "team ids should have matched")
  2266  
  2267  	// Check with various invalid requests.
  2268  	_, resp = Client.AddTeamMembers("junk", userList)
  2269  	CheckBadRequestStatus(t, resp)
  2270  
  2271  	_, resp = Client.AddTeamMembers(GenerateTestId(), userList)
  2272  	CheckNotFoundStatus(t, resp)
  2273  
  2274  	testUserList := append(userList, GenerateTestId())
  2275  	_, resp = Client.AddTeamMembers(team.Id, testUserList)
  2276  	CheckNotFoundStatus(t, resp)
  2277  
  2278  	// Test with many users.
  2279  	for i := 0; i < 260; i++ {
  2280  		testUserList = append(testUserList, GenerateTestId())
  2281  	}
  2282  	_, resp = Client.AddTeamMembers(team.Id, testUserList)
  2283  	CheckBadRequestStatus(t, resp)
  2284  
  2285  	Client.Logout()
  2286  
  2287  	// Check the appropriate permissions are enforced.
  2288  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  2289  	defer func() {
  2290  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
  2291  	}()
  2292  
  2293  	// Set the config so that only team admins can add a user to a team.
  2294  	th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
  2295  	th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
  2296  	th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  2297  	th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
  2298  
  2299  	th.LoginBasic()
  2300  
  2301  	// Check that a regular user can't add someone to the team.
  2302  	_, resp = Client.AddTeamMembers(team.Id, userList)
  2303  	CheckForbiddenStatus(t, resp)
  2304  
  2305  	// Update user to team admin
  2306  	th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
  2307  	th.App.Srv().InvalidateAllCaches()
  2308  	th.LoginBasic()
  2309  
  2310  	// Should work as a team admin.
  2311  	_, resp = Client.AddTeamMembers(team.Id, userList)
  2312  	CheckNoError(t, resp)
  2313  
  2314  	// Change permission level to team user
  2315  	th.AddPermissionToRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_USER_ROLE_ID)
  2316  	th.AddPermissionToRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_USER_ROLE_ID)
  2317  	th.RemovePermissionFromRole(model.PERMISSION_INVITE_USER.Id, model.TEAM_ADMIN_ROLE_ID)
  2318  	th.RemovePermissionFromRole(model.PERMISSION_ADD_USER_TO_TEAM.Id, model.TEAM_ADMIN_ROLE_ID)
  2319  
  2320  	th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
  2321  	th.App.Srv().InvalidateAllCaches()
  2322  	th.LoginBasic()
  2323  
  2324  	// Should work as a regular user.
  2325  	_, resp = Client.AddTeamMembers(team.Id, userList)
  2326  	CheckNoError(t, resp)
  2327  
  2328  	// Set a team to group-constrained
  2329  	team.GroupConstrained = model.NewBool(true)
  2330  	_, err = th.App.UpdateTeam(team)
  2331  	require.Nil(t, err)
  2332  
  2333  	// User is not in associated groups so shouldn't be allowed
  2334  	_, resp = Client.AddTeamMembers(team.Id, userList)
  2335  	CheckErrorMessage(t, resp, "api.team.add_members.user_denied")
  2336  
  2337  	// Ensure that a group synced team can still add bots
  2338  	_, resp = Client.AddTeamMembers(team.Id, []string{bot.UserId})
  2339  	CheckNoError(t, resp)
  2340  
  2341  	// Associate group to team
  2342  	_, err = th.App.UpsertGroupSyncable(&model.GroupSyncable{
  2343  		GroupId:    th.Group.Id,
  2344  		SyncableId: team.Id,
  2345  		Type:       model.GroupSyncableTypeTeam,
  2346  	})
  2347  	require.Nil(t, err)
  2348  
  2349  	// Add user to group
  2350  	_, err = th.App.UpsertGroupMember(th.Group.Id, userList[0])
  2351  	require.Nil(t, err)
  2352  
  2353  	_, resp = Client.AddTeamMembers(team.Id, userList)
  2354  	CheckNoError(t, resp)
  2355  }
  2356  
  2357  func TestRemoveTeamMember(t *testing.T) {
  2358  	th := Setup(t).InitBasic()
  2359  	defer th.TearDown()
  2360  	Client := th.Client
  2361  
  2362  	th.App.UpdateConfig(func(cfg *model.Config) {
  2363  		*cfg.ServiceSettings.EnableBotAccountCreation = true
  2364  	})
  2365  	bot := th.CreateBotWithSystemAdminClient()
  2366  
  2367  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2368  		pass, resp := client.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id)
  2369  		CheckNoError(t, resp)
  2370  
  2371  		require.True(t, pass, "should have passed")
  2372  
  2373  		_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.BasicUser.Id)
  2374  		CheckNoError(t, resp)
  2375  	})
  2376  
  2377  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2378  		_, resp := client.RemoveTeamMember(th.BasicTeam.Id, "junk")
  2379  		CheckBadRequestStatus(t, resp)
  2380  
  2381  		_, resp = client.RemoveTeamMember("junk", th.BasicUser2.Id)
  2382  		CheckBadRequestStatus(t, resp)
  2383  	})
  2384  
  2385  	_, resp := Client.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser2.Id)
  2386  	CheckForbiddenStatus(t, resp)
  2387  
  2388  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2389  		_, resp = client.RemoveTeamMember(model.NewId(), th.BasicUser.Id)
  2390  		CheckNotFoundStatus(t, resp)
  2391  	})
  2392  
  2393  	_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, th.SystemAdminUser.Id)
  2394  	CheckNoError(t, resp)
  2395  
  2396  	_, resp = th.SystemAdminClient.AddTeamMember(th.BasicTeam.Id, bot.UserId)
  2397  	CheckNoError(t, resp)
  2398  
  2399  	// If the team is group-constrained the user cannot be removed
  2400  	th.BasicTeam.GroupConstrained = model.NewBool(true)
  2401  	_, err := th.App.UpdateTeam(th.BasicTeam)
  2402  	require.Nil(t, err)
  2403  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  2404  		_, resp = client.RemoveTeamMember(th.BasicTeam.Id, th.BasicUser.Id)
  2405  		require.Equal(t, "api.team.remove_member.group_constrained.app_error", resp.Error.Id)
  2406  	})
  2407  
  2408  	// Can remove a bot even if team is group-constrained
  2409  
  2410  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  2411  		_, resp = client.RemoveTeamMember(th.BasicTeam.Id, bot.UserId)
  2412  		CheckNoError(t, resp)
  2413  		_, resp = client.AddTeamMember(th.BasicTeam.Id, bot.UserId)
  2414  		CheckNoError(t, resp)
  2415  	})
  2416  
  2417  	// Can remove self even if team is group-constrained
  2418  	_, resp = th.SystemAdminClient.RemoveTeamMember(th.BasicTeam.Id, th.SystemAdminUser.Id)
  2419  	CheckNoError(t, resp)
  2420  }
  2421  
  2422  func TestGetTeamStats(t *testing.T) {
  2423  	th := Setup(t).InitBasic()
  2424  	defer th.TearDown()
  2425  	Client := th.Client
  2426  	team := th.BasicTeam
  2427  
  2428  	rstats, resp := Client.GetTeamStats(team.Id, "")
  2429  	CheckNoError(t, resp)
  2430  
  2431  	require.Equal(t, rstats.TeamId, team.Id, "wrong team id")
  2432  
  2433  	require.Equal(t, rstats.TotalMemberCount, int64(3), "wrong count")
  2434  
  2435  	require.Equal(t, rstats.ActiveMemberCount, int64(3), "wrong count")
  2436  
  2437  	_, resp = Client.GetTeamStats("junk", "")
  2438  	CheckBadRequestStatus(t, resp)
  2439  
  2440  	_, resp = Client.GetTeamStats(model.NewId(), "")
  2441  	CheckForbiddenStatus(t, resp)
  2442  
  2443  	_, resp = th.SystemAdminClient.GetTeamStats(team.Id, "")
  2444  	CheckNoError(t, resp)
  2445  
  2446  	// deactivate BasicUser2
  2447  	th.UpdateActiveUser(th.BasicUser2, false)
  2448  
  2449  	rstats, resp = th.SystemAdminClient.GetTeamStats(team.Id, "")
  2450  	CheckNoError(t, resp)
  2451  
  2452  	require.Equal(t, rstats.TotalMemberCount, int64(3), "wrong count")
  2453  
  2454  	require.Equal(t, rstats.ActiveMemberCount, int64(2), "wrong count")
  2455  
  2456  	// login with different user and test if forbidden
  2457  	user := th.CreateUser()
  2458  	Client.Login(user.Email, user.Password)
  2459  	_, resp = Client.GetTeamStats(th.BasicTeam.Id, "")
  2460  	CheckForbiddenStatus(t, resp)
  2461  
  2462  	Client.Logout()
  2463  	_, resp = Client.GetTeamStats(th.BasicTeam.Id, "")
  2464  	CheckUnauthorizedStatus(t, resp)
  2465  }
  2466  
  2467  func TestUpdateTeamMemberRoles(t *testing.T) {
  2468  	th := Setup(t).InitBasic()
  2469  	defer th.TearDown()
  2470  	Client := th.Client
  2471  	SystemAdminClient := th.SystemAdminClient
  2472  
  2473  	const TeamMember = "team_user"
  2474  	const TeamAdmin = "team_user team_admin"
  2475  
  2476  	// user 1 tries to promote user 2
  2477  	ok, resp := Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TeamAdmin)
  2478  	CheckForbiddenStatus(t, resp)
  2479  	require.False(t, ok, "should have returned false")
  2480  
  2481  	// user 1 tries to promote himself
  2482  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TeamAdmin)
  2483  	CheckForbiddenStatus(t, resp)
  2484  
  2485  	// user 1 tries to demote someone
  2486  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TeamMember)
  2487  	CheckForbiddenStatus(t, resp)
  2488  
  2489  	// system admin promotes user 1
  2490  	ok, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TeamAdmin)
  2491  	CheckNoError(t, resp)
  2492  	require.True(t, ok, "should have returned true")
  2493  
  2494  	// user 1 (team admin) promotes user 2
  2495  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TeamAdmin)
  2496  	CheckNoError(t, resp)
  2497  
  2498  	// user 1 (team admin) demotes user 2 (team admin)
  2499  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TeamMember)
  2500  	CheckNoError(t, resp)
  2501  
  2502  	// user 1 (team admin) tries to demote system admin (not member of a team)
  2503  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TeamMember)
  2504  	CheckNotFoundStatus(t, resp)
  2505  
  2506  	// user 1 (team admin) demotes system admin (member of a team)
  2507  	th.LinkUserToTeam(th.SystemAdminUser, th.BasicTeam)
  2508  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, TeamMember)
  2509  	CheckNoError(t, resp)
  2510  	// Note from API v3
  2511  	// Note to anyone who thinks this (above) test is wrong:
  2512  	// This operation will not affect the system admin's permissions because they have global access to all teams.
  2513  	// Their team level permissions are irrelevant. A team admin should be able to manage team level permissions.
  2514  
  2515  	// System admins should be able to manipulate permission no matter what their team level permissions are.
  2516  	// system admin promotes user 2
  2517  	_, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TeamAdmin)
  2518  	CheckNoError(t, resp)
  2519  
  2520  	// system admin demotes user 2 (team admin)
  2521  	_, resp = SystemAdminClient.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser2.Id, TeamMember)
  2522  	CheckNoError(t, resp)
  2523  
  2524  	// user 1 (team admin) tries to promote himself to a random team
  2525  	_, resp = Client.UpdateTeamMemberRoles(model.NewId(), th.BasicUser.Id, TeamAdmin)
  2526  	CheckForbiddenStatus(t, resp)
  2527  
  2528  	// user 1 (team admin) tries to promote a random user
  2529  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, model.NewId(), TeamAdmin)
  2530  	CheckNotFoundStatus(t, resp)
  2531  
  2532  	// user 1 (team admin) tries to promote invalid team permission
  2533  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, "junk")
  2534  	CheckBadRequestStatus(t, resp)
  2535  
  2536  	// user 1 (team admin) demotes himself
  2537  	_, resp = Client.UpdateTeamMemberRoles(th.BasicTeam.Id, th.BasicUser.Id, TeamMember)
  2538  	CheckNoError(t, resp)
  2539  }
  2540  
  2541  func TestUpdateTeamMemberSchemeRoles(t *testing.T) {
  2542  	th := Setup(t).InitBasic()
  2543  	defer th.TearDown()
  2544  	SystemAdminClient := th.SystemAdminClient
  2545  	th.LoginBasic()
  2546  
  2547  	s1 := &model.SchemeRoles{
  2548  		SchemeAdmin: false,
  2549  		SchemeUser:  false,
  2550  		SchemeGuest: false,
  2551  	}
  2552  	_, r1 := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s1)
  2553  	CheckNoError(t, r1)
  2554  
  2555  	tm1, rtm1 := SystemAdminClient.GetTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "")
  2556  	CheckNoError(t, rtm1)
  2557  	assert.Equal(t, false, tm1.SchemeGuest)
  2558  	assert.Equal(t, false, tm1.SchemeUser)
  2559  	assert.Equal(t, false, tm1.SchemeAdmin)
  2560  
  2561  	s2 := &model.SchemeRoles{
  2562  		SchemeAdmin: false,
  2563  		SchemeUser:  true,
  2564  		SchemeGuest: false,
  2565  	}
  2566  	_, r2 := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s2)
  2567  	CheckNoError(t, r2)
  2568  
  2569  	tm2, rtm2 := SystemAdminClient.GetTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "")
  2570  	CheckNoError(t, rtm2)
  2571  	assert.Equal(t, false, tm2.SchemeGuest)
  2572  	assert.Equal(t, true, tm2.SchemeUser)
  2573  	assert.Equal(t, false, tm2.SchemeAdmin)
  2574  
  2575  	s3 := &model.SchemeRoles{
  2576  		SchemeAdmin: true,
  2577  		SchemeUser:  false,
  2578  		SchemeGuest: false,
  2579  	}
  2580  	_, r3 := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s3)
  2581  	CheckNoError(t, r3)
  2582  
  2583  	tm3, rtm3 := SystemAdminClient.GetTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "")
  2584  	CheckNoError(t, rtm3)
  2585  	assert.Equal(t, false, tm3.SchemeGuest)
  2586  	assert.Equal(t, false, tm3.SchemeUser)
  2587  	assert.Equal(t, true, tm3.SchemeAdmin)
  2588  
  2589  	s4 := &model.SchemeRoles{
  2590  		SchemeAdmin: true,
  2591  		SchemeUser:  true,
  2592  		SchemeGuest: false,
  2593  	}
  2594  	_, r4 := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s4)
  2595  	CheckNoError(t, r4)
  2596  
  2597  	tm4, rtm4 := SystemAdminClient.GetTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "")
  2598  	CheckNoError(t, rtm4)
  2599  	assert.Equal(t, false, tm4.SchemeGuest)
  2600  	assert.Equal(t, true, tm4.SchemeUser)
  2601  	assert.Equal(t, true, tm4.SchemeAdmin)
  2602  
  2603  	s5 := &model.SchemeRoles{
  2604  		SchemeAdmin: false,
  2605  		SchemeUser:  false,
  2606  		SchemeGuest: true,
  2607  	}
  2608  	_, r5 := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s5)
  2609  	CheckNoError(t, r5)
  2610  
  2611  	tm5, rtm5 := SystemAdminClient.GetTeamMember(th.BasicTeam.Id, th.BasicUser.Id, "")
  2612  	CheckNoError(t, rtm5)
  2613  	assert.Equal(t, true, tm5.SchemeGuest)
  2614  	assert.Equal(t, false, tm5.SchemeUser)
  2615  	assert.Equal(t, false, tm5.SchemeAdmin)
  2616  
  2617  	s6 := &model.SchemeRoles{
  2618  		SchemeAdmin: false,
  2619  		SchemeUser:  true,
  2620  		SchemeGuest: true,
  2621  	}
  2622  	_, resp := SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s6)
  2623  	CheckBadRequestStatus(t, resp)
  2624  
  2625  	_, resp = SystemAdminClient.UpdateTeamMemberSchemeRoles(model.NewId(), th.BasicUser.Id, s4)
  2626  	CheckNotFoundStatus(t, resp)
  2627  
  2628  	_, resp = SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, model.NewId(), s4)
  2629  	CheckNotFoundStatus(t, resp)
  2630  
  2631  	_, resp = SystemAdminClient.UpdateTeamMemberSchemeRoles("ASDF", th.BasicUser.Id, s4)
  2632  	CheckBadRequestStatus(t, resp)
  2633  
  2634  	_, resp = SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, "ASDF", s4)
  2635  	CheckBadRequestStatus(t, resp)
  2636  
  2637  	th.LoginBasic2()
  2638  	_, resp = th.Client.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.BasicUser.Id, s4)
  2639  	CheckForbiddenStatus(t, resp)
  2640  
  2641  	SystemAdminClient.Logout()
  2642  	_, resp = SystemAdminClient.UpdateTeamMemberSchemeRoles(th.BasicTeam.Id, th.SystemAdminUser.Id, s4)
  2643  	CheckUnauthorizedStatus(t, resp)
  2644  }
  2645  
  2646  func TestGetMyTeamsUnread(t *testing.T) {
  2647  	th := Setup(t).InitBasic()
  2648  	defer th.TearDown()
  2649  	Client := th.Client
  2650  
  2651  	user := th.BasicUser
  2652  	Client.Login(user.Email, user.Password)
  2653  
  2654  	teams, resp := Client.GetTeamsUnreadForUser(user.Id, "")
  2655  	CheckNoError(t, resp)
  2656  	require.NotEqual(t, len(teams), 0, "should have results")
  2657  
  2658  	teams, resp = Client.GetTeamsUnreadForUser(user.Id, th.BasicTeam.Id)
  2659  	CheckNoError(t, resp)
  2660  	require.Empty(t, teams, "should not have results")
  2661  
  2662  	_, resp = Client.GetTeamsUnreadForUser("fail", "")
  2663  	CheckBadRequestStatus(t, resp)
  2664  
  2665  	_, resp = Client.GetTeamsUnreadForUser(model.NewId(), "")
  2666  	CheckForbiddenStatus(t, resp)
  2667  
  2668  	Client.Logout()
  2669  	_, resp = Client.GetTeamsUnreadForUser(user.Id, "")
  2670  	CheckUnauthorizedStatus(t, resp)
  2671  }
  2672  
  2673  func TestTeamExists(t *testing.T) {
  2674  	th := Setup(t).InitBasic()
  2675  	defer th.TearDown()
  2676  	Client := th.Client
  2677  	public_member_team := th.BasicTeam
  2678  	err := th.App.UpdateTeamPrivacy(public_member_team.Id, model.TEAM_OPEN, true)
  2679  	require.Nil(t, err)
  2680  
  2681  	public_not_member_team := th.CreateTeamWithClient(th.SystemAdminClient)
  2682  	err = th.App.UpdateTeamPrivacy(public_not_member_team.Id, model.TEAM_OPEN, true)
  2683  	require.Nil(t, err)
  2684  
  2685  	private_member_team := th.CreateTeamWithClient(th.SystemAdminClient)
  2686  	th.LinkUserToTeam(th.BasicUser, private_member_team)
  2687  	err = th.App.UpdateTeamPrivacy(private_member_team.Id, model.TEAM_INVITE, false)
  2688  	require.Nil(t, err)
  2689  
  2690  	private_not_member_team := th.CreateTeamWithClient(th.SystemAdminClient)
  2691  	err = th.App.UpdateTeamPrivacy(private_not_member_team.Id, model.TEAM_INVITE, false)
  2692  	require.Nil(t, err)
  2693  
  2694  	// Check the appropriate permissions are enforced.
  2695  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  2696  	defer func() {
  2697  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
  2698  	}()
  2699  
  2700  	th.AddPermissionToRole(model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2701  	th.AddPermissionToRole(model.PERMISSION_LIST_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2702  
  2703  	t.Run("Logged user with permissions and valid public team", func(t *testing.T) {
  2704  		th.LoginBasic()
  2705  		exists, resp := Client.TeamExists(public_not_member_team.Name, "")
  2706  		CheckNoError(t, resp)
  2707  		assert.True(t, exists, "team should exist")
  2708  	})
  2709  
  2710  	t.Run("Logged user with permissions and valid private team", func(t *testing.T) {
  2711  		th.LoginBasic()
  2712  		exists, resp := Client.TeamExists(private_not_member_team.Name, "")
  2713  		CheckNoError(t, resp)
  2714  		assert.True(t, exists, "team should exist")
  2715  	})
  2716  
  2717  	t.Run("Logged user and invalid team", func(t *testing.T) {
  2718  		th.LoginBasic()
  2719  		exists, resp := Client.TeamExists("testingteam", "")
  2720  		CheckNoError(t, resp)
  2721  		assert.False(t, exists, "team should not exist")
  2722  	})
  2723  
  2724  	t.Run("Logged out user", func(t *testing.T) {
  2725  		Client.Logout()
  2726  		_, resp := Client.TeamExists(public_not_member_team.Name, "")
  2727  		CheckUnauthorizedStatus(t, resp)
  2728  	})
  2729  
  2730  	t.Run("Logged without LIST_PUBLIC_TEAMS permissions and member public team", func(t *testing.T) {
  2731  		th.LoginBasic()
  2732  		th.RemovePermissionFromRole(model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2733  
  2734  		exists, resp := Client.TeamExists(public_member_team.Name, "")
  2735  		CheckNoError(t, resp)
  2736  		assert.True(t, exists, "team should be visible")
  2737  	})
  2738  
  2739  	t.Run("Logged without LIST_PUBLIC_TEAMS permissions and not member public team", func(t *testing.T) {
  2740  		th.LoginBasic()
  2741  		th.RemovePermissionFromRole(model.PERMISSION_LIST_PUBLIC_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2742  
  2743  		exists, resp := Client.TeamExists(public_not_member_team.Name, "")
  2744  		CheckNoError(t, resp)
  2745  		assert.False(t, exists, "team should not be visible")
  2746  	})
  2747  
  2748  	t.Run("Logged without LIST_PRIVATE_TEAMS permissions and member private team", func(t *testing.T) {
  2749  		th.LoginBasic()
  2750  		th.RemovePermissionFromRole(model.PERMISSION_LIST_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2751  
  2752  		exists, resp := Client.TeamExists(private_member_team.Name, "")
  2753  		CheckNoError(t, resp)
  2754  		assert.True(t, exists, "team should be visible")
  2755  	})
  2756  
  2757  	t.Run("Logged without LIST_PRIVATE_TEAMS permissions and not member private team", func(t *testing.T) {
  2758  		th.LoginBasic()
  2759  		th.RemovePermissionFromRole(model.PERMISSION_LIST_PRIVATE_TEAMS.Id, model.SYSTEM_USER_ROLE_ID)
  2760  
  2761  		exists, resp := Client.TeamExists(private_not_member_team.Name, "")
  2762  		CheckNoError(t, resp)
  2763  		assert.False(t, exists, "team should not be visible")
  2764  	})
  2765  }
  2766  
  2767  func TestImportTeam(t *testing.T) {
  2768  	th := Setup(t).InitBasic()
  2769  	defer th.TearDown()
  2770  
  2771  	th.TestForAllClients(t, func(T *testing.T, c *model.Client4) {
  2772  		data, err := testutils.ReadTestFile("Fake_Team_Import.zip")
  2773  
  2774  		require.False(t, err != nil && len(data) == 0, "Error while reading the test file.")
  2775  		_, resp := th.SystemAdminClient.ImportTeam(data, binary.Size(data), "XYZ", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2776  		CheckBadRequestStatus(t, resp)
  2777  
  2778  		_, resp = th.SystemAdminClient.ImportTeam(data, binary.Size(data), "", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2779  		CheckBadRequestStatus(t, resp)
  2780  	}, "Import from unknown and source")
  2781  
  2782  	t.Run("ImportTeam", func(t *testing.T) {
  2783  		var data []byte
  2784  		var err error
  2785  		data, err = testutils.ReadTestFile("Fake_Team_Import.zip")
  2786  
  2787  		require.False(t, err != nil && len(data) == 0, "Error while reading the test file.")
  2788  
  2789  		// Import the channels/users/posts
  2790  		fileResp, resp := th.SystemAdminClient.ImportTeam(data, binary.Size(data), "slack", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2791  		CheckNoError(t, resp)
  2792  
  2793  		fileData, err := base64.StdEncoding.DecodeString(fileResp["results"])
  2794  		require.NoError(t, err, "failed to decode base64 results data")
  2795  
  2796  		fileReturned := fmt.Sprintf("%s", fileData)
  2797  		require.Truef(t, strings.Contains(fileReturned, "darth.vader@stardeath.com"), "failed to report the user was imported, fileReturned: %s", fileReturned)
  2798  
  2799  		// Checking the imported users
  2800  		importedUser, resp := th.SystemAdminClient.GetUserByUsername("bot_test", "")
  2801  		CheckNoError(t, resp)
  2802  		require.Equal(t, importedUser.Username, "bot_test", "username should match with the imported user")
  2803  
  2804  		importedUser, resp = th.SystemAdminClient.GetUserByUsername("lordvader", "")
  2805  		CheckNoError(t, resp)
  2806  		require.Equal(t, importedUser.Username, "lordvader", "username should match with the imported user")
  2807  
  2808  		// Checking the imported Channels
  2809  		importedChannel, resp := th.SystemAdminClient.GetChannelByName("testchannel", th.BasicTeam.Id, "")
  2810  		CheckNoError(t, resp)
  2811  		require.Equal(t, importedChannel.Name, "testchannel", "names did not match expected: testchannel")
  2812  
  2813  		importedChannel, resp = th.SystemAdminClient.GetChannelByName("general", th.BasicTeam.Id, "")
  2814  		CheckNoError(t, resp)
  2815  		require.Equal(t, importedChannel.Name, "general", "names did not match expected: general")
  2816  
  2817  		posts, resp := th.SystemAdminClient.GetPostsForChannel(importedChannel.Id, 0, 60, "", false)
  2818  		CheckNoError(t, resp)
  2819  		require.Equal(t, posts.Posts[posts.Order[3]].Message, "This is a test post to test the import process", "missing posts in the import process")
  2820  	})
  2821  
  2822  	t.Run("Cloud Forbidden", func(t *testing.T) {
  2823  		var data []byte
  2824  		var err error
  2825  		data, err = testutils.ReadTestFile("Fake_Team_Import.zip")
  2826  
  2827  		require.False(t, err != nil && len(data) == 0, "Error while reading the test file.")
  2828  		th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
  2829  
  2830  		// Import the channels/users/posts
  2831  		_, resp := th.SystemAdminClient.ImportTeam(data, binary.Size(data), "slack", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2832  		CheckForbiddenStatus(t, resp)
  2833  		th.App.Srv().SetLicense(nil)
  2834  	})
  2835  
  2836  	t.Run("MissingFile", func(t *testing.T) {
  2837  		_, resp := th.SystemAdminClient.ImportTeam(nil, 4343, "slack", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2838  		CheckBadRequestStatus(t, resp)
  2839  	})
  2840  
  2841  	t.Run("WrongPermission", func(t *testing.T) {
  2842  		var data []byte
  2843  		var err error
  2844  		data, err = testutils.ReadTestFile("Fake_Team_Import.zip")
  2845  		require.False(t, err != nil && len(data) == 0, "Error while reading the test file.")
  2846  
  2847  		// Import the channels/users/posts
  2848  		_, resp := th.Client.ImportTeam(data, binary.Size(data), "slack", "Fake_Team_Import.zip", th.BasicTeam.Id)
  2849  		CheckForbiddenStatus(t, resp)
  2850  	})
  2851  }
  2852  
  2853  func TestInviteUsersToTeam(t *testing.T) {
  2854  	th := Setup(t).InitBasic()
  2855  	defer th.TearDown()
  2856  
  2857  	user1 := th.GenerateTestEmail()
  2858  	user2 := th.GenerateTestEmail()
  2859  
  2860  	emailList := []string{user1, user2}
  2861  
  2862  	//Delete all the messages before check the sample email
  2863  	mail.DeleteMailBox(user1)
  2864  	mail.DeleteMailBox(user2)
  2865  
  2866  	enableEmailInvitations := *th.App.Config().ServiceSettings.EnableEmailInvitations
  2867  	restrictCreationToDomains := th.App.Config().TeamSettings.RestrictCreationToDomains
  2868  	defer func() {
  2869  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableEmailInvitations = &enableEmailInvitations })
  2870  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = restrictCreationToDomains })
  2871  	}()
  2872  
  2873  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = false })
  2874  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2875  		_, resp := client.InviteUsersToTeam(th.BasicTeam.Id, emailList)
  2876  		require.NotNil(t, resp.Error, "Should be disabled")
  2877  	})
  2878  
  2879  	checkEmail := func(t *testing.T, expectedSubject string) {
  2880  		//Check if the email was sent to the right email address
  2881  		for _, email := range emailList {
  2882  			var resultsMailbox mail.JSONMessageHeaderInbucket
  2883  			err := mail.RetryInbucket(5, func() error {
  2884  				var err error
  2885  				resultsMailbox, err = mail.GetMailBox(email)
  2886  				return err
  2887  			})
  2888  			if err != nil {
  2889  				t.Log(err)
  2890  				t.Log("No email was received, maybe due load on the server. Disabling this verification")
  2891  			}
  2892  			if err == nil && len(resultsMailbox) > 0 {
  2893  				require.True(t, strings.ContainsAny(resultsMailbox[len(resultsMailbox)-1].To[0], email), "Wrong To recipient")
  2894  				resultsEmail, err := mail.GetMessageFromMailbox(email, resultsMailbox[len(resultsMailbox)-1].ID)
  2895  				if err == nil {
  2896  					require.Equalf(t, resultsEmail.Subject, expectedSubject, "Wrong Subject, actual: %s, expected: %s", resultsEmail.Subject, expectedSubject)
  2897  				}
  2898  			}
  2899  		}
  2900  	}
  2901  
  2902  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = true })
  2903  	okMsg, resp := th.SystemAdminClient.InviteUsersToTeam(th.BasicTeam.Id, emailList)
  2904  	CheckNoError(t, resp)
  2905  	require.True(t, okMsg, "should return true")
  2906  	nameFormat := *th.App.Config().TeamSettings.TeammateNameDisplay
  2907  	expectedSubject := i18n.T("api.templates.invite_subject",
  2908  		map[string]interface{}{"SenderName": th.SystemAdminUser.GetDisplayName(nameFormat),
  2909  			"TeamDisplayName": th.BasicTeam.DisplayName,
  2910  			"SiteName":        th.App.ClientConfig()["SiteName"]})
  2911  	checkEmail(t, expectedSubject)
  2912  
  2913  	mail.DeleteMailBox(user1)
  2914  	mail.DeleteMailBox(user2)
  2915  	okMsg, resp = th.LocalClient.InviteUsersToTeam(th.BasicTeam.Id, emailList)
  2916  	CheckNoError(t, resp)
  2917  	require.True(t, okMsg, "should return true")
  2918  	expectedSubject = i18n.T("api.templates.invite_subject",
  2919  		map[string]interface{}{"SenderName": "Administrator",
  2920  			"TeamDisplayName": th.BasicTeam.DisplayName,
  2921  			"SiteName":        th.App.ClientConfig()["SiteName"]})
  2922  	checkEmail(t, expectedSubject)
  2923  
  2924  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictCreationToDomains = "@global.com,@common.com" })
  2925  
  2926  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2927  		okMsg, resp := client.InviteUsersToTeam(th.BasicTeam.Id, emailList)
  2928  		require.False(t, okMsg, "should return false")
  2929  		require.NotNil(t, resp.Error, "Adding users with non-restricted domains was allowed")
  2930  
  2931  		invitesWithErrors, resp := client.InviteUsersToTeamGracefully(th.BasicTeam.Id, emailList)
  2932  		CheckNoError(t, resp)
  2933  		require.Len(t, invitesWithErrors, 2)
  2934  		require.NotNil(t, invitesWithErrors[0].Error)
  2935  		require.NotNil(t, invitesWithErrors[1].Error)
  2936  	}, "restricted domains")
  2937  
  2938  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2939  		th.BasicTeam.AllowedDomains = "invalid.com,common.com"
  2940  		_, err := th.App.UpdateTeam(th.BasicTeam)
  2941  		require.NotNil(t, err, "Should not update the team")
  2942  
  2943  		th.BasicTeam.AllowedDomains = "common.com"
  2944  		_, err = th.App.UpdateTeam(th.BasicTeam)
  2945  		require.Nilf(t, err, "%v, Should update the team", err)
  2946  
  2947  		okMsg, resp := client.InviteUsersToTeam(th.BasicTeam.Id, []string{"test@global.com"})
  2948  		require.False(t, okMsg, "should return false")
  2949  		require.NotNilf(t, resp.Error, "%v, Per team restriction should take precedence over the globally allowed domains", err)
  2950  
  2951  		okMsg, resp = client.InviteUsersToTeam(th.BasicTeam.Id, []string{"test@common.com"})
  2952  		require.True(t, okMsg, "should return true")
  2953  		require.Nilf(t, resp.Error, "%v, Failed to invite user which was common between team and global domain restriction", err)
  2954  
  2955  		okMsg, resp = client.InviteUsersToTeam(th.BasicTeam.Id, []string{"test@invalid.com"})
  2956  		require.False(t, okMsg, "should return false")
  2957  		require.NotNilf(t, resp.Error, "%v, Should not invite user", err)
  2958  
  2959  		invitesWithErrors, resp := client.InviteUsersToTeamGracefully(th.BasicTeam.Id, []string{"test@invalid.com", "test@common.com"})
  2960  		CheckNoError(t, resp)
  2961  		require.Len(t, invitesWithErrors, 2)
  2962  		require.NotNil(t, invitesWithErrors[0].Error)
  2963  		require.Nil(t, invitesWithErrors[1].Error)
  2964  	}, "override restricted domains")
  2965  
  2966  	th.TestForAllClients(t, func(t *testing.T, client *model.Client4) {
  2967  		th.BasicTeam.AllowedDomains = "common.com"
  2968  		_, err := th.App.UpdateTeam(th.BasicTeam)
  2969  		require.Nilf(t, err, "%v, Should update the team", err)
  2970  
  2971  		emailList := make([]string, 22)
  2972  		for i := 0; i < 22; i++ {
  2973  			emailList[i] = "test-" + strconv.Itoa(i) + "@common.com"
  2974  		}
  2975  		okMsg, resp := client.InviteUsersToTeam(th.BasicTeam.Id, emailList)
  2976  		require.False(t, okMsg, "should return false")
  2977  		CheckRequestEntityTooLargeStatus(t, resp)
  2978  		CheckErrorMessage(t, resp, "app.email.rate_limit_exceeded.app_error")
  2979  
  2980  		_, resp = client.InviteUsersToTeamGracefully(th.BasicTeam.Id, emailList)
  2981  		CheckRequestEntityTooLargeStatus(t, resp)
  2982  		CheckErrorMessage(t, resp, "app.email.rate_limit_exceeded.app_error")
  2983  	}, "rate limits")
  2984  }
  2985  
  2986  func TestInviteGuestsToTeam(t *testing.T) {
  2987  	th := Setup(t).InitBasic()
  2988  	defer th.TearDown()
  2989  
  2990  	guest1 := th.GenerateTestEmail()
  2991  	guest2 := th.GenerateTestEmail()
  2992  
  2993  	emailList := []string{guest1, guest2}
  2994  
  2995  	//Delete all the messages before check the sample email
  2996  	mail.DeleteMailBox(guest1)
  2997  	mail.DeleteMailBox(guest2)
  2998  
  2999  	enableEmailInvitations := *th.App.Config().ServiceSettings.EnableEmailInvitations
  3000  	restrictCreationToDomains := th.App.Config().TeamSettings.RestrictCreationToDomains
  3001  	guestRestrictCreationToDomains := th.App.Config().GuestAccountsSettings.RestrictCreationToDomains
  3002  	enableGuestAccounts := *th.App.Config().GuestAccountsSettings.Enable
  3003  	defer func() {
  3004  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableEmailInvitations = &enableEmailInvitations })
  3005  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = restrictCreationToDomains })
  3006  		th.App.UpdateConfig(func(cfg *model.Config) {
  3007  			cfg.GuestAccountsSettings.RestrictCreationToDomains = guestRestrictCreationToDomains
  3008  		})
  3009  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GuestAccountsSettings.Enable = &enableGuestAccounts })
  3010  	}()
  3011  
  3012  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  3013  
  3014  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = false })
  3015  	_, resp := th.SystemAdminClient.InviteGuestsToTeam(th.BasicTeam.Id, emailList, []string{th.BasicChannel.Id}, "test-message")
  3016  	assert.NotNil(t, resp.Error, "Should be disabled")
  3017  
  3018  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true })
  3019  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = false })
  3020  	_, resp = th.SystemAdminClient.InviteGuestsToTeam(th.BasicTeam.Id, emailList, []string{th.BasicChannel.Id}, "test-message")
  3021  	require.NotNil(t, resp.Error, "Should be disabled")
  3022  
  3023  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableEmailInvitations = true })
  3024  
  3025  	th.App.Srv().SetLicense(nil)
  3026  
  3027  	_, resp = th.SystemAdminClient.InviteGuestsToTeam(th.BasicTeam.Id, emailList, []string{th.BasicChannel.Id}, "test-message")
  3028  	require.NotNil(t, resp.Error, "Should be disabled")
  3029  
  3030  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  3031  	defer th.App.Srv().SetLicense(nil)
  3032  
  3033  	okMsg, resp := th.SystemAdminClient.InviteGuestsToTeam(th.BasicTeam.Id, emailList, []string{th.BasicChannel.Id}, "test-message")
  3034  	CheckNoError(t, resp)
  3035  	require.True(t, okMsg, "should return true")
  3036  
  3037  	t.Run("invalid data in request body", func(t *testing.T) {
  3038  		res, err := th.SystemAdminClient.DoApiPost(th.SystemAdminClient.GetTeamRoute(th.BasicTeam.Id)+"/invite-guests/email", "bad data")
  3039  		require.NotNil(t, err)
  3040  		require.Equal(t, "api.team.invite_guests_to_channels.invalid_body.app_error", err.Id)
  3041  		require.Equal(t, http.StatusBadRequest, res.StatusCode)
  3042  	})
  3043  
  3044  	nameFormat := *th.App.Config().TeamSettings.TeammateNameDisplay
  3045  	expectedSubject := i18n.T("api.templates.invite_guest_subject",
  3046  		map[string]interface{}{"SenderName": th.SystemAdminUser.GetDisplayName(nameFormat),
  3047  			"TeamDisplayName": th.BasicTeam.DisplayName,
  3048  			"SiteName":        th.App.ClientConfig()["SiteName"]})
  3049  
  3050  	//Check if the email was send to the right email address
  3051  	for _, email := range emailList {
  3052  		var resultsMailbox mail.JSONMessageHeaderInbucket
  3053  		err := mail.RetryInbucket(5, func() error {
  3054  			var err error
  3055  			resultsMailbox, err = mail.GetMailBox(email)
  3056  			return err
  3057  		})
  3058  		if err != nil {
  3059  			t.Log(err)
  3060  			t.Log("No email was received, maybe due load on the server. Disabling this verification")
  3061  		}
  3062  		if err == nil && len(resultsMailbox) > 0 {
  3063  			require.True(t, strings.ContainsAny(resultsMailbox[len(resultsMailbox)-1].To[0], email), "Wrong To recipient")
  3064  			resultsEmail, err := mail.GetMessageFromMailbox(email, resultsMailbox[len(resultsMailbox)-1].ID)
  3065  			if err == nil {
  3066  				require.Equalf(t, resultsEmail.Subject, expectedSubject, "Wrong Subject, actual: %s, expected: %s", resultsEmail.Subject, expectedSubject)
  3067  			}
  3068  		}
  3069  	}
  3070  
  3071  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictCreationToDomains = "@global.com,@common.com" })
  3072  
  3073  	t.Run("team domain restrictions should not affect inviting guests", func(t *testing.T) {
  3074  		err := th.App.InviteGuestsToChannels(th.BasicTeam.Id, &model.GuestsInvite{Emails: emailList, Channels: []string{th.BasicChannel.Id}, Message: "test message"}, th.BasicUser.Id)
  3075  		require.Nil(t, err, "guest user invites should not be affected by team restrictions")
  3076  	})
  3077  
  3078  	t.Run("guest restrictions should affect guest users", func(t *testing.T) {
  3079  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.RestrictCreationToDomains = "@guest.com" })
  3080  
  3081  		err := th.App.InviteGuestsToChannels(th.BasicTeam.Id, &model.GuestsInvite{Emails: []string{"guest1@invalid.com"}, Channels: []string{th.BasicChannel.Id}, Message: "test message"}, th.BasicUser.Id)
  3082  		require.NotNil(t, err, "guest user invites should be affected by the guest domain restrictions")
  3083  
  3084  		res, err := th.App.InviteGuestsToChannelsGracefully(th.BasicTeam.Id, &model.GuestsInvite{Emails: []string{"guest1@invalid.com", "guest1@guest.com"}, Channels: []string{th.BasicChannel.Id}, Message: "test message"}, th.BasicUser.Id)
  3085  		require.Nil(t, err)
  3086  		require.Len(t, res, 2)
  3087  		require.NotNil(t, res[0].Error)
  3088  		require.Nil(t, res[1].Error)
  3089  
  3090  		err = th.App.InviteGuestsToChannels(th.BasicTeam.Id, &model.GuestsInvite{Emails: []string{"guest1@guest.com"}, Channels: []string{th.BasicChannel.Id}, Message: "test message"}, th.BasicUser.Id)
  3091  		require.Nil(t, err, "whitelisted guest user email should be allowed by the guest domain restrictions")
  3092  	})
  3093  
  3094  	t.Run("guest restrictions should not affect inviting new team members", func(t *testing.T) {
  3095  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.RestrictCreationToDomains = "@guest.com" })
  3096  
  3097  		err := th.App.InviteNewUsersToTeam([]string{"user@global.com"}, th.BasicTeam.Id, th.BasicUser.Id)
  3098  		require.Nil(t, err, "non guest user invites should not be affected by the guest domain restrictions")
  3099  	})
  3100  
  3101  	t.Run("rate limit", func(t *testing.T) {
  3102  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.RestrictCreationToDomains = "@guest.com" })
  3103  
  3104  		_, err := th.App.UpdateTeam(th.BasicTeam)
  3105  		require.Nilf(t, err, "%v, Should update the team", err)
  3106  
  3107  		emailList := make([]string, 22)
  3108  		for i := 0; i < 22; i++ {
  3109  			emailList[i] = "test-" + strconv.Itoa(i) + "@guest.com"
  3110  		}
  3111  		invite := &model.GuestsInvite{
  3112  			Emails:   emailList,
  3113  			Channels: []string{th.BasicChannel.Id},
  3114  			Message:  "test message",
  3115  		}
  3116  		err = th.App.InviteGuestsToChannels(th.BasicTeam.Id, invite, th.BasicUser.Id)
  3117  		require.NotNil(t, err)
  3118  		assert.Equal(t, "app.email.rate_limit_exceeded.app_error", err.Id)
  3119  		assert.Equal(t, http.StatusRequestEntityTooLarge, err.StatusCode)
  3120  
  3121  		_, err = th.App.InviteGuestsToChannelsGracefully(th.BasicTeam.Id, invite, th.BasicUser.Id)
  3122  		require.NotNil(t, err)
  3123  		assert.Equal(t, "app.email.rate_limit_exceeded.app_error", err.Id)
  3124  		assert.Equal(t, http.StatusRequestEntityTooLarge, err.StatusCode)
  3125  	})
  3126  }
  3127  
  3128  func TestGetTeamInviteInfo(t *testing.T) {
  3129  	th := Setup(t).InitBasic()
  3130  	defer th.TearDown()
  3131  	Client := th.Client
  3132  	team := th.BasicTeam
  3133  
  3134  	team, resp := Client.GetTeamInviteInfo(team.InviteId)
  3135  	CheckNoError(t, resp)
  3136  
  3137  	require.NotEmpty(t, team.DisplayName, "should not be empty")
  3138  
  3139  	require.Empty(t, team.Email, "should be empty")
  3140  
  3141  	team.InviteId = "12345678901234567890123456789012"
  3142  	team, resp = th.SystemAdminClient.UpdateTeam(team)
  3143  	CheckNoError(t, resp)
  3144  
  3145  	_, resp = Client.GetTeamInviteInfo(team.InviteId)
  3146  	CheckNoError(t, resp)
  3147  
  3148  	_, resp = Client.GetTeamInviteInfo("junk")
  3149  	CheckNotFoundStatus(t, resp)
  3150  }
  3151  
  3152  func TestSetTeamIcon(t *testing.T) {
  3153  	th := Setup(t).InitBasic()
  3154  	defer th.TearDown()
  3155  	Client := th.Client
  3156  	team := th.BasicTeam
  3157  
  3158  	data, err := testutils.ReadTestFile("test.png")
  3159  	require.NoError(t, err, err)
  3160  
  3161  	th.LoginTeamAdmin()
  3162  
  3163  	ok, resp := Client.SetTeamIcon(team.Id, data)
  3164  	require.True(t, ok, resp.Error)
  3165  
  3166  	CheckNoError(t, resp)
  3167  
  3168  	ok, resp = Client.SetTeamIcon(model.NewId(), data)
  3169  	require.False(t, ok, "Should return false, set team icon not allowed")
  3170  
  3171  	CheckForbiddenStatus(t, resp)
  3172  
  3173  	th.LoginBasic()
  3174  
  3175  	_, resp = Client.SetTeamIcon(team.Id, data)
  3176  	if resp.StatusCode == http.StatusForbidden {
  3177  		CheckForbiddenStatus(t, resp)
  3178  	} else if resp.StatusCode == http.StatusUnauthorized {
  3179  		CheckUnauthorizedStatus(t, resp)
  3180  	} else {
  3181  		require.Fail(t, "Should have failed either forbidden or unauthorized")
  3182  	}
  3183  
  3184  	Client.Logout()
  3185  
  3186  	_, resp = Client.SetTeamIcon(team.Id, data)
  3187  	if resp.StatusCode == http.StatusForbidden {
  3188  		CheckForbiddenStatus(t, resp)
  3189  	} else if resp.StatusCode == http.StatusUnauthorized {
  3190  		CheckUnauthorizedStatus(t, resp)
  3191  	} else {
  3192  		require.Fail(t, "Should have failed either forbidden or unauthorized")
  3193  	}
  3194  
  3195  	teamBefore, appErr := th.App.GetTeam(team.Id)
  3196  	require.Nil(t, appErr)
  3197  
  3198  	_, resp = th.SystemAdminClient.SetTeamIcon(team.Id, data)
  3199  	CheckNoError(t, resp)
  3200  
  3201  	teamAfter, appErr := th.App.GetTeam(team.Id)
  3202  	require.Nil(t, appErr)
  3203  	assert.True(t, teamBefore.LastTeamIconUpdate < teamAfter.LastTeamIconUpdate, "LastTeamIconUpdate should have been updated for team")
  3204  
  3205  	info := &model.FileInfo{Path: "teams/" + team.Id + "/teamIcon.png"}
  3206  	err = th.cleanupTestFile(info)
  3207  	require.NoError(t, err)
  3208  }
  3209  
  3210  func TestGetTeamIcon(t *testing.T) {
  3211  	th := Setup(t).InitBasic()
  3212  	defer th.TearDown()
  3213  	Client := th.Client
  3214  	team := th.BasicTeam
  3215  
  3216  	// should always fail because no initial image and no auto creation
  3217  	_, resp := Client.GetTeamIcon(team.Id, "")
  3218  	CheckNotFoundStatus(t, resp)
  3219  
  3220  	Client.Logout()
  3221  
  3222  	_, resp = Client.GetTeamIcon(team.Id, "")
  3223  	CheckUnauthorizedStatus(t, resp)
  3224  }
  3225  
  3226  func TestRemoveTeamIcon(t *testing.T) {
  3227  	th := Setup(t).InitBasic()
  3228  	defer th.TearDown()
  3229  	Client := th.Client
  3230  	team := th.BasicTeam
  3231  
  3232  	th.LoginTeamAdmin()
  3233  	data, _ := testutils.ReadTestFile("test.png")
  3234  	Client.SetTeamIcon(team.Id, data)
  3235  
  3236  	_, resp := Client.RemoveTeamIcon(team.Id)
  3237  	CheckNoError(t, resp)
  3238  	teamAfter, _ := th.App.GetTeam(team.Id)
  3239  	require.Equal(t, teamAfter.LastTeamIconUpdate, int64(0), "should update LastTeamIconUpdate to 0")
  3240  
  3241  	Client.SetTeamIcon(team.Id, data)
  3242  
  3243  	_, resp = th.SystemAdminClient.RemoveTeamIcon(team.Id)
  3244  	CheckNoError(t, resp)
  3245  	teamAfter, _ = th.App.GetTeam(team.Id)
  3246  	require.Equal(t, teamAfter.LastTeamIconUpdate, int64(0), "should update LastTeamIconUpdate to 0")
  3247  
  3248  	Client.SetTeamIcon(team.Id, data)
  3249  	Client.Logout()
  3250  
  3251  	_, resp = Client.RemoveTeamIcon(team.Id)
  3252  	CheckUnauthorizedStatus(t, resp)
  3253  
  3254  	th.LoginBasic()
  3255  	_, resp = Client.RemoveTeamIcon(team.Id)
  3256  	CheckForbiddenStatus(t, resp)
  3257  }
  3258  
  3259  func TestUpdateTeamScheme(t *testing.T) {
  3260  	th := Setup(t)
  3261  	defer th.TearDown()
  3262  
  3263  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  3264  
  3265  	th.App.SetPhase2PermissionsMigrationStatus(true)
  3266  
  3267  	team := &model.Team{
  3268  		DisplayName:     "Name",
  3269  		Description:     "Some description",
  3270  		CompanyName:     "Some company name",
  3271  		AllowOpenInvite: false,
  3272  		InviteId:        "inviteid0",
  3273  		Name:            "z-z-" + model.NewId() + "a",
  3274  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  3275  		Type:            model.TEAM_OPEN,
  3276  	}
  3277  	team, _ = th.SystemAdminClient.CreateTeam(team)
  3278  
  3279  	teamScheme := &model.Scheme{
  3280  		DisplayName: "DisplayName",
  3281  		Name:        model.NewId(),
  3282  		Description: "Some description",
  3283  		Scope:       model.SCHEME_SCOPE_TEAM,
  3284  	}
  3285  	teamScheme, _ = th.SystemAdminClient.CreateScheme(teamScheme)
  3286  	channelScheme := &model.Scheme{
  3287  		DisplayName: "DisplayName",
  3288  		Name:        model.NewId(),
  3289  		Description: "Some description",
  3290  		Scope:       model.SCHEME_SCOPE_CHANNEL,
  3291  	}
  3292  	channelScheme, _ = th.SystemAdminClient.CreateScheme(channelScheme)
  3293  
  3294  	// Test the setup/base case.
  3295  	_, resp := th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
  3296  	CheckNoError(t, resp)
  3297  
  3298  	// Test the return to default scheme
  3299  	_, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, "")
  3300  	CheckNoError(t, resp)
  3301  
  3302  	// Test various invalid team and scheme id combinations.
  3303  	_, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, "x")
  3304  	CheckBadRequestStatus(t, resp)
  3305  	_, resp = th.SystemAdminClient.UpdateTeamScheme("x", teamScheme.Id)
  3306  	CheckBadRequestStatus(t, resp)
  3307  	_, resp = th.SystemAdminClient.UpdateTeamScheme("x", "x")
  3308  	CheckBadRequestStatus(t, resp)
  3309  
  3310  	// Test that permissions are required.
  3311  	_, resp = th.Client.UpdateTeamScheme(team.Id, teamScheme.Id)
  3312  	CheckForbiddenStatus(t, resp)
  3313  
  3314  	// Test that a license is required.
  3315  	th.App.Srv().SetLicense(nil)
  3316  	_, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
  3317  	CheckNotImplementedStatus(t, resp)
  3318  	th.App.Srv().SetLicense(model.NewTestLicense(""))
  3319  
  3320  	// Test an invalid scheme scope.
  3321  	_, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, channelScheme.Id)
  3322  	CheckBadRequestStatus(t, resp)
  3323  
  3324  	// Test that an unauthenticated user gets rejected.
  3325  	th.SystemAdminClient.Logout()
  3326  	_, resp = th.SystemAdminClient.UpdateTeamScheme(team.Id, teamScheme.Id)
  3327  	CheckUnauthorizedStatus(t, resp)
  3328  }
  3329  
  3330  func TestTeamMembersMinusGroupMembers(t *testing.T) {
  3331  	th := Setup(t).InitBasic()
  3332  	defer th.TearDown()
  3333  
  3334  	user1 := th.BasicUser
  3335  	user2 := th.BasicUser2
  3336  
  3337  	team := th.CreateTeam()
  3338  	team.GroupConstrained = model.NewBool(true)
  3339  	team, err := th.App.UpdateTeam(team)
  3340  	require.Nil(t, err)
  3341  
  3342  	_, err = th.App.AddTeamMember(th.Context, team.Id, user1.Id)
  3343  	require.Nil(t, err)
  3344  	_, err = th.App.AddTeamMember(th.Context, team.Id, user2.Id)
  3345  	require.Nil(t, err)
  3346  
  3347  	group1 := th.CreateGroup()
  3348  	group2 := th.CreateGroup()
  3349  
  3350  	_, err = th.App.UpsertGroupMember(group1.Id, user1.Id)
  3351  	require.Nil(t, err)
  3352  	_, err = th.App.UpsertGroupMember(group2.Id, user2.Id)
  3353  	require.Nil(t, err)
  3354  
  3355  	// No permissions
  3356  	_, _, res := th.Client.TeamMembersMinusGroupMembers(team.Id, []string{group1.Id, group2.Id}, 0, 100, "")
  3357  	require.Equal(t, "api.context.permissions.app_error", res.Error.Id)
  3358  
  3359  	testCases := map[string]struct {
  3360  		groupIDs        []string
  3361  		page            int
  3362  		perPage         int
  3363  		length          int
  3364  		count           int
  3365  		otherAssertions func([]*model.UserWithGroups)
  3366  	}{
  3367  		"All groups, expect no users removed": {
  3368  			groupIDs: []string{group1.Id, group2.Id},
  3369  			page:     0,
  3370  			perPage:  100,
  3371  			length:   0,
  3372  			count:    0,
  3373  		},
  3374  		"Some nonexistent group, page 0": {
  3375  			groupIDs: []string{model.NewId()},
  3376  			page:     0,
  3377  			perPage:  1,
  3378  			length:   1,
  3379  			count:    2,
  3380  		},
  3381  		"Some nonexistent group, page 1": {
  3382  			groupIDs: []string{model.NewId()},
  3383  			page:     1,
  3384  			perPage:  1,
  3385  			length:   1,
  3386  			count:    2,
  3387  		},
  3388  		"One group, expect one user removed": {
  3389  			groupIDs: []string{group1.Id},
  3390  			page:     0,
  3391  			perPage:  100,
  3392  			length:   1,
  3393  			count:    1,
  3394  			otherAssertions: func(uwg []*model.UserWithGroups) {
  3395  				require.Equal(t, uwg[0].Id, user2.Id)
  3396  			},
  3397  		},
  3398  		"Other group, expect other user removed": {
  3399  			groupIDs: []string{group2.Id},
  3400  			page:     0,
  3401  			perPage:  100,
  3402  			length:   1,
  3403  			count:    1,
  3404  			otherAssertions: func(uwg []*model.UserWithGroups) {
  3405  				require.Equal(t, uwg[0].Id, user1.Id)
  3406  			},
  3407  		},
  3408  	}
  3409  
  3410  	for name, tc := range testCases {
  3411  		t.Run(name, func(t *testing.T) {
  3412  			uwg, count, res := th.SystemAdminClient.TeamMembersMinusGroupMembers(team.Id, tc.groupIDs, tc.page, tc.perPage, "")
  3413  			require.Nil(t, res.Error)
  3414  			require.Len(t, uwg, tc.length)
  3415  			require.Equal(t, tc.count, int(count))
  3416  			if tc.otherAssertions != nil {
  3417  				tc.otherAssertions(uwg)
  3418  			}
  3419  		})
  3420  	}
  3421  }
  3422  
  3423  func TestInvalidateAllEmailInvites(t *testing.T) {
  3424  	th := Setup(t)
  3425  	defer th.TearDown()
  3426  
  3427  	t.Run("Forbidden when request performed by system user", func(t *testing.T) {
  3428  		ok, res := th.Client.InvalidateEmailInvites()
  3429  		require.Equal(t, false, ok)
  3430  		CheckForbiddenStatus(t, res)
  3431  	})
  3432  
  3433  	t.Run("OK when request performed by system user with requisite system permission", func(t *testing.T) {
  3434  		th.AddPermissionToRole(model.PERMISSION_INVALIDATE_EMAIL_INVITE.Id, model.SYSTEM_USER_ROLE_ID)
  3435  		defer th.RemovePermissionFromRole(model.PERMISSION_INVALIDATE_EMAIL_INVITE.Id, model.SYSTEM_USER_ROLE_ID)
  3436  		ok, res := th.Client.InvalidateEmailInvites()
  3437  		require.Equal(t, true, ok)
  3438  		CheckOKStatus(t, res)
  3439  	})
  3440  
  3441  	t.Run("OK when request performed by system admin", func(t *testing.T) {
  3442  		ok, res := th.SystemAdminClient.InvalidateEmailInvites()
  3443  		require.Equal(t, true, ok)
  3444  		CheckOKStatus(t, res)
  3445  	})
  3446  }