mirror of
https://github.com/bitwarden/server
synced 2025-12-17 08:43:27 +00:00
added auto confirm restriction on top of single org.
This commit is contained in:
@@ -418,12 +418,15 @@ public class ProviderService : IProviderService
|
|||||||
"The organization is subscribed to Secrets Manager. Please contact Customer Support to manage the subscription.");
|
"The organization is subscribed to Secrets Manager. Please contact Customer Support to manage the subscription.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var organizationAutoConfirmPolicyRequirement = await _policyRequirementQuery
|
if (_featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
.GetManyByOrganizationIdAsync<AutomaticUserConfirmationPolicyRequirement>(organizationId);
|
|
||||||
|
|
||||||
if (organizationAutoConfirmPolicyRequirement.Any())
|
|
||||||
{
|
{
|
||||||
throw new BadRequestException(new AutoConfirmDoesNotAllowProviderUsers().Message);
|
var organizationAutoConfirmPolicyRequirement = await _policyRequirementQuery
|
||||||
|
.GetManyByOrganizationIdAsync<AutomaticUserConfirmationPolicyRequirement>(organizationId);
|
||||||
|
|
||||||
|
if (organizationAutoConfirmPolicyRequirement.Any())
|
||||||
|
{
|
||||||
|
throw new BadRequestException(new AutoConfirmDoesNotAllowProviderUsers().Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var providerOrganization = new ProviderOrganization
|
var providerOrganization = new ProviderOrganization
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.DeleteClaimedAccount;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.DeleteClaimedAccount;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Enforcement.AutoConfirm;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.AdminConsole.Utilities.v2;
|
using Bit.Core.AdminConsole.Utilities.v2;
|
||||||
@@ -8,6 +9,7 @@ using Bit.Core.AdminConsole.Utilities.v2.Validation;
|
|||||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Core.Services;
|
||||||
using static Bit.Core.AdminConsole.Utilities.v2.Validation.ValidationResultHelpers;
|
using static Bit.Core.AdminConsole.Utilities.v2.Validation.ValidationResultHelpers;
|
||||||
|
|
||||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
|
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.AutoConfirmUser;
|
||||||
@@ -16,6 +18,8 @@ public class AutomaticallyConfirmOrganizationUsersValidator(
|
|||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
||||||
IPolicyRequirementQuery policyRequirementQuery,
|
IPolicyRequirementQuery policyRequirementQuery,
|
||||||
|
IAutomaticUserConfirmationPolicyEnforcementQuery automaticUserConfirmationPolicyEnforcementQuery,
|
||||||
|
IUserService userService,
|
||||||
IPolicyRepository policyRepository) : IAutomaticallyConfirmOrganizationUsersValidator
|
IPolicyRepository policyRepository) : IAutomaticallyConfirmOrganizationUsersValidator
|
||||||
{
|
{
|
||||||
public async Task<ValidationResult<AutomaticallyConfirmOrganizationUserValidationRequest>> ValidateAsync(
|
public async Task<ValidationResult<AutomaticallyConfirmOrganizationUserValidationRequest>> ValidateAsync(
|
||||||
@@ -61,7 +65,7 @@ public class AutomaticallyConfirmOrganizationUsersValidator(
|
|||||||
return Invalid(request, new UserDoesNotHaveTwoFactorEnabled());
|
return Invalid(request, new UserDoesNotHaveTwoFactorEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await OrganizationUserConformsToSingleOrgPolicyAsync(request) is { } error)
|
if (await OrganizationUserConformsToAutomaticUserConfirmationPolicyAsync(request) is { } error)
|
||||||
{
|
{
|
||||||
return Invalid(request, error);
|
return Invalid(request, error);
|
||||||
}
|
}
|
||||||
@@ -87,30 +91,27 @@ public class AutomaticallyConfirmOrganizationUsersValidator(
|
|||||||
.IsTwoFactorRequiredForOrganization(request.Organization!.Id);
|
.IsTwoFactorRequiredForOrganization(request.Organization!.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Error?> OrganizationUserConformsToSingleOrgPolicyAsync(
|
private async Task<Error?> OrganizationUserConformsToAutomaticUserConfirmationPolicyAsync(
|
||||||
AutomaticallyConfirmOrganizationUserValidationRequest request)
|
AutomaticallyConfirmOrganizationUserValidationRequest request)
|
||||||
{
|
{
|
||||||
var allOrganizationUsersForUser = await organizationUserRepository
|
var allOrganizationUsersForUser = await organizationUserRepository
|
||||||
.GetManyByUserAsync(request.OrganizationUser!.UserId!.Value);
|
.GetManyByUserAsync(request.OrganizationUser!.UserId!.Value);
|
||||||
|
|
||||||
|
var user = await userService.GetUserByIdAsync(request.OrganizationUser!.UserId!.Value);
|
||||||
|
|
||||||
if (allOrganizationUsersForUser.Count == 1)
|
if (allOrganizationUsersForUser.Count == 1)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var policyRequirement = await policyRequirementQuery
|
return (await automaticUserConfirmationPolicyEnforcementQuery.IsCompliantAsync(
|
||||||
.GetAsync<SingleOrganizationPolicyRequirement>(request.OrganizationUser!.UserId!.Value);
|
new AutomaticUserConfirmationPolicyEnforcementRequest(
|
||||||
|
request.OrganizationUser,
|
||||||
if (policyRequirement.IsSingleOrgEnabledForThisOrganization(request.Organization!.Id))
|
allOrganizationUsersForUser.Where(x => x.OrganizationId != request.OrganizationId),
|
||||||
{
|
user)))
|
||||||
return new OrganizationEnforcesSingleOrgPolicy();
|
.Match<Error?>(
|
||||||
}
|
error => error,
|
||||||
|
_ => null
|
||||||
if (policyRequirement.IsSingleOrgEnabledForOrganizationsOtherThan(request.Organization.Id))
|
);
|
||||||
{
|
|
||||||
return new OtherOrganizationEnforcesSingleOrgPolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Enforcement.AutoConfirm;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
using Bit.Core.Auth.UserFeatures.TwoFactorAuth.Interfaces;
|
||||||
@@ -33,6 +34,7 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
||||||
private readonly IFeatureService _featureService;
|
private readonly IFeatureService _featureService;
|
||||||
private readonly ICollectionRepository _collectionRepository;
|
private readonly ICollectionRepository _collectionRepository;
|
||||||
|
private readonly IAutomaticUserConfirmationPolicyEnforcementQuery _automaticUserConfirmationPolicyEnforcementQuery;
|
||||||
|
|
||||||
public ConfirmOrganizationUserCommand(
|
public ConfirmOrganizationUserCommand(
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
@@ -47,7 +49,8 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
IDeviceRepository deviceRepository,
|
IDeviceRepository deviceRepository,
|
||||||
IPolicyRequirementQuery policyRequirementQuery,
|
IPolicyRequirementQuery policyRequirementQuery,
|
||||||
IFeatureService featureService,
|
IFeatureService featureService,
|
||||||
ICollectionRepository collectionRepository)
|
ICollectionRepository collectionRepository,
|
||||||
|
IAutomaticUserConfirmationPolicyEnforcementQuery automaticUserConfirmationPolicyEnforcementQuery)
|
||||||
{
|
{
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
@@ -62,6 +65,7 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
_policyRequirementQuery = policyRequirementQuery;
|
_policyRequirementQuery = policyRequirementQuery;
|
||||||
_featureService = featureService;
|
_featureService = featureService;
|
||||||
_collectionRepository = collectionRepository;
|
_collectionRepository = collectionRepository;
|
||||||
|
_automaticUserConfirmationPolicyEnforcementQuery = automaticUserConfirmationPolicyEnforcementQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key,
|
public async Task<OrganizationUser> ConfirmUserAsync(Guid organizationId, Guid organizationUserId, string key,
|
||||||
@@ -127,6 +131,7 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
|
|
||||||
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
||||||
var allUsersOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(validSelectedUserIds);
|
var allUsersOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(validSelectedUserIds);
|
||||||
|
|
||||||
var users = await _userRepository.GetManyAsync(validSelectedUserIds);
|
var users = await _userRepository.GetManyAsync(validSelectedUserIds);
|
||||||
var usersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(validSelectedUserIds);
|
var usersTwoFactorEnabled = await _twoFactorIsEnabledQuery.TwoFactorIsEnabledAsync(validSelectedUserIds);
|
||||||
|
|
||||||
@@ -188,6 +193,25 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
await ValidateTwoFactorAuthenticationPolicyAsync(user, organizationId, userTwoFactorEnabled);
|
await ValidateTwoFactorAuthenticationPolicyAsync(user, organizationId, userTwoFactorEnabled);
|
||||||
|
|
||||||
var hasOtherOrgs = userOrgs.Any(ou => ou.OrganizationId != organizationId);
|
var hasOtherOrgs = userOrgs.Any(ou => ou.OrganizationId != organizationId);
|
||||||
|
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
|
{
|
||||||
|
var error = (await _automaticUserConfirmationPolicyEnforcementQuery.IsCompliantAsync(
|
||||||
|
new AutomaticUserConfirmationPolicyEnforcementRequest(
|
||||||
|
userOrgs.First(x => x.OrganizationId == organizationId),
|
||||||
|
userOrgs.Where(x => x.OrganizationId != organizationId),
|
||||||
|
user)))
|
||||||
|
.Match(
|
||||||
|
error => error.Message,
|
||||||
|
_ => string.Empty
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(error))
|
||||||
|
{
|
||||||
|
throw new BadRequestException(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var singleOrgPolicies = await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg);
|
var singleOrgPolicies = await _policyService.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg);
|
||||||
var otherSingleOrgPolicies =
|
var otherSingleOrgPolicies =
|
||||||
singleOrgPolicies.Where(p => p.OrganizationId != organizationId);
|
singleOrgPolicies.Where(p => p.OrganizationId != organizationId);
|
||||||
|
|||||||
Reference in New Issue
Block a user