1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 15:42: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

@ -0,0 +1,295 @@
using Bit.Api.Auth.Controllers;
using Bit.Api.Auth.Models.Request;
using Bit.Api.Auth.Models.Request.Accounts;
using Bit.Api.Auth.Models.Response.TwoFactor;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Auth.Identity.TokenProviders;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes;
using NSubstitute;
using Xunit;
namespace Bit.Api.Test.Auth.Controllers;
[ControllerCustomize(typeof(TwoFactorController))]
[SutProviderCustomize]
public class TwoFactorControllerTests
{
[Theory, BitAutoData]
public async Task CheckAsync_UserNull_ThrowsUnauthorizedException(SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
sutProvider.GetDependency<IUserService>()
.GetUserByPrincipalAsync(default)
.ReturnsForAnyArgs(null as User);
// Act
var result = () => sutProvider.Sut.GetDuo(request);
// Assert
await Assert.ThrowsAsync<UnauthorizedAccessException>(result);
}
[Theory, BitAutoData]
public async Task CheckAsync_BadSecret_ThrowsBadRequestException(User user, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
sutProvider.GetDependency<IUserService>()
.GetUserByPrincipalAsync(default)
.ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>()
.VerifySecretAsync(default, default)
.ReturnsForAnyArgs(false);
// Act
try
{
await sutProvider.Sut.GetDuo(request);
}
catch (BadRequestException e)
{
// Assert
Assert.Equal("The model state is invalid.", e.Message);
}
}
[Theory, BitAutoData]
public async Task CheckAsync_CannotAccessPremium_ThrowsBadRequestException(User user, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
sutProvider.GetDependency<IUserService>()
.GetUserByPrincipalAsync(default)
.ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>()
.VerifySecretAsync(default, default)
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IUserService>()
.CanAccessPremium(default)
.ReturnsForAnyArgs(false);
// Act
try
{
await sutProvider.Sut.GetDuo(request);
}
catch (BadRequestException e)
{
// Assert
Assert.Equal("Premium status is required.", e.Message);
}
}
[Theory, BitAutoData]
public async Task GetDuo_Success(User user, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
user.TwoFactorProviders = GetUserTwoFactorDuoProvidersJson();
SetupCheckAsyncToPass(sutProvider, user);
// Act
var result = await sutProvider.Sut.GetDuo(request);
// Assert
Assert.NotNull(result);
Assert.IsType<TwoFactorDuoResponseModel>(result);
}
[Theory, BitAutoData]
public async Task PutDuo_InvalidConfiguration_ThrowsBadRequestException(User user, UpdateTwoFactorDuoRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
SetupCheckAsyncToPass(sutProvider, user);
sutProvider.GetDependency<IDuoUniversalTokenService>()
.ValidateDuoConfiguration(default, default, default)
.Returns(false);
// Act
try
{
await sutProvider.Sut.PutDuo(request);
}
catch (BadRequestException e)
{
// Assert
Assert.Equal("Duo configuration settings are not valid. Please re-check the Duo Admin panel.", e.Message);
}
}
[Theory, BitAutoData]
public async Task PutDuo_Success(User user, UpdateTwoFactorDuoRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
user.TwoFactorProviders = GetUserTwoFactorDuoProvidersJson();
SetupCheckAsyncToPass(sutProvider, user);
sutProvider.GetDependency<IDuoUniversalTokenService>()
.ValidateDuoConfiguration(default, default, default)
.ReturnsForAnyArgs(true);
// Act
var result = await sutProvider.Sut.PutDuo(request);
// Assert
Assert.NotNull(result);
Assert.IsType<TwoFactorDuoResponseModel>(result);
Assert.Equal(user.TwoFactorProviders, request.ToUser(user).TwoFactorProviders);
}
[Theory, BitAutoData]
public async Task CheckOrganizationAsync_ManagePolicies_ThrowsNotFoundException(
User user, Organization organization, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
organization.TwoFactorProviders = GetOrganizationTwoFactorDuoProvidersJson();
SetupCheckAsyncToPass(sutProvider, user);
sutProvider.GetDependency<ICurrentContext>()
.ManagePolicies(default)
.ReturnsForAnyArgs(false);
// Act
var result = () => sutProvider.Sut.GetOrganizationDuo(organization.Id.ToString(), request);
// Assert
await Assert.ThrowsAsync<NotFoundException>(result);
}
[Theory, BitAutoData]
public async Task CheckOrganizationAsync_GetByIdAsync_ThrowsNotFoundException(
User user, Organization organization, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
organization.TwoFactorProviders = GetOrganizationTwoFactorDuoProvidersJson();
SetupCheckAsyncToPass(sutProvider, user);
sutProvider.GetDependency<ICurrentContext>()
.ManagePolicies(default)
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IOrganizationRepository>()
.GetByIdAsync(default)
.ReturnsForAnyArgs(null as Organization);
// Act
var result = () => sutProvider.Sut.GetOrganizationDuo(organization.Id.ToString(), request);
// Assert
await Assert.ThrowsAsync<NotFoundException>(result);
}
[Theory, BitAutoData]
public async Task GetOrganizationDuo_Success(
User user, Organization organization, SecretVerificationRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
organization.TwoFactorProviders = GetOrganizationTwoFactorDuoProvidersJson();
SetupCheckAsyncToPass(sutProvider, user);
SetupCheckOrganizationAsyncToPass(sutProvider, organization);
// Act
var result = await sutProvider.Sut.GetOrganizationDuo(organization.Id.ToString(), request);
// Assert
Assert.NotNull(result);
Assert.IsType<TwoFactorDuoResponseModel>(result);
}
[Theory, BitAutoData]
public async Task PutOrganizationDuo_InvalidConfiguration_ThrowsBadRequestException(
User user, Organization organization, UpdateTwoFactorDuoRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
SetupCheckAsyncToPass(sutProvider, user);
SetupCheckOrganizationAsyncToPass(sutProvider, organization);
sutProvider.GetDependency<IDuoUniversalTokenService>()
.ValidateDuoConfiguration(default, default, default)
.ReturnsForAnyArgs(false);
// Act
try
{
await sutProvider.Sut.PutOrganizationDuo(organization.Id.ToString(), request);
}
catch (BadRequestException e)
{
// Assert
Assert.Equal("Duo configuration settings are not valid. Please re-check the Duo Admin panel.", e.Message);
}
}
[Theory, BitAutoData]
public async Task PutOrganizationDuo_Success(
User user, Organization organization, UpdateTwoFactorDuoRequestModel request, SutProvider<TwoFactorController> sutProvider)
{
// Arrange
SetupCheckAsyncToPass(sutProvider, user);
SetupCheckOrganizationAsyncToPass(sutProvider, organization);
organization.TwoFactorProviders = GetUserTwoFactorDuoProvidersJson();
sutProvider.GetDependency<IDuoUniversalTokenService>()
.ValidateDuoConfiguration(default, default, default)
.ReturnsForAnyArgs(true);
// Act
var result =
await sutProvider.Sut.PutOrganizationDuo(organization.Id.ToString(), request);
// Assert
Assert.NotNull(result);
Assert.IsType<TwoFactorDuoResponseModel>(result);
Assert.Equal(organization.TwoFactorProviders, request.ToOrganization(organization).TwoFactorProviders);
}
private string GetUserTwoFactorDuoProvidersJson()
{
return
"{\"2\":{\"Enabled\":true,\"MetaData\":{\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
private string GetOrganizationTwoFactorDuoProvidersJson()
{
return
"{\"6\":{\"Enabled\":true,\"MetaData\":{\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
/// <summary>
/// Sets up the CheckAsync method to pass.
/// </summary>
/// <param name="sutProvider">uses bit auto data</param>
/// <param name="user">uses bit auto data</param>
private void SetupCheckAsyncToPass(SutProvider<TwoFactorController> sutProvider, User user)
{
sutProvider.GetDependency<IUserService>()
.GetUserByPrincipalAsync(default)
.ReturnsForAnyArgs(user);
sutProvider.GetDependency<IUserService>()
.VerifySecretAsync(default, default)
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IUserService>()
.CanAccessPremium(default)
.ReturnsForAnyArgs(true);
}
private void SetupCheckOrganizationAsyncToPass(SutProvider<TwoFactorController> sutProvider, Organization organization)
{
sutProvider.GetDependency<ICurrentContext>()
.ManagePolicies(default)
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IOrganizationRepository>()
.GetByIdAsync(default)
.ReturnsForAnyArgs(organization);
}
}

View File

@ -18,8 +18,6 @@ public class OrganizationTwoFactorDuoRequestModelTests
{
ClientId = "clientId",
ClientSecret = "clientSecret",
IntegrationKey = "integrationKey",
SecretKey = "secretKey",
Host = "example.com"
};
@ -30,8 +28,6 @@ public class OrganizationTwoFactorDuoRequestModelTests
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.OrganizationDuo));
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientId"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientSecret"]);
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["IKey"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].Enabled);
}
@ -49,8 +45,6 @@ public class OrganizationTwoFactorDuoRequestModelTests
{
ClientId = "newClientId",
ClientSecret = "newClientSecret",
IntegrationKey = "newIntegrationKey",
SecretKey = "newSecretKey",
Host = "newExample.com"
};
@ -61,61 +55,7 @@ public class OrganizationTwoFactorDuoRequestModelTests
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.OrganizationDuo));
Assert.Equal("newClientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientId"]);
Assert.Equal("newClientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientSecret"]);
Assert.Equal("newClientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["IKey"]);
Assert.Equal("newClientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["SKey"]);
Assert.Equal("newExample.com", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].Enabled);
}
[Fact]
public void DuoV2ParamsSync_WhenExistingProviderDoesNotExist()
{
// Arrange
var existingOrg = new Organization();
var model = new UpdateTwoFactorDuoRequestModel
{
IntegrationKey = "integrationKey",
SecretKey = "secretKey",
Host = "example.com"
};
// Act
var result = model.ToOrganization(existingOrg);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.OrganizationDuo));
Assert.Equal("integrationKey", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientId"]);
Assert.Equal("secretKey", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientSecret"]);
Assert.Equal("integrationKey", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["IKey"]);
Assert.Equal("secretKey", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].Enabled);
}
[Fact]
public void DuoV4ParamsSync_WhenExistingProviderDoesNotExist()
{
// Arrange
var existingOrg = new Organization();
var model = new UpdateTwoFactorDuoRequestModel
{
ClientId = "clientId",
ClientSecret = "clientSecret",
Host = "example.com"
};
// Act
var result = model.ToOrganization(existingOrg);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.OrganizationDuo));
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientId"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["ClientSecret"]);
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["IKey"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.OrganizationDuo].Enabled);
}
}

View File

@ -39,12 +39,9 @@ public class TwoFactorDuoRequestModelValidationTests
var result = model.Validate(new ValidationContext(model));
// Assert
Assert.Single(result);
Assert.Equal("Neither v2 or v4 values are valid.", result.First().ErrorMessage);
Assert.Contains("ClientId", result.First().MemberNames);
Assert.Contains("ClientSecret", result.First().MemberNames);
Assert.Contains("IntegrationKey", result.First().MemberNames);
Assert.Contains("SecretKey", result.First().MemberNames);
Assert.NotEmpty(result);
Assert.True(result.Select(x => x.MemberNames.Contains("ClientId")).Any());
Assert.True(result.Select(x => x.MemberNames.Contains("ClientSecret")).Any());
}
[Fact]

View File

@ -17,8 +17,6 @@ public class UserTwoFactorDuoRequestModelTests
{
ClientId = "clientId",
ClientSecret = "clientSecret",
IntegrationKey = "integrationKey",
SecretKey = "secretKey",
Host = "example.com"
};
@ -26,12 +24,9 @@ public class UserTwoFactorDuoRequestModelTests
var result = model.ToUser(existingUser);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.Duo));
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientId"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientSecret"]);
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["IKey"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].Enabled);
}
@ -49,8 +44,6 @@ public class UserTwoFactorDuoRequestModelTests
{
ClientId = "newClientId",
ClientSecret = "newClientSecret",
IntegrationKey = "newIntegrationKey",
SecretKey = "newSecretKey",
Host = "newExample.com"
};
@ -58,65 +51,10 @@ public class UserTwoFactorDuoRequestModelTests
var result = model.ToUser(existingUser);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.Duo));
Assert.Equal("newClientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientId"]);
Assert.Equal("newClientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientSecret"]);
Assert.Equal("newClientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["IKey"]);
Assert.Equal("newClientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["SKey"]);
Assert.Equal("newExample.com", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].Enabled);
}
[Fact]
public void DuoV2ParamsSync_WhenExistingProviderDoesNotExist()
{
// Arrange
var existingUser = new User();
var model = new UpdateTwoFactorDuoRequestModel
{
IntegrationKey = "integrationKey",
SecretKey = "secretKey",
Host = "example.com"
};
// Act
var result = model.ToUser(existingUser);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.Duo));
Assert.Equal("integrationKey", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientId"]);
Assert.Equal("secretKey", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientSecret"]);
Assert.Equal("integrationKey", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["IKey"]);
Assert.Equal("secretKey", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].Enabled);
}
[Fact]
public void DuoV4ParamsSync_WhenExistingProviderDoesNotExist()
{
// Arrange
var existingUser = new User();
var model = new UpdateTwoFactorDuoRequestModel
{
ClientId = "clientId",
ClientSecret = "clientSecret",
Host = "example.com"
};
// Act
var result = model.ToUser(existingUser);
// Assert
// IKey and SKey should be the same as ClientId and ClientSecret
Assert.True(result.GetTwoFactorProviders().ContainsKey(TwoFactorProviderType.Duo));
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientId"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["ClientSecret"]);
Assert.Equal("clientId", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["IKey"]);
Assert.Equal("clientSecret", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["SKey"]);
Assert.Equal("example.com", result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].MetaData["Host"]);
Assert.True(result.GetTwoFactorProviders()[TwoFactorProviderType.Duo].Enabled);
}
}

View File

@ -8,42 +8,6 @@ namespace Bit.Api.Test.Auth.Models.Response;
public class OrganizationTwoFactorDuoResponseModelTests
{
[Theory]
[BitAutoData]
public void Organization_WithDuoV4_ShouldBuildModel(Organization organization)
{
// Arrange
organization.TwoFactorProviders = GetTwoFactorOrganizationDuoV4ProvidersJson();
// Act
var model = new TwoFactorDuoResponseModel(organization);
// Assert if v4 data Ikey and Skey are set to clientId and clientSecret
Assert.NotNull(model);
Assert.Equal("clientId", model.ClientId);
Assert.Equal("secret************", model.ClientSecret);
Assert.Equal("clientId", model.IntegrationKey);
Assert.Equal("secret************", model.SecretKey);
}
[Theory]
[BitAutoData]
public void Organization_WithDuoV2_ShouldBuildModel(Organization organization)
{
// Arrange
organization.TwoFactorProviders = GetTwoFactorOrganizationDuoV2ProvidersJson();
// Act
var model = new TwoFactorDuoResponseModel(organization);
// Assert if only v2 data clientId and clientSecret are set to Ikey and Sk
Assert.NotNull(model);
Assert.Equal("IKey", model.ClientId);
Assert.Equal("SKey", model.ClientSecret);
Assert.Equal("IKey", model.IntegrationKey);
Assert.Equal("SKey", model.SecretKey);
}
[Theory]
[BitAutoData]
public void Organization_WithDuo_ShouldBuildModel(Organization organization)
@ -54,12 +18,10 @@ public class OrganizationTwoFactorDuoResponseModelTests
// Act
var model = new TwoFactorDuoResponseModel(organization);
/// Assert Even if both versions are present priority is given to v4 data
// Assert
Assert.NotNull(model);
Assert.Equal("clientId", model.ClientId);
Assert.Equal("secret************", model.ClientSecret);
Assert.Equal("clientId", model.IntegrationKey);
Assert.Equal("secret************", model.SecretKey);
}
[Theory]
@ -72,38 +34,33 @@ public class OrganizationTwoFactorDuoResponseModelTests
// Act
var model = new TwoFactorDuoResponseModel(organization);
/// Assert
// Assert
Assert.False(model.Enabled);
}
[Theory]
[BitAutoData]
public void Organization_WithTwoFactorProvidersNull_ShouldFail(Organization organization)
public void Organization_WithTwoFactorProvidersNull_ShouldThrow(Organization organization)
{
// Arrange
organization.TwoFactorProviders = "{\"6\" : {}}";
organization.TwoFactorProviders = null;
// Act
var model = new TwoFactorDuoResponseModel(organization);
try
{
var model = new TwoFactorDuoResponseModel(organization);
/// Assert
Assert.False(model.Enabled);
}
catch (Exception ex)
{
// Assert
Assert.IsType<ArgumentNullException>(ex);
}
}
private string GetTwoFactorOrganizationDuoProvidersJson()
{
return
"{\"6\":{\"Enabled\":true,\"MetaData\":{\"SKey\":\"SKey\",\"IKey\":\"IKey\",\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
private string GetTwoFactorOrganizationDuoV4ProvidersJson()
{
return
"{\"6\":{\"Enabled\":true,\"MetaData\":{\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
private string GetTwoFactorOrganizationDuoV2ProvidersJson()
{
return "{\"6\":{\"Enabled\":true,\"MetaData\":{\"SKey\":\"SKey\",\"IKey\":\"IKey\",\"Host\":\"example.com\"}}}";
}
}

View File

@ -10,38 +10,21 @@ public class UserTwoFactorDuoResponseModelTests
{
[Theory]
[BitAutoData]
public void User_WithDuoV4_ShouldBuildModel(User user)
public void User_WithDuo_UserNull_ThrowsArgumentException(User user)
{
// Arrange
user.TwoFactorProviders = GetTwoFactorDuoV4ProvidersJson();
user.TwoFactorProviders = GetTwoFactorDuoProvidersJson();
// Act
var model = new TwoFactorDuoResponseModel(user);
// Assert if v4 data Ikey and Skey are set to clientId and clientSecret
Assert.NotNull(model);
Assert.Equal("clientId", model.ClientId);
Assert.Equal("secret************", model.ClientSecret);
Assert.Equal("clientId", model.IntegrationKey);
Assert.Equal("secret************", model.SecretKey);
}
[Theory]
[BitAutoData]
public void User_WithDuov2_ShouldBuildModel(User user)
{
// Arrange
user.TwoFactorProviders = GetTwoFactorDuoV2ProvidersJson();
// Act
var model = new TwoFactorDuoResponseModel(user);
// Assert if only v2 data clientId and clientSecret are set to Ikey and Skey
Assert.NotNull(model);
Assert.Equal("IKey", model.ClientId);
Assert.Equal("SKey", model.ClientSecret);
Assert.Equal("IKey", model.IntegrationKey);
Assert.Equal("SKey", model.SecretKey);
try
{
var model = new TwoFactorDuoResponseModel(null as User);
}
catch (ArgumentNullException e)
{
// Assert
Assert.Equal("Value cannot be null. (Parameter 'user')", e.Message);
}
}
[Theory]
@ -54,12 +37,10 @@ public class UserTwoFactorDuoResponseModelTests
// Act
var model = new TwoFactorDuoResponseModel(user);
// Assert Even if both versions are present priority is given to v4 data
// Assert
Assert.NotNull(model);
Assert.Equal("clientId", model.ClientId);
Assert.Equal("secret************", model.ClientSecret);
Assert.Equal("clientId", model.IntegrationKey);
Assert.Equal("secret************", model.SecretKey);
}
[Theory]
@ -84,26 +65,23 @@ public class UserTwoFactorDuoResponseModelTests
user.TwoFactorProviders = null;
// Act
var model = new TwoFactorDuoResponseModel(user);
try
{
var model = new TwoFactorDuoResponseModel(user);
}
catch (Exception ex)
{
// Assert
Assert.IsType<ArgumentNullException>(ex);
}
/// Assert
Assert.False(model.Enabled);
}
private string GetTwoFactorDuoProvidersJson()
{
return
"{\"2\":{\"Enabled\":true,\"MetaData\":{\"SKey\":\"SKey\",\"IKey\":\"IKey\",\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
private string GetTwoFactorDuoV4ProvidersJson()
{
return
"{\"2\":{\"Enabled\":true,\"MetaData\":{\"ClientSecret\":\"secretClientSecret\",\"ClientId\":\"clientId\",\"Host\":\"example.com\"}}}";
}
private string GetTwoFactorDuoV2ProvidersJson()
{
return "{\"2\":{\"Enabled\":true,\"MetaData\":{\"SKey\":\"SKey\",\"IKey\":\"IKey\",\"Host\":\"example.com\"}}}";
}
}