1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-05 18:12:48 -05:00

[PM-8107] Remove Duo v2 from server (#4934)

refactor(TwoFactorAuthentication): Remove references to old Duo SDK version 2 code and replace them with the Duo SDK version 4 supported library DuoUniversal code.

Increased unit test coverage in the Two Factor Authentication code space. We opted to use DI instead of Inheritance for the Duo and OrganizaitonDuo two factor tokens to increase testability, since creating a testing mock of the Duo.Client was non-trivial.

Reviewed-by: @JaredSnider-Bitwarden
This commit is contained in:
Ike
2024-11-18 15:58:05 -08:00
committed by GitHub
parent e16cad50b1
commit ab5d4738d6
36 changed files with 1412 additions and 1369 deletions

View File

@ -4,15 +4,14 @@ using Bit.Api.Auth.Models.Response.TwoFactor;
using Bit.Api.Models.Request;
using Bit.Api.Models.Response;
using Bit.Core.Auth.Enums;
using Bit.Core.Auth.Identity.TokenProviders;
using Bit.Core.Auth.LoginFeatures.PasswordlessLogin.Interfaces;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Auth.Utilities;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
using Bit.Core.Tokens;
using Bit.Core.Utilities;
using Fido2NetLib;
@ -29,11 +28,10 @@ public class TwoFactorController : Controller
private readonly IUserService _userService;
private readonly IOrganizationRepository _organizationRepository;
private readonly IOrganizationService _organizationService;
private readonly GlobalSettings _globalSettings;
private readonly UserManager<User> _userManager;
private readonly ICurrentContext _currentContext;
private readonly IVerifyAuthRequestCommand _verifyAuthRequestCommand;
private readonly IFeatureService _featureService;
private readonly IDuoUniversalTokenService _duoUniversalTokenService;
private readonly IDataProtectorTokenFactory<TwoFactorAuthenticatorUserVerificationTokenable> _twoFactorAuthenticatorDataProtector;
private readonly IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> _ssoEmailTwoFactorSessionDataProtector;
@ -41,22 +39,20 @@ public class TwoFactorController : Controller
IUserService userService,
IOrganizationRepository organizationRepository,
IOrganizationService organizationService,
GlobalSettings globalSettings,
UserManager<User> userManager,
ICurrentContext currentContext,
IVerifyAuthRequestCommand verifyAuthRequestCommand,
IFeatureService featureService,
IDuoUniversalTokenService duoUniversalConfigService,
IDataProtectorTokenFactory<TwoFactorAuthenticatorUserVerificationTokenable> twoFactorAuthenticatorDataProtector,
IDataProtectorTokenFactory<SsoEmail2faSessionTokenable> ssoEmailTwoFactorSessionDataProtector)
{
_userService = userService;
_organizationRepository = organizationRepository;
_organizationService = organizationService;
_globalSettings = globalSettings;
_userManager = userManager;
_currentContext = currentContext;
_verifyAuthRequestCommand = verifyAuthRequestCommand;
_featureService = featureService;
_duoUniversalTokenService = duoUniversalConfigService;
_twoFactorAuthenticatorDataProtector = twoFactorAuthenticatorDataProtector;
_ssoEmailTwoFactorSessionDataProtector = ssoEmailTwoFactorSessionDataProtector;
}
@ -184,21 +180,7 @@ public class TwoFactorController : Controller
public async Task<TwoFactorDuoResponseModel> PutDuo([FromBody] UpdateTwoFactorDuoRequestModel model)
{
var user = await CheckAsync(model, true);
try
{
// for backwards compatibility - will be removed with PM-8107
DuoApi duoApi = null;
if (model.ClientId != null && model.ClientSecret != null)
{
duoApi = new DuoApi(model.ClientId, model.ClientSecret, model.Host);
}
else
{
duoApi = new DuoApi(model.IntegrationKey, model.SecretKey, model.Host);
}
await duoApi.JSONApiCall("GET", "/auth/v2/check");
}
catch (DuoException)
if (!await _duoUniversalTokenService.ValidateDuoConfiguration(model.ClientSecret, model.ClientId, model.Host))
{
throw new BadRequestException(
"Duo configuration settings are not valid. Please re-check the Duo Admin panel.");
@ -241,21 +223,7 @@ public class TwoFactorController : Controller
}
var organization = await _organizationRepository.GetByIdAsync(orgIdGuid) ?? throw new NotFoundException();
try
{
// for backwards compatibility - will be removed with PM-8107
DuoApi duoApi = null;
if (model.ClientId != null && model.ClientSecret != null)
{
duoApi = new DuoApi(model.ClientId, model.ClientSecret, model.Host);
}
else
{
duoApi = new DuoApi(model.IntegrationKey, model.SecretKey, model.Host);
}
await duoApi.JSONApiCall("GET", "/auth/v2/check");
}
catch (DuoException)
if (!await _duoUniversalTokenService.ValidateDuoConfiguration(model.ClientId, model.ClientSecret, model.Host))
{
throw new BadRequestException(
"Duo configuration settings are not valid. Please re-check the Duo Admin panel.");