mirror of
https://github.com/bitwarden/server.git
synced 2025-02-22 02:51:33 +01:00
CheckPoliciesOnTwoFactorRemoval
for 2fa recovery (#659)
This commit is contained in:
parent
ae893c72bd
commit
71d9ffdd9d
@ -359,7 +359,8 @@ namespace Bit.Api.Controllers
|
||||
[AllowAnonymous]
|
||||
public async Task PostRecover([FromBody]TwoFactorRecoveryRequestModel model)
|
||||
{
|
||||
if(!await _userService.RecoverTwoFactorAsync(model.Email, model.MasterPasswordHash, model.RecoveryCode))
|
||||
if(!await _userService.RecoverTwoFactorAsync(model.Email, model.MasterPasswordHash, model.RecoveryCode,
|
||||
_organizationService))
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
throw new BadRequestException(string.Empty, "Invalid information. Try again.");
|
||||
|
@ -39,7 +39,8 @@ namespace Bit.Core.Services
|
||||
Task UpdateTwoFactorProviderAsync(User user, TwoFactorProviderType type);
|
||||
Task DisableTwoFactorProviderAsync(User user, TwoFactorProviderType type,
|
||||
IOrganizationService organizationService);
|
||||
Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode);
|
||||
Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode,
|
||||
IOrganizationService organizationService);
|
||||
Task<string> GenerateUserTokenAsync(User user, string tokenProvider, string purpose);
|
||||
Task<IdentityResult> DeleteAsync(User user);
|
||||
Task<IdentityResult> DeleteAsync(User user, string token);
|
||||
|
@ -668,28 +668,12 @@ namespace Bit.Core.Services
|
||||
|
||||
if(!await TwoFactorIsEnabledAsync(user))
|
||||
{
|
||||
var policies = await _policyRepository.GetManyByUserIdAsync(user.Id);
|
||||
var twoFactorPolicies = policies.Where(p => p.Type == PolicyType.TwoFactorAuthentication && p.Enabled);
|
||||
if(twoFactorPolicies.Any())
|
||||
{
|
||||
var userOrgs = await _organizationUserRepository.GetManyByUserAsync(user.Id);
|
||||
var ownerOrgs = userOrgs.Where(o => o.Type == OrganizationUserType.Owner)
|
||||
.Select(o => o.OrganizationId).ToHashSet();
|
||||
foreach(var policy in twoFactorPolicies)
|
||||
{
|
||||
if(!ownerOrgs.Contains(policy.OrganizationId))
|
||||
{
|
||||
await organizationService.DeleteUserAsync(policy.OrganizationId, user.Id);
|
||||
var organization = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||
await _mailService.SendOrganizationUserRemovedForPolicyTwoStepEmailAsync(
|
||||
organization.Name, user.Email);
|
||||
}
|
||||
}
|
||||
}
|
||||
await CheckPoliciesOnTwoFactorRemovalAsync(user, organizationService);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode)
|
||||
public async Task<bool> RecoverTwoFactorAsync(string email, string masterPassword, string recoveryCode,
|
||||
IOrganizationService organizationService)
|
||||
{
|
||||
var user = await _userRepository.GetByEmailAsync(email);
|
||||
if(user == null)
|
||||
@ -713,6 +697,7 @@ namespace Bit.Core.Services
|
||||
await SaveUserAsync(user);
|
||||
await _mailService.SendRecoverTwoFactorEmail(user.Email, DateTime.UtcNow, _currentContext.IpAddress);
|
||||
await _eventService.LogUserEventAsync(user.Id, EventType.User_Recovered2fa);
|
||||
await CheckPoliciesOnTwoFactorRemovalAsync(user, organizationService);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1094,5 +1079,27 @@ namespace Bit.Core.Services
|
||||
user.TwoFactorRecoveryCode = CoreHelpers.SecureRandomString(32, upper: false, special: false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckPoliciesOnTwoFactorRemovalAsync(User user, IOrganizationService organizationService)
|
||||
{
|
||||
var policies = await _policyRepository.GetManyByUserIdAsync(user.Id);
|
||||
var twoFactorPolicies = policies.Where(p => p.Type == PolicyType.TwoFactorAuthentication && p.Enabled);
|
||||
if(twoFactorPolicies.Any())
|
||||
{
|
||||
var userOrgs = await _organizationUserRepository.GetManyByUserAsync(user.Id);
|
||||
var ownerOrgs = userOrgs.Where(o => o.Type == OrganizationUserType.Owner)
|
||||
.Select(o => o.OrganizationId).ToHashSet();
|
||||
foreach(var policy in twoFactorPolicies)
|
||||
{
|
||||
if(!ownerOrgs.Contains(policy.OrganizationId))
|
||||
{
|
||||
await organizationService.DeleteUserAsync(policy.OrganizationId, user.Id);
|
||||
var organization = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
|
||||
await _mailService.SendOrganizationUserRemovedForPolicyTwoStepEmailAsync(
|
||||
organization.Name, user.Email);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user