1
0
mirror of https://github.com/bitwarden/server synced 2025-12-22 19:23:45 +00:00

[PM-24582] Bugfix: exclude admins and owners from default user collection creation on confirmation (#6177)

* Update the OrganizationUserController integration Confirm tests to handle the Owner type

* Refactor ConfirmOrganizationUserCommand to simplify side-effect handling in organization user confirmation.
Update IPolicyRequirementQuery to return eligible org user IDs for policy enforcement.
Update tests for method signature changes and default collection creation logic.
This commit is contained in:
Rui Tomé
2025-08-11 16:36:40 +01:00
committed by GitHub
parent e88c9b3525
commit e042572cfb
6 changed files with 99 additions and 95 deletions

View File

@@ -81,11 +81,11 @@ public class PolicyRequirementQueryTests
}
[Theory, BitAutoData]
public async Task GetByOrganizationAsync_IgnoresOtherPolicyTypes(Guid organizationId)
public async Task GetManyByOrganizationIdAsync_IgnoresOtherPolicyTypes(Guid organizationId)
{
var policyRepository = Substitute.For<IPolicyRepository>();
var thisPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, UserId = Guid.NewGuid() };
var otherPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.RequireSso, UserId = Guid.NewGuid() };
var thisPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, OrganizationUserId = Guid.NewGuid() };
var otherPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.RequireSso, OrganizationUserId = Guid.NewGuid() };
// Force the repository to return both policies even though that is not the expected result
policyRepository.GetPolicyDetailsByOrganizationIdAsync(organizationId, PolicyType.SingleOrg)
.Returns([thisPolicy, otherPolicy]);
@@ -93,20 +93,20 @@ public class PolicyRequirementQueryTests
var factory = new TestPolicyRequirementFactory(_ => true);
var sut = new PolicyRequirementQuery(policyRepository, [factory]);
var requirement = await sut.GetByOrganizationAsync<TestPolicyRequirement>(organizationId);
var organizationUserIds = await sut.GetManyByOrganizationIdAsync<TestPolicyRequirement>(organizationId);
await policyRepository.Received(1).GetPolicyDetailsByOrganizationIdAsync(organizationId, PolicyType.SingleOrg);
Assert.Contains(thisPolicy, requirement.Policies.Cast<OrganizationPolicyDetails>());
Assert.DoesNotContain(otherPolicy, requirement.Policies.Cast<OrganizationPolicyDetails>());
Assert.Contains(thisPolicy.OrganizationUserId, organizationUserIds);
Assert.DoesNotContain(otherPolicy.OrganizationUserId, organizationUserIds);
}
[Theory, BitAutoData]
public async Task GetByOrganizationAsync_CallsEnforceCallback(Guid organizationId)
public async Task GetManyByOrganizationIdAsync_CallsEnforceCallback(Guid organizationId)
{
var policyRepository = Substitute.For<IPolicyRepository>();
var thisPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, UserId = Guid.NewGuid() };
var otherPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, UserId = Guid.NewGuid() };
var thisPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, OrganizationUserId = Guid.NewGuid() };
var otherPolicy = new OrganizationPolicyDetails { PolicyType = PolicyType.SingleOrg, OrganizationUserId = Guid.NewGuid() };
policyRepository.GetPolicyDetailsByOrganizationIdAsync(organizationId, PolicyType.SingleOrg).Returns([thisPolicy, otherPolicy]);
var callback = Substitute.For<Func<PolicyDetails, bool>>();
@@ -115,28 +115,28 @@ public class PolicyRequirementQueryTests
var factory = new TestPolicyRequirementFactory(callback);
var sut = new PolicyRequirementQuery(policyRepository, [factory]);
var requirement = await sut.GetByOrganizationAsync<TestPolicyRequirement>(organizationId);
var organizationUserIds = await sut.GetManyByOrganizationIdAsync<TestPolicyRequirement>(organizationId);
Assert.Contains(thisPolicy, requirement.Policies.Cast<OrganizationPolicyDetails>());
Assert.DoesNotContain(otherPolicy, requirement.Policies.Cast<OrganizationPolicyDetails>());
Assert.Contains(thisPolicy.OrganizationUserId, organizationUserIds);
Assert.DoesNotContain(otherPolicy.OrganizationUserId, organizationUserIds);
callback.Received()(Arg.Is<PolicyDetails>(p => p == thisPolicy));
callback.Received()(Arg.Is<PolicyDetails>(p => p == otherPolicy));
}
[Theory, BitAutoData]
public async Task GetByOrganizationAsync_ThrowsIfNoFactoryRegistered(Guid organizationId)
public async Task GetManyByOrganizationIdAsync_ThrowsIfNoFactoryRegistered(Guid organizationId)
{
var policyRepository = Substitute.For<IPolicyRepository>();
var sut = new PolicyRequirementQuery(policyRepository, []);
var exception = await Assert.ThrowsAsync<NotImplementedException>(()
=> sut.GetByOrganizationAsync<TestPolicyRequirement>(organizationId));
=> sut.GetManyByOrganizationIdAsync<TestPolicyRequirement>(organizationId));
Assert.Contains("No Requirement Factory found", exception.Message);
}
[Theory, BitAutoData]
public async Task GetByOrganizationAsync_HandlesNoPolicies(Guid organizationId)
public async Task GetManyByOrganizationIdAsync_HandlesNoPolicies(Guid organizationId)
{
var policyRepository = Substitute.For<IPolicyRepository>();
policyRepository.GetPolicyDetailsByOrganizationIdAsync(organizationId, PolicyType.SingleOrg).Returns([]);
@@ -144,8 +144,8 @@ public class PolicyRequirementQueryTests
var factory = new TestPolicyRequirementFactory(x => x.IsProvider);
var sut = new PolicyRequirementQuery(policyRepository, [factory]);
var requirement = await sut.GetByOrganizationAsync<TestPolicyRequirement>(organizationId);
var organizationUserIds = await sut.GetManyByOrganizationIdAsync<TestPolicyRequirement>(organizationId);
Assert.Empty(requirement.Policies);
Assert.Empty(organizationUserIds);
}
}