1
0
mirror of https://github.com/bitwarden/server.git synced 2024-12-12 15:26:48 +01:00
bitwarden-server/test/Api.Test/Auth/Controllers/TwoFactorControllerTests.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

296 lines
10 KiB
C#
Raw Normal View History

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);
}
}