mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 07:36:14 -05:00
[PM-17449] Add logic to handle email updates for managed users. (#5422)
This commit is contained in:
@ -149,12 +149,6 @@ public class AccountsController : Controller
|
||||
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
|
||||
}
|
||||
|
||||
// If Account Deprovisioning is enabled, we need to check if the user is managed by any organization.
|
||||
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||
&& await _userService.IsManagedByAnyOrganizationAsync(user.Id))
|
||||
{
|
||||
throw new BadRequestException("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.");
|
||||
}
|
||||
|
||||
await _userService.InitiateEmailChangeAsync(user, model.NewEmail);
|
||||
}
|
||||
@ -173,12 +167,6 @@ public class AccountsController : Controller
|
||||
throw new BadRequestException("You cannot change your email when using Key Connector.");
|
||||
}
|
||||
|
||||
// If Account Deprovisioning is enabled, we need to check if the user is managed by any organization.
|
||||
if (_featureService.IsEnabled(FeatureFlagKeys.AccountDeprovisioning)
|
||||
&& await _userService.IsManagedByAnyOrganizationAsync(user.Id))
|
||||
{
|
||||
throw new BadRequestException("Cannot change emails for accounts owned by an organization. Contact your organization administrator for additional details.");
|
||||
}
|
||||
|
||||
var result = await _userService.ChangeEmailAsync(user, model.MasterPasswordHash, model.NewEmail,
|
||||
model.NewMasterPasswordHash, model.Token, model.Key);
|
||||
|
@ -49,6 +49,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
private readonly ICipherRepository _cipherRepository;
|
||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||
private readonly IOrganizationRepository _organizationRepository;
|
||||
private readonly IOrganizationDomainRepository _organizationDomainRepository;
|
||||
private readonly IMailService _mailService;
|
||||
private readonly IPushNotificationService _pushService;
|
||||
private readonly IdentityErrorDescriber _identityErrorDescriber;
|
||||
@ -81,6 +82,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
ICipherRepository cipherRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationDomainRepository organizationDomainRepository,
|
||||
IMailService mailService,
|
||||
IPushNotificationService pushService,
|
||||
IUserStore<User> store,
|
||||
@ -127,6 +129,7 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
_cipherRepository = cipherRepository;
|
||||
_organizationUserRepository = organizationUserRepository;
|
||||
_organizationRepository = organizationRepository;
|
||||
_organizationDomainRepository = organizationDomainRepository;
|
||||
_mailService = mailService;
|
||||
_pushService = pushService;
|
||||
_identityOptions = optionsAccessor?.Value ?? new IdentityOptions();
|
||||
@ -521,6 +524,13 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
return IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch());
|
||||
}
|
||||
|
||||
var managedUserValidationResult = await ValidateManagedUserAsync(user, newEmail);
|
||||
|
||||
if (!managedUserValidationResult.Succeeded)
|
||||
{
|
||||
return managedUserValidationResult;
|
||||
}
|
||||
|
||||
if (!await base.VerifyUserTokenAsync(user, _identityOptions.Tokens.ChangeEmailTokenProvider,
|
||||
GetChangeEmailTokenPurpose(newEmail), token))
|
||||
{
|
||||
@ -586,6 +596,31 @@ public class UserService : UserManager<User>, IUserService, IDisposable
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
private async Task<IdentityResult> ValidateManagedUserAsync(User user, string newEmail)
|
||||
{
|
||||
var managingOrganizations = await GetOrganizationsManagingUserAsync(user.Id);
|
||||
|
||||
if (!managingOrganizations.Any())
|
||||
{
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
var newDomain = CoreHelpers.GetEmailDomain(newEmail);
|
||||
|
||||
var verifiedDomains = await _organizationDomainRepository.GetVerifiedDomainsByOrganizationIdsAsync(managingOrganizations.Select(org => org.Id));
|
||||
|
||||
if (verifiedDomains.Any(verifiedDomain => verifiedDomain.DomainName == newDomain))
|
||||
{
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
return IdentityResult.Failed(new IdentityError
|
||||
{
|
||||
Code = "EmailDomainMismatch",
|
||||
Description = "Your new email must match your organization domain."
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<IdentityResult> ChangePasswordAsync(User user, string masterPassword, string newMasterPassword, string passwordHint,
|
||||
string key)
|
||||
{
|
||||
|
Reference in New Issue
Block a user