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