From 08f508f5364207364eac869526fce9f7097ad6ac Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Wed, 30 Jun 2021 09:21:41 +0200 Subject: [PATCH] Extract single-org policy check to OrganizationService (#1410) --- .../Controllers/OrganizationsController.cs | 28 +------------------ .../Implementations/OrganizationService.cs | 21 ++++++++++++++ 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/Api/Controllers/OrganizationsController.cs b/src/Api/Controllers/OrganizationsController.cs index 340cfb895..3259fd50c 100644 --- a/src/Api/Controllers/OrganizationsController.cs +++ b/src/Api/Controllers/OrganizationsController.cs @@ -28,7 +28,6 @@ namespace Bit.Api.Controllers private readonly IPaymentService _paymentService; private readonly ICurrentContext _currentContext; private readonly GlobalSettings _globalSettings; - private readonly IPolicyRepository _policyRepository; public OrganizationsController( IOrganizationRepository organizationRepository, @@ -37,8 +36,7 @@ namespace Bit.Api.Controllers IUserService userService, IPaymentService paymentService, ICurrentContext currentContext, - GlobalSettings globalSettings, - IPolicyRepository policyRepository) + GlobalSettings globalSettings) { _organizationRepository = organizationRepository; _organizationUserRepository = organizationUserRepository; @@ -47,7 +45,6 @@ namespace Bit.Api.Controllers _paymentService = paymentService; _currentContext = currentContext; _globalSettings = globalSettings; - _policyRepository = policyRepository; } [HttpGet("{id}")] @@ -163,22 +160,6 @@ namespace Bit.Api.Controllers throw new Exception("Invalid plan selected."); } - var policies = await _policyRepository.GetManyByUserIdAsync(user.Id); - var orgUsers = await _organizationUserRepository.GetManyByUserAsync(user.Id); - - var orgsWithSingleOrgPolicy = policies.Where(p => p.Enabled && p.Type == PolicyType.SingleOrg) - .Select(p => p.OrganizationId); - var blockedBySingleOrgPolicy = orgUsers.Any(ou => ou.Type != OrganizationUserType.Owner && - ou.Type != OrganizationUserType.Admin && - ou.Status != OrganizationUserStatusType.Invited && - orgsWithSingleOrgPolicy.Contains(ou.OrganizationId)); - - if (blockedBySingleOrgPolicy) - { - throw new Exception("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 organizationSignup = model.ToOrganizationSignup(user); var result = await _organizationService.SignUpAsync(organizationSignup); return new OrganizationResponseModel(result.Item1); @@ -200,13 +181,6 @@ namespace Bit.Api.Controllers throw new BadRequestException("Invalid license"); } - var policies = await _policyRepository.GetManyByUserIdAsync(user.Id); - if (policies.Any(policy => policy.Enabled && policy.Type == PolicyType.SingleOrg)) - { - throw new Exception("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 result = await _organizationService.SignUpAsync(license, user, model.Key, model.CollectionName, model.Keys?.PublicKey, model.Keys?.EncryptedPrivateKey); return new OrganizationResponseModel(result.Item1); diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 5dd063e15..070c66575 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -557,6 +557,7 @@ namespace Bit.Core.Services throw new BadRequestException("Plan not found."); } + await ValidateSignUpPoliciesAsync(signup.Owner.Id); ValidateOrganizationUpgradeParameters(plan, signup); var organization = new Organization @@ -622,6 +623,24 @@ namespace Bit.Core.Services return returnValue; } + private async Task ValidateSignUpPoliciesAsync(Guid ownerId) + { + var policies = await _policyRepository.GetManyByUserIdAsync(ownerId); + var orgUsers = await _organizationUserRepository.GetManyByUserAsync(ownerId); + + var orgsWithSingleOrgPolicy = policies.Where(p => p.Enabled && p.Type == PolicyType.SingleOrg) + .Select(p => p.OrganizationId); + var blockedBySingleOrgPolicy = orgUsers.Any(ou => ou is {Type: OrganizationUserType.Owner} && + ou.Type != OrganizationUserType.Admin && + ou.Status != OrganizationUserStatusType.Invited && + orgsWithSingleOrgPolicy.Contains(ou.OrganizationId)); + if (blockedBySingleOrgPolicy) + { + 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."); + } + } + public async Task> SignUpAsync( OrganizationLicense license, User owner, string ownerKey, string collectionName, string publicKey, string privateKey) @@ -649,6 +668,8 @@ namespace Bit.Core.Services throw new BadRequestException("License is already in use by another organization."); } + await ValidateSignUpPoliciesAsync(owner.Id); + var organization = new Organization { Name = license.Name,