mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[AC-1070] Enforce master password policy on login (#2714)
* [EC-1070] Add API endpoint to retrieve all policies for the current user The additional API endpoint is required to avoid forcing a full sync call before every login for master password policy enforcement on login. * [EC-1070] Add MasterPasswordPolicyData model * [EC-1070] Move PolicyResponseModel to Core project The response model is used by both the Identity and Api projects. * [EC-1070] Supply master password polices as a custom identity token response * [EC-1070] Include master password policies in 2FA token response * [EC-1070] Add response model to verify-password endpoint that includes master password policies * [AC-1070] Introduce MasterPasswordPolicyResponseModel * [AC-1070] Add policy service method to retrieve a user's master password policy * [AC-1070] User new policy service method - Update BaseRequestValidator - Update AccountsController for /verify-password endpoint - Update VerifyMasterPasswordResponseModel to accept MasterPasswordPolicyData * [AC-1070] Cleanup new policy service method - Use User object instead of Guid - Remove TODO message - Use `PolicyRepository.GetManyByTypeApplicableToUserIdAsync` instead of filtering locally * [AC-1070] Cleanup MasterPasswordPolicy models - Remove default values from both models - Add missing `RequireLower` - Fix mismatched properties in `CombineWith` method - Make properties nullable in response model * [AC-1070] Remove now un-used GET /policies endpoint * [AC-1070] Update policy service method to use GetManyByUserIdAsync * [AC-1070] Ensure existing value is not null before comparison * [AC-1070] Remove redundant VerifyMasterPasswordResponse model * [AC-1070] Fix service typo in constructor
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
|
||||
namespace Bit.Core.Services;
|
||||
|
||||
@ -6,4 +7,9 @@ public interface IPolicyService
|
||||
{
|
||||
Task SaveAsync(Policy policy, IUserService userService, IOrganizationService organizationService,
|
||||
Guid? savingUserId);
|
||||
|
||||
/// <summary>
|
||||
/// Get the combined master password policy options for the specified user.
|
||||
/// </summary>
|
||||
Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.Repositories;
|
||||
|
||||
namespace Bit.Core.Services;
|
||||
@ -141,6 +142,27 @@ public class PolicyService : IPolicyService
|
||||
await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Updated);
|
||||
}
|
||||
|
||||
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
||||
{
|
||||
var policies = (await _policyRepository.GetManyByUserIdAsync(user.Id))
|
||||
.Where(p => p.Type == PolicyType.MasterPassword && p.Enabled)
|
||||
.ToList();
|
||||
|
||||
if (!policies.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var enforcedOptions = new MasterPasswordPolicyData();
|
||||
|
||||
foreach (var policy in policies)
|
||||
{
|
||||
enforcedOptions.CombineWith(policy.GetDataModel<MasterPasswordPolicyData>());
|
||||
}
|
||||
|
||||
return enforcedOptions;
|
||||
}
|
||||
|
||||
private async Task DependsOnSingleOrgAsync(Organization org)
|
||||
{
|
||||
var singleOrg = await _policyRepository.GetByOrganizationIdTypeAsync(org.Id, PolicyType.SingleOrg);
|
||||
|
Reference in New Issue
Block a user