mirror of
https://github.com/bitwarden/server.git
synced 2025-06-07 11:40:31 -05:00
feat(change-password-component): Change Password Update [18720] - Now sending back accepted mp policies on base validator
This commit is contained in:
parent
8165651285
commit
7ed190006b
@ -81,12 +81,15 @@ public class SyncController : Controller
|
||||
throw new BadRequestException("User not found.");
|
||||
}
|
||||
|
||||
var organizationUserDetails = await _organizationUserRepository.GetManyDetailsByUserAsync(user.Id,
|
||||
var organizationUserDetails = await _organizationUserRepository.GetManyDetailsByUserAsync(
|
||||
user.Id,
|
||||
OrganizationUserStatusType.Confirmed);
|
||||
var providerUserDetails = await _providerUserRepository.GetManyDetailsByUserAsync(user.Id,
|
||||
var providerUserDetails = await _providerUserRepository.GetManyDetailsByUserAsync(
|
||||
user.Id,
|
||||
ProviderUserStatusType.Confirmed);
|
||||
var providerUserOrganizationDetails =
|
||||
await _providerUserRepository.GetManyOrganizationDetailsByUserAsync(user.Id,
|
||||
await _providerUserRepository.GetManyOrganizationDetailsByUserAsync(
|
||||
user.Id,
|
||||
ProviderUserStatusType.Confirmed);
|
||||
var hasEnabledOrgs = organizationUserDetails.Any(o => o.Enabled);
|
||||
|
||||
|
@ -20,6 +20,7 @@ public interface IPolicyRepository : IRepository<Policy, Guid>
|
||||
Task<Policy?> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type);
|
||||
Task<ICollection<Policy>> GetManyByOrganizationIdAsync(Guid organizationId);
|
||||
Task<ICollection<Policy>> GetManyByUserIdAsync(Guid userId);
|
||||
Task<ICollection<Policy>> GetManyAcceptedOrConfirmedByUserIdAsync(Guid userId);
|
||||
/// <summary>
|
||||
/// Gets all PolicyDetails for a user for all policy types.
|
||||
/// </summary>
|
||||
|
@ -11,7 +11,7 @@ public interface IPolicyService
|
||||
/// <summary>
|
||||
/// Get the combined master password policy options for the specified user.
|
||||
/// </summary>
|
||||
Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user);
|
||||
Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user, bool getConfirmedOrAccepted = false);
|
||||
Task<ICollection<OrganizationUserPolicyDetails>> GetPoliciesApplicableToUserAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted);
|
||||
Task<bool> AnyPoliciesApplicableToUserAsync(Guid userId, PolicyType policyType, OrganizationUserStatusType minStatus = OrganizationUserStatusType.Accepted);
|
||||
}
|
||||
|
@ -29,9 +29,13 @@ public class PolicyService : IPolicyService
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user)
|
||||
public async Task<MasterPasswordPolicyData> GetMasterPasswordPolicyForUserAsync(User user, bool getConfirmedOrAccepted = false)
|
||||
{
|
||||
var policies = (await _policyRepository.GetManyByUserIdAsync(user.Id))
|
||||
var policies = getConfirmedOrAccepted ?
|
||||
(await _policyRepository.GetManyAcceptedOrConfirmedByUserIdAsync(user.Id))
|
||||
.Where(p => p.Type == PolicyType.MasterPassword && p.Enabled)
|
||||
.ToList()
|
||||
: (await _policyRepository.GetManyByUserIdAsync(user.Id))
|
||||
.Where(p => p.Type == PolicyType.MasterPassword && p.Enabled)
|
||||
.ToList();
|
||||
|
||||
|
@ -32,6 +32,7 @@ public class CurrentContext : ICurrentContext
|
||||
public virtual string IpAddress { get; set; }
|
||||
public virtual string CountryName { get; set; }
|
||||
public virtual List<CurrentContextOrganization> Organizations { get; set; }
|
||||
public virtual List<CurrentContextOrganization> OrganizationsConfirmedOrAccepted { get; set; }
|
||||
public virtual List<CurrentContextProvider> Providers { get; set; }
|
||||
public virtual Guid? InstallationId { get; set; }
|
||||
public virtual Guid? OrganizationId { get; set; }
|
||||
@ -481,6 +482,22 @@ public class CurrentContext : ICurrentContext
|
||||
return Organizations;
|
||||
}
|
||||
|
||||
public async Task<ICollection<CurrentContextOrganization>> OrganizationAcceptedOrConfirmedAsync(
|
||||
IOrganizationUserRepository organizationUserRepository, Guid userId)
|
||||
{
|
||||
if (OrganizationsConfirmedOrAccepted == null)
|
||||
{
|
||||
// If we haven't had our user id set, take the one passed in since we are about to get information
|
||||
// for them anyways.
|
||||
UserId ??= userId;
|
||||
|
||||
var userOrgs = await organizationUserRepository.GetManyDetailsByUserAsync(userId);
|
||||
OrganizationsConfirmedOrAccepted = userOrgs.Where(ou => ou.Status == OrganizationUserStatusType.Confirmed || ou.Status == OrganizationUserStatusType.Accepted)
|
||||
.Select(ou => new CurrentContextOrganization(ou)).ToList();
|
||||
}
|
||||
return OrganizationsConfirmedOrAccepted;
|
||||
}
|
||||
|
||||
public async Task<ICollection<CurrentContextProvider>> ProviderMembershipAsync(
|
||||
IProviderUserRepository providerUserRepository, Guid userId)
|
||||
{
|
||||
|
@ -70,6 +70,9 @@ public interface ICurrentContext
|
||||
Task<ICollection<CurrentContextOrganization>> OrganizationMembershipAsync(
|
||||
IOrganizationUserRepository organizationUserRepository, Guid userId);
|
||||
|
||||
Task<ICollection<CurrentContextOrganization>> OrganizationAcceptedOrConfirmedAsync(
|
||||
IOrganizationUserRepository organizationUserRepository, Guid userId);
|
||||
|
||||
Task<ICollection<CurrentContextProvider>> ProviderMembershipAsync(
|
||||
IProviderUserRepository providerUserRepository, Guid userId);
|
||||
|
||||
|
@ -361,7 +361,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
private async Task<MasterPasswordPolicyResponseModel> GetMasterPasswordPolicyAsync(User user)
|
||||
{
|
||||
// Check current context/cache to see if user is in any organizations, avoids extra DB call if not
|
||||
var orgs = (await CurrentContext.OrganizationMembershipAsync(_organizationUserRepository, user.Id))
|
||||
var orgs = (await CurrentContext.OrganizationAcceptedOrConfirmedAsync(_organizationUserRepository, user.Id))
|
||||
.ToList();
|
||||
|
||||
if (orgs.Count == 0)
|
||||
@ -369,7 +369,7 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
return null;
|
||||
}
|
||||
|
||||
return new MasterPasswordPolicyResponseModel(await PolicyService.GetMasterPasswordPolicyForUserAsync(user));
|
||||
return new MasterPasswordPolicyResponseModel(await PolicyService.GetMasterPasswordPolicyForUserAsync(user, true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -401,8 +401,8 @@ public abstract class BaseRequestValidator<T> where T : class
|
||||
/// <summary>
|
||||
/// Builds the custom response that will be sent to the client upon successful authentication, which
|
||||
/// includes the information needed for the client to initialize the user's account in state.
|
||||
/// </summary>
|
||||
/// <param name="user">The authenticated user.</param>
|
||||
/// </summary>
|
||||
/// <param name="user">The authenticated user.</param>
|
||||
/// <param name="context">The current request context.</param>
|
||||
/// <param name="device">The device used for authentication.</param>
|
||||
/// <param name="sendRememberToken">Whether to send a 2FA remember token.</param>
|
||||
|
@ -61,6 +61,19 @@ public class PolicyRepository : Repository<Policy, Guid>, IPolicyRepository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ICollection<Policy>> GetManyAcceptedOrConfirmedByUserIdAsync(Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.QueryAsync<Policy>(
|
||||
$"[{Schema}].[{Table}_ReadAcceptedOrConfirmedByUserId]",
|
||||
new { UserId = userId },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
return results.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PolicyDetails>> GetPolicyDetailsByUserId(Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -20,37 +20,41 @@ public class PolicyRepository : Repository<AdminConsoleEntities.Policy, Policy,
|
||||
|
||||
public async Task<AdminConsoleEntities.Policy> GetByOrganizationIdTypeAsync(Guid organizationId, PolicyType type)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var results = await dbContext.Policies
|
||||
.FirstOrDefaultAsync(p => p.OrganizationId == organizationId && p.Type == type);
|
||||
return Mapper.Map<AdminConsoleEntities.Policy>(results);
|
||||
}
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var results = await dbContext.Policies
|
||||
.FirstOrDefaultAsync(p => p.OrganizationId == organizationId && p.Type == type);
|
||||
return Mapper.Map<AdminConsoleEntities.Policy>(results);
|
||||
}
|
||||
|
||||
public async Task<ICollection<AdminConsoleEntities.Policy>> GetManyByOrganizationIdAsync(Guid organizationId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var results = await dbContext.Policies
|
||||
.Where(p => p.OrganizationId == organizationId)
|
||||
.ToListAsync();
|
||||
return Mapper.Map<List<AdminConsoleEntities.Policy>>(results);
|
||||
}
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var results = await dbContext.Policies
|
||||
.Where(p => p.OrganizationId == organizationId)
|
||||
.ToListAsync();
|
||||
return Mapper.Map<List<AdminConsoleEntities.Policy>>(results);
|
||||
}
|
||||
|
||||
public async Task<ICollection<AdminConsoleEntities.Policy>> GetManyByUserIdAsync(Guid userId)
|
||||
{
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
||||
var query = new PolicyReadByUserIdQuery(userId);
|
||||
var results = await query.Run(dbContext).ToListAsync();
|
||||
return Mapper.Map<List<AdminConsoleEntities.Policy>>(results);
|
||||
}
|
||||
var query = new PolicyReadByUserIdQuery(userId);
|
||||
var results = await query.Run(dbContext).ToListAsync();
|
||||
return Mapper.Map<List<AdminConsoleEntities.Policy>>(results);
|
||||
}
|
||||
|
||||
public async Task<ICollection<AdminConsoleEntities.Policy>> GetManyAcceptedOrConfirmedByUserIdAsync(Guid userId)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
|
||||
var query = new PolicyReadAcceptedOrConfirmedByUserIdQuery(userId);
|
||||
var results = await query.Run(dbContext).ToListAsync();
|
||||
return Mapper.Map<List<AdminConsoleEntities.Policy>>(results);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<PolicyDetails>> GetPolicyDetailsByUserId(Guid userId)
|
||||
|
@ -0,0 +1,31 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Infrastructure.EntityFramework.AdminConsole.Models;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Repositories.Queries;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.AdminConsole.Repositories.Queries;
|
||||
|
||||
public class PolicyReadAcceptedOrConfirmedByUserIdQuery : IQuery<Policy>
|
||||
{
|
||||
private readonly Guid _userId;
|
||||
|
||||
public PolicyReadAcceptedOrConfirmedByUserIdQuery(Guid userId)
|
||||
{
|
||||
_userId = userId;
|
||||
}
|
||||
|
||||
public IQueryable<Policy> Run(DatabaseContext dbContext)
|
||||
{
|
||||
var query = from p in dbContext.Policies
|
||||
join ou in dbContext.OrganizationUsers
|
||||
on p.OrganizationId equals ou.OrganizationId
|
||||
join o in dbContext.Organizations
|
||||
on ou.OrganizationId equals o.Id
|
||||
where ou.UserId == _userId &&
|
||||
(ou.Status == OrganizationUserStatusType.Confirmed
|
||||
|| ou.Status == OrganizationUserStatusType.Accepted)
|
||||
select p;
|
||||
|
||||
return query;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
CREATE PROCEDURE [dbo].[Policy_ReadAcceptedOrConfirmedByUserId]
|
||||
@UserId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
P.*
|
||||
FROM
|
||||
[dbo].[PolicyView] P
|
||||
INNER JOIN
|
||||
[dbo].[OrganizationUser] OU ON P.[OrganizationId] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON OU.[OrganizationId] = O.[Id]
|
||||
WHERE
|
||||
OU.[UserId] = @UserId
|
||||
AND (OU.[Status] = 1 OR OU.[Status] = 2) -- 1 = Accepted, 2 = Confirmed
|
||||
END
|
@ -0,0 +1,18 @@
|
||||
CREATE OR ALTER PROCEDURE [dbo].[Policy_ReadAcceptedOrConfirmedByUserId]
|
||||
@UserId UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
SELECT
|
||||
P.*
|
||||
FROM
|
||||
[dbo].[PolicyView] P
|
||||
INNER JOIN
|
||||
[dbo].[OrganizationUser] OU ON P.[OrganizationId] = OU.[OrganizationId]
|
||||
INNER JOIN
|
||||
[dbo].[Organization] O ON OU.[OrganizationId] = O.[Id]
|
||||
WHERE
|
||||
OU.[UserId] = @UserId
|
||||
AND (OU.[Status] = 1 OR OU.[Status] = 2) -- 1 = Accepted, 2 = Confirmed
|
||||
END
|
Loading…
x
Reference in New Issue
Block a user