1
0
mirror of https://github.com/bitwarden/server synced 2025-12-20 18:23:44 +00:00

Cleaned up accept org user command tests

This commit is contained in:
Jared McCannon
2025-12-01 10:24:38 -06:00
parent 4bea324503
commit f5d03068cb
2 changed files with 29 additions and 128 deletions

View File

@@ -92,12 +92,12 @@ public class PolicyService : IPolicyService
OrganizationUserType[] excludedUserTypes; OrganizationUserType[] excludedUserTypes;
if (policyType == PolicyType.SingleOrg // looking for single org if (policyType == PolicyType.SingleOrg
&& _featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers) // if autoconfirm is enabled && _featureService.IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers)
&& (await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, PolicyType.AutomaticUserConfirmation)).Any()) // any auto confirm details associated with user id && (await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId, PolicyType.AutomaticUserConfirmation)).Any())
{ {
minStatus = OrganizationUserStatusType.Revoked; // all statuses count minStatus = OrganizationUserStatusType.Revoked;
excludedUserTypes = []; // no excluded types excludedUserTypes = [];
} }
else else
{ {

View File

@@ -680,100 +680,26 @@ public class AcceptOrgUserCommandTests
[Theory] [Theory]
[BitAutoData] [BitAutoData]
public async Task AcceptOrgUserAsync_WithAutoConfirmEnabledOnOrgAndUserBelongsToAnotherOrg_ThrowsBadRequest( public async Task AcceptOrgUserAsync_WithAutoConfirmIsNotEnabled_DoesNotCheckCompliance(
SutProvider<AcceptOrgUserCommand> sutProvider,
User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails,
OrganizationUser otherOrgUser)
{
// Arrange
SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails);
// User belongs to another organization
otherOrgUser.UserId = user.Id;
otherOrgUser.OrganizationId = Guid.NewGuid(); // Different org
var allOrgUsers = new List<OrganizationUser> { otherOrgUser };
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByUserAsync(user.Id)
.Returns(Task.FromResult<ICollection<OrganizationUser>>(allOrgUsers));
// Mock auto-confirm enforcement query to return error
sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>()
.IsCompliantAsync(Arg.Is<AutomaticUserConfirmationPolicyEnforcementRequest>(r =>
r.OrganizationUser == orgUser &&
r.User == user))
.Returns(Invalid(
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, allOrgUsers, user),
new OrganizationEnforcesSingleOrgPolicy()));
// Act & Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService));
Assert.Equal(new OrganizationEnforcesSingleOrgPolicy().Message, exception.Message);
}
[Theory]
[BitAutoData]
public async Task AcceptOrgUserAsync_WithAutoConfirmEnabledOnOtherOrgAndUserBelongsToAnotherOrg_ThrowsBadRequest(
SutProvider<AcceptOrgUserCommand> sutProvider,
User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails,
OrganizationUser otherOrgUser)
{
// Arrange
SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails);
// User belongs to another organization
otherOrgUser.UserId = user.Id;
otherOrgUser.OrganizationId = Guid.NewGuid(); // Different org
var allOrgUsers = new List<OrganizationUser> { otherOrgUser };
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByUserAsync(user.Id)
.Returns(Task.FromResult<ICollection<OrganizationUser>>(allOrgUsers));
// Mock auto-confirm enforcement query to return error for other org having auto-confirm
sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>()
.IsCompliantAsync(Arg.Is<AutomaticUserConfirmationPolicyEnforcementRequest>(r =>
r.OrganizationUser == orgUser &&
r.User == user))
.Returns(Invalid(
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, allOrgUsers, user),
new OtherOrganizationEnforcesSingleOrgPolicy()));
// Act & Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService));
Assert.Equal(new OtherOrganizationEnforcesSingleOrgPolicy().Message, exception.Message);
}
[Theory]
[BitAutoData]
public async Task AcceptOrgUserAsync_WithAutoConfirmEnabledAndUserIsProvider_ThrowsBadRequest(
SutProvider<AcceptOrgUserCommand> sutProvider, SutProvider<AcceptOrgUserCommand> sutProvider,
User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails) User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails)
{ {
// Arrange // Arrange
SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails); SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails);
// Mock auto-confirm enforcement query to return provider error // Act
sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>() var resultOrgUser = await sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService);
.IsCompliantAsync(Arg.Is<AutomaticUserConfirmationPolicyEnforcementRequest>(r =>
r.OrganizationUser == orgUser &&
r.User == user))
.Returns(Invalid(
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, [], user),
new ProviderUsersCannotJoin()));
// Act & Assert // Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(() => AssertValidAcceptedOrgUser(resultOrgUser, orgUser, user);
sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService));
Assert.Equal(new ProviderUsersCannotJoin().Message, exception.Message); await sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>().DidNotReceiveWithAnyArgs()
.IsCompliantAsync(Arg.Any<AutomaticUserConfirmationPolicyEnforcementRequest>());
} }
[Theory] [Theory]
[BitAutoData] [BitAutoData]
public async Task AcceptOrgUserAsync_WithAutoConfirmNotApplicable_AcceptsUser( public async Task AcceptOrgUserAsync_WithUserThatIsCompliantWithAutoConfirm_AcceptsUser(
SutProvider<AcceptOrgUserCommand> sutProvider, SutProvider<AcceptOrgUserCommand> sutProvider,
User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails) User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails)
{ {
@@ -797,7 +723,7 @@ public class AcceptOrgUserCommandTests
[Theory] [Theory]
[BitAutoData] [BitAutoData]
public async Task AcceptOrgUserAsync_WithAutoConfirmValidationBeforeSingleOrgPolicy_ChecksAutoConfirmFirst( public async Task AcceptOrgUserAsync_WithAutoConfirmIsEnabledAndFailsCompliance_ThrowsBadRequestException(
SutProvider<AcceptOrgUserCommand> sutProvider, SutProvider<AcceptOrgUserCommand> sutProvider,
User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails, User user, Organization org, OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails,
OrganizationUser otherOrgUser) OrganizationUser otherOrgUser)
@@ -805,36 +731,22 @@ public class AcceptOrgUserCommandTests
// Arrange // Arrange
SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails); SetupCommonAcceptOrgUserMocks(sutProvider, user, org, orgUser, adminUserDetails);
// Setup conditions that would fail BOTH auto-confirm AND single org policy checks sutProvider.GetDependency<IFeatureService>()
otherOrgUser.UserId = user.Id; .IsEnabled(FeatureFlagKeys.AutomaticConfirmUsers)
otherOrgUser.OrganizationId = Guid.NewGuid(); .Returns(true);
var allOrgUsers = new List<OrganizationUser> { otherOrgUser };
sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByUserAsync(user.Id)
.Returns(Task.FromResult<ICollection<OrganizationUser>>(allOrgUsers));
// Make organization they are trying to join have the single org policy (would fail single org check)
var singleOrgPolicy = new OrganizationUserPolicyDetails { OrganizationId = orgUser.OrganizationId };
sutProvider.GetDependency<IPolicyService>()
.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg, OrganizationUserStatusType.Invited)
.Returns(Task.FromResult<ICollection<OrganizationUserPolicyDetails>>(
new List<OrganizationUserPolicyDetails> { singleOrgPolicy }));
// Mock auto-confirm to fail FIRST (should be checked before single org policy)
sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>() sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>()
.IsCompliantAsync(Arg.Any<AutomaticUserConfirmationPolicyEnforcementRequest>()) .IsCompliantAsync(Arg.Any<AutomaticUserConfirmationPolicyEnforcementRequest>())
.Returns(Invalid( .Returns(Invalid(
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, allOrgUsers, user), new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, [otherOrgUser], user),
new OrganizationEnforcesSingleOrgPolicy())); new OrganizationEnforcesSingleOrgPolicy()));
// Act & Assert // Act & Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(() => var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService)); sutProvider.Sut.AcceptOrgUserAsync(orgUser, user, _userService));
// Should get auto-confirm error (OrganizationEnforcesSingleOrgPolicy) NOT the regular single org policy error // Should get auto-confirm error
Assert.Equal(new OrganizationEnforcesSingleOrgPolicy().Message, exception.Message); Assert.Equal(new OrganizationEnforcesSingleOrgPolicy().Message, exception.Message);
Assert.NotEqual("You may not join this organization until you leave or remove all other organizations.",
exception.Message);
} }
// Private helpers ------------------------------------------------------------------------------------------------- // Private helpers -------------------------------------------------------------------------------------------------
@@ -880,7 +792,7 @@ public class AcceptOrgUserCommandTests
/// - Provides mock data for an admin to validate email functionality. /// - Provides mock data for an admin to validate email functionality.
/// - Returns the corresponding organization for the given org ID. /// - Returns the corresponding organization for the given org ID.
/// </summary> /// </summary>
private void SetupCommonAcceptOrgUserMocks(SutProvider<AcceptOrgUserCommand> sutProvider, User user, private static void SetupCommonAcceptOrgUserMocks(SutProvider<AcceptOrgUserCommand> sutProvider, User user,
Organization org, Organization org,
OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails) OrganizationUser orgUser, OrganizationUserUserDetails adminUserDetails)
{ {
@@ -893,18 +805,12 @@ public class AcceptOrgUserCommandTests
// User is not part of any other orgs // User is not part of any other orgs
sutProvider.GetDependency<IOrganizationUserRepository>() sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByUserAsync(user.Id) .GetManyByUserAsync(user.Id)
.Returns( .Returns([]);
Task.FromResult<ICollection<OrganizationUser>>(new List<OrganizationUser>())
);
// Org they are trying to join does not have single org policy // Org they are trying to join does not have single org policy
sutProvider.GetDependency<IPolicyService>() sutProvider.GetDependency<IPolicyService>()
.GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg, OrganizationUserStatusType.Invited) .GetPoliciesApplicableToUserAsync(user.Id, PolicyType.SingleOrg, OrganizationUserStatusType.Invited)
.Returns( .Returns([]);
Task.FromResult<ICollection<OrganizationUserPolicyDetails>>(
new List<OrganizationUserPolicyDetails>()
)
);
// User is not part of any organization that applies the single org policy // User is not part of any organization that applies the single org policy
sutProvider.GetDependency<IPolicyService>() sutProvider.GetDependency<IPolicyService>()
@@ -914,29 +820,24 @@ public class AcceptOrgUserCommandTests
// Org does not require 2FA // Org does not require 2FA
sutProvider.GetDependency<IPolicyService>().GetPoliciesApplicableToUserAsync(user.Id, sutProvider.GetDependency<IPolicyService>().GetPoliciesApplicableToUserAsync(user.Id,
PolicyType.TwoFactorAuthentication, OrganizationUserStatusType.Invited) PolicyType.TwoFactorAuthentication, OrganizationUserStatusType.Invited)
.Returns(Task.FromResult<ICollection<OrganizationUserPolicyDetails>>( .Returns([]);
new List<OrganizationUserPolicyDetails>()));
// Provide at least 1 admin to test email functionality // Provide at least 1 admin to test email functionality
sutProvider.GetDependency<IOrganizationUserRepository>() sutProvider.GetDependency<IOrganizationUserRepository>()
.GetManyByMinimumRoleAsync(orgUser.OrganizationId, OrganizationUserType.Admin) .GetManyByMinimumRoleAsync(orgUser.OrganizationId, OrganizationUserType.Admin)
.Returns(Task.FromResult<IEnumerable<OrganizationUserUserDetails>>( .Returns([adminUserDetails]);
new List<OrganizationUserUserDetails>() { adminUserDetails }
));
// Return org // Return org
sutProvider.GetDependency<IOrganizationRepository>() sutProvider.GetDependency<IOrganizationRepository>()
.GetByIdAsync(org.Id) .GetByIdAsync(org.Id)
.Returns(Task.FromResult(org)); .Returns(org);
// Auto-confirm enforcement query returns valid by default (no restrictions) // Auto-confirm enforcement query returns valid by default (no restrictions)
var request = new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser, [], user);
sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>() sutProvider.GetDependency<IAutomaticUserConfirmationPolicyEnforcementQuery>()
.IsCompliantAsync(Arg.Any<AutomaticUserConfirmationPolicyEnforcementRequest>()) .IsCompliantAsync(request)
.Returns(callInfo => .Returns(Valid(request));
{
var request = callInfo.Arg<AutomaticUserConfirmationPolicyEnforcementRequest>();
return Valid(request);
});
} }