diff --git a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs index 70a3227a71..6194aea6c7 100644 --- a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs +++ b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs @@ -1951,6 +1951,11 @@ public class OrganizationService : IOrganizationService await RepositoryRevokeUserAsync(organizationUser); await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked); + + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } } public async Task RevokeUserAsync(OrganizationUser organizationUser, @@ -1958,6 +1963,11 @@ public class OrganizationService : IOrganizationService { await RepositoryRevokeUserAsync(organizationUser); await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked, systemUser); + + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } } private async Task RepositoryRevokeUserAsync(OrganizationUser organizationUser) @@ -2023,6 +2033,10 @@ public class OrganizationService : IOrganizationService await _organizationUserRepository.RevokeAsync(organizationUser.Id); organizationUser.Status = OrganizationUserStatusType.Revoked; await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked); + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } result.Add(Tuple.Create(organizationUser, "")); } @@ -2050,12 +2064,22 @@ public class OrganizationService : IOrganizationService await RepositoryRestoreUserAsync(organizationUser); await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); + + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } } public async Task RestoreUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser) { await RepositoryRestoreUserAsync(organizationUser); await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, systemUser); + + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } } private async Task RepositoryRestoreUserAsync(OrganizationUser organizationUser) @@ -2147,6 +2171,10 @@ public class OrganizationService : IOrganizationService await _organizationUserRepository.RestoreAsync(organizationUser.Id, status); organizationUser.Status = status; await _eventService.LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); + if (_featureService.IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) && organizationUser.UserId.HasValue) + { + await _pushNotificationService.PushSyncOrgKeysAsync(organizationUser.UserId.Value); + } result.Add(Tuple.Create(organizationUser, "")); } diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index ba3b8b0795..3e59a9390b 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -108,6 +108,7 @@ public static class FeatureFlagKeys public const string IntegrationPage = "pm-14505-admin-console-integration-page"; public const string DeviceApprovalRequestAdminNotifications = "pm-15637-device-approval-request-admin-notifications"; public const string LimitItemDeletion = "pm-15493-restrict-item-deletion-to-can-manage-permission"; + public const string PushSyncOrgKeysOnRevokeRestore = "pm-17168-push-sync-org-keys-on-revoke-restore"; /* Tools Team */ public const string ItemShare = "item-share"; diff --git a/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs b/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs index cd680f2ef0..f4440a65a3 100644 --- a/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs +++ b/test/Core.Test/AdminConsole/Services/OrganizationServiceTests.cs @@ -19,6 +19,7 @@ using Bit.Core.Models.Data; using Bit.Core.Models.Data.Organizations.OrganizationUsers; using Bit.Core.Models.Mail; using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface; +using Bit.Core.Platform.Push; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; @@ -1450,76 +1451,174 @@ OrganizationUserInvite invite, SutProvider sutProvider) [OrganizationUser] OrganizationUser organizationUser, SutProvider sutProvider) { RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); await sutProvider.Sut.RevokeUserAsync(organizationUser, owner.Id); - await organizationUserRepository.Received().RevokeAsync(organizationUser.Id); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RevokeAsync(organizationUser.Id); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked); } + [Theory, BitAutoData] + public async Task RevokeUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner, + [OrganizationUser] OrganizationUser organizationUser, SutProvider sutProvider) + { + RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) + .Returns(true); + + await sutProvider.Sut.RevokeUserAsync(organizationUser, owner.Id); + + await sutProvider.GetDependency() + .Received(1) + .RevokeAsync(organizationUser.Id); + await sutProvider.GetDependency() + .Received(1) + .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked); + await sutProvider.GetDependency() + .Received(1) + .PushSyncOrgKeysAsync(organizationUser.UserId!.Value); + } + [Theory, BitAutoData] public async Task RevokeUser_WithEventSystemUser_Success(Organization organization, [OrganizationUser] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider sutProvider) { RestoreRevokeUser_Setup(organization, null, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); await sutProvider.Sut.RevokeUserAsync(organizationUser, eventSystemUser); - await organizationUserRepository.Received().RevokeAsync(organizationUser.Id); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RevokeAsync(organizationUser.Id); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked, eventSystemUser); } + [Theory, BitAutoData] + public async Task RevokeUser_WithEventSystemUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider sutProvider) + { + RestoreRevokeUser_Setup(organization, null, organizationUser, sutProvider); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) + .Returns(true); + + await sutProvider.Sut.RevokeUserAsync(organizationUser, eventSystemUser); + + await sutProvider.GetDependency() + .Received(1) + .RevokeAsync(organizationUser.Id); + await sutProvider.GetDependency() + .Received(1) + .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Revoked, eventSystemUser); + await sutProvider.GetDependency() + .Received(1) + .PushSyncOrgKeysAsync(organizationUser.UserId!.Value); + } + [Theory, BitAutoData] public async Task RestoreUser_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner, [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider sutProvider) { RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id); - await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); } + [Theory, BitAutoData] + public async Task RestoreUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner, + [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider sutProvider) + { + RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) + .Returns(true); + + await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id); + + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); + await sutProvider.GetDependency() + .Received(1) + .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); + await sutProvider.GetDependency() + .Received(1) + .PushSyncOrgKeysAsync(organizationUser.UserId!.Value); + } + [Theory, BitAutoData] public async Task RestoreUser_WithEventSystemUser_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider sutProvider) { RestoreRevokeUser_Setup(organization, null, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser); - await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, eventSystemUser); } + [Theory, BitAutoData] + public async Task RestoreUser_WithEventSystemUser_WithPushSyncOrgKeysOnRevokeRestoreEnabled_Success(Organization organization, [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, EventSystemUser eventSystemUser, SutProvider sutProvider) + { + RestoreRevokeUser_Setup(organization, null, organizationUser, sutProvider); + + sutProvider.GetDependency() + .IsEnabled(FeatureFlagKeys.PushSyncOrgKeysOnRevokeRestore) + .Returns(true); + + await sutProvider.Sut.RestoreUserAsync(organizationUser, eventSystemUser); + + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Invited); + await sutProvider.GetDependency() + .Received(1) + .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored, eventSystemUser); + await sutProvider.GetDependency() + .Received(1) + .PushSyncOrgKeysAsync(organizationUser.UserId!.Value); + } + [Theory, BitAutoData] public async Task RestoreUser_RestoreThemselves_Fails(Organization organization, [OrganizationUser(OrganizationUserStatusType.Confirmed, OrganizationUserType.Owner)] OrganizationUser owner, [OrganizationUser(OrganizationUserStatusType.Revoked)] OrganizationUser organizationUser, SutProvider sutProvider) { organizationUser.UserId = owner.Id; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); var exception = await Assert.ThrowsAsync( () => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id)); Assert.Contains("you cannot restore yourself", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory] @@ -1531,17 +1630,21 @@ OrganizationUserInvite invite, SutProvider sutProvider) { restoringUser.Type = restoringUserType; RestoreRevokeUser_Setup(organization, restoringUser, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); var exception = await Assert.ThrowsAsync( () => sutProvider.Sut.RestoreUserAsync(organizationUser, restoringUser.Id)); Assert.Contains("only owners can restore other owners", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory] @@ -1553,17 +1656,21 @@ OrganizationUserInvite invite, SutProvider sutProvider) { organizationUser.Status = userStatus; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); var exception = await Assert.ThrowsAsync( () => sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id)); Assert.Contains("already active", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1575,8 +1682,6 @@ OrganizationUserInvite invite, SutProvider sutProvider) { organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); sutProvider.GetDependency() .AnyPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.SingleOrg, Arg.Any()) @@ -1591,9 +1696,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com belongs to an organization that doesn't allow them to join multiple organizations", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1610,8 +1721,6 @@ OrganizationUserInvite invite, SutProvider sutProvider) .Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, false) }); RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any()) @@ -1626,9 +1735,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com is not compliant with the two-step login policy", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1640,8 +1755,6 @@ OrganizationUserInvite invite, SutProvider sutProvider) { organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any()) @@ -1652,8 +1765,11 @@ OrganizationUserInvite invite, SutProvider sutProvider) await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id); - await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); } @@ -1668,10 +1784,10 @@ OrganizationUserInvite invite, SutProvider sutProvider) organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke secondOrganizationUser.UserId = organizationUser.UserId; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); - organizationUserRepository.GetManyByUserAsync(organizationUser.UserId.Value).Returns(new[] { organizationUser, secondOrganizationUser }); + sutProvider.GetDependency() + .GetManyByUserAsync(organizationUser.UserId.Value) + .Returns(new[] { organizationUser, secondOrganizationUser }); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.SingleOrg, Arg.Any()) .Returns(new[] @@ -1688,9 +1804,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com is not compliant with the single organization policy", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1704,11 +1826,8 @@ OrganizationUserInvite invite, SutProvider sutProvider) organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke secondOrganizationUser.UserId = organizationUser.UserId; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); - var twoFactorIsEnabledQuery = sutProvider.GetDependency(); - twoFactorIsEnabledQuery + sutProvider.GetDependency() .TwoFactorIsEnabledAsync(Arg.Is>(i => i.Contains(organizationUser.UserId.Value))) .Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, true) }); @@ -1725,9 +1844,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com belongs to an organization that doesn't allow them to join multiple organizations", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1741,10 +1866,10 @@ OrganizationUserInvite invite, SutProvider sutProvider) organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke secondOrganizationUser.UserId = organizationUser.UserId; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); - organizationUserRepository.GetManyByUserAsync(organizationUser.UserId.Value).Returns(new[] { organizationUser, secondOrganizationUser }); + sutProvider.GetDependency() + .GetManyByUserAsync(organizationUser.UserId.Value) + .Returns(new[] { organizationUser, secondOrganizationUser }); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.SingleOrg, Arg.Any()) .Returns(new[] @@ -1768,9 +1893,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com is not compliant with the single organization and two-step login polciy", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1783,8 +1914,6 @@ OrganizationUserInvite invite, SutProvider sutProvider) organizationUser.Email = null; RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any()) @@ -1799,9 +1928,15 @@ OrganizationUserInvite invite, SutProvider sutProvider) Assert.Contains("test@bitwarden.com is not compliant with the two-step login policy", exception.Message.ToLowerInvariant()); - await organizationUserRepository.DidNotReceiveWithAnyArgs().RestoreAsync(Arg.Any(), Arg.Any()); - await eventService.DidNotReceiveWithAnyArgs() + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .RestoreAsync(Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() .LogOrganizationUserEventAsync(Arg.Any(), Arg.Any(), Arg.Any()); + await sutProvider.GetDependency() + .DidNotReceiveWithAnyArgs() + .PushSyncOrgKeysAsync(Arg.Any()); } [Theory, BitAutoData] @@ -1813,22 +1948,22 @@ OrganizationUserInvite invite, SutProvider sutProvider) { organizationUser.Email = null; // this is required to mock that the user as had already been confirmed before the revoke RestoreRevokeUser_Setup(organization, owner, organizationUser, sutProvider); - var organizationUserRepository = sutProvider.GetDependency(); - var eventService = sutProvider.GetDependency(); - var twoFactorIsEnabledQuery = sutProvider.GetDependency(); sutProvider.GetDependency() .GetPoliciesApplicableToUserAsync(organizationUser.UserId.Value, PolicyType.TwoFactorAuthentication, Arg.Any()) .Returns(new[] { new OrganizationUserPolicyDetails { OrganizationId = organizationUser.OrganizationId, PolicyType = PolicyType.TwoFactorAuthentication } }); - twoFactorIsEnabledQuery + sutProvider.GetDependency() .TwoFactorIsEnabledAsync(Arg.Is>(i => i.Contains(organizationUser.UserId.Value))) .Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (organizationUser.UserId.Value, true) }); await sutProvider.Sut.RestoreUserAsync(organizationUser, owner.Id); - await organizationUserRepository.Received().RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed); - await eventService.Received() + await sutProvider.GetDependency() + .Received(1) + .RestoreAsync(organizationUser.Id, OrganizationUserStatusType.Confirmed); + await sutProvider.GetDependency() + .Received(1) .LogOrganizationUserEventAsync(organizationUser, EventType.OrganizationUser_Restored); }