diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs
index 9bad7b6dcc..5bc642fdcb 100644
--- a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs
+++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs
@@ -28,13 +28,15 @@ public class RequireTwoFactorPolicyRequirement : IPolicyRequirement
_policyDetails.Any(p => p.OrganizationId == organizationId);
///
- /// Gets the active two-factor authentication policies for active memberships.
+ /// Returns tuples of (OrganizationId, OrganizationUserId) for active memberships where two-factor authentication is required.
+ /// Users should be revoked from these organizations if they disable all 2FA methods.
///
- /// The active two-factor authentication policies for active memberships.
- public IEnumerable TwoFactorPoliciesForActiveMemberships =>
- _policyDetails.Where(p => p.OrganizationUserStatus is
+ public IEnumerable<(Guid OrganizationId, Guid OrganizationUserId)> OrganizationsRequiringTwoFactor =>
+ _policyDetails
+ .Where(p => p.OrganizationUserStatus is
OrganizationUserStatusType.Accepted or
- OrganizationUserStatusType.Confirmed);
+ OrganizationUserStatusType.Confirmed)
+ .Select(p => (p.OrganizationId, p.OrganizationUserId));
}
public class RequireTwoFactorPolicyRequirementFactory : BasePolicyRequirementFactory
diff --git a/src/Core/Services/Implementations/UserService.cs b/src/Core/Services/Implementations/UserService.cs
index b1e7159b7c..59a758ac64 100644
--- a/src/Core/Services/Implementations/UserService.cs
+++ b/src/Core/Services/Implementations/UserService.cs
@@ -1403,13 +1403,13 @@ public class UserService : UserManager, IUserService, IDisposable
{
var requirement = await _policyRequirementQuery.GetAsync(user.Id);
- var removeOrgUserTasks = requirement.TwoFactorPoliciesForActiveMemberships.Select(async p =>
+ var removeOrgUserTasks = requirement.OrganizationsRequiringTwoFactor.Select(async o =>
{
- var organization = await _organizationRepository.GetByIdAsync(p.OrganizationId);
+ var organization = await _organizationRepository.GetByIdAsync(o.OrganizationId);
await _revokeNonCompliantOrganizationUserCommand.RevokeNonCompliantOrganizationUsersAsync(
new RevokeOrganizationUsersRequest(
- p.OrganizationId,
- [new OrganizationUserUserDetails { Id = p.OrganizationUserId, OrganizationId = p.OrganizationId }],
+ o.OrganizationId,
+ [new OrganizationUserUserDetails { Id = o.OrganizationUserId, OrganizationId = o.OrganizationId }],
new SystemUser(EventSystemUser.TwoFactorDisabled)));
await _mailService.SendOrganizationUserRevokedForTwoFactorPolicyEmailAsync(organization.DisplayName(), user.Email);
}).ToArray();
diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs
index e03d1a564c..c20ea494ab 100644
--- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs
+++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs
@@ -59,17 +59,18 @@ public class RequireTwoFactorPolicyRequirementFactoryTests
}
[Theory, BitAutoData]
- public void TwoFactorPoliciesForActiveMemberships_WithNoPolicies_ReturnsEmptyCollection(
+ public void OrganizationsRequiringTwoFactor_WithNoPolicies_ReturnsEmptyCollection(
SutProvider sutProvider)
{
var actual = sutProvider.Sut.Create([]);
- Assert.Empty(actual.TwoFactorPoliciesForActiveMemberships);
+ Assert.Empty(actual.OrganizationsRequiringTwoFactor);
}
[Theory, BitAutoData]
- public void TwoFactorPoliciesForActiveMemberships_WithMultiplePolicies_ReturnsActiveMemberships(
- Guid orgId1, Guid orgId2, Guid orgId3, Guid orgId4,
+ public void OrganizationsRequiringTwoFactor_WithMultiplePolicies_ReturnsActiveMemberships(
+ Guid orgId1, Guid orgUserId1, Guid orgId2, Guid orgUserId2,
+ Guid orgId3, Guid orgUserId3, Guid orgId4, Guid orgUserId4,
SutProvider sutProvider)
{
var policies = new[]
@@ -77,24 +78,28 @@ public class RequireTwoFactorPolicyRequirementFactoryTests
new PolicyDetails
{
OrganizationId = orgId1,
+ OrganizationUserId = orgUserId1,
PolicyType = PolicyType.TwoFactorAuthentication,
OrganizationUserStatus = OrganizationUserStatusType.Accepted
},
new PolicyDetails
{
OrganizationId = orgId2,
+ OrganizationUserId = orgUserId2,
PolicyType = PolicyType.TwoFactorAuthentication,
OrganizationUserStatus = OrganizationUserStatusType.Confirmed
},
new PolicyDetails
{
OrganizationId = orgId3,
+ OrganizationUserId = orgUserId3,
PolicyType = PolicyType.TwoFactorAuthentication,
OrganizationUserStatus = OrganizationUserStatusType.Invited
},
new PolicyDetails
{
OrganizationId = orgId4,
+ OrganizationUserId = orgUserId4,
PolicyType = PolicyType.TwoFactorAuthentication,
OrganizationUserStatus = OrganizationUserStatusType.Revoked
}
@@ -102,11 +107,11 @@ public class RequireTwoFactorPolicyRequirementFactoryTests
var actual = sutProvider.Sut.Create(policies);
- var result = actual.TwoFactorPoliciesForActiveMemberships.ToList();
+ var result = actual.OrganizationsRequiringTwoFactor.ToList();
Assert.Equal(2, result.Count);
- Assert.Contains(result, p => p.OrganizationId == orgId1);
- Assert.Contains(result, p => p.OrganizationId == orgId2);
- Assert.DoesNotContain(result, p => p.OrganizationId == orgId3);
- Assert.DoesNotContain(result, p => p.OrganizationId == orgId4);
+ Assert.Contains(result, p => p.OrganizationId == orgId1 && p.OrganizationUserId == orgUserId1);
+ Assert.Contains(result, p => p.OrganizationId == orgId2 && p.OrganizationUserId == orgUserId2);
+ Assert.DoesNotContain(result, p => p.OrganizationId == orgId3 && p.OrganizationUserId == orgUserId3);
+ Assert.DoesNotContain(result, p => p.OrganizationId == orgId4 && p.OrganizationUserId == orgUserId4);
}
}