diff --git a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs index 08fbb72429..759e774b03 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirement.cs @@ -42,12 +42,28 @@ public class RequireTwoFactorPolicyRequirement : IPolicyRequirement (p.OrganizationUserStatus is OrganizationUserStatusType.Accepted or OrganizationUserStatusType.Confirmed)); + + + /// + /// Determines if the user can be restored in an organization. + /// + /// Whether the user has two-step login enabled. + /// The ID of the organization. + /// True if the user can be restored, false otherwise. + public bool CanBeRestored(bool twoFactorEnabled, Guid organizationId) => + twoFactorEnabled || + !_policyDetails.Any(p => p.OrganizationId == organizationId && + (p.OrganizationUserStatus is + OrganizationUserStatusType.Revoked or + OrganizationUserStatusType.Invited or + OrganizationUserStatusType.Accepted or + OrganizationUserStatusType.Confirmed)); } public class RequireTwoFactorPolicyRequirementFactory : BasePolicyRequirementFactory { public override PolicyType PolicyType => PolicyType.TwoFactorAuthentication; - protected override IEnumerable ExemptStatuses => [OrganizationUserStatusType.Revoked]; + protected override IEnumerable ExemptStatuses => []; public override RequireTwoFactorPolicyRequirement Create(IEnumerable policyDetails) { diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs index dd8922ba15..5d613cd7ac 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/Policies/PolicyRequirements/RequireTwoFactorPolicyRequirementFactoryTests.cs @@ -155,4 +155,60 @@ public class RequireTwoFactorPolicyRequirementFactoryTests Assert.False(actual.CanBeConfirmed(false, organizationId)); } + + [Theory] + [BitAutoData(true)] + [BitAutoData(false)] + public void CanBeRestored_WithNoPolicies_ReturnsTrue( + bool twoFactorEnabled, Guid organizationId, + SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create([]); + + Assert.True(actual.CanBeRestored(twoFactorEnabled, organizationId)); + } + + [Theory] + [BitAutoData(OrganizationUserStatusType.Revoked)] + [BitAutoData(OrganizationUserStatusType.Invited)] + [BitAutoData(OrganizationUserStatusType.Accepted)] + [BitAutoData(OrganizationUserStatusType.Confirmed)] + public void CanBeRestored_WithTwoFactorEnabled_ReturnsTrue( + OrganizationUserStatusType userStatus, Guid organizationId, + SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create( + [ + new PolicyDetails + { + OrganizationId = organizationId, + PolicyType = PolicyType.TwoFactorAuthentication, + OrganizationUserStatus = userStatus + } + ]); + + Assert.True(actual.CanBeRestored(true, organizationId)); + } + + [Theory] + [BitAutoData(OrganizationUserStatusType.Revoked)] + [BitAutoData(OrganizationUserStatusType.Invited)] + [BitAutoData(OrganizationUserStatusType.Accepted)] + [BitAutoData(OrganizationUserStatusType.Confirmed)] + public void CanBeRestored_WithAnyStatus_ReturnsFalse( + OrganizationUserStatusType userStatus, Guid organizationId, + SutProvider sutProvider) + { + var actual = sutProvider.Sut.Create( + [ + new PolicyDetails + { + OrganizationId = organizationId, + PolicyType = PolicyType.TwoFactorAuthentication, + OrganizationUserStatus = userStatus + } + ]); + + Assert.False(actual.CanBeRestored(false, organizationId)); + } }