github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/app/user_test.go (about)

     1  // Copyright (c) 2016-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"image"
    10  	"image/color"
    11  	"math/rand"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  
    19  	"github.com/xzl8028/xenia-server/einterfaces"
    20  	"github.com/xzl8028/xenia-server/model"
    21  	oauthgitlab "github.com/xzl8028/xenia-server/model/gitlab"
    22  )
    23  
    24  func TestIsUsernameTaken(t *testing.T) {
    25  	th := Setup(t).InitBasic()
    26  	defer th.TearDown()
    27  
    28  	user := th.BasicUser
    29  	taken := th.App.IsUsernameTaken(user.Username)
    30  
    31  	if !taken {
    32  		t.Logf("the username '%v' should be taken", user.Username)
    33  		t.FailNow()
    34  	}
    35  
    36  	newUsername := "randomUsername"
    37  	taken = th.App.IsUsernameTaken(newUsername)
    38  
    39  	if taken {
    40  		t.Logf("the username '%v' should not be taken", newUsername)
    41  		t.FailNow()
    42  	}
    43  }
    44  
    45  func TestCheckUserDomain(t *testing.T) {
    46  	th := Setup(t).InitBasic()
    47  	defer th.TearDown()
    48  
    49  	user := th.BasicUser
    50  
    51  	cases := []struct {
    52  		domains string
    53  		matched bool
    54  	}{
    55  		{"simulator.amazonses.com", true},
    56  		{"gmail.com", false},
    57  		{"", true},
    58  		{"gmail.com simulator.amazonses.com", true},
    59  	}
    60  	for _, c := range cases {
    61  		matched := CheckUserDomain(user, c.domains)
    62  		if matched != c.matched {
    63  			if c.matched {
    64  				t.Logf("'%v' should have matched '%v'", user.Email, c.domains)
    65  			} else {
    66  				t.Logf("'%v' should not have matched '%v'", user.Email, c.domains)
    67  			}
    68  			t.FailNow()
    69  		}
    70  	}
    71  }
    72  
    73  func TestCreateOAuthUser(t *testing.T) {
    74  	th := Setup(t).InitBasic()
    75  	defer th.TearDown()
    76  
    77  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
    78  	glUser := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)) + 1, Username: "o" + model.NewId(), Email: model.NewId() + "@simulator.amazonses.com", Name: "Joram Wilander"}
    79  
    80  	json := glUser.ToJson()
    81  	user, err := th.App.CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id)
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  
    86  	if user.Username != glUser.Username {
    87  		t.Fatal("usernames didn't match")
    88  	}
    89  
    90  	th.App.PermanentDeleteUser(user)
    91  
    92  	*th.App.Config().TeamSettings.EnableUserCreation = false
    93  
    94  	_, err = th.App.CreateOAuthUser(model.USER_AUTH_SERVICE_GITLAB, strings.NewReader(json), th.BasicTeam.Id)
    95  	if err == nil {
    96  		t.Fatal("should have failed - user creation disabled")
    97  	}
    98  }
    99  
   100  func TestCreateProfileImage(t *testing.T) {
   101  	b, err := CreateProfileImage("Corey Hulen", "eo1zkdr96pdj98pjmq8zy35wba", "nunito-bold.ttf")
   102  	if err != nil {
   103  		t.Fatal(err)
   104  	}
   105  
   106  	rdr := bytes.NewReader(b)
   107  	img, _, err2 := image.Decode(rdr)
   108  	if err2 != nil {
   109  		t.Fatal(err)
   110  	}
   111  
   112  	colorful := color.RGBA{116, 49, 196, 255}
   113  
   114  	if img.At(1, 1) != colorful {
   115  		t.Fatal("Failed to create correct color")
   116  	}
   117  }
   118  
   119  func TestSetDefaultProfileImage(t *testing.T) {
   120  	th := Setup(t).InitBasic()
   121  	defer th.TearDown()
   122  
   123  	err := th.App.SetDefaultProfileImage(&model.User{
   124  		Id:       model.NewId(),
   125  		Username: "notvaliduser",
   126  	})
   127  	require.Error(t, err)
   128  
   129  	user := th.BasicUser
   130  
   131  	err = th.App.SetDefaultProfileImage(user)
   132  	require.Nil(t, err)
   133  
   134  	user = getUserFromDB(th.App, user.Id, t)
   135  	assert.Equal(t, int64(0), user.LastPictureUpdate)
   136  }
   137  
   138  func TestUpdateUserToRestrictedDomain(t *testing.T) {
   139  	th := Setup(t)
   140  	defer th.TearDown()
   141  
   142  	user := th.CreateUser()
   143  	defer th.App.PermanentDeleteUser(user)
   144  
   145  	th.App.UpdateConfig(func(cfg *model.Config) {
   146  		*cfg.TeamSettings.RestrictCreationToDomains = "foo.com"
   147  	})
   148  
   149  	_, err := th.App.UpdateUser(user, false)
   150  	assert.True(t, err == nil)
   151  
   152  	user.Email = "asdf@ghjk.l"
   153  	_, err = th.App.UpdateUser(user, false)
   154  	assert.False(t, err == nil)
   155  }
   156  
   157  func TestUpdateUserActive(t *testing.T) {
   158  	th := Setup(t)
   159  	defer th.TearDown()
   160  
   161  	user := th.CreateUser()
   162  
   163  	EnableUserDeactivation := th.App.Config().TeamSettings.EnableUserDeactivation
   164  	defer func() {
   165  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableUserDeactivation = EnableUserDeactivation })
   166  	}()
   167  
   168  	th.App.UpdateConfig(func(cfg *model.Config) {
   169  		*cfg.TeamSettings.EnableUserDeactivation = true
   170  	})
   171  	err := th.App.UpdateUserActive(user.Id, false)
   172  	assert.Nil(t, err)
   173  }
   174  
   175  func TestUpdateActiveBotsSideEffect(t *testing.T) {
   176  	th := Setup(t).InitBasic()
   177  	defer th.TearDown()
   178  
   179  	bot, err := th.App.CreateBot(&model.Bot{
   180  		Username:    "username",
   181  		Description: "a bot",
   182  		OwnerId:     th.BasicUser.Id,
   183  	})
   184  	require.Nil(t, err)
   185  	defer th.App.PermanentDeleteBot(bot.UserId)
   186  
   187  	// Automatic deactivation disabled
   188  	th.App.UpdateConfig(func(cfg *model.Config) {
   189  		*cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = false
   190  	})
   191  
   192  	th.App.UpdateActive(th.BasicUser, false)
   193  
   194  	retbot1, err := th.App.GetBot(bot.UserId, true)
   195  	require.Nil(t, err)
   196  	require.Zero(t, retbot1.DeleteAt)
   197  	user1, err := th.App.GetUser(bot.UserId)
   198  	require.Nil(t, err)
   199  	require.Zero(t, user1.DeleteAt)
   200  
   201  	th.App.UpdateActive(th.BasicUser, true)
   202  
   203  	// Automatic deactivation enabled
   204  	th.App.UpdateConfig(func(cfg *model.Config) {
   205  		*cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated = true
   206  	})
   207  
   208  	th.App.UpdateActive(th.BasicUser, false)
   209  
   210  	retbot2, err := th.App.GetBot(bot.UserId, true)
   211  	require.Nil(t, err)
   212  	require.NotZero(t, retbot2.DeleteAt)
   213  	user2, err := th.App.GetUser(bot.UserId)
   214  	require.Nil(t, err)
   215  	require.NotZero(t, user2.DeleteAt)
   216  
   217  	th.App.UpdateActive(th.BasicUser, true)
   218  }
   219  
   220  func TestUpdateOAuthUserAttrs(t *testing.T) {
   221  	th := Setup(t)
   222  	defer th.TearDown()
   223  
   224  	id := model.NewId()
   225  	id2 := model.NewId()
   226  	gitlabProvider := einterfaces.GetOauthProvider("gitlab")
   227  
   228  	username := "user" + id
   229  	username2 := "user" + id2
   230  
   231  	email := "user" + id + "@nowhere.com"
   232  	email2 := "user" + id2 + "@nowhere.com"
   233  
   234  	var user, user2 *model.User
   235  	var gitlabUserObj oauthgitlab.GitLabUser
   236  	user, gitlabUserObj = createGitlabUser(t, th.App, username, email)
   237  	user2, _ = createGitlabUser(t, th.App, username2, email2)
   238  
   239  	t.Run("UpdateUsername", func(t *testing.T) {
   240  		t.Run("NoExistingUserWithSameUsername", func(t *testing.T) {
   241  			gitlabUserObj.Username = "updateduser" + model.NewId()
   242  			gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   243  			data := bytes.NewReader(gitlabUser)
   244  
   245  			user = getUserFromDB(th.App, user.Id, t)
   246  			th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   247  			user = getUserFromDB(th.App, user.Id, t)
   248  
   249  			if user.Username != gitlabUserObj.Username {
   250  				t.Fatal("user's username is not updated")
   251  			}
   252  		})
   253  
   254  		t.Run("ExistinguserWithSameUsername", func(t *testing.T) {
   255  			gitlabUserObj.Username = user2.Username
   256  
   257  			gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   258  			data := bytes.NewReader(gitlabUser)
   259  
   260  			user = getUserFromDB(th.App, user.Id, t)
   261  			th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   262  			user = getUserFromDB(th.App, user.Id, t)
   263  
   264  			if user.Username == gitlabUserObj.Username {
   265  				t.Fatal("user's username is updated though there already exists another user with the same username")
   266  			}
   267  		})
   268  	})
   269  
   270  	t.Run("UpdateEmail", func(t *testing.T) {
   271  		t.Run("NoExistingUserWithSameEmail", func(t *testing.T) {
   272  			gitlabUserObj.Email = "newuser" + model.NewId() + "@nowhere.com"
   273  			gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   274  			data := bytes.NewReader(gitlabUser)
   275  
   276  			user = getUserFromDB(th.App, user.Id, t)
   277  			th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   278  			user = getUserFromDB(th.App, user.Id, t)
   279  
   280  			if user.Email != gitlabUserObj.Email {
   281  				t.Fatal("user's email is not updated")
   282  			}
   283  
   284  			if !user.EmailVerified {
   285  				t.Fatal("user's email should have been verified")
   286  			}
   287  		})
   288  
   289  		t.Run("ExistingUserWithSameEmail", func(t *testing.T) {
   290  			gitlabUserObj.Email = user2.Email
   291  
   292  			gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   293  			data := bytes.NewReader(gitlabUser)
   294  
   295  			user = getUserFromDB(th.App, user.Id, t)
   296  			th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   297  			user = getUserFromDB(th.App, user.Id, t)
   298  
   299  			if user.Email == gitlabUserObj.Email {
   300  				t.Fatal("user's email is updated though there already exists another user with the same email")
   301  			}
   302  		})
   303  	})
   304  
   305  	t.Run("UpdateFirstName", func(t *testing.T) {
   306  		gitlabUserObj.Name = "Updated User"
   307  		gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   308  		data := bytes.NewReader(gitlabUser)
   309  
   310  		user = getUserFromDB(th.App, user.Id, t)
   311  		th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   312  		user = getUserFromDB(th.App, user.Id, t)
   313  
   314  		if user.FirstName != "Updated" {
   315  			t.Fatal("user's first name is not updated")
   316  		}
   317  	})
   318  
   319  	t.Run("UpdateLastName", func(t *testing.T) {
   320  		gitlabUserObj.Name = "Updated Lastname"
   321  		gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   322  		data := bytes.NewReader(gitlabUser)
   323  
   324  		user = getUserFromDB(th.App, user.Id, t)
   325  		th.App.UpdateOAuthUserAttrs(data, user, gitlabProvider, "gitlab")
   326  		user = getUserFromDB(th.App, user.Id, t)
   327  
   328  		if user.LastName != "Lastname" {
   329  			t.Fatal("user's last name is not updated")
   330  		}
   331  	})
   332  }
   333  
   334  func TestUpdateUserEmail(t *testing.T) {
   335  	th := Setup(t)
   336  	defer th.TearDown()
   337  
   338  	user := th.CreateUser()
   339  
   340  	t.Run("RequireVerification", func(t *testing.T) {
   341  		th.App.UpdateConfig(func(cfg *model.Config) {
   342  			*cfg.EmailSettings.RequireEmailVerification = true
   343  		})
   344  
   345  		currentEmail := user.Email
   346  		newEmail := th.MakeEmail()
   347  
   348  		user.Email = newEmail
   349  		user2, err := th.App.UpdateUser(user, false)
   350  		assert.Nil(t, err)
   351  		assert.Equal(t, currentEmail, user2.Email)
   352  		assert.True(t, user2.EmailVerified)
   353  
   354  		token, err := th.App.CreateVerifyEmailToken(user2.Id, newEmail)
   355  		assert.Nil(t, err)
   356  
   357  		err = th.App.VerifyEmailFromToken(token.Token)
   358  		assert.Nil(t, err)
   359  
   360  		user2, err = th.App.GetUser(user2.Id)
   361  		assert.Nil(t, err)
   362  		assert.Equal(t, newEmail, user2.Email)
   363  		assert.True(t, user2.EmailVerified)
   364  	})
   365  
   366  	t.Run("RequireVerificationAlreadyUsedEmail", func(t *testing.T) {
   367  		th.App.UpdateConfig(func(cfg *model.Config) {
   368  			*cfg.EmailSettings.RequireEmailVerification = true
   369  		})
   370  
   371  		user2 := th.CreateUser()
   372  		newEmail := user2.Email
   373  
   374  		user.Email = newEmail
   375  		user3, err := th.App.UpdateUser(user, false)
   376  		assert.NotNil(t, err)
   377  		assert.Nil(t, user3)
   378  	})
   379  
   380  	t.Run("NoVerification", func(t *testing.T) {
   381  		th.App.UpdateConfig(func(cfg *model.Config) {
   382  			*cfg.EmailSettings.RequireEmailVerification = false
   383  		})
   384  
   385  		newEmail := th.MakeEmail()
   386  
   387  		user.Email = newEmail
   388  		user2, err := th.App.UpdateUser(user, false)
   389  		assert.Nil(t, err)
   390  		assert.Equal(t, newEmail, user2.Email)
   391  	})
   392  }
   393  
   394  func getUserFromDB(a *App, id string, t *testing.T) *model.User {
   395  	user, err := a.GetUser(id)
   396  	if err != nil {
   397  		t.Fatal("user is not found", err)
   398  		return nil
   399  	}
   400  	return user
   401  }
   402  
   403  func getGitlabUserPayload(gitlabUser oauthgitlab.GitLabUser, t *testing.T) []byte {
   404  	var payload []byte
   405  	var err error
   406  	if payload, err = json.Marshal(gitlabUser); err != nil {
   407  		t.Fatal("Serialization of gitlab user to json failed", err)
   408  	}
   409  
   410  	return payload
   411  }
   412  
   413  func createGitlabUser(t *testing.T, a *App, username string, email string) (*model.User, oauthgitlab.GitLabUser) {
   414  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   415  	gitlabUserObj := oauthgitlab.GitLabUser{Id: int64(r.Intn(1000)) + 1, Username: username, Login: "user1", Email: email, Name: "Test User"}
   416  	gitlabUser := getGitlabUserPayload(gitlabUserObj, t)
   417  
   418  	var user *model.User
   419  	var err *model.AppError
   420  
   421  	if user, err = a.CreateOAuthUser("gitlab", bytes.NewReader(gitlabUser), ""); err != nil {
   422  		t.Fatal("unable to create the user", err)
   423  	}
   424  
   425  	return user, gitlabUserObj
   426  }
   427  
   428  func TestGetUsersByStatus(t *testing.T) {
   429  	th := Setup(t)
   430  	defer th.TearDown()
   431  
   432  	team := th.CreateTeam()
   433  	channel, err := th.App.CreateChannel(&model.Channel{
   434  		DisplayName: "dn_" + model.NewId(),
   435  		Name:        "name_" + model.NewId(),
   436  		Type:        model.CHANNEL_OPEN,
   437  		TeamId:      team.Id,
   438  		CreatorId:   model.NewId(),
   439  	}, false)
   440  	if err != nil {
   441  		t.Fatalf("failed to create channel: %v", err)
   442  	}
   443  
   444  	createUserWithStatus := func(username string, status string) *model.User {
   445  		id := model.NewId()
   446  
   447  		user, err := th.App.CreateUser(&model.User{
   448  			Email:    "success+" + id + "@simulator.amazonses.com",
   449  			Username: "un_" + username + "_" + id,
   450  			Nickname: "nn_" + id,
   451  			Password: "Password1",
   452  		})
   453  		if err != nil {
   454  			t.Fatalf("failed to create user: %v", err)
   455  		}
   456  
   457  		th.LinkUserToTeam(user, team)
   458  		th.AddUserToChannel(user, channel)
   459  
   460  		th.App.SaveAndBroadcastStatus(&model.Status{
   461  			UserId: user.Id,
   462  			Status: status,
   463  			Manual: true,
   464  		})
   465  
   466  		return user
   467  	}
   468  
   469  	// Creating these out of order in case that affects results
   470  	awayUser1 := createUserWithStatus("away1", model.STATUS_AWAY)
   471  	awayUser2 := createUserWithStatus("away2", model.STATUS_AWAY)
   472  	dndUser1 := createUserWithStatus("dnd1", model.STATUS_DND)
   473  	dndUser2 := createUserWithStatus("dnd2", model.STATUS_DND)
   474  	offlineUser1 := createUserWithStatus("offline1", model.STATUS_OFFLINE)
   475  	offlineUser2 := createUserWithStatus("offline2", model.STATUS_OFFLINE)
   476  	onlineUser1 := createUserWithStatus("online1", model.STATUS_ONLINE)
   477  	onlineUser2 := createUserWithStatus("online2", model.STATUS_ONLINE)
   478  
   479  	t.Run("sorting by status then alphabetical", func(t *testing.T) {
   480  		usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 8, true)
   481  		if err != nil {
   482  			t.Fatal(err)
   483  		}
   484  
   485  		expectedUsersByStatus := []*model.User{
   486  			onlineUser1,
   487  			onlineUser2,
   488  			awayUser1,
   489  			awayUser2,
   490  			dndUser1,
   491  			dndUser2,
   492  			offlineUser1,
   493  			offlineUser2,
   494  		}
   495  
   496  		if len(usersByStatus) != len(expectedUsersByStatus) {
   497  			t.Fatalf("received only %v users, expected %v", len(usersByStatus), len(expectedUsersByStatus))
   498  		}
   499  
   500  		for i := range usersByStatus {
   501  			if usersByStatus[i].Id != expectedUsersByStatus[i].Id {
   502  				t.Fatalf("received user %v at index %v, expected %v", usersByStatus[i].Username, i, expectedUsersByStatus[i].Username)
   503  			}
   504  		}
   505  	})
   506  
   507  	t.Run("paging", func(t *testing.T) {
   508  		usersByStatus, err := th.App.GetUsersInChannelPageByStatus(channel.Id, 0, 3, true)
   509  		if err != nil {
   510  			t.Fatal(err)
   511  		}
   512  
   513  		if len(usersByStatus) != 3 {
   514  			t.Fatal("received too many users")
   515  		}
   516  
   517  		if usersByStatus[0].Id != onlineUser1.Id && usersByStatus[1].Id != onlineUser2.Id {
   518  			t.Fatal("expected to receive online users first")
   519  		}
   520  
   521  		if usersByStatus[2].Id != awayUser1.Id {
   522  			t.Fatal("expected to receive away users second")
   523  		}
   524  
   525  		usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 3, true)
   526  		if err != nil {
   527  			t.Fatal(err)
   528  		}
   529  
   530  		if usersByStatus[0].Id != awayUser2.Id {
   531  			t.Fatal("expected to receive away users second")
   532  		}
   533  
   534  		if usersByStatus[1].Id != dndUser1.Id && usersByStatus[2].Id != dndUser2.Id {
   535  			t.Fatal("expected to receive dnd users third")
   536  		}
   537  
   538  		usersByStatus, err = th.App.GetUsersInChannelPageByStatus(channel.Id, 1, 4, true)
   539  		if err != nil {
   540  			t.Fatal(err)
   541  		}
   542  
   543  		if len(usersByStatus) != 4 {
   544  			t.Fatal("received too many users")
   545  		}
   546  
   547  		if usersByStatus[0].Id != dndUser1.Id && usersByStatus[1].Id != dndUser2.Id {
   548  			t.Fatal("expected to receive dnd users third")
   549  		}
   550  
   551  		if usersByStatus[2].Id != offlineUser1.Id && usersByStatus[3].Id != offlineUser2.Id {
   552  			t.Fatal("expected to receive offline users last")
   553  		}
   554  	})
   555  }
   556  
   557  func TestCreateUserWithToken(t *testing.T) {
   558  	th := Setup(t).InitBasic()
   559  	defer th.TearDown()
   560  
   561  	user := model.User{Email: strings.ToLower(model.NewId()) + "success+test@example.com", Nickname: "Darth Vader", Username: "vader" + model.NewId(), Password: "passwd1", AuthService: ""}
   562  
   563  	t.Run("invalid token", func(t *testing.T) {
   564  		if _, err := th.App.CreateUserWithToken(&user, "123"); err == nil {
   565  			t.Fatal("Should fail on unexisting token")
   566  		}
   567  	})
   568  
   569  	t.Run("invalid token type", func(t *testing.T) {
   570  		token := model.NewToken(
   571  			TOKEN_TYPE_VERIFY_EMAIL,
   572  			model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}),
   573  		)
   574  		require.Nil(t, th.App.Srv.Store.Token().Save(token))
   575  		defer th.App.DeleteToken(token)
   576  		if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil {
   577  			t.Fatal("Should fail on bad token type")
   578  		}
   579  	})
   580  
   581  	t.Run("expired token", func(t *testing.T) {
   582  		token := model.NewToken(
   583  			TOKEN_TYPE_TEAM_INVITATION,
   584  			model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": user.Email}),
   585  		)
   586  		token.CreateAt = model.GetMillis() - TEAM_INVITATION_EXPIRY_TIME - 1
   587  		require.Nil(t, th.App.Srv.Store.Token().Save(token))
   588  		defer th.App.DeleteToken(token)
   589  		if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil {
   590  			t.Fatal("Should fail on expired token")
   591  		}
   592  	})
   593  
   594  	t.Run("invalid team id", func(t *testing.T) {
   595  		token := model.NewToken(
   596  			TOKEN_TYPE_TEAM_INVITATION,
   597  			model.MapToJson(map[string]string{"teamId": model.NewId(), "email": user.Email}),
   598  		)
   599  		require.Nil(t, th.App.Srv.Store.Token().Save(token))
   600  		defer th.App.DeleteToken(token)
   601  		if _, err := th.App.CreateUserWithToken(&user, token.Token); err == nil {
   602  			t.Fatal("Should fail on bad team id")
   603  		}
   604  	})
   605  
   606  	t.Run("valid request", func(t *testing.T) {
   607  		invitationEmail := model.NewId() + "other-email@test.com"
   608  		token := model.NewToken(
   609  			TOKEN_TYPE_TEAM_INVITATION,
   610  			model.MapToJson(map[string]string{"teamId": th.BasicTeam.Id, "email": invitationEmail}),
   611  		)
   612  		require.Nil(t, th.App.Srv.Store.Token().Save(token))
   613  		newUser, err := th.App.CreateUserWithToken(&user, token.Token)
   614  		if err != nil {
   615  			t.Log(err)
   616  			t.Fatal("Should add user to the team")
   617  		}
   618  		if newUser.Email != invitationEmail {
   619  			t.Fatal("The user email must be the invitation one")
   620  		}
   621  		_, err = th.App.Srv.Store.Token().GetByToken(token.Token)
   622  		require.NotNil(t, err, "The token must be deleted after be used")
   623  	})
   624  }
   625  
   626  func TestPermanentDeleteUser(t *testing.T) {
   627  	th := Setup(t).InitBasic()
   628  	defer th.TearDown()
   629  
   630  	b := []byte("testimage")
   631  
   632  	finfo, err := th.App.DoUploadFile(time.Now(), th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, "testfile.txt", b)
   633  
   634  	if err != nil {
   635  		t.Log(err)
   636  		t.Fatal("Unable to upload file")
   637  	}
   638  
   639  	err = th.App.PermanentDeleteUser(th.BasicUser)
   640  	if err != nil {
   641  		t.Log(err)
   642  		t.Fatal("Unable to delete user")
   643  	}
   644  
   645  	res, err := th.App.FileExists(finfo.Path)
   646  
   647  	if err != nil {
   648  		t.Log(err)
   649  		t.Fatal("Unable to check whether file exists")
   650  	}
   651  
   652  	if res {
   653  		t.Log(err)
   654  		t.Fatal("File was not deleted on FS")
   655  	}
   656  
   657  	finfo, err = th.App.GetFileInfo(finfo.Id)
   658  
   659  	if finfo != nil {
   660  		t.Log(err)
   661  		t.Fatal("Unable to find finfo")
   662  	}
   663  
   664  	if err == nil {
   665  		t.Log(err)
   666  		t.Fatal("GetFileInfo after DeleteUser is nil")
   667  	}
   668  }
   669  
   670  func TestPasswordRecovery(t *testing.T) {
   671  	th := Setup(t).InitBasic()
   672  	defer th.TearDown()
   673  
   674  	token, err := th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email)
   675  	assert.Nil(t, err)
   676  
   677  	tokenData := struct {
   678  		UserId string
   679  		Email  string
   680  	}{}
   681  
   682  	err2 := json.Unmarshal([]byte(token.Extra), &tokenData)
   683  	assert.Nil(t, err2)
   684  	assert.Equal(t, th.BasicUser.Id, tokenData.UserId)
   685  	assert.Equal(t, th.BasicUser.Email, tokenData.Email)
   686  
   687  	// Password token with same eMail as during creation
   688  	err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh")
   689  	assert.Nil(t, err)
   690  
   691  	// Password token with modified eMail after creation
   692  	token, err = th.App.CreatePasswordRecoveryToken(th.BasicUser.Id, th.BasicUser.Email)
   693  	assert.Nil(t, err)
   694  
   695  	th.App.UpdateConfig(func(c *model.Config) {
   696  		*c.EmailSettings.RequireEmailVerification = false
   697  	})
   698  
   699  	th.BasicUser.Email = th.MakeEmail()
   700  	_, err = th.App.UpdateUser(th.BasicUser, false)
   701  	assert.Nil(t, err)
   702  
   703  	err = th.App.ResetPasswordFromToken(token.Token, "abcdefgh")
   704  	assert.NotNil(t, err)
   705  }
   706  
   707  func TestGetViewUsersRestrictions(t *testing.T) {
   708  	th := Setup(t).InitBasic()
   709  	defer th.TearDown()
   710  
   711  	team1 := th.CreateTeam()
   712  	team2 := th.CreateTeam()
   713  	th.CreateTeam() // Another team
   714  
   715  	user1 := th.CreateUser()
   716  
   717  	th.LinkUserToTeam(user1, team1)
   718  	th.LinkUserToTeam(user1, team2)
   719  
   720  	th.App.UpdateTeamMemberRoles(team1.Id, user1.Id, "team_user team_admin")
   721  
   722  	team1channel1 := th.CreateChannel(team1)
   723  	team1channel2 := th.CreateChannel(team1)
   724  	th.CreateChannel(team1) // Another channel
   725  	team1offtopic, err := th.App.GetChannelByName("off-topic", team1.Id, false)
   726  	require.Nil(t, err)
   727  	team1townsquare, err := th.App.GetChannelByName("town-square", team1.Id, false)
   728  	require.Nil(t, err)
   729  
   730  	team2channel1 := th.CreateChannel(team2)
   731  	th.CreateChannel(team2) // Another channel
   732  	team2offtopic, err := th.App.GetChannelByName("off-topic", team2.Id, false)
   733  	require.Nil(t, err)
   734  	team2townsquare, err := th.App.GetChannelByName("town-square", team2.Id, false)
   735  	require.Nil(t, err)
   736  
   737  	th.App.AddUserToChannel(user1, team1channel1)
   738  	th.App.AddUserToChannel(user1, team1channel2)
   739  	th.App.AddUserToChannel(user1, team2channel1)
   740  
   741  	addPermission := func(role *model.Role, permission string) *model.AppError {
   742  		newPermissions := append(role.Permissions, permission)
   743  		_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
   744  		return err
   745  	}
   746  
   747  	removePermission := func(role *model.Role, permission string) *model.AppError {
   748  		newPermissions := []string{}
   749  		for _, oldPermission := range role.Permissions {
   750  			if permission != oldPermission {
   751  				newPermissions = append(newPermissions, oldPermission)
   752  			}
   753  		}
   754  		_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
   755  		return err
   756  	}
   757  
   758  	t.Run("VIEW_MEMBERS permission granted at system level", func(t *testing.T) {
   759  		restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
   760  		require.Nil(t, err)
   761  
   762  		assert.Nil(t, restrictions)
   763  	})
   764  
   765  	t.Run("VIEW_MEMBERS permission granted at team level", func(t *testing.T) {
   766  		systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
   767  		require.Nil(t, err)
   768  		teamUserRole, err := th.App.GetRoleByName(model.TEAM_USER_ROLE_ID)
   769  		require.Nil(t, err)
   770  
   771  		require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   772  		defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   773  		require.Nil(t, addPermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   774  		defer removePermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   775  
   776  		restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
   777  		require.Nil(t, err)
   778  
   779  		assert.NotNil(t, restrictions)
   780  		assert.NotNil(t, restrictions.Teams)
   781  		assert.Len(t, restrictions.Channels, 0)
   782  		assert.ElementsMatch(t, []string{team1.Id, team2.Id}, restrictions.Teams)
   783  	})
   784  
   785  	t.Run("VIEW_MEMBERS permission not granted at any level", func(t *testing.T) {
   786  		systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
   787  		require.Nil(t, err)
   788  		require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   789  		defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   790  
   791  		restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
   792  		require.Nil(t, err)
   793  
   794  		assert.NotNil(t, restrictions)
   795  		assert.Len(t, restrictions.Teams, 0)
   796  		assert.NotNil(t, restrictions.Channels)
   797  		assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions.Channels)
   798  	})
   799  
   800  	t.Run("VIEW_MEMBERS permission for some teams but not for others", func(t *testing.T) {
   801  		systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
   802  		require.Nil(t, err)
   803  		teamAdminRole, err := th.App.GetRoleByName(model.TEAM_ADMIN_ROLE_ID)
   804  		require.Nil(t, err)
   805  
   806  		require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   807  		defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   808  		require.Nil(t, addPermission(teamAdminRole, model.PERMISSION_VIEW_MEMBERS.Id))
   809  		defer removePermission(teamAdminRole, model.PERMISSION_VIEW_MEMBERS.Id)
   810  
   811  		restrictions, err := th.App.GetViewUsersRestrictions(user1.Id)
   812  		require.Nil(t, err)
   813  
   814  		assert.NotNil(t, restrictions)
   815  		assert.NotNil(t, restrictions.Teams)
   816  		assert.NotNil(t, restrictions.Channels)
   817  		assert.ElementsMatch(t, restrictions.Teams, []string{team1.Id})
   818  		assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions.Channels)
   819  	})
   820  }
   821  
   822  func TestGetViewUsersRestrictionsForTeam(t *testing.T) {
   823  	th := Setup(t).InitBasic()
   824  	defer th.TearDown()
   825  
   826  	team1 := th.CreateTeam()
   827  	team2 := th.CreateTeam()
   828  	th.CreateTeam() // Another team
   829  
   830  	user1 := th.CreateUser()
   831  
   832  	th.LinkUserToTeam(user1, team1)
   833  	th.LinkUserToTeam(user1, team2)
   834  
   835  	th.App.UpdateTeamMemberRoles(team1.Id, user1.Id, "team_user team_admin")
   836  
   837  	team1channel1 := th.CreateChannel(team1)
   838  	team1channel2 := th.CreateChannel(team1)
   839  	th.CreateChannel(team1) // Another channel
   840  	team1offtopic, err := th.App.GetChannelByName("off-topic", team1.Id, false)
   841  	require.Nil(t, err)
   842  	team1townsquare, err := th.App.GetChannelByName("town-square", team1.Id, false)
   843  	require.Nil(t, err)
   844  
   845  	team2channel1 := th.CreateChannel(team2)
   846  	th.CreateChannel(team2) // Another channel
   847  	team2offtopic, err := th.App.GetChannelByName("off-topic", team2.Id, false)
   848  	require.Nil(t, err)
   849  	team2townsquare, err := th.App.GetChannelByName("town-square", team2.Id, false)
   850  	require.Nil(t, err)
   851  
   852  	th.App.AddUserToChannel(user1, team1channel1)
   853  	th.App.AddUserToChannel(user1, team1channel2)
   854  	th.App.AddUserToChannel(user1, team2channel1)
   855  
   856  	addPermission := func(role *model.Role, permission string) *model.AppError {
   857  		newPermissions := append(role.Permissions, permission)
   858  		_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
   859  		return err
   860  	}
   861  
   862  	removePermission := func(role *model.Role, permission string) *model.AppError {
   863  		newPermissions := []string{}
   864  		for _, oldPermission := range role.Permissions {
   865  			if permission != oldPermission {
   866  				newPermissions = append(newPermissions, oldPermission)
   867  			}
   868  		}
   869  		_, err := th.App.PatchRole(role, &model.RolePatch{Permissions: &newPermissions})
   870  		return err
   871  	}
   872  
   873  	t.Run("VIEW_MEMBERS permission granted at system level", func(t *testing.T) {
   874  		restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
   875  		require.Nil(t, err)
   876  
   877  		assert.Nil(t, restrictions)
   878  	})
   879  
   880  	t.Run("VIEW_MEMBERS permission granted at team level", func(t *testing.T) {
   881  		systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
   882  		require.Nil(t, err)
   883  		teamUserRole, err := th.App.GetRoleByName(model.TEAM_USER_ROLE_ID)
   884  		require.Nil(t, err)
   885  
   886  		require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   887  		defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   888  		require.Nil(t, addPermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   889  		defer removePermission(teamUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   890  
   891  		restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
   892  		require.Nil(t, err)
   893  		assert.Nil(t, restrictions)
   894  	})
   895  
   896  	t.Run("VIEW_MEMBERS permission not granted at any level", func(t *testing.T) {
   897  		systemUserRole, err := th.App.GetRoleByName(model.SYSTEM_USER_ROLE_ID)
   898  		require.Nil(t, err)
   899  		require.Nil(t, removePermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id))
   900  		defer addPermission(systemUserRole, model.PERMISSION_VIEW_MEMBERS.Id)
   901  
   902  		restrictions, err := th.App.GetViewUsersRestrictionsForTeam(user1.Id, team1.Id)
   903  		require.Nil(t, err)
   904  
   905  		assert.NotNil(t, restrictions)
   906  		assert.ElementsMatch(t, []string{team1townsquare.Id, team1offtopic.Id, team1channel1.Id, team1channel2.Id, team2townsquare.Id, team2offtopic.Id, team2channel1.Id}, restrictions)
   907  	})
   908  }