mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
Ac/pm 18240 implement policy requirement for reset password policy (#5521)
* wip * fix test * fix test * refactor * fix factory method and tests * cleanup * refactor * update copy * cleanup
This commit is contained in:
@ -7,6 +7,8 @@ using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Auth.Entities;
|
||||
using Bit.Core.Auth.Repositories;
|
||||
@ -424,4 +426,93 @@ public class OrganizationUsersControllerTests
|
||||
.GetManyDetailsByOrganizationAsync(organizationAbility.Id, Arg.Any<bool>(), Arg.Any<bool>())
|
||||
.Returns(organizationUsers);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task Accept_WhenOrganizationUsePoliciesIsEnabledAndResetPolicyIsEnabled_WithPolicyRequirementsEnabled_ShouldHandleResetPassword(Guid orgId, Guid orgUserId,
|
||||
OrganizationUserAcceptRequestModel model, User user, SutProvider<OrganizationUsersController> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
var applicationCacheService = sutProvider.GetDependency<IApplicationCacheService>();
|
||||
applicationCacheService.GetOrganizationAbilityAsync(orgId).Returns(new OrganizationAbility { UsePolicies = true });
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
|
||||
var policy = new Policy
|
||||
{
|
||||
Enabled = true,
|
||||
Data = CoreHelpers.ClassToJsonData(new ResetPasswordDataModel { AutoEnrollEnabled = true, }),
|
||||
};
|
||||
var userService = sutProvider.GetDependency<IUserService>();
|
||||
userService.GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
|
||||
|
||||
var policyRequirementQuery = sutProvider.GetDependency<IPolicyRequirementQuery>();
|
||||
|
||||
var policyRepository = sutProvider.GetDependency<IPolicyRepository>();
|
||||
|
||||
var policyRequirement = new ResetPasswordPolicyRequirement { AutoEnrollOrganizations = [orgId] };
|
||||
|
||||
policyRequirementQuery.GetAsync<ResetPasswordPolicyRequirement>(user.Id).Returns(policyRequirement);
|
||||
|
||||
// Act
|
||||
await sutProvider.Sut.Accept(orgId, orgUserId, model);
|
||||
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IAcceptOrgUserCommand>().Received(1)
|
||||
.AcceptOrgUserByEmailTokenAsync(orgUserId, user, model.Token, userService);
|
||||
await sutProvider.GetDependency<IOrganizationService>().Received(1)
|
||||
.UpdateUserResetPasswordEnrollmentAsync(orgId, user.Id, model.ResetPasswordKey, user.Id);
|
||||
|
||||
await userService.Received(1).GetUserByPrincipalAsync(default);
|
||||
await applicationCacheService.Received(0).GetOrganizationAbilityAsync(orgId);
|
||||
await policyRepository.Received(0).GetByOrganizationIdTypeAsync(orgId, PolicyType.ResetPassword);
|
||||
await policyRequirementQuery.Received(1).GetAsync<ResetPasswordPolicyRequirement>(user.Id);
|
||||
Assert.True(policyRequirement.AutoEnrollEnabled(orgId));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public async Task Accept_WithInvalidModelResetPasswordKey_WithPolicyRequirementsEnabled_ThrowsBadRequestException(Guid orgId, Guid orgUserId,
|
||||
OrganizationUserAcceptRequestModel model, User user, SutProvider<OrganizationUsersController> sutProvider)
|
||||
{
|
||||
// Arrange
|
||||
model.ResetPasswordKey = " ";
|
||||
var applicationCacheService = sutProvider.GetDependency<IApplicationCacheService>();
|
||||
applicationCacheService.GetOrganizationAbilityAsync(orgId).Returns(new OrganizationAbility { UsePolicies = true });
|
||||
|
||||
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
|
||||
var policy = new Policy
|
||||
{
|
||||
Enabled = true,
|
||||
Data = CoreHelpers.ClassToJsonData(new ResetPasswordDataModel { AutoEnrollEnabled = true, }),
|
||||
};
|
||||
var userService = sutProvider.GetDependency<IUserService>();
|
||||
userService.GetUserByPrincipalAsync(default).ReturnsForAnyArgs(user);
|
||||
|
||||
var policyRepository = sutProvider.GetDependency<IPolicyRepository>();
|
||||
|
||||
var policyRequirementQuery = sutProvider.GetDependency<IPolicyRequirementQuery>();
|
||||
|
||||
var policyRequirement = new ResetPasswordPolicyRequirement { AutoEnrollOrganizations = [orgId] };
|
||||
|
||||
policyRequirementQuery.GetAsync<ResetPasswordPolicyRequirement>(user.Id).Returns(policyRequirement);
|
||||
|
||||
// Act
|
||||
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||
sutProvider.Sut.Accept(orgId, orgUserId, model));
|
||||
|
||||
// Assert
|
||||
await sutProvider.GetDependency<IAcceptOrgUserCommand>().Received(0)
|
||||
.AcceptOrgUserByEmailTokenAsync(orgUserId, user, model.Token, userService);
|
||||
await sutProvider.GetDependency<IOrganizationService>().Received(0)
|
||||
.UpdateUserResetPasswordEnrollmentAsync(orgId, user.Id, model.ResetPasswordKey, user.Id);
|
||||
|
||||
await userService.Received(1).GetUserByPrincipalAsync(default);
|
||||
await applicationCacheService.Received(0).GetOrganizationAbilityAsync(orgId);
|
||||
await policyRepository.Received(0).GetByOrganizationIdTypeAsync(orgId, PolicyType.ResetPassword);
|
||||
await policyRequirementQuery.Received(1).GetAsync<ResetPasswordPolicyRequirement>(user.Id);
|
||||
|
||||
Assert.Equal("Master Password reset is required, but not provided.", exception.Message);
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,15 @@ using Bit.Api.AdminConsole.Controllers;
|
||||
using Bit.Api.Auth.Models.Request.Accounts;
|
||||
using Bit.Core;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Models.Business.Tokenables;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationApiKeys.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Organizations.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.Policies.PolicyRequirements;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Auth.Entities;
|
||||
using Bit.Core.Auth.Enums;
|
||||
@ -55,6 +58,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
private readonly IRemoveOrganizationUserCommand _removeOrganizationUserCommand;
|
||||
private readonly ICloudOrganizationSignUpCommand _cloudOrganizationSignUpCommand;
|
||||
private readonly IOrganizationDeleteCommand _organizationDeleteCommand;
|
||||
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
||||
private readonly IPricingClient _pricingClient;
|
||||
private readonly OrganizationsController _sut;
|
||||
|
||||
@ -80,6 +84,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
_removeOrganizationUserCommand = Substitute.For<IRemoveOrganizationUserCommand>();
|
||||
_cloudOrganizationSignUpCommand = Substitute.For<ICloudOrganizationSignUpCommand>();
|
||||
_organizationDeleteCommand = Substitute.For<IOrganizationDeleteCommand>();
|
||||
_policyRequirementQuery = Substitute.For<IPolicyRequirementQuery>();
|
||||
_pricingClient = Substitute.For<IPricingClient>();
|
||||
|
||||
_sut = new OrganizationsController(
|
||||
@ -103,6 +108,7 @@ public class OrganizationsControllerTests : IDisposable
|
||||
_removeOrganizationUserCommand,
|
||||
_cloudOrganizationSignUpCommand,
|
||||
_organizationDeleteCommand,
|
||||
_policyRequirementQuery,
|
||||
_pricingClient);
|
||||
}
|
||||
|
||||
@ -236,4 +242,55 @@ public class OrganizationsControllerTests : IDisposable
|
||||
|
||||
await _organizationDeleteCommand.Received(1).DeleteAsync(organization);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public async Task GetAutoEnrollStatus_WithPolicyRequirementsEnabled_ReturnsOrganizationAutoEnrollStatus_WithResetPasswordEnabledTrue(
|
||||
User user,
|
||||
Organization organization,
|
||||
OrganizationUser organizationUser
|
||||
)
|
||||
{
|
||||
var policyRequirement = new ResetPasswordPolicyRequirement() { AutoEnrollOrganizations = [organization.Id] };
|
||||
|
||||
_userService.GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
||||
_organizationRepository.GetByIdentifierAsync(organization.Id.ToString()).Returns(organization);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(true);
|
||||
_organizationUserRepository.GetByOrganizationAsync(organization.Id, user.Id).Returns(organizationUser);
|
||||
_policyRequirementQuery.GetAsync<ResetPasswordPolicyRequirement>(user.Id).Returns(policyRequirement);
|
||||
|
||||
var result = await _sut.GetAutoEnrollStatus(organization.Id.ToString());
|
||||
|
||||
await _userService.Received(1).GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>());
|
||||
await _organizationRepository.Received(1).GetByIdentifierAsync(organization.Id.ToString());
|
||||
await _policyRequirementQuery.Received(1).GetAsync<ResetPasswordPolicyRequirement>(user.Id);
|
||||
|
||||
Assert.True(result.ResetPasswordEnabled);
|
||||
Assert.Equal(result.Id, organization.Id);
|
||||
}
|
||||
|
||||
[Theory, AutoData]
|
||||
public async Task GetAutoEnrollStatus_WithPolicyRequirementsDisabled_ReturnsOrganizationAutoEnrollStatus_WithResetPasswordEnabledTrue(
|
||||
User user,
|
||||
Organization organization,
|
||||
OrganizationUser organizationUser
|
||||
)
|
||||
{
|
||||
|
||||
var policy = new Policy() { Type = PolicyType.ResetPassword, Enabled = true, Data = "{\"AutoEnrollEnabled\": true}", OrganizationId = organization.Id };
|
||||
|
||||
_userService.GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
||||
_organizationRepository.GetByIdentifierAsync(organization.Id.ToString()).Returns(organization);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.PolicyRequirements).Returns(false);
|
||||
_organizationUserRepository.GetByOrganizationAsync(organization.Id, user.Id).Returns(organizationUser);
|
||||
_policyRepository.GetByOrganizationIdTypeAsync(organization.Id, PolicyType.ResetPassword).Returns(policy);
|
||||
|
||||
var result = await _sut.GetAutoEnrollStatus(organization.Id.ToString());
|
||||
|
||||
await _userService.Received(1).GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>());
|
||||
await _organizationRepository.Received(1).GetByIdentifierAsync(organization.Id.ToString());
|
||||
await _policyRequirementQuery.Received(0).GetAsync<ResetPasswordPolicyRequirement>(user.Id);
|
||||
await _policyRepository.Received(1).GetByOrganizationIdTypeAsync(organization.Id, PolicyType.ResetPassword);
|
||||
|
||||
Assert.True(result.ResetPasswordEnabled);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user