github.com/adacta-ru/mattermost-server/v6@v6.0.0/app/syncables_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/adacta-ru/mattermost-server/v6/model"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestCreateDefaultMemberships(t *testing.T) {
    14  	th := Setup(t).InitBasic()
    15  	defer th.TearDown()
    16  
    17  	singersTeam, err := th.App.CreateTeam(&model.Team{
    18  		DisplayName: "Singers",
    19  		Name:        "zz" + model.NewId(),
    20  		Email:       "singers@test.com",
    21  		Type:        model.TEAM_OPEN,
    22  	})
    23  	if err != nil {
    24  		t.Errorf("test team not created: %s", err.Error())
    25  	}
    26  
    27  	nerdsTeam, err := th.App.CreateTeam(&model.Team{
    28  		DisplayName: "Nerds",
    29  		Name:        "zz" + model.NewId(),
    30  		Email:       "nerds@test.com",
    31  		Type:        model.TEAM_INVITE,
    32  	})
    33  	if err != nil {
    34  		t.Errorf("test team not created: %s", err.Error())
    35  	}
    36  
    37  	practiceChannel, err := th.App.CreateChannel(&model.Channel{
    38  		TeamId:      singersTeam.Id,
    39  		DisplayName: "Practices",
    40  		Name:        model.NewId(),
    41  		Type:        model.CHANNEL_OPEN,
    42  	}, false)
    43  	if err != nil {
    44  		t.Errorf("test channel not created: %s", err.Error())
    45  	}
    46  
    47  	experimentsChannel, err := th.App.CreateChannel(&model.Channel{
    48  		TeamId:      singersTeam.Id,
    49  		DisplayName: "Experiments",
    50  		Name:        model.NewId(),
    51  		Type:        model.CHANNEL_PRIVATE,
    52  	}, false)
    53  	if err != nil {
    54  		t.Errorf("test channel not created: %s", err.Error())
    55  	}
    56  
    57  	gleeGroup, err := th.App.CreateGroup(&model.Group{
    58  		Name:        model.NewString(model.NewId()),
    59  		DisplayName: "Glee Club",
    60  		RemoteId:    model.NewId(),
    61  		Source:      model.GroupSourceLdap,
    62  	})
    63  	if err != nil {
    64  		t.Errorf("test group not created: %s", err.Error())
    65  	}
    66  
    67  	scienceGroup, err := th.App.CreateGroup(&model.Group{
    68  		Name:        model.NewString(model.NewId()),
    69  		DisplayName: "Science Club",
    70  		RemoteId:    model.NewId(),
    71  		Source:      model.GroupSourceLdap,
    72  	})
    73  	if err != nil {
    74  		t.Errorf("test group not created: %s", err.Error())
    75  	}
    76  
    77  	_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(gleeGroup.Id, practiceChannel.Id, true))
    78  	if err != nil {
    79  		t.Errorf("test groupchannel not created: %s", err.Error())
    80  	}
    81  
    82  	scienceTeamGroupSyncable, err := th.App.UpsertGroupSyncable(model.NewGroupTeam(scienceGroup.Id, nerdsTeam.Id, false))
    83  	if err != nil {
    84  		t.Errorf("test groupteam not created: %s", err.Error())
    85  	}
    86  
    87  	scienceChannelGroupSyncable, err := th.App.UpsertGroupSyncable(model.NewGroupChannel(scienceGroup.Id, experimentsChannel.Id, false))
    88  	if err != nil {
    89  		t.Errorf("test groupchannel not created: %s", err.Error())
    90  	}
    91  
    92  	singer1 := th.BasicUser
    93  	scientist1 := th.BasicUser2
    94  
    95  	_, err = th.App.UpsertGroupMember(gleeGroup.Id, singer1.Id)
    96  	if err != nil {
    97  		t.Errorf("test groupmember not created: %s", err.Error())
    98  	}
    99  
   100  	scientistGroupMember, err := th.App.UpsertGroupMember(scienceGroup.Id, scientist1.Id)
   101  	if err != nil {
   102  		t.Errorf("test groupmember not created: %s", err.Error())
   103  	}
   104  
   105  	pErr := th.App.CreateDefaultMemberships(0)
   106  	if pErr != nil {
   107  		t.Errorf("faild to populate syncables: %s", pErr.Error())
   108  	}
   109  
   110  	// Singer should be in team and channel
   111  	_, err = th.App.GetTeamMember(singersTeam.Id, singer1.Id)
   112  	if err != nil {
   113  		t.Errorf("error retrieving team member: %s", err.Error())
   114  	}
   115  	_, err = th.App.GetChannelMember(practiceChannel.Id, singer1.Id)
   116  	if err != nil {
   117  		t.Errorf("error retrieving channel member: %s", err.Error())
   118  	}
   119  
   120  	tMembers, err := th.App.GetTeamMembers(singersTeam.Id, 0, 999, nil)
   121  	if err != nil {
   122  		t.Errorf("error retrieving team members: %s", err.Error())
   123  	}
   124  	expected := 1
   125  	actual := len(tMembers)
   126  	if actual != expected {
   127  		t.Errorf("expected %d team members but got %d", expected, actual)
   128  	}
   129  
   130  	cMembersCount, err := th.App.GetChannelMemberCount(practiceChannel.Id)
   131  	if err != nil {
   132  		t.Errorf("error retrieving team members: %s", err.Error())
   133  	}
   134  	if cMembersCount != int64(expected) {
   135  		t.Errorf("expected %d team member but got %d", expected, cMembersCount)
   136  	}
   137  
   138  	// Scientist should not be in team or channel
   139  	_, err = th.App.GetTeamMember(nerdsTeam.Id, scientist1.Id)
   140  	if err.Id != "app.team.get_member.missing.app_error" {
   141  		t.Errorf("wrong error: %s", err.Id)
   142  	}
   143  
   144  	_, err = th.App.GetChannelMember(experimentsChannel.Id, scientist1.Id)
   145  	if err.Id != "app.channel.get_member.missing.app_error" {
   146  		t.Errorf("wrong error: %s", err.Id)
   147  	}
   148  
   149  	tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
   150  	if err != nil {
   151  		t.Errorf("error retrieving team members: %s", err.Error())
   152  	}
   153  	expected = 0
   154  	actual = len(tMembers)
   155  	if actual != expected {
   156  		t.Errorf("expected %d team members but got %d", expected, actual)
   157  	}
   158  
   159  	cMembersCount, err = th.App.GetChannelMemberCount(experimentsChannel.Id)
   160  	if err != nil {
   161  		t.Errorf("error retrieving team members: %s", err.Error())
   162  	}
   163  	if cMembersCount != int64(expected) {
   164  		t.Errorf("expected %d team members but got %d", expected, cMembersCount)
   165  	}
   166  
   167  	// update AutoAdd to true
   168  	scienceTeamGroupSyncable.AutoAdd = true
   169  	scienceTeamGroupSyncable, err = th.App.UpdateGroupSyncable(scienceTeamGroupSyncable)
   170  	if err != nil {
   171  		t.Errorf("error updating group syncable: %s", err.Error())
   172  	}
   173  
   174  	// Sync everything after syncable was created (proving that team updates trigger re-sync)
   175  	pErr = th.App.CreateDefaultMemberships(scientistGroupMember.CreateAt + 1)
   176  	if pErr != nil {
   177  		t.Errorf("faild to populate syncables: %s", pErr.Error())
   178  	}
   179  
   180  	// Scientist should be in team but not the channel
   181  	_, err = th.App.GetTeamMember(nerdsTeam.Id, scientist1.Id)
   182  	if err != nil {
   183  		t.Errorf("error retrieving team member: %s", err.Error())
   184  	}
   185  
   186  	_, err = th.App.GetChannelMember(experimentsChannel.Id, scientist1.Id)
   187  	if err.Id != "app.channel.get_member.missing.app_error" {
   188  		t.Errorf("wrong error: %s", err.Id)
   189  	}
   190  
   191  	tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
   192  	if err != nil {
   193  		t.Errorf("error retrieving team members: %s", err.Error())
   194  	}
   195  	expected = 1
   196  	actual = len(tMembers)
   197  	if actual != expected {
   198  		t.Errorf("expected %d team members but got %d", expected, actual)
   199  	}
   200  
   201  	expected = 0
   202  	cMembersCount, err = th.App.GetChannelMemberCount(experimentsChannel.Id)
   203  	if err != nil {
   204  		t.Errorf("error retrieving team members: %s", err.Error())
   205  	}
   206  	if cMembersCount != int64(expected) {
   207  		t.Errorf("expected %d team members but got %d", expected, cMembersCount)
   208  	}
   209  
   210  	// Update the channel syncable
   211  	scienceChannelGroupSyncable.AutoAdd = true
   212  	scienceChannelGroupSyncable, err = th.App.UpdateGroupSyncable(scienceChannelGroupSyncable)
   213  	if err != nil {
   214  		t.Errorf("error updating group syncable: %s", err.Error())
   215  	}
   216  
   217  	// Sync everything after syncable was created (proving that channel updates trigger re-sync)
   218  	pErr = th.App.CreateDefaultMemberships(scientistGroupMember.CreateAt + 1)
   219  	if pErr != nil {
   220  		t.Errorf("faild to populate syncables: %s", pErr.Error())
   221  	}
   222  
   223  	expected = 1
   224  	cMembersCount, err = th.App.GetChannelMemberCount(experimentsChannel.Id)
   225  	if err != nil {
   226  		t.Errorf("error retrieving team members: %s", err.Error())
   227  	}
   228  	if cMembersCount != int64(expected) {
   229  		t.Errorf("expected %d team members but got %d", expected, cMembersCount)
   230  	}
   231  
   232  	// singer leaves team and channel
   233  	err = th.App.LeaveChannel(practiceChannel.Id, singer1.Id)
   234  	if err != nil {
   235  		t.Errorf("error leaving channel: %s", err.Error())
   236  	}
   237  	err = th.App.LeaveTeam(singersTeam, singer1, "")
   238  	if err != nil {
   239  		t.Errorf("error leaving team: %s", err.Error())
   240  	}
   241  
   242  	// Even re-syncing from the beginning doesn't re-add to channel or team
   243  	pErr = th.App.CreateDefaultMemberships(0)
   244  	if pErr != nil {
   245  		t.Errorf("faild to populate syncables: %s", pErr.Error())
   246  	}
   247  
   248  	// Singer should not be in team or channel
   249  	tMember, err := th.App.GetTeamMember(singersTeam.Id, singer1.Id)
   250  	if err != nil {
   251  		t.Errorf("error retrieving team member: %s", err.Error())
   252  	}
   253  	if tMember.DeleteAt == 0 {
   254  		t.Error("expected team member to remain deleted")
   255  	}
   256  
   257  	_, err = th.App.GetChannelMember(practiceChannel.Id, singer1.Id)
   258  	if err == nil {
   259  		t.Error("Expected channel member to remain deleted")
   260  	}
   261  
   262  	// Ensure members are in channel
   263  	_, err = th.App.AddChannelMember(scientist1.Id, experimentsChannel, "", "")
   264  	if err != nil {
   265  		t.Errorf("unable to add user to channel: %s", err.Error())
   266  	}
   267  
   268  	// Add other user so that user can leave channel
   269  	_, err = th.App.AddTeamMember(singersTeam.Id, singer1.Id)
   270  	if err != nil {
   271  		t.Errorf("unable to add user to team: %s", err.Error())
   272  	}
   273  	_, err = th.App.AddChannelMember(singer1.Id, experimentsChannel, "", "")
   274  	if err != nil {
   275  		t.Errorf("unable to add user to channel: %s", err.Error())
   276  	}
   277  
   278  	// the channel syncable is updated
   279  	scienceChannelGroupSyncable, err = th.App.UpdateGroupSyncable(scienceChannelGroupSyncable)
   280  	if err != nil {
   281  		t.Errorf("error updating group syncable: %s", err.Error())
   282  	}
   283  
   284  	pErr = th.App.CreateDefaultMemberships(0)
   285  	if pErr != nil {
   286  		t.Errorf("faild to populate syncables: %s", pErr.Error())
   287  	}
   288  
   289  	timeBeforeLeaving := model.GetMillis()
   290  
   291  	// User leaves channel
   292  	err = th.App.LeaveChannel(experimentsChannel.Id, scientist1.Id)
   293  	if err != nil {
   294  		t.Errorf("unable to add user to channel: %s", err.Error())
   295  	}
   296  
   297  	timeAfterLeaving := model.GetMillis()
   298  
   299  	// Purging channelmemberhistory doesn't re-add user to channel
   300  	_, nErr := th.App.Srv().Store.ChannelMemberHistory().PermanentDeleteBatch(timeBeforeLeaving, 1000)
   301  	if nErr != nil {
   302  		t.Errorf("error permanently deleting channelmemberhistory: %s", nErr.Error())
   303  	}
   304  
   305  	pErr = th.App.CreateDefaultMemberships(scienceChannelGroupSyncable.UpdateAt)
   306  	if pErr != nil {
   307  		t.Errorf("failed to populate syncables: %s", pErr.Error())
   308  	}
   309  
   310  	_, err = th.App.GetChannelMember(experimentsChannel.Id, scientist1.Id)
   311  	if err == nil {
   312  		t.Error("Expected channel member to remain deleted")
   313  	}
   314  
   315  	// Purging channelmemberhistory doesn't re-add user to channel
   316  	_, nErr = th.App.Srv().Jobs.Store.ChannelMemberHistory().PermanentDeleteBatch(timeAfterLeaving, 1000)
   317  	if nErr != nil {
   318  		t.Errorf("error permanently deleting channelmemberhistory: %s", nErr.Error())
   319  	}
   320  
   321  	pErr = th.App.CreateDefaultMemberships(scienceChannelGroupSyncable.UpdateAt)
   322  	if pErr != nil {
   323  		t.Errorf("failed to populate syncables: %s", pErr.Error())
   324  	}
   325  
   326  	// Channel member is re-added.
   327  	_, err = th.App.GetChannelMember(experimentsChannel.Id, scientist1.Id)
   328  	if err != nil {
   329  		t.Errorf("expected channel member: %s", err.Error())
   330  	}
   331  
   332  	t.Run("Team with restricted domains skips over members that do not match the allowed domains", func(t *testing.T) {
   333  		restrictedUser := th.CreateUser()
   334  		restrictedUser.Email = "restricted@mattermost.org"
   335  		_, err = th.App.UpdateUser(restrictedUser, false)
   336  		require.Nil(t, err)
   337  		_, err = th.App.UpsertGroupMember(scienceGroup.Id, restrictedUser.Id)
   338  		require.Nil(t, err)
   339  
   340  		restrictedTeam, err := th.App.CreateTeam(&model.Team{
   341  			DisplayName:    "Restricted",
   342  			Name:           "restricted" + model.NewId(),
   343  			Email:          "restricted@mattermost.org",
   344  			AllowedDomains: "mattermost.org",
   345  			Type:           model.TEAM_OPEN,
   346  		})
   347  		require.Nil(t, err)
   348  		_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(scienceGroup.Id, restrictedTeam.Id, true))
   349  		require.Nil(t, err)
   350  
   351  		restrictedChannel, err := th.App.CreateChannel(&model.Channel{
   352  			TeamId:      restrictedTeam.Id,
   353  			DisplayName: "Restricted",
   354  			Name:        "restricted" + model.NewId(),
   355  			Type:        model.CHANNEL_OPEN,
   356  		}, false)
   357  		require.Nil(t, err)
   358  		_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(scienceGroup.Id, restrictedChannel.Id, true))
   359  		require.Nil(t, err)
   360  
   361  		pErr = th.App.CreateDefaultMemberships(0)
   362  		require.Nil(t, pErr)
   363  
   364  		// Ensure only the restricted user was added to both the team and channel
   365  		cMembersCount, err = th.App.GetChannelMemberCount(restrictedChannel.Id)
   366  		require.Nil(t, err)
   367  		require.Equal(t, cMembersCount, int64(1))
   368  		tmembers, err := th.App.GetTeamMembers(restrictedTeam.Id, 0, 100, nil)
   369  		require.Nil(t, err)
   370  		require.Len(t, tmembers, 1)
   371  		require.Equal(t, tmembers[0].UserId, restrictedUser.Id)
   372  	})
   373  }
   374  
   375  func TestDeleteGroupMemberships(t *testing.T) {
   376  	th := Setup(t).InitBasic()
   377  	defer th.TearDown()
   378  
   379  	group := th.CreateGroup()
   380  
   381  	userIDs := []string{th.BasicUser.Id, th.BasicUser2.Id, th.SystemAdminUser.Id}
   382  
   383  	var err *model.AppError
   384  	// add users to teams and channels
   385  	for _, userID := range userIDs {
   386  		_, err = th.App.AddTeamMember(th.BasicTeam.Id, userID)
   387  		require.Nil(t, err)
   388  
   389  		_, err = th.App.AddChannelMember(userID, th.BasicChannel, "", "")
   390  		require.Nil(t, err)
   391  	}
   392  
   393  	// make team group-constrained
   394  	team := th.BasicTeam
   395  	team.GroupConstrained = model.NewBool(true)
   396  	team, err = th.App.UpdateTeam(team)
   397  	require.Nil(t, err)
   398  	require.True(t, *team.GroupConstrained)
   399  
   400  	// make channel group-constrained
   401  	channel := th.BasicChannel
   402  	channel.GroupConstrained = model.NewBool(true)
   403  	channel, err = th.App.UpdateChannel(channel)
   404  	require.Nil(t, err)
   405  	require.True(t, *channel.GroupConstrained)
   406  
   407  	// create groupteam and groupchannel
   408  	_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(group.Id, team.Id, true))
   409  	require.Nil(t, err)
   410  	_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group.Id, channel.Id, true))
   411  	require.Nil(t, err)
   412  
   413  	// verify the member count
   414  	tmembers, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
   415  	require.Nil(t, err)
   416  	require.Len(t, tmembers, 3)
   417  
   418  	cmemberCount, err := th.App.GetChannelMemberCount(th.BasicChannel.Id)
   419  	require.Nil(t, err)
   420  	require.Equal(t, 3, int(cmemberCount))
   421  
   422  	// add a user to the group
   423  	_, err = th.App.UpsertGroupMember(group.Id, th.SystemAdminUser.Id)
   424  	require.Nil(t, err)
   425  
   426  	// run the delete
   427  	appErr := th.App.DeleteGroupConstrainedMemberships()
   428  	require.Nil(t, appErr)
   429  
   430  	// verify the new member counts
   431  	tmembers, err = th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
   432  	require.Nil(t, err)
   433  	require.Len(t, tmembers, 1)
   434  	require.Equal(t, th.SystemAdminUser.Id, tmembers[0].UserId)
   435  
   436  	cmembers, err := th.App.GetChannelMembersPage(channel.Id, 0, 99)
   437  	require.Nil(t, err)
   438  	require.Len(t, (*cmembers), 1)
   439  	require.Equal(t, th.SystemAdminUser.Id, (*cmembers)[0].UserId)
   440  }
   441  
   442  func TestSyncSyncableRoles(t *testing.T) {
   443  	th := Setup(t).InitBasic()
   444  	defer th.TearDown()
   445  
   446  	team := th.CreateTeam()
   447  
   448  	channel := th.CreateChannel(team)
   449  	channel.GroupConstrained = model.NewBool(true)
   450  	channel, err := th.App.UpdateChannel(channel)
   451  	require.Nil(t, err)
   452  
   453  	user1 := th.CreateUser()
   454  	user2 := th.CreateUser()
   455  	group := th.CreateGroup()
   456  
   457  	teamSyncable, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
   458  		SyncableId: team.Id,
   459  		Type:       model.GroupSyncableTypeTeam,
   460  		GroupId:    group.Id,
   461  	})
   462  	require.Nil(t, err)
   463  
   464  	channelSyncable, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
   465  		SyncableId: channel.Id,
   466  		Type:       model.GroupSyncableTypeChannel,
   467  		GroupId:    group.Id,
   468  	})
   469  	require.Nil(t, err)
   470  
   471  	for _, user := range []*model.User{user1, user2} {
   472  		_, err = th.App.UpsertGroupMember(group.Id, user.Id)
   473  		require.Nil(t, err)
   474  
   475  		var tm *model.TeamMember
   476  		tm, err = th.App.AddTeamMember(team.Id, user.Id)
   477  		require.Nil(t, err)
   478  		require.False(t, tm.SchemeAdmin)
   479  
   480  		cm := th.AddUserToChannel(user, channel)
   481  		require.False(t, cm.SchemeAdmin)
   482  	}
   483  
   484  	teamSyncable.SchemeAdmin = true
   485  	_, err = th.App.UpdateGroupSyncable(teamSyncable)
   486  	require.Nil(t, err)
   487  
   488  	channelSyncable.SchemeAdmin = true
   489  	_, err = th.App.UpdateGroupSyncable(channelSyncable)
   490  	require.Nil(t, err)
   491  
   492  	err = th.App.SyncSyncableRoles(channel.Id, model.GroupSyncableTypeChannel)
   493  	require.Nil(t, err)
   494  
   495  	err = th.App.SyncSyncableRoles(team.Id, model.GroupSyncableTypeTeam)
   496  	require.Nil(t, err)
   497  
   498  	for _, user := range []*model.User{user1, user2} {
   499  		tm, err := th.App.GetTeamMember(team.Id, user.Id)
   500  		require.Nil(t, err)
   501  		require.True(t, tm.SchemeAdmin)
   502  
   503  		cm, err := th.App.GetChannelMember(channel.Id, user.Id)
   504  		require.Nil(t, err)
   505  		require.True(t, cm.SchemeAdmin)
   506  	}
   507  }