Files
server/src/Core/Services/Implementations/PolicyService.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

297 lines
12 KiB
C#
Raw Normal View History

using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Repositories;
[PM-1188] Server owner auth migration (#2825) * [PM-1188] add sso project to auth * [PM-1188] move sso api models to auth * [PM-1188] fix sso api model namespace & imports * [PM-1188] move core files to auth * [PM-1188] fix core sso namespace & models * [PM-1188] move sso repository files to auth * [PM-1188] fix sso repo files namespace & imports * [PM-1188] move sso sql files to auth folder * [PM-1188] move sso test files to auth folders * [PM-1188] fix sso tests namespace & imports * [PM-1188] move auth api files to auth folder * [PM-1188] fix auth api files namespace & imports * [PM-1188] move auth core files to auth folder * [PM-1188] fix auth core files namespace & imports * [PM-1188] move auth email templates to auth folder * [PM-1188] move auth email folder back into shared directory * [PM-1188] fix auth email names * [PM-1188] move auth core models to auth folder * [PM-1188] fix auth model namespace & imports * [PM-1188] add entire Identity project to auth codeowners * [PM-1188] fix auth orm files namespace & imports * [PM-1188] move auth orm files to auth folder * [PM-1188] move auth sql files to auth folder * [PM-1188] move auth tests to auth folder * [PM-1188] fix auth test files namespace & imports * [PM-1188] move emergency access api files to auth folder * [PM-1188] fix emergencyaccess api files namespace & imports * [PM-1188] move emergency access core files to auth folder * [PM-1188] fix emergency access core files namespace & imports * [PM-1188] move emergency access orm files to auth folder * [PM-1188] fix emergency access orm files namespace & imports * [PM-1188] move emergency access sql files to auth folder * [PM-1188] move emergencyaccess test files to auth folder * [PM-1188] fix emergency access test files namespace & imports * [PM-1188] move captcha files to auth folder * [PM-1188] fix captcha files namespace & imports * [PM-1188] move auth admin files into auth folder * [PM-1188] fix admin auth files namespace & imports - configure mvc to look in auth folders for views * [PM-1188] remove extra imports and formatting * [PM-1188] fix ef auth model imports * [PM-1188] fix DatabaseContextModelSnapshot paths * [PM-1188] fix grant import in ef * [PM-1188] update sqlproj * [PM-1188] move missed sqlproj files * [PM-1188] move auth ef models out of auth folder * [PM-1188] fix auth ef models namespace * [PM-1188] remove auth ef models unused imports * [PM-1188] fix imports for auth ef models * [PM-1188] fix more ef model imports * [PM-1188] fix file encodings
2023-04-14 13:25:56 -04:00
using Bit.Core.Entities;
using Bit.Core.Enums;
2020-01-15 09:19:28 -05:00
using Bit.Core.Exceptions;
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
[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
2023-04-17 07:35:47 -07:00
using Bit.Core.Models.Data.Organizations.Policies;
2020-01-15 09:19:28 -05:00
using Bit.Core.Repositories;
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
using Bit.Core.Settings;
2020-01-15 09:19:28 -05:00
namespace Bit.Core.Services;
2022-08-29 16:06:55 -04:00
2020-01-15 09:19:28 -05:00
public class PolicyService : IPolicyService
{
private readonly IEventService _eventService;
private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IPolicyRepository _policyRepository;
private readonly ISsoConfigRepository _ssoConfigRepository;
private readonly IMailService _mailService;
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
private readonly GlobalSettings _globalSettings;
2022-08-29 16:06:55 -04:00
private IEnumerable<OrganizationUserPolicyDetails> _cachedOrganizationUserPolicyDetails;
2020-01-15 09:19:28 -05:00
public PolicyService(
IEventService eventService,
IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository,
IPolicyRepository policyRepository,
ISsoConfigRepository ssoConfigRepository,
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
IMailService mailService,
GlobalSettings globalSettings)
2020-01-15 09:19:28 -05:00
{
_eventService = eventService;
_organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository;
_policyRepository = policyRepository;
_ssoConfigRepository = ssoConfigRepository;
_mailService = mailService;
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
_globalSettings = globalSettings;
2022-08-29 16:06:55 -04:00
}
2020-01-15 09:19:28 -05:00
public async Task SaveAsync(Policy policy, IUserService userService, IOrganizationService organizationService,
2020-02-19 14:56:16 -05:00
Guid? savingUserId)
2022-08-29 16:06:55 -04:00
{
var org = await _organizationRepository.GetByIdAsync(policy.OrganizationId);
if (org == null)
2020-01-15 09:19:28 -05:00
{
throw new BadRequestException("Organization not found");
}
2020-02-19 14:56:16 -05:00
if (!org.UsePolicies)
2020-01-15 09:19:28 -05:00
{
throw new BadRequestException("This organization cannot use policies.");
}
2021-12-16 15:35:09 +01:00
// Handle dependent policy checks
switch (policy.Type)
{
case PolicyType.SingleOrg:
if (!policy.Enabled)
{
await RequiredBySsoAsync(org);
await RequiredByVaultTimeoutAsync(org);
await RequiredByKeyConnectorAsync(org);
await RequiredByAccountRecoveryAsync(org);
}
break;
case PolicyType.RequireSso:
if (policy.Enabled)
{
await DependsOnSingleOrgAsync(org);
}
else
{
await RequiredByKeyConnectorAsync(org);
}
break;
2020-01-15 09:19:28 -05:00
case PolicyType.ResetPassword:
if (!policy.Enabled || policy.GetDataModel<ResetPasswordDataModel>()?.AutoEnrollEnabled == false)
{
await RequiredBySsoTrustedDeviceEncryptionAsync(org);
}
if (policy.Enabled)
{
await DependsOnSingleOrgAsync(org);
}
break;
2020-01-20 09:02:41 -05:00
case PolicyType.MaximumVaultTimeout:
if (policy.Enabled)
2020-01-15 09:19:28 -05:00
{
2020-01-20 09:02:41 -05:00
await DependsOnSingleOrgAsync(org);
}
2020-01-20 09:02:41 -05:00
break;
// Activate Autofill is only available to Enterprise 2020-current plans
case PolicyType.ActivateAutofill:
if (policy.Enabled)
{
LockedTo2020Plan(org);
}
break;
2020-01-15 09:19:28 -05:00
}
2020-01-20 09:02:41 -05:00
var now = DateTime.UtcNow;
if (policy.Id == default(Guid))
{
2020-01-20 09:02:41 -05:00
policy.CreationDate = now;
}
if (policy.Enabled)
2022-08-29 16:06:55 -04:00
{
2020-02-19 14:56:16 -05:00
var currentPolicy = await _policyRepository.GetByIdAsync(policy.Id);
if (!currentPolicy?.Enabled ?? true)
2020-02-19 14:56:16 -05:00
{
var orgUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(
policy.OrganizationId);
var removableOrgUsers = orgUsers.Where(ou =>
ou.Status != Enums.OrganizationUserStatusType.Invited && ou.Status != Enums.OrganizationUserStatusType.Revoked &&
ou.Type != Enums.OrganizationUserType.Owner && ou.Type != Enums.OrganizationUserType.Admin &&
ou.UserId != savingUserId);
switch (policy.Type)
2020-02-19 14:56:16 -05:00
{
case Enums.PolicyType.TwoFactorAuthentication:
foreach (var orgUser in removableOrgUsers)
2022-08-29 16:06:55 -04:00
{
if (!await userService.TwoFactorIsEnabledAsync(orgUser))
2020-02-19 14:56:16 -05:00
{
await organizationService.DeleteUserAsync(policy.OrganizationId, orgUser.Id,
savingUserId);
await _mailService.SendOrganizationUserRemovedForPolicyTwoStepEmailAsync(
org.Name, orgUser.Email);
2020-02-19 14:56:16 -05:00
}
2022-08-29 16:06:55 -04:00
}
break;
case Enums.PolicyType.SingleOrg:
var userOrgs = await _organizationUserRepository.GetManyByManyUsersAsync(
removableOrgUsers.Select(ou => ou.UserId.Value));
foreach (var orgUser in removableOrgUsers)
2022-08-29 16:06:55 -04:00
{
if (userOrgs.Any(ou => ou.UserId == orgUser.UserId
&& ou.OrganizationId != org.Id
&& ou.Status != OrganizationUserStatusType.Invited))
{
await organizationService.DeleteUserAsync(policy.OrganizationId, orgUser.Id,
savingUserId);
await _mailService.SendOrganizationUserRemovedForPolicySingleOrgEmailAsync(
org.Name, orgUser.Email);
}
2022-08-29 16:06:55 -04:00
}
break;
default:
break;
2020-02-19 14:56:16 -05:00
}
}
2020-01-15 09:19:28 -05:00
}
policy.RevisionDate = now;
2020-01-20 09:02:41 -05:00
await _policyRepository.UpsertAsync(policy);
await _eventService.LogPolicyEventAsync(policy, Enums.EventType.Policy_Updated);
2022-08-29 16:06:55 -04: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
2023-04-17 07:35:47 -07:00
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;
}
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
public async Task<ICollection<OrganizationUserPolicyDetails>> GetPoliciesApplicableToUserAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
{
var result = await QueryOrganizationUserPolicyDetailsAsync(userId, policyType, minStatus);
return result.ToList();
}
public async Task<bool> AnyPoliciesApplicableToUserAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
{
var result = await QueryOrganizationUserPolicyDetailsAsync(userId, policyType, minStatus);
return result.Any();
}
private async Task<IEnumerable<OrganizationUserPolicyDetails>> QueryOrganizationUserPolicyDetailsAsync(Guid userId, PolicyType? policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted)
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
{
// Check if the cached policies are available
if (_cachedOrganizationUserPolicyDetails == null)
{
// Cached policies not available, retrieve from the repository
_cachedOrganizationUserPolicyDetails = await _organizationUserRepository.GetByUserIdWithPolicyDetailsAsync(userId);
}
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
var excludedUserTypes = GetUserTypesExcludedFromPolicy(policyType);
return _cachedOrganizationUserPolicyDetails.Where(o =>
(policyType == null || o.PolicyType == policyType) &&
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
o.PolicyEnabled &&
!excludedUserTypes.Contains(o.OrganizationUserType) &&
o.OrganizationUserStatus >= minStatus &&
!o.IsProvider);
}
private OrganizationUserType[] GetUserTypesExcludedFromPolicy(PolicyType? policyType)
[EC-787] Create a method in PolicyService to check if a policy applies to a user (#2537) * [EC-787] Add new stored procedure OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Add new method IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Add OrganizationUserPolicyDetails to represent policies applicable to a specific user * [EC-787] Add method IPolicyService.GetPoliciesApplicableToUser to filter the obtained policy data * [EC-787] Returning PolicyData on stored procedures * [EC-787] Changed GetPoliciesApplicableToUserAsync to return ICollection * [EC-787] Switched all usings of IPolicyRepository.GetManyByTypeApplicableToUserIdAsync to IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Removed policy logic from BaseRequestValidator and added usage of IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for IPolicyService.GetPoliciesApplicableToUserAsync * [EC-787] Added unit tests for OrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Changed integration test to check for single result * [EC-787] Marked IPolicyRepository methods GetManyByTypeApplicableToUserIdAsync and GetCountByTypeApplicableToUserIdAsync as obsolete * [EC-787] Returning OrganizationUserId on OrganizationUser_ReadByUserIdWithPolicyDetails * [EC-787] Remove deprecated stored procedures Policy_CountByTypeApplicableToUser, Policy_ReadByTypeApplicableToUser and function PolicyApplicableToUser * [EC-787] Added method IPolicyService.AnyPoliciesApplicableToUserAsync * [EC-787] Removed 'OrganizationUserType' parameter from queries * [EC-787] Formatted OrganizationUserPolicyDetailsCompare * [EC-787] Renamed SQL migration files * [EC-787] Changed OrganizationUser_ReadByUserIdWithPolicyDetails to return Permissions json * [EC-787] Refactored excluded user types for each Policy * [EC-787] Updated dates on dbo_future files * [EC-787] Remove dbo_future files from sql proj * [EC-787] Added parameter PolicyType to IOrganizationUserRepository.GetByUserIdWithPolicyDetailsAsync * [EC-787] Rewrote OrganizationUser_ReadByUserIdWithPolicyDetails and added parameter for PolicyType * Update util/Migrator/DbScripts/2023-03-10_00_OrganizationUserReadByUserIdWithPolicyDetails.sql Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com> --------- Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2023-05-12 08:22:19 +01:00
{
switch (policyType)
{
case PolicyType.MasterPassword:
return Array.Empty<OrganizationUserType>();
case PolicyType.RequireSso:
// If 'EnforceSsoPolicyForAllUsers' is set to true then SSO policy applies to all user types otherwise it does not apply to Owner or Admin
if (_globalSettings.Sso.EnforceSsoPolicyForAllUsers)
{
return Array.Empty<OrganizationUserType>();
}
break;
}
return new[] { OrganizationUserType.Owner, OrganizationUserType.Admin };
}
private async Task DependsOnSingleOrgAsync(Organization org)
2022-08-29 16:06:55 -04:00
{
var singleOrg = await _policyRepository.GetByOrganizationIdTypeAsync(org.Id, PolicyType.SingleOrg);
if (singleOrg?.Enabled != true)
{
throw new BadRequestException("Single Organization policy not enabled.");
}
2022-08-29 16:06:55 -04:00
}
private async Task RequiredBySsoAsync(Organization org)
2022-08-29 16:06:55 -04:00
{
var requireSso = await _policyRepository.GetByOrganizationIdTypeAsync(org.Id, PolicyType.RequireSso);
if (requireSso?.Enabled == true)
{
throw new BadRequestException("Single Sign-On Authentication policy is enabled.");
}
2022-08-29 16:06:55 -04:00
}
private async Task RequiredByKeyConnectorAsync(Organization org)
{
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.KeyConnector)
{
throw new BadRequestException("Key Connector is enabled.");
}
2022-08-29 16:06:55 -04:00
}
private async Task RequiredByAccountRecoveryAsync(Organization org)
{
var requireSso = await _policyRepository.GetByOrganizationIdTypeAsync(org.Id, PolicyType.ResetPassword);
if (requireSso?.Enabled == true)
{
throw new BadRequestException("Account recovery policy is enabled.");
}
}
private async Task RequiredByVaultTimeoutAsync(Organization org)
2022-08-29 16:06:55 -04:00
{
var vaultTimeout = await _policyRepository.GetByOrganizationIdTypeAsync(org.Id, PolicyType.MaximumVaultTimeout);
if (vaultTimeout?.Enabled == true)
{
throw new BadRequestException("Maximum Vault Timeout policy is enabled.");
}
2020-01-15 09:19:28 -05:00
}
private void LockedTo2020Plan(Organization org)
{
if (org.PlanType != PlanType.EnterpriseAnnually && org.PlanType != PlanType.EnterpriseMonthly)
{
throw new BadRequestException("This policy is only available to 2020 Enterprise plans.");
}
}
private async Task RequiredBySsoTrustedDeviceEncryptionAsync(Organization org)
{
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id);
if (ssoConfig?.GetData()?.MemberDecryptionType == MemberDecryptionType.TrustedDeviceEncryption)
{
throw new BadRequestException("Trusted device encryption is on and requires this policy.");
}
}
2020-01-15 09:19:28 -05:00
}