mirror of
https://github.com/bitwarden/server.git
synced 2024-12-03 14:03:33 +01:00
Have the dapper query working. Working on the ef query.
This commit is contained in:
parent
b974899127
commit
bca5eff1a8
@ -6,10 +6,10 @@ using Bit.Api.Models.Response;
|
|||||||
using Bit.Core.Auth.Models.Api.Request;
|
using Bit.Core.Auth.Models.Api.Request;
|
||||||
using Bit.Core.Auth.Models.Api.Response;
|
using Bit.Core.Auth.Models.Api.Response;
|
||||||
using Bit.Core.Context;
|
using Bit.Core.Context;
|
||||||
using Bit.Core.Entities;
|
|
||||||
using Bit.Core.Exceptions;
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Settings;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -25,6 +25,7 @@ public class DevicesController : Controller
|
|||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
private readonly ICurrentContext _currentContext;
|
private readonly ICurrentContext _currentContext;
|
||||||
|
private readonly IGlobalSettings _globalSettings;
|
||||||
private readonly ILogger<DevicesController> _logger;
|
private readonly ILogger<DevicesController> _logger;
|
||||||
|
|
||||||
public DevicesController(
|
public DevicesController(
|
||||||
@ -33,6 +34,7 @@ public class DevicesController : Controller
|
|||||||
IUserService userService,
|
IUserService userService,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
ICurrentContext currentContext,
|
ICurrentContext currentContext,
|
||||||
|
IGlobalSettings globalSettings,
|
||||||
ILogger<DevicesController> logger)
|
ILogger<DevicesController> logger)
|
||||||
{
|
{
|
||||||
_deviceRepository = deviceRepository;
|
_deviceRepository = deviceRepository;
|
||||||
@ -40,6 +42,7 @@ public class DevicesController : Controller
|
|||||||
_userService = userService;
|
_userService = userService;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
|
_globalSettings = globalSettings;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +72,16 @@ public class DevicesController : Controller
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// working here
|
||||||
[HttpGet("")]
|
[HttpGet("")]
|
||||||
public async Task<ListResponseModel<DeviceResponseModel>> Get()
|
public async Task<ListResponseModel<DeviceAuthRequestResponseModel>> Get()
|
||||||
{
|
{
|
||||||
ICollection<Device> devices = await _deviceRepository.GetManyByUserIdAsync(_userService.GetProperUserId(User).Value);
|
var expirationMinutes = _globalSettings.PasswordlessAuth.UserRequestExpiration.TotalMinutes;
|
||||||
var responses = devices.Select(d => new DeviceResponseModel(d));
|
var devices = await _deviceRepository.GetManyByUserIdWithDeviceAuth(_userService.GetProperUserId(User).Value, (int)expirationMinutes);
|
||||||
return new ListResponseModel<DeviceResponseModel>(responses);
|
var responses = devices.Select(d => new DeviceAuthRequestResponseModel(d));
|
||||||
|
return new ListResponseModel<DeviceAuthRequestResponseModel>(responses);
|
||||||
}
|
}
|
||||||
|
// end working here
|
||||||
|
|
||||||
[HttpPost("")]
|
[HttpPost("")]
|
||||||
public async Task<DeviceResponseModel> Post([FromBody] DeviceRequestModel model)
|
public async Task<DeviceResponseModel> Post([FromBody] DeviceRequestModel model)
|
||||||
|
41
src/Api/Models/Response/DeviceAuthRequestResponseModel.cs
Normal file
41
src/Api/Models/Response/DeviceAuthRequestResponseModel.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using Bit.Core.Auth.Utilities;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models.Api;
|
||||||
|
|
||||||
|
namespace Bit.Api.Models.Response;
|
||||||
|
|
||||||
|
public class DeviceAuthRequestResponseModel : ResponseModel
|
||||||
|
{
|
||||||
|
public DeviceAuthRequestResponseModel(Device device)
|
||||||
|
: base("device")
|
||||||
|
{
|
||||||
|
if (device == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
Id = device.Id;
|
||||||
|
Name = device.Name;
|
||||||
|
Type = device.Type;
|
||||||
|
Identifier = device.Identifier;
|
||||||
|
CreationDate = device.CreationDate;
|
||||||
|
IsTrusted = device.IsTrusted();
|
||||||
|
DevicePendingAuthRequest = new PendingAuthRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public DeviceType Type { get; set; }
|
||||||
|
public string Identifier { get; set; }
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
public bool IsTrusted { get; set; }
|
||||||
|
|
||||||
|
public PendingAuthRequest DevicePendingAuthRequest { get; set; }
|
||||||
|
|
||||||
|
public class PendingAuthRequest
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace Bit.Core.Auth.UserFeatures.DeviceReadActiveWithPendingAuthRequestsByUserId;
|
||||||
|
|
||||||
|
public interface IDeviceReadActiveWithPendingAuthRequestsByUserIdQuery
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
namespace Bit.Core.Auth.UserFeatures.DeviceReadActiveWithPendingAuthRequestsByUserId;
|
||||||
|
|
||||||
|
public class DeviceReadActiveWithPendingAuthRequestsByUserIdQuery
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -10,5 +10,6 @@ public interface IDeviceRepository : IRepository<Device, Guid>
|
|||||||
Task<Device?> GetByIdentifierAsync(string identifier);
|
Task<Device?> GetByIdentifierAsync(string identifier);
|
||||||
Task<Device?> GetByIdentifierAsync(string identifier, Guid userId);
|
Task<Device?> GetByIdentifierAsync(string identifier, Guid userId);
|
||||||
Task<ICollection<Device>> GetManyByUserIdAsync(Guid userId);
|
Task<ICollection<Device>> GetManyByUserIdAsync(Guid userId);
|
||||||
|
Task<ICollection<Device>> GetManyByUserIdWithDeviceAuth(Guid userId, int expirationMinutes);
|
||||||
Task ClearPushTokenAsync(Guid id);
|
Task ClearPushTokenAsync(Guid id);
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,23 @@ public class DeviceRepository : Repository<Device, Guid>, IDeviceRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Device>> GetManyByUserIdWithDeviceAuth(Guid userId, int expirationMinutes)
|
||||||
|
{
|
||||||
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.QueryAsync<Device>(
|
||||||
|
$"[{Schema}].[{Table}_ReadActiveWithPendingAuthRequestsByUserId]",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
UserId = userId,
|
||||||
|
ExpirationMinutes = expirationMinutes
|
||||||
|
},
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
|
return results.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ClearPushTokenAsync(Guid id)
|
public async Task ClearPushTokenAsync(Guid id)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
|
@ -69,4 +69,27 @@ public class DeviceRepository : Repository<Core.Entities.Device, Device, Guid>,
|
|||||||
return Mapper.Map<List<Core.Entities.Device>>(devices);
|
return Mapper.Map<List<Core.Entities.Device>>(devices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Core.Entities.Device>> GetManyByUserIdWithDeviceAuth(Guid userId, int expirationMinutes)
|
||||||
|
{
|
||||||
|
using (var scope = ServiceScopeFactory.CreateScope())
|
||||||
|
{
|
||||||
|
var dbContext = GetDatabaseContext(scope);
|
||||||
|
|
||||||
|
// This is getting closer, need to keep work-shopping it.
|
||||||
|
var query = from device in dbContext.Devices
|
||||||
|
join authRequest in dbContext.AuthRequests
|
||||||
|
on device.UserId equals authRequest.UserId
|
||||||
|
into deviceRequests
|
||||||
|
where device.UserId == userId && device.Active == true
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
AuthRequestId = from authRequest in deviceRequests select authRequest.Id,
|
||||||
|
AuthCreationDate = from authRequest in deviceRequests select authRequest.CreationDate,
|
||||||
|
};
|
||||||
|
|
||||||
|
var devices = await query.ToListAsync();
|
||||||
|
return Mapper.Map<List<Core.Entities.Device>>(devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[Device_ReadActiveWithPendingAuthRequestsByUserId]
|
||||||
|
@UserId UNIQUEIDENTIFIER,
|
||||||
|
@ExpirationMinutes INT
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SELECT D.*,
|
||||||
|
AR.Id as AuthRequestId,
|
||||||
|
AR.CreationDate as AuthRequestCreationDate
|
||||||
|
FROM [dbo].[DeviceView] D
|
||||||
|
LEFT OUTER JOIN [dbo].[AuthRequestView] AR
|
||||||
|
ON D.userId = AR.userId
|
||||||
|
AND AR.RequestDeviceIdentifier = D.Identifier
|
||||||
|
AND AR.Type IN (0, 1) -- Exclude Admin Approval (type 2)
|
||||||
|
AND DATEADD(mi, @ExpirationMinutes, AR.CreationDate) < GETUTCDATE() -- This means it hasn't expired
|
||||||
|
AND AR.Approved IS NOT NULL -- This means it hasn't been approved already
|
||||||
|
WHERE D.UserId = @UserId
|
||||||
|
AND D.Active = 1 -- Device is active
|
||||||
|
END
|
@ -0,0 +1,18 @@
|
|||||||
|
CREATE OR ALTER PROCEDURE [dbo].[Device_ReadActiveWithPendingAuthRequestsByUserId]
|
||||||
|
@UserId UNIQUEIDENTIFIER,
|
||||||
|
@ExpirationMinutes INT
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SELECT D.*,
|
||||||
|
AR.Id as AuthRequestId,
|
||||||
|
AR.CreationDate as AuthRequestCreationDate
|
||||||
|
FROM [dbo].[DeviceView] D
|
||||||
|
LEFT OUTER JOIN [dbo].[AuthRequestView] AR
|
||||||
|
ON D.userId = AR.userId
|
||||||
|
AND AR.RequestDeviceIdentifier = D.Identifier
|
||||||
|
AND AR.Type IN (0, 1) -- Exclude Admin Approval (type 2)
|
||||||
|
AND DATEADD(mi, @ExpirationMinutes, AR.CreationDate) < GETUTCDATE() -- This means it hasn't expired
|
||||||
|
AND AR.Approved IS NOT NULL -- This means it hasn't been approved already
|
||||||
|
WHERE D.UserId = @UserId
|
||||||
|
AND D.Active = 1 -- Device is active
|
||||||
|
END
|
Loading…
Reference in New Issue
Block a user