mirror of
https://github.com/bitwarden/server.git
synced 2025-03-12 13:29:14 +01:00
Ac/pm 17449/add managed user validation to email token (#5437)
This commit is contained in:
parent
6bc579f51e
commit
6ca98df721
@ -149,6 +149,12 @@ public class AccountsController : Controller
|
||||
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
|
||||
}
|
||||
|
||||
var managedUserValidationResult = await _userService.ValidateManagedUserDomainAsync(user, model.NewEmail);
|
||||
|
||||
if (!managedUserValidationResult.Succeeded)
|
||||
{
|
||||
throw new BadRequestException(managedUserValidationResult.Errors);
|
||||
}
|
||||
|
||||
await _userService.InitiateEmailChangeAsync(user, model.NewEmail);
|
||||
}
|
||||
@ -167,7 +173,6 @@ public class AccountsController : Controller
|
||||
throw new BadRequestException("You cannot change your email when using Key Connector.");
|
||||
}
|
||||
|
||||
|
||||
var result = await _userService.ChangeEmailAsync(user, model.MasterPasswordHash, model.NewEmail,
|
||||
model.NewMasterPasswordHash, model.Token, model.Key);
|
||||
if (result.Succeeded)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace Bit.Core.Exceptions;
|
||||
|
||||
@ -29,5 +30,16 @@ public class BadRequestException : Exception
|
||||
ModelState = modelState;
|
||||
}
|
||||
|
||||
public BadRequestException(IEnumerable<IdentityError> identityErrors)
|
||||
: base("The model state is invalid.")
|
||||
{
|
||||
ModelState = new ModelStateDictionary();
|
||||
|
||||
foreach (var error in identityErrors)
|
||||
{
|
||||
ModelState.AddModelError(error.Code, error.Description);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelStateDictionary ModelState { get; set; }
|
||||
}
|
||||
|
@ -136,6 +136,16 @@ public interface IUserService
|
||||
/// </returns>
|
||||
Task<bool> IsManagedByAnyOrganizationAsync(Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Verify whether the new email domain meets the requirements for managed users.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
/// <returns>
|
||||
/// IdentityResult
|
||||
/// </returns>
|
||||
Task<IdentityResult> ValidateManagedUserDomainAsync(User user, string newEmail);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the organizations that manage the user.
|
||||
/// </summary>
|
||||
|
@ -545,7 +545,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
return IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch());
|
||||
}
|
||||
|
||||
var managedUserValidationResult = await ValidateManagedUserAsync(user, newEmail);
|
||||
var managedUserValidationResult = await ValidateManagedUserDomainAsync(user, newEmail);
|
||||
|
||||
if (!managedUserValidationResult.Succeeded)
|
||||
{
|
||||
@ -617,7 +617,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
private async Task<IdentityResult> ValidateManagedUserAsync(User user, string newEmail)
|
||||
public async Task<IdentityResult> ValidateManagedUserDomainAsync(User user, string newEmail)
|
||||
{
|
||||
var managingOrganizations = await GetOrganizationsManagingUserAsync(user.Id);
|
||||
|
||||
|
@ -134,29 +134,43 @@ public class AccountsControllerTests : IDisposable
|
||||
[Fact]
|
||||
public async Task PostEmailToken_ShouldInitiateEmailChange()
|
||||
{
|
||||
// Arrange
|
||||
var user = GenerateExampleUser();
|
||||
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||
ConfigureUserServiceToAcceptPasswordFor(user);
|
||||
var newEmail = "example@user.com";
|
||||
const string newEmail = "example@user.com";
|
||||
_userService.ValidateManagedUserDomainAsync(user, newEmail).Returns(IdentityResult.Success);
|
||||
|
||||
// Act
|
||||
await _sut.PostEmailToken(new EmailTokenRequestModel { NewEmail = newEmail });
|
||||
|
||||
// Assert
|
||||
await _userService.Received(1).InitiateEmailChangeAsync(user, newEmail);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PostEmailToken_WithAccountDeprovisioningEnabled_WhenUserIsNotManagedByAnOrganization_ShouldInitiateEmailChange()
|
||||
public async Task PostEmailToken_WhenValidateManagedUserDomainAsyncFails_ShouldReturnError()
|
||||
{
|
||||
// Arrange
|
||||
var user = GenerateExampleUser();
|
||||
ConfigureUserServiceToReturnValidPrincipalFor(user);
|
||||
ConfigureUserServiceToAcceptPasswordFor(user);
|
||||
_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning).Returns(true);
|
||||
_userService.IsManagedByAnyOrganizationAsync(user.Id).Returns(false);
|
||||
var newEmail = "example@user.com";
|
||||
|
||||
await _sut.PostEmailToken(new EmailTokenRequestModel { NewEmail = newEmail });
|
||||
const string newEmail = "example@user.com";
|
||||
|
||||
await _userService.Received(1).InitiateEmailChangeAsync(user, newEmail);
|
||||
_userService.ValidateManagedUserDomainAsync(user, newEmail)
|
||||
.Returns(IdentityResult.Failed(new IdentityError
|
||||
{
|
||||
Code = "TestFailure",
|
||||
Description = "This is a test."
|
||||
}));
|
||||
|
||||
|
||||
// Act
|
||||
// Assert
|
||||
await Assert.ThrowsAsync<BadRequestException>(
|
||||
() => _sut.PostEmailToken(new EmailTokenRequestModel { NewEmail = newEmail })
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
Loading…
Reference in New Issue
Block a user