validate and email on sso privisioning (#6734)

This commit is contained in:
Kyle Spearrin
2025-12-15 15:19:17 -05:00
committed by GitHub
parent 3c44430979
commit bead4f1d5a
2 changed files with 89 additions and 0 deletions

View File

@@ -99,6 +99,9 @@ public class RegisterUserCommand : IRegisterUserCommand
public async Task<IdentityResult> RegisterSSOAutoProvisionedUserAsync(User user, Organization organization) public async Task<IdentityResult> RegisterSSOAutoProvisionedUserAsync(User user, Organization organization)
{ {
// Validate that the email domain is not blocked by another organization's policy
await ValidateEmailDomainNotBlockedAsync(user.Email, organization.Id);
var result = await _userService.CreateUserAsync(user); var result = await _userService.CreateUserAsync(user);
if (result == IdentityResult.Success) if (result == IdentityResult.Success)
{ {

View File

@@ -1382,4 +1382,90 @@ public class RegisterUserCommandTests
.Received(1) .Received(1)
.SendOrganizationUserWelcomeEmailAsync(user, organization.DisplayName()); .SendOrganizationUserWelcomeEmailAsync(user, organization.DisplayName());
} }
[Theory, BitAutoData]
public async Task RegisterSSOAutoProvisionedUserAsync_WithBlockedDomain_ThrowsException(
User user,
Organization organization,
SutProvider<RegisterUserCommand> sutProvider)
{
// Arrange
user.Email = "user@blocked-domain.com";
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.BlockClaimedDomainAccountCreation)
.Returns(true);
sutProvider.GetDependency<IOrganizationDomainRepository>()
.HasVerifiedDomainWithBlockClaimedDomainPolicyAsync("blocked-domain.com", organization.Id)
.Returns(true);
// Act & Assert
var exception = await Assert.ThrowsAsync<BadRequestException>(() =>
sutProvider.Sut.RegisterSSOAutoProvisionedUserAsync(user, organization));
Assert.Equal("This email address is claimed by an organization using Bitwarden.", exception.Message);
}
[Theory, BitAutoData]
public async Task RegisterSSOAutoProvisionedUserAsync_WithOwnClaimedDomain_Succeeds(
User user,
Organization organization,
SutProvider<RegisterUserCommand> sutProvider)
{
// Arrange
user.Email = "user@company-domain.com";
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.BlockClaimedDomainAccountCreation)
.Returns(true);
// Domain is claimed by THIS organization, so it should be allowed
sutProvider.GetDependency<IOrganizationDomainRepository>()
.HasVerifiedDomainWithBlockClaimedDomainPolicyAsync("company-domain.com", organization.Id)
.Returns(false); // Not blocked because organization.Id is excluded
sutProvider.GetDependency<IUserService>()
.CreateUserAsync(user)
.Returns(IdentityResult.Success);
// Act
var result = await sutProvider.Sut.RegisterSSOAutoProvisionedUserAsync(user, organization);
// Assert
Assert.True(result.Succeeded);
await sutProvider.GetDependency<IUserService>()
.Received(1)
.CreateUserAsync(user);
}
[Theory, BitAutoData]
public async Task RegisterSSOAutoProvisionedUserAsync_WithNonClaimedDomain_Succeeds(
User user,
Organization organization,
SutProvider<RegisterUserCommand> sutProvider)
{
// Arrange
user.Email = "user@unclaimed-domain.com";
sutProvider.GetDependency<IFeatureService>()
.IsEnabled(FeatureFlagKeys.BlockClaimedDomainAccountCreation)
.Returns(true);
sutProvider.GetDependency<IOrganizationDomainRepository>()
.HasVerifiedDomainWithBlockClaimedDomainPolicyAsync("unclaimed-domain.com", organization.Id)
.Returns(false); // Domain is not claimed by any org
sutProvider.GetDependency<IUserService>()
.CreateUserAsync(user)
.Returns(IdentityResult.Success);
// Act
var result = await sutProvider.Sut.RegisterSSOAutoProvisionedUserAsync(user, organization);
// Assert
Assert.True(result.Succeeded);
await sutProvider.GetDependency<IUserService>()
.Received(1)
.CreateUserAsync(user);
}
} }