mirror of
https://github.com/bitwarden/server
synced 2025-12-14 07:13:39 +00:00
Added auto confirm to single org check locations. Removed additional call within policy service.
This commit is contained in:
@@ -202,13 +202,13 @@ public class ConfirmOrganizationUserCommand : IConfirmOrganizationUserCommand
|
|||||||
userOrgs,
|
userOrgs,
|
||||||
user)))
|
user)))
|
||||||
.Match(
|
.Match(
|
||||||
error => error.Message,
|
error => new BadRequestException(error.Message),
|
||||||
_ => string.Empty
|
_ => null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(error))
|
if (error is not null)
|
||||||
{
|
{
|
||||||
throw new BadRequestException(error);
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
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;
|
||||||
@@ -29,7 +30,8 @@ public class RestoreOrganizationUserCommand(
|
|||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
IFeatureService featureService,
|
IFeatureService featureService,
|
||||||
IPolicyRequirementQuery policyRequirementQuery) : IRestoreOrganizationUserCommand
|
IPolicyRequirementQuery policyRequirementQuery,
|
||||||
|
IAutomaticUserConfirmationPolicyEnforcementValidator automaticUserConfirmationPolicyEnforcementValidator) : IRestoreOrganizationUserCommand
|
||||||
{
|
{
|
||||||
public async Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId)
|
public async Task RestoreUserAsync(OrganizationUser organizationUser, Guid? restoringUserId)
|
||||||
{
|
{
|
||||||
@@ -300,6 +302,25 @@ public class RestoreOrganizationUserCommand(
|
|||||||
{
|
{
|
||||||
throw new BadRequestException(user.Email + " is not compliant with the two-step login policy");
|
throw new BadRequestException(user.Email + " is not compliant with the two-step login policy");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
|
{
|
||||||
|
var validationResult = await automaticUserConfirmationPolicyEnforcementValidator.IsCompliantAsync(
|
||||||
|
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser.OrganizationId,
|
||||||
|
allOrgUsers,
|
||||||
|
user!));
|
||||||
|
|
||||||
|
var badRequestException = validationResult.Match(
|
||||||
|
error => new BadRequestException(user.Email +
|
||||||
|
" is not compliant with the automatic user confirmation policy: " +
|
||||||
|
error.Message),
|
||||||
|
_ => null);
|
||||||
|
|
||||||
|
if (badRequestException is not null)
|
||||||
|
{
|
||||||
|
throw badRequestException;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> IsTwoFactorRequiredForOrganizationAsync(Guid userId, Guid organizationId)
|
private async Task<bool> IsTwoFactorRequiredForOrganizationAsync(Guid userId, Guid organizationId)
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Billing.Enums;
|
using Bit.Core.Billing.Enums;
|
||||||
using Bit.Core.Billing.Organizations.Models;
|
using Bit.Core.Billing.Organizations.Models;
|
||||||
@@ -42,7 +44,9 @@ public class CloudOrganizationSignUpCommand(
|
|||||||
IPushNotificationService pushNotificationService,
|
IPushNotificationService pushNotificationService,
|
||||||
ICollectionRepository collectionRepository,
|
ICollectionRepository collectionRepository,
|
||||||
IDeviceRepository deviceRepository,
|
IDeviceRepository deviceRepository,
|
||||||
IPricingClient pricingClient) : ICloudOrganizationSignUpCommand
|
IPricingClient pricingClient,
|
||||||
|
IPolicyRequirementQuery policyRequirementQuery,
|
||||||
|
IFeatureService featureService) : ICloudOrganizationSignUpCommand
|
||||||
{
|
{
|
||||||
public async Task<SignUpOrganizationResponse> SignUpOrganizationAsync(OrganizationSignup signup)
|
public async Task<SignUpOrganizationResponse> SignUpOrganizationAsync(OrganizationSignup signup)
|
||||||
{
|
{
|
||||||
@@ -236,6 +240,17 @@ public class CloudOrganizationSignUpCommand(
|
|||||||
|
|
||||||
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
||||||
{
|
{
|
||||||
|
if (featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
|
{
|
||||||
|
var requirement = await policyRequirementQuery.GetAsync<AutomaticUserConfirmationPolicyRequirement>(ownerId);
|
||||||
|
|
||||||
|
if (requirement.UserBelongsToOrganizationWithAutomaticUserConfirmationEnabled())
|
||||||
|
{
|
||||||
|
throw new BadRequestException("You may not create an organization. You belong to an organization " +
|
||||||
|
"which has a policy that prohibits you from being a member of any other organization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var anySingleOrgPolicies = await policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
var anySingleOrgPolicies = await policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
||||||
if (anySingleOrgPolicies)
|
if (anySingleOrgPolicies)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Auth.Models.Business.Tokenables;
|
using Bit.Core.Auth.Models.Business.Tokenables;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
@@ -28,6 +30,8 @@ public class InitPendingOrganizationCommand : IInitPendingOrganizationCommand
|
|||||||
private readonly IGlobalSettings _globalSettings;
|
private readonly IGlobalSettings _globalSettings;
|
||||||
private readonly IPolicyService _policyService;
|
private readonly IPolicyService _policyService;
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
|
private readonly IFeatureService _featureService;
|
||||||
|
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
||||||
|
|
||||||
public InitPendingOrganizationCommand(
|
public InitPendingOrganizationCommand(
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
@@ -37,7 +41,9 @@ public class InitPendingOrganizationCommand : IInitPendingOrganizationCommand
|
|||||||
IDataProtectionProvider dataProtectionProvider,
|
IDataProtectionProvider dataProtectionProvider,
|
||||||
IGlobalSettings globalSettings,
|
IGlobalSettings globalSettings,
|
||||||
IPolicyService policyService,
|
IPolicyService policyService,
|
||||||
IOrganizationUserRepository organizationUserRepository
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
|
IFeatureService featureService,
|
||||||
|
IPolicyRequirementQuery policyRequirementQuery
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_organizationService = organizationService;
|
_organizationService = organizationService;
|
||||||
@@ -48,6 +54,8 @@ public class InitPendingOrganizationCommand : IInitPendingOrganizationCommand
|
|||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_policyService = policyService;
|
_policyService = policyService;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
|
_featureService = featureService;
|
||||||
|
_policyRequirementQuery = policyRequirementQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InitPendingOrganizationAsync(User user, Guid organizationId, Guid organizationUserId, string publicKey, string privateKey, string collectionName, string emailToken)
|
public async Task InitPendingOrganizationAsync(User user, Guid organizationId, Guid organizationUserId, string publicKey, string privateKey, string collectionName, string emailToken)
|
||||||
@@ -113,6 +121,17 @@ public class InitPendingOrganizationCommand : IInitPendingOrganizationCommand
|
|||||||
|
|
||||||
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
||||||
{
|
{
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
|
{
|
||||||
|
var requirement = await _policyRequirementQuery.GetAsync<AutomaticUserConfirmationPolicyRequirement>(ownerId);
|
||||||
|
|
||||||
|
if (requirement.UserBelongsToOrganizationWithAutomaticUserConfirmationEnabled())
|
||||||
|
{
|
||||||
|
throw new BadRequestException("You may not create an organization. You belong to an organization " +
|
||||||
|
"which has a policy that prohibits you from being a member of any other organization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var anySingleOrgPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
var anySingleOrgPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
||||||
if (anySingleOrgPolicies)
|
if (anySingleOrgPolicies)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Enums;
|
using Bit.Core.AdminConsole.Enums;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||||
using Bit.Core.AdminConsole.Services;
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Billing.Organizations.Models;
|
using Bit.Core.Billing.Organizations.Models;
|
||||||
using Bit.Core.Billing.Services;
|
using Bit.Core.Billing.Services;
|
||||||
@@ -31,6 +33,8 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
|
|||||||
private readonly IPolicyService _policyService;
|
private readonly IPolicyService _policyService;
|
||||||
private readonly IGlobalSettings _globalSettings;
|
private readonly IGlobalSettings _globalSettings;
|
||||||
private readonly IPaymentService _paymentService;
|
private readonly IPaymentService _paymentService;
|
||||||
|
private readonly IFeatureService _featureService;
|
||||||
|
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
||||||
|
|
||||||
public SelfHostedOrganizationSignUpCommand(
|
public SelfHostedOrganizationSignUpCommand(
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
@@ -44,7 +48,9 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
|
|||||||
ILicensingService licensingService,
|
ILicensingService licensingService,
|
||||||
IPolicyService policyService,
|
IPolicyService policyService,
|
||||||
IGlobalSettings globalSettings,
|
IGlobalSettings globalSettings,
|
||||||
IPaymentService paymentService)
|
IPaymentService paymentService,
|
||||||
|
IFeatureService featureService,
|
||||||
|
IPolicyRequirementQuery policyRequirementQuery)
|
||||||
{
|
{
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
@@ -58,6 +64,8 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
|
|||||||
_policyService = policyService;
|
_policyService = policyService;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
_paymentService = paymentService;
|
_paymentService = paymentService;
|
||||||
|
_featureService = featureService;
|
||||||
|
_policyRequirementQuery = policyRequirementQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(Organization organization, OrganizationUser? organizationUser)> SignUpAsync(
|
public async Task<(Organization organization, OrganizationUser? organizationUser)> SignUpAsync(
|
||||||
@@ -103,6 +111,17 @@ public class SelfHostedOrganizationSignUpCommand : ISelfHostedOrganizationSignUp
|
|||||||
|
|
||||||
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
private async Task ValidateSignUpPoliciesAsync(Guid ownerId)
|
||||||
{
|
{
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers))
|
||||||
|
{
|
||||||
|
var requirement = await _policyRequirementQuery.GetAsync<AutomaticUserConfirmationPolicyRequirement>(ownerId);
|
||||||
|
|
||||||
|
if (requirement.UserBelongsToOrganizationWithAutomaticUserConfirmationEnabled())
|
||||||
|
{
|
||||||
|
throw new BadRequestException("You may not create an organization. You belong to an organization " +
|
||||||
|
"which has a policy that prohibits you from being a member of any other organization.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var anySingleOrgPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
var anySingleOrgPolicies = await _policyService.AnyPoliciesApplicableToUserAsync(ownerId, PolicyType.SingleOrg);
|
||||||
if (anySingleOrgPolicies)
|
if (anySingleOrgPolicies)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -89,31 +89,14 @@ public class PolicyService : IPolicyService
|
|||||||
private async Task<IEnumerable<OrganizationUserPolicyDetails>> QueryOrganizationUserPolicyDetailsAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
|
private async Task<IEnumerable<OrganizationUserPolicyDetails>> QueryOrganizationUserPolicyDetailsAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
|
||||||
{
|
{
|
||||||
var organizationUserPolicyDetails = await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, policyType);
|
var organizationUserPolicyDetails = await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, policyType);
|
||||||
|
var excludedUserTypes = GetUserTypesExcludedFromPolicy(policyType);
|
||||||
OrganizationUserType[] excludedUserTypes;
|
|
||||||
var appliesToProviders = false;
|
|
||||||
|
|
||||||
if (policyType == PolicyType.SingleOrg
|
|
||||||
&& _featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers)
|
|
||||||
&& (await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, PolicyType.AutomaticUserConfirmation)).Any())
|
|
||||||
{
|
|
||||||
minStatus = OrganizationUserStatusType.Revoked;
|
|
||||||
excludedUserTypes = [];
|
|
||||||
appliesToProviders = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
excludedUserTypes = GetUserTypesExcludedFromPolicy(policyType);
|
|
||||||
}
|
|
||||||
|
|
||||||
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
var orgAbilities = await _applicationCacheService.GetOrganizationAbilitiesAsync();
|
||||||
|
|
||||||
return organizationUserPolicyDetails.Where(o =>
|
return organizationUserPolicyDetails.Where(o =>
|
||||||
(!orgAbilities.TryGetValue(o.OrganizationId, out var orgAbility) || orgAbility.UsePolicies) &&
|
(!orgAbilities.TryGetValue(o.OrganizationId, out var orgAbility) || orgAbility.UsePolicies) &&
|
||||||
o.PolicyEnabled &&
|
o.PolicyEnabled &&
|
||||||
!excludedUserTypes.Contains(o.OrganizationUserType) &&
|
!excludedUserTypes.Contains(o.OrganizationUserType) &&
|
||||||
o.OrganizationUserStatus >= minStatus &&
|
o.OrganizationUserStatus >= minStatus &&
|
||||||
(o.IsProvider && appliesToProviders || !o.IsProvider)); // the user is a provider and the policy applies to providers, or they are not a provider
|
!o.IsProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrganizationUserType[] GetUserTypesExcludedFromPolicy(PolicyType policyType)
|
private OrganizationUserType[] GetUserTypesExcludedFromPolicy(PolicyType policyType)
|
||||||
|
|||||||
Reference in New Issue
Block a user