mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 16:12:49 -05:00
feat(NewDeviceVerification) : (#5153)
feat(NewDeviceVerification) : Added constat for the cache key in Bit.Core because the cache key format needs to be shared between the Identity Server and the MVC Admin project. Updated DeviceValidator class to handle checking cache for user information to allow pass through. Updated and Added tests to handle new flow.
This commit is contained in:
@ -10,6 +10,7 @@ using Bit.Core.Services;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Identity.IdentityServer.Enums;
|
||||
using Duende.IdentityServer.Validation;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
|
||||
namespace Bit.Identity.IdentityServer.RequestValidators;
|
||||
|
||||
@ -20,6 +21,8 @@ public class DeviceValidator(
|
||||
IMailService mailService,
|
||||
ICurrentContext currentContext,
|
||||
IUserService userService,
|
||||
IDistributedCache distributedCache,
|
||||
ILogger<DeviceValidator> logger,
|
||||
IFeatureService featureService) : IDeviceValidator
|
||||
{
|
||||
private readonly IDeviceService _deviceService = deviceService;
|
||||
@ -28,6 +31,8 @@ public class DeviceValidator(
|
||||
private readonly IMailService _mailService = mailService;
|
||||
private readonly ICurrentContext _currentContext = currentContext;
|
||||
private readonly IUserService _userService = userService;
|
||||
private readonly IDistributedCache distributedCache = distributedCache;
|
||||
private readonly ILogger<DeviceValidator> _logger = logger;
|
||||
private readonly IFeatureService _featureService = featureService;
|
||||
|
||||
public async Task<bool> ValidateRequestDeviceAsync(ValidatedTokenRequest request, CustomValidatorRequestContext context)
|
||||
@ -67,7 +72,6 @@ public class DeviceValidator(
|
||||
!context.SsoRequired &&
|
||||
_globalSettings.EnableNewDeviceVerification)
|
||||
{
|
||||
// We only want to return early if the device is invalid or there is an error
|
||||
var validationResult = await HandleNewDeviceVerificationAsync(context.User, request);
|
||||
if (validationResult != DeviceValidationResultType.Success)
|
||||
{
|
||||
@ -121,6 +125,18 @@ public class DeviceValidator(
|
||||
return DeviceValidationResultType.InvalidUser;
|
||||
}
|
||||
|
||||
// CS exception flow
|
||||
// Check cache for user information
|
||||
var cacheKey = string.Format(AuthConstants.NewDeviceVerificationExceptionCacheKeyFormat, user.Id.ToString());
|
||||
var cacheValue = await distributedCache.GetAsync(cacheKey);
|
||||
if (cacheValue != null)
|
||||
{
|
||||
// if found in cache return success result and remove from cache
|
||||
await distributedCache.RemoveAsync(cacheKey);
|
||||
_logger.LogInformation("New device verification exception for user {UserId} found in cache", user.Id);
|
||||
return DeviceValidationResultType.Success;
|
||||
}
|
||||
|
||||
// parse request for NewDeviceOtp to validate
|
||||
var newDeviceOtp = request.Raw["NewDeviceOtp"]?.ToString();
|
||||
// we only check null here since an empty OTP will be considered an incorrect OTP
|
||||
|
Reference in New Issue
Block a user