mirror of
https://github.com/bitwarden/server.git
synced 2025-03-02 04:11:04 +01:00
Optimized implementations of sqlite and other db interactions.
This commit is contained in:
parent
406f941538
commit
23c049a617
@ -31,7 +31,7 @@ public class DeviceAuthRequestResponseModel : ResponseModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is there a better way to do this in Dapper so that I don't need to explicitly
|
* Is there a better way to do this for Dapper so that I don't need to explicitly
|
||||||
* enumerate all the properties in the constructor for mapping?
|
* enumerate all the properties in the constructor for mapping?
|
||||||
*/
|
*/
|
||||||
public DeviceAuthRequestResponseModel(
|
public DeviceAuthRequestResponseModel(
|
||||||
@ -56,7 +56,9 @@ public class DeviceAuthRequestResponseModel : ResponseModel
|
|||||||
Type = (DeviceType)type;
|
Type = (DeviceType)type;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
CreationDate = creationDate;
|
CreationDate = creationDate;
|
||||||
IsTrusted = active;
|
IsTrusted = !string.IsNullOrEmpty(encryptedUserKey) &&
|
||||||
|
!string.IsNullOrEmpty(encryptedPublicKey) &&
|
||||||
|
!string.IsNullOrEmpty(encryptedPrivateKey);
|
||||||
if (authRequestId != Guid.Empty && authRequestCreationDate != DateTime.MinValue)
|
if (authRequestId != Guid.Empty && authRequestCreationDate != DateTime.MinValue)
|
||||||
{
|
{
|
||||||
DevicePendingAuthRequest = new PendingAuthRequest()
|
DevicePendingAuthRequest = new PendingAuthRequest()
|
||||||
@ -67,6 +69,7 @@ public class DeviceAuthRequestResponseModel : ResponseModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public DeviceType Type { get; set; }
|
public DeviceType Type { get; set; }
|
||||||
|
@ -90,6 +90,19 @@ public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
|||||||
},
|
},
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
foreach (var result in results)
|
||||||
|
{
|
||||||
|
result.IsTrusted = result.IsTrusted;
|
||||||
|
if (result.DevicePendingAuthRequest != null)
|
||||||
|
{
|
||||||
|
result.DevicePendingAuthRequest = new DeviceAuthRequestResponseModel.PendingAuthRequest
|
||||||
|
{
|
||||||
|
Id = result.DevicePendingAuthRequest.Id,
|
||||||
|
CreationDate = result.DevicePendingAuthRequest.CreationDate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return results.ToList();
|
return results.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
using AutoMapper;
|
|
||||||
using Bit.Core.Auth.Models.Api.Response;
|
|
||||||
|
|
||||||
namespace Bit.Infrastructure.EntityFramework.Auth.Models;
|
|
||||||
|
|
||||||
public class DeviceAuthRequestResponseModelMapperProfile : Profile
|
|
||||||
{
|
|
||||||
public DeviceAuthRequestResponseModelMapperProfile()
|
|
||||||
{
|
|
||||||
CreateMap<Core.Entities.Device, DeviceAuthRequestResponseModel>().ReverseMap();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,73 @@
|
|||||||
|
using Bit.Core.Auth.Enums;
|
||||||
|
using Bit.Core.Auth.Models.Api.Response;
|
||||||
|
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Bit.Infrastructure.EntityFramework.Auth.Repositories.Queries;
|
||||||
|
|
||||||
|
public class DeviceWithPendingAuthByUserIdQuery
|
||||||
|
{
|
||||||
|
public IQueryable<DeviceAuthRequestResponseModel> GetQuery(
|
||||||
|
DatabaseContext dbContext,
|
||||||
|
Guid userId,
|
||||||
|
int expirationMinutes)
|
||||||
|
{
|
||||||
|
// Handle sqlite differently because it cannot convert some linq queries into sql syntax.
|
||||||
|
// This error is thrown when trying to run the join else clause below with sqlite:
|
||||||
|
// 'Translating this query requires the SQL APPLY operation, which is not supported on SQLite.'
|
||||||
|
if (dbContext.Database.IsSqlite())
|
||||||
|
{
|
||||||
|
var query =
|
||||||
|
(from device in dbContext.Devices
|
||||||
|
where device.UserId == userId && device.Active
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
device,
|
||||||
|
authRequest =
|
||||||
|
(from authRequest in dbContext.AuthRequests
|
||||||
|
where authRequest.RequestDeviceIdentifier == device.Identifier
|
||||||
|
where authRequest.Type == AuthRequestType.AuthenticateAndUnlock ||
|
||||||
|
authRequest.Type == AuthRequestType.Unlock
|
||||||
|
where authRequest.Approved == null
|
||||||
|
where authRequest.UserId == userId
|
||||||
|
where authRequest.CreationDate.AddMinutes(expirationMinutes) > DateTime.UtcNow
|
||||||
|
orderby authRequest.CreationDate descending
|
||||||
|
select authRequest).First()
|
||||||
|
}
|
||||||
|
).Select(deviceWithAuthRequest => new DeviceAuthRequestResponseModel(
|
||||||
|
deviceWithAuthRequest.device,
|
||||||
|
deviceWithAuthRequest.authRequest != null ? deviceWithAuthRequest.authRequest.Id : Guid.Empty,
|
||||||
|
deviceWithAuthRequest.authRequest != null
|
||||||
|
? deviceWithAuthRequest.authRequest.CreationDate
|
||||||
|
: DateTime.MinValue));
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var query =
|
||||||
|
from device in dbContext.Devices
|
||||||
|
join authRequest in dbContext.AuthRequests
|
||||||
|
on device.Identifier equals authRequest.RequestDeviceIdentifier
|
||||||
|
into deviceRequests
|
||||||
|
from authRequest in deviceRequests
|
||||||
|
.Where(ar => ar.Type == AuthRequestType.AuthenticateAndUnlock || ar.Type == AuthRequestType.Unlock)
|
||||||
|
.Where(ar => ar.Approved == null)
|
||||||
|
.Where(ar => ar.CreationDate.AddMinutes(expirationMinutes) > DateTime.UtcNow)
|
||||||
|
.OrderByDescending(ar => ar.CreationDate)
|
||||||
|
.Take(1)
|
||||||
|
where device.UserId == userId && device.Active == true
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
Device = device,
|
||||||
|
AuthRequestId = authRequest.Id,
|
||||||
|
AuthRequestCreationDate = authRequest.CreationDate
|
||||||
|
};
|
||||||
|
|
||||||
|
var devicesWithAuthQuery = query.Select(deviceAndAuthProperty => new DeviceAuthRequestResponseModel(
|
||||||
|
deviceAndAuthProperty.Device, deviceAndAuthProperty.AuthRequestId, deviceAndAuthProperty.AuthRequestCreationDate));
|
||||||
|
|
||||||
|
return devicesWithAuthQuery;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Bit.Core.Auth.Enums;
|
|
||||||
using Bit.Core.Auth.Models.Api.Response;
|
using Bit.Core.Auth.Models.Api.Response;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
|
using Bit.Infrastructure.EntityFramework.Auth.Repositories.Queries;
|
||||||
using Bit.Infrastructure.EntityFramework.Models;
|
using Bit.Infrastructure.EntityFramework.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@ -77,29 +77,8 @@ public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>,
|
|||||||
using (var scope = ServiceScopeFactory.CreateScope())
|
using (var scope = ServiceScopeFactory.CreateScope())
|
||||||
{
|
{
|
||||||
var dbContext = GetDatabaseContext(scope);
|
var dbContext = GetDatabaseContext(scope);
|
||||||
|
var query = new DeviceWithPendingAuthByUserIdQuery();
|
||||||
var query = from device in dbContext.Devices
|
return await query.GetQuery(dbContext, userId, expirationMinutes).ToListAsync();
|
||||||
where device.UserId == userId && device.Active
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
device,
|
|
||||||
authRequest = (from authRequest in dbContext.AuthRequests
|
|
||||||
where authRequest.RequestDeviceIdentifier == device.Identifier
|
|
||||||
where authRequest.Type == AuthRequestType.AuthenticateAndUnlock || authRequest.Type == AuthRequestType.Unlock
|
|
||||||
where authRequest.Approved == null
|
|
||||||
where authRequest.UserId == userId
|
|
||||||
where authRequest.CreationDate.AddMinutes(expirationMinutes) > DateTime.UtcNow
|
|
||||||
orderby authRequest.CreationDate descending
|
|
||||||
select authRequest).First()
|
|
||||||
};
|
|
||||||
|
|
||||||
var devices =
|
|
||||||
await query.Select(deviceWithAuthRequest => new DeviceAuthRequestResponseModel(
|
|
||||||
deviceWithAuthRequest.device,
|
|
||||||
deviceWithAuthRequest.authRequest != null ? deviceWithAuthRequest.authRequest.Id : Guid.Empty,
|
|
||||||
deviceWithAuthRequest.authRequest != null ? deviceWithAuthRequest.authRequest.CreationDate : DateTime.MinValue)).ToListAsync();
|
|
||||||
|
|
||||||
return devices;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user