mirror of
https://github.com/bitwarden/server.git
synced 2025-05-23 04:21:05 -05:00
Enhance ConfirmOrganizationUserCommand to validate two-factor authentication policy based on feature flag; refactor validation logic and update related tests for improved policy handling.
This commit is contained in:
parent
02cbdd64a4
commit
ec81ed786a
@ -152,7 +152,19 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
ICollection<OrganizationUser> userOrgs, bool userTwoFactorEnabled)
|
ICollection<OrganizationUser> userOrgs, bool userTwoFactorEnabled)
|
||||||
{
|
{
|
||||||
// Enforce Two Factor Authentication Policy for this organization
|
// Enforce Two Factor Authentication Policy for this organization
|
||||||
await CheckTwoFactorPolicyAsync(organizationId, user, userTwoFactorEnabled);
|
if (_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements))
|
||||||
|
{
|
||||||
|
await ValidateTwoFactorAuthenticationPolicyAsync(user, organizationId, userTwoFactorEnabled);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var orgRequiresTwoFactor = (await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication))
|
||||||
|
.Any(p => p.OrganizationId == organizationId);
|
||||||
|
if (orgRequiresTwoFactor && !userTwoFactorEnabled)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("User does not have two-step login enabled.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var hasOtherOrgs = userOrgs.Any(ou => ou.OrganizationId != organizationId);
|
var hasOtherOrgs = userOrgs.Any(ou => ou.OrganizationId != organizationId);
|
||||||
var singleOrgPolicies = await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg);
|
var singleOrgPolicies = await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg);
|
||||||
@ -170,27 +182,25 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckTwoFactorPolicyAsync(Guid organizationId, User user, bool userTwoFactorEnabled)
|
/// <summary>
|
||||||
|
/// Validates the two-factor authentication policy for the organization user.
|
||||||
|
/// If the user has two-step login enabled, the policy is not enforced.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">The user to validate the policy for.</param>
|
||||||
|
/// <param name="organizationId">The ID of the organization to validate the policy for.</param>
|
||||||
|
/// <param name="userTwoFactorEnabled">Whether the user has two-step login enabled.</param>
|
||||||
|
private async Task ValidateTwoFactorAuthenticationPolicyAsync(User user, Guid organizationId, bool userTwoFactorEnabled)
|
||||||
{
|
{
|
||||||
if (userTwoFactorEnabled)
|
if (userTwoFactorEnabled)
|
||||||
{
|
{
|
||||||
|
// If the user has two-step login enabled, the policy is not enforced.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool requireTwoFactor;
|
var requirement = await _policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id);
|
||||||
|
var canBeConfirmed = requirement.CanBeConfirmed(userTwoFactorEnabled, organizationId);
|
||||||
|
|
||||||
if (_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements))
|
if (!canBeConfirmed)
|
||||||
{
|
|
||||||
var requirement = await _policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id);
|
|
||||||
requireTwoFactor = requirement.RequireTwoFactor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
requireTwoFactor = (await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.TwoFactorAuthentication))
|
|
||||||
.Any(p => p.OrganizationId == organizationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requireTwoFactor)
|
|
||||||
{
|
{
|
||||||
throw new BadRequestException("User does not have two-step login enabled.");
|
throw new BadRequestException("User does not have two-step login enabled.");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
@ -344,7 +345,15 @@ public class ConfirmOrganizationUserCommandTests
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||||
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
||||||
.Returns(new RequireTwoFactorPolicyRequirement { RequireTwoFactor = true });
|
.Returns(new RequireTwoFactorPolicyRequirement(
|
||||||
|
[
|
||||||
|
new PolicyDetails
|
||||||
|
{
|
||||||
|
OrganizationId = org.Id,
|
||||||
|
OrganizationUserStatus = OrganizationUserStatusType.Accepted,
|
||||||
|
PolicyType = PolicyType.TwoFactorAuthentication
|
||||||
|
}
|
||||||
|
]));
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
||||||
|
|
||||||
@ -374,7 +383,15 @@ public class ConfirmOrganizationUserCommandTests
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||||
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
||||||
.Returns(new RequireTwoFactorPolicyRequirement { RequireTwoFactor = false });
|
.Returns(new RequireTwoFactorPolicyRequirement(
|
||||||
|
[
|
||||||
|
new PolicyDetails
|
||||||
|
{
|
||||||
|
OrganizationId = Guid.NewGuid(),
|
||||||
|
OrganizationUserStatus = OrganizationUserStatusType.Invited,
|
||||||
|
PolicyType = PolicyType.TwoFactorAuthentication,
|
||||||
|
}
|
||||||
|
]));
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, false) });
|
||||||
|
|
||||||
@ -406,7 +423,15 @@ public class ConfirmOrganizationUserCommandTests
|
|||||||
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
userRepository.GetManyAsync(default).ReturnsForAnyArgs(new[] { user });
|
||||||
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||||
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
policyRequirementQuery.GetAsync<RequireTwoFactorPolicyRequirement>(user.Id)
|
||||||
.Returns(new RequireTwoFactorPolicyRequirement { RequireTwoFactor = true });
|
.Returns(new RequireTwoFactorPolicyRequirement(
|
||||||
|
[
|
||||||
|
new PolicyDetails
|
||||||
|
{
|
||||||
|
OrganizationId = org.Id,
|
||||||
|
OrganizationUserStatus = OrganizationUserStatusType.Accepted,
|
||||||
|
PolicyType = PolicyType.TwoFactorAuthentication
|
||||||
|
}
|
||||||
|
]));
|
||||||
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(Arg.Is<IEnumerable<Guid>>(ids => ids.Contains(user.Id)))
|
||||||
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, true) });
|
.Returns(new List<(Guid userId, bool twoFactorIsEnabled)>() { (user.Id, true) });
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user