mirror of
https://github.com/bitwarden/server.git
synced 2025-04-05 05:00:19 -05:00
[PM-10314] Auto-enable Single Org when a Domain is Verified (#4897)
Updated domain verification to auto-enable single org policy.
This commit is contained in:
parent
a128cf1506
commit
0c346d6070
@ -0,0 +1,6 @@
|
|||||||
|
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
||||||
|
|
||||||
|
public interface IOrganizationHasVerifiedDomainsQuery
|
||||||
|
{
|
||||||
|
Task<bool> HasVerifiedDomainsAsync(Guid orgId);
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
|
||||||
|
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
||||||
|
|
||||||
|
public class OrganizationHasVerifiedDomainsQuery(IOrganizationDomainRepository domainRepository) : IOrganizationHasVerifiedDomainsQuery
|
||||||
|
{
|
||||||
|
public async Task<bool> HasVerifiedDomainsAsync(Guid orgId) =>
|
||||||
|
(await domainRepository.GetDomainsByOrganizationIdAsync(orgId)).Any(od => od.VerifiedDate is not null);
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
@ -15,6 +18,9 @@ public class VerifyOrganizationDomainCommand : IVerifyOrganizationDomainCommand
|
|||||||
private readonly IDnsResolverService _dnsResolverService;
|
private readonly IDnsResolverService _dnsResolverService;
|
||||||
private readonly IEventService _eventService;
|
private readonly IEventService _eventService;
|
||||||
private readonly IGlobalSettings _globalSettings;
|
private readonly IGlobalSettings _globalSettings;
|
||||||
|
private readonly IPolicyService _policyService;
|
||||||
|
private readonly IFeatureService _featureService;
|
||||||
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly ILogger<VerifyOrganizationDomainCommand> _logger;
|
private readonly ILogger<VerifyOrganizationDomainCommand> _logger;
|
||||||
|
|
||||||
public VerifyOrganizationDomainCommand(
|
public VerifyOrganizationDomainCommand(
|
||||||
@ -22,12 +28,18 @@ public class VerifyOrganizationDomainCommand : IVerifyOrganizationDomainCommand
|
|||||||
IDnsResolverService dnsResolverService,
|
IDnsResolverService dnsResolverService,
|
||||||
IEventService eventService,
|
IEventService eventService,
|
||||||
IGlobalSettings globalSettings,
|
IGlobalSettings globalSettings,
|
||||||
|
IPolicyService policyService,
|
||||||
|
IFeatureService featureService,
|
||||||
|
IOrganizationService organizationService,
|
||||||
ILogger<VerifyOrganizationDomainCommand> logger)
|
ILogger<VerifyOrganizationDomainCommand> logger)
|
||||||
{
|
{
|
||||||
_organizationDomainRepository = organizationDomainRepository;
|
_organizationDomainRepository = organizationDomainRepository;
|
||||||
_dnsResolverService = dnsResolverService;
|
_dnsResolverService = dnsResolverService;
|
||||||
_eventService = eventService;
|
_eventService = eventService;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
|
_policyService = policyService;
|
||||||
|
_featureService = featureService;
|
||||||
|
_organizationService = organizationService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +114,8 @@ public class VerifyOrganizationDomainCommand : IVerifyOrganizationDomainCommand
|
|||||||
if (await _dnsResolverService.ResolveAsync(domain.DomainName, domain.Txt))
|
if (await _dnsResolverService.ResolveAsync(domain.DomainName, domain.Txt))
|
||||||
{
|
{
|
||||||
domain.SetVerifiedDate();
|
domain.SetVerifiedDate();
|
||||||
|
|
||||||
|
await EnableSingleOrganizationPolicyAsync(domain.OrganizationId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@ -112,4 +126,13 @@ public class VerifyOrganizationDomainCommand : IVerifyOrganizationDomainCommand
|
|||||||
|
|
||||||
return domain;
|
return domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task EnableSingleOrganizationPolicyAsync(Guid organizationId)
|
||||||
|
{
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning))
|
||||||
|
{
|
||||||
|
await _policyService.SaveAsync(
|
||||||
|
new Policy { OrganizationId = organizationId, Type = PolicyType.SingleOrg, Enabled = true }, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,4 @@ public interface IOrganizationDomainService
|
|||||||
{
|
{
|
||||||
Task ValidateOrganizationsDomainAsync();
|
Task ValidateOrganizationsDomainAsync();
|
||||||
Task OrganizationDomainMaintenanceAsync();
|
Task OrganizationDomainMaintenanceAsync();
|
||||||
/// <summary>
|
|
||||||
/// Indicates if the organization has any verified domains.
|
|
||||||
/// </summary>
|
|
||||||
Task<bool> HasVerifiedDomainsAsync(Guid orgId);
|
|
||||||
}
|
}
|
||||||
|
@ -106,12 +106,6 @@ public class OrganizationDomainService : IOrganizationDomainService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> HasVerifiedDomainsAsync(Guid orgId)
|
|
||||||
{
|
|
||||||
var orgDomains = await _domainRepository.GetDomainsByOrganizationIdAsync(orgId);
|
|
||||||
return orgDomains.Any(od => od.VerifiedDate != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<string>> GetAdminEmailsAsync(Guid organizationId)
|
private async Task<List<string>> GetAdminEmailsAsync(Guid organizationId)
|
||||||
{
|
{
|
||||||
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(organizationId);
|
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(organizationId);
|
||||||
|
@ -1,6 +1,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.Models.Data.Organizations.Policies;
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
||||||
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.Models;
|
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.Models;
|
||||||
@ -32,6 +33,7 @@ public class PolicyService : IPolicyService
|
|||||||
private readonly IFeatureService _featureService;
|
private readonly IFeatureService _featureService;
|
||||||
private readonly ISavePolicyCommand _savePolicyCommand;
|
private readonly ISavePolicyCommand _savePolicyCommand;
|
||||||
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
|
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
|
||||||
|
private readonly IOrganizationHasVerifiedDomainsQuery _organizationHasVerifiedDomainsQuery;
|
||||||
|
|
||||||
public PolicyService(
|
public PolicyService(
|
||||||
IApplicationCacheService applicationCacheService,
|
IApplicationCacheService applicationCacheService,
|
||||||
@ -45,7 +47,8 @@ public class PolicyService : IPolicyService
|
|||||||
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
ITwoFactorIsEnabledQuery twoFactorIsEnabledQuery,
|
||||||
IFeatureService featureService,
|
IFeatureService featureService,
|
||||||
ISavePolicyCommand savePolicyCommand,
|
ISavePolicyCommand savePolicyCommand,
|
||||||
IRemoveOrganizationUserCommand removeOrganizationUserCommand)
|
IRemoveOrganizationUserCommand removeOrganizationUserCommand,
|
||||||
|
IOrganizationHasVerifiedDomainsQuery organizationHasVerifiedDomainsQuery)
|
||||||
{
|
{
|
||||||
_applicationCacheService = applicationCacheService;
|
_applicationCacheService = applicationCacheService;
|
||||||
_eventService = eventService;
|
_eventService = eventService;
|
||||||
@ -59,6 +62,7 @@ public class PolicyService : IPolicyService
|
|||||||
_featureService = featureService;
|
_featureService = featureService;
|
||||||
_savePolicyCommand = savePolicyCommand;
|
_savePolicyCommand = savePolicyCommand;
|
||||||
_removeOrganizationUserCommand = removeOrganizationUserCommand;
|
_removeOrganizationUserCommand = removeOrganizationUserCommand;
|
||||||
|
_organizationHasVerifiedDomainsQuery = organizationHasVerifiedDomainsQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(Policy policy, Guid? savingUserId)
|
public async Task SaveAsync(Policy policy, Guid? savingUserId)
|
||||||
@ -239,6 +243,7 @@ public class PolicyService : IPolicyService
|
|||||||
case PolicyType.SingleOrg:
|
case PolicyType.SingleOrg:
|
||||||
if (!policy.Enabled)
|
if (!policy.Enabled)
|
||||||
{
|
{
|
||||||
|
await HasVerifiedDomainsAsync(org);
|
||||||
await RequiredBySsoAsync(org);
|
await RequiredBySsoAsync(org);
|
||||||
await RequiredByVaultTimeoutAsync(org);
|
await RequiredByVaultTimeoutAsync(org);
|
||||||
await RequiredByKeyConnectorAsync(org);
|
await RequiredByKeyConnectorAsync(org);
|
||||||
@ -279,6 +284,15 @@ public class PolicyService : IPolicyService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HasVerifiedDomainsAsync(Organization org)
|
||||||
|
{
|
||||||
|
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
&& await _organizationHasVerifiedDomainsQuery.HasVerifiedDomainsAsync(org.Id))
|
||||||
|
{
|
||||||
|
throw new BadRequestException("Organization has verified domains.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SetPolicyConfiguration(Policy policy)
|
private async Task SetPolicyConfiguration(Policy policy)
|
||||||
{
|
{
|
||||||
await _policyRepository.UpsertAsync(policy);
|
await _policyRepository.UpsertAsync(policy);
|
||||||
|
@ -130,6 +130,7 @@ public static class OrganizationServiceCollectionExtensions
|
|||||||
services.AddScoped<IGetOrganizationDomainByIdOrganizationIdQuery, GetOrganizationDomainByIdOrganizationIdQuery>();
|
services.AddScoped<IGetOrganizationDomainByIdOrganizationIdQuery, GetOrganizationDomainByIdOrganizationIdQuery>();
|
||||||
services.AddScoped<IGetOrganizationDomainByOrganizationIdQuery, GetOrganizationDomainByOrganizationIdQuery>();
|
services.AddScoped<IGetOrganizationDomainByOrganizationIdQuery, GetOrganizationDomainByOrganizationIdQuery>();
|
||||||
services.AddScoped<IDeleteOrganizationDomainCommand, DeleteOrganizationDomainCommand>();
|
services.AddScoped<IDeleteOrganizationDomainCommand, DeleteOrganizationDomainCommand>();
|
||||||
|
services.AddScoped<IOrganizationHasVerifiedDomainsQuery, OrganizationHasVerifiedDomainsQuery>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddOrganizationAuthCommands(this IServiceCollection services)
|
private static void AddOrganizationAuthCommands(this IServiceCollection services)
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Test.Common.AutoFixture;
|
||||||
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
|
using NSubstitute;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
||||||
|
|
||||||
|
[SutProviderCustomize]
|
||||||
|
public class OrganizationHasVerifiedDomainsQueryTests
|
||||||
|
{
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task HasVerifiedDomainsAsync_WithVerifiedDomain_ReturnsTrue(
|
||||||
|
OrganizationDomain organizationDomain,
|
||||||
|
SutProvider<OrganizationHasVerifiedDomainsQuery> sutProvider)
|
||||||
|
{
|
||||||
|
organizationDomain.SetVerifiedDate(); // Set the verified date to make it verified
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetDomainsByOrganizationIdAsync(organizationDomain.OrganizationId)
|
||||||
|
.Returns(new List<OrganizationDomain> { organizationDomain });
|
||||||
|
|
||||||
|
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationDomain.OrganizationId);
|
||||||
|
|
||||||
|
Assert.True(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task HasVerifiedDomainsAsync_WithoutVerifiedDomain_ReturnsFalse(
|
||||||
|
OrganizationDomain organizationDomain,
|
||||||
|
SutProvider<OrganizationHasVerifiedDomainsQuery> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetDomainsByOrganizationIdAsync(organizationDomain.OrganizationId)
|
||||||
|
.Returns(new List<OrganizationDomain> { organizationDomain });
|
||||||
|
|
||||||
|
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationDomain.OrganizationId);
|
||||||
|
|
||||||
|
Assert.False(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task HasVerifiedDomainsAsync_WithoutOrganizationDomains_ReturnsFalse(
|
||||||
|
Guid organizationId,
|
||||||
|
SutProvider<OrganizationHasVerifiedDomainsQuery> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetDomainsByOrganizationIdAsync(organizationId)
|
||||||
|
.Returns(new List<OrganizationDomain>());
|
||||||
|
|
||||||
|
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationId);
|
||||||
|
|
||||||
|
Assert.False(result);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.AdminConsole.Enums;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
||||||
|
using Bit.Core.AdminConsole.Services;
|
||||||
using Bit.Core.Entities;
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
@ -15,7 +18,7 @@ namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.OrganizationDomains;
|
|||||||
public class VerifyOrganizationDomainCommandTests
|
public class VerifyOrganizationDomainCommandTests
|
||||||
{
|
{
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task UserVerifyOrganizationDomain_ShouldThrowConflict_WhenDomainHasBeenClaimed(Guid id,
|
public async Task UserVerifyOrganizationDomainAsync_ShouldThrowConflict_WhenDomainHasBeenClaimed(Guid id,
|
||||||
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
{
|
{
|
||||||
var expected = new OrganizationDomain
|
var expected = new OrganizationDomain
|
||||||
@ -37,7 +40,7 @@ public class VerifyOrganizationDomainCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task UserVerifyOrganizationDomain_ShouldThrowConflict_WhenDomainHasBeenClaimedByAnotherOrganization(Guid id,
|
public async Task UserVerifyOrganizationDomainAsync_ShouldThrowConflict_WhenDomainHasBeenClaimedByAnotherOrganization(Guid id,
|
||||||
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
{
|
{
|
||||||
var expected = new OrganizationDomain
|
var expected = new OrganizationDomain
|
||||||
@ -61,7 +64,7 @@ public class VerifyOrganizationDomainCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task UserVerifyOrganizationDomain_ShouldVerifyDomainUpdateAndLogEvent_WhenTxtRecordExists(Guid id,
|
public async Task UserVerifyOrganizationDomainAsync_ShouldVerifyDomainUpdateAndLogEvent_WhenTxtRecordExists(Guid id,
|
||||||
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
{
|
{
|
||||||
var expected = new OrganizationDomain
|
var expected = new OrganizationDomain
|
||||||
@ -91,7 +94,7 @@ public class VerifyOrganizationDomainCommandTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task UserVerifyOrganizationDomain_ShouldNotSetVerifiedDate_WhenTxtRecordDoesNotExist(Guid id,
|
public async Task UserVerifyOrganizationDomainAsync_ShouldNotSetVerifiedDate_WhenTxtRecordDoesNotExist(Guid id,
|
||||||
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
{
|
{
|
||||||
var expected = new OrganizationDomain
|
var expected = new OrganizationDomain
|
||||||
@ -120,7 +123,7 @@ public class VerifyOrganizationDomainCommandTests
|
|||||||
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
[Theory, BitAutoData]
|
||||||
public async Task SystemVerifyOrganizationDomain_CallsEventServiceWithUpdatedJobRunCount(SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
public async Task SystemVerifyOrganizationDomainAsync_CallsEventServiceWithUpdatedJobRunCount(SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
{
|
{
|
||||||
var domain = new OrganizationDomain()
|
var domain = new OrganizationDomain()
|
||||||
{
|
{
|
||||||
@ -137,4 +140,97 @@ public class VerifyOrganizationDomainCommandTests
|
|||||||
.LogOrganizationDomainEventAsync(default, EventType.OrganizationDomain_NotVerified,
|
.LogOrganizationDomainEventAsync(default, EventType.OrganizationDomain_NotVerified,
|
||||||
EventSystemUser.DomainVerification);
|
EventSystemUser.DomainVerification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task UserVerifyOrganizationDomainAsync_GivenOrganizationDomainWithAccountDeprovisioningEnabled_WhenDomainIsVerified_ThenSingleOrgPolicyShouldBeEnabled(
|
||||||
|
OrganizationDomain domain, SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetClaimedDomainsByDomainNameAsync(domain.DomainName)
|
||||||
|
.Returns([]);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IDnsResolverService>()
|
||||||
|
.ResolveAsync(domain.DomainName, domain.Txt)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IFeatureService>()
|
||||||
|
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
_ = await sutProvider.Sut.UserVerifyOrganizationDomainAsync(domain);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<IPolicyService>()
|
||||||
|
.Received(1)
|
||||||
|
.SaveAsync(Arg.Is<Policy>(x => x.Type == PolicyType.SingleOrg && x.OrganizationId == domain.OrganizationId && x.Enabled), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task UserVerifyOrganizationDomainAsync_GivenOrganizationDomainWithAccountDeprovisioningDisabled_WhenDomainIsVerified_ThenSingleOrgPolicyShouldBeNotBeEnabled(
|
||||||
|
OrganizationDomain domain, SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetClaimedDomainsByDomainNameAsync(domain.DomainName)
|
||||||
|
.Returns([]);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IDnsResolverService>()
|
||||||
|
.ResolveAsync(domain.DomainName, domain.Txt)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IFeatureService>()
|
||||||
|
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
_ = await sutProvider.Sut.UserVerifyOrganizationDomainAsync(domain);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<IPolicyService>()
|
||||||
|
.DidNotReceive()
|
||||||
|
.SaveAsync(Arg.Any<Policy>(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task UserVerifyOrganizationDomainAsync_GivenOrganizationDomainWithAccountDeprovisioningEnabled_WhenDomainIsNotVerified_ThenSingleOrgPolicyShouldNotBeEnabled(
|
||||||
|
OrganizationDomain domain, SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetClaimedDomainsByDomainNameAsync(domain.DomainName)
|
||||||
|
.Returns([]);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IDnsResolverService>()
|
||||||
|
.ResolveAsync(domain.DomainName, domain.Txt)
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IFeatureService>()
|
||||||
|
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
_ = await sutProvider.Sut.UserVerifyOrganizationDomainAsync(domain);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<IPolicyService>()
|
||||||
|
.DidNotReceive()
|
||||||
|
.SaveAsync(Arg.Any<Policy>(), null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task UserVerifyOrganizationDomainAsync_GivenOrganizationDomainWithAccountDeprovisioningDisabled_WhenDomainIsNotVerified_ThenSingleOrgPolicyShouldBeNotBeEnabled(
|
||||||
|
OrganizationDomain domain, SutProvider<VerifyOrganizationDomainCommand> sutProvider)
|
||||||
|
{
|
||||||
|
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
||||||
|
.GetClaimedDomainsByDomainNameAsync(domain.DomainName)
|
||||||
|
.Returns([]);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IDnsResolverService>()
|
||||||
|
.ResolveAsync(domain.DomainName, domain.Txt)
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IFeatureService>()
|
||||||
|
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
_ = await sutProvider.Sut.UserVerifyOrganizationDomainAsync(domain);
|
||||||
|
|
||||||
|
await sutProvider.GetDependency<IPolicyService>()
|
||||||
|
.DidNotReceive()
|
||||||
|
.SaveAsync(Arg.Any<Policy>(), null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,48 +76,4 @@ public class OrganizationDomainServiceTests
|
|||||||
await sutProvider.GetDependency<IOrganizationDomainRepository>().ReceivedWithAnyArgs(1)
|
await sutProvider.GetDependency<IOrganizationDomainRepository>().ReceivedWithAnyArgs(1)
|
||||||
.DeleteExpiredAsync(7);
|
.DeleteExpiredAsync(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task HasVerifiedDomainsAsync_WithVerifiedDomain_ReturnsTrue(
|
|
||||||
OrganizationDomain organizationDomain,
|
|
||||||
SutProvider<OrganizationDomainService> sutProvider)
|
|
||||||
{
|
|
||||||
organizationDomain.SetVerifiedDate(); // Set the verified date to make it verified
|
|
||||||
|
|
||||||
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
|
||||||
.GetDomainsByOrganizationIdAsync(organizationDomain.OrganizationId)
|
|
||||||
.Returns(new List<OrganizationDomain> { organizationDomain });
|
|
||||||
|
|
||||||
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationDomain.OrganizationId);
|
|
||||||
|
|
||||||
Assert.True(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task HasVerifiedDomainsAsync_WithoutVerifiedDomain_ReturnsFalse(
|
|
||||||
OrganizationDomain organizationDomain,
|
|
||||||
SutProvider<OrganizationDomainService> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
|
||||||
.GetDomainsByOrganizationIdAsync(organizationDomain.OrganizationId)
|
|
||||||
.Returns(new List<OrganizationDomain> { organizationDomain });
|
|
||||||
|
|
||||||
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationDomain.OrganizationId);
|
|
||||||
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory, BitAutoData]
|
|
||||||
public async Task HasVerifiedDomainsAsync_WithoutOrganizationDomains_ReturnsFalse(
|
|
||||||
Guid organizationId,
|
|
||||||
SutProvider<OrganizationDomainService> sutProvider)
|
|
||||||
{
|
|
||||||
sutProvider.GetDependency<IOrganizationDomainRepository>()
|
|
||||||
.GetDomainsByOrganizationIdAsync(organizationId)
|
|
||||||
.Returns(new List<OrganizationDomain>());
|
|
||||||
|
|
||||||
var result = await sutProvider.Sut.HasVerifiedDomainsAsync(organizationId);
|
|
||||||
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,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.Models.Data.Organizations.Policies;
|
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||||
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationDomains.Interfaces;
|
||||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||||
using Bit.Core.AdminConsole.Repositories;
|
using Bit.Core.AdminConsole.Repositories;
|
||||||
using Bit.Core.AdminConsole.Services.Implementations;
|
using Bit.Core.AdminConsole.Services.Implementations;
|
||||||
@ -815,4 +816,32 @@ public class PolicyServiceTests
|
|||||||
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.DisableSend, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.User, OrganizationUserStatus = OrganizationUserStatusType.Invited, IsProvider = true }
|
new() { OrganizationId = Guid.NewGuid(), PolicyType = PolicyType.DisableSend, PolicyEnabled = true, OrganizationUserType = OrganizationUserType.User, OrganizationUserStatus = OrganizationUserStatusType.Invited, IsProvider = true }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Theory, BitAutoData]
|
||||||
|
public async Task SaveAsync_GivenOrganizationUsingPoliciesAndHasVerifiedDomains_WhenSingleOrgPolicyIsDisabled_ThenAnErrorShouldBeThrownOrganizationHasVerifiedDomains(
|
||||||
|
[AdminConsoleFixtures.Policy(PolicyType.SingleOrg)] Policy policy, Organization org, SutProvider<PolicyService> sutProvider)
|
||||||
|
{
|
||||||
|
org.Id = policy.OrganizationId;
|
||||||
|
org.UsePolicies = true;
|
||||||
|
|
||||||
|
policy.Enabled = false;
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IFeatureService>()
|
||||||
|
.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IOrganizationRepository>()
|
||||||
|
.GetByIdAsync(policy.OrganizationId)
|
||||||
|
.Returns(org);
|
||||||
|
|
||||||
|
sutProvider.GetDependency<IOrganizationHasVerifiedDomainsQuery>()
|
||||||
|
.HasVerifiedDomainsAsync(org.Id)
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
var badRequestException = await Assert.ThrowsAsync<BadRequestException>(
|
||||||
|
() => sutProvider.Sut.SaveAsync(policy, null));
|
||||||
|
|
||||||
|
Assert.Equal("Organization has verified domains.", badRequestException.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user