1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-15 07:43:37 +00:00
Files
mobile/test/Core.Test/Utilities/Fido2/Fido2GetAssertionUserInterfaceTests.cs
Andreas Coroiu 71de3bedf4 [PM-5731] Create C# WebAuthn authenticator to support maui apps (#2951)
* [PM-5731] feat: implement get assertion params object

* [PM-5731] feat: add first test

* [PM-5731] feat: add rp mismatch test

* [PM-5731] feat: ask for credentials when found

* [PM-5731] feat: find discoverable credentials

* [PM-5731] feat: add tests for successful UV requests

* [PM-5731] feat: add user does not consent test

* [PM-5731] feat: check for UV when reprompt is active

* [PM-5731] fix: tests a bit, needed some additional "arrange" steps

* [PM-5731] feat: add support for counter

* [PM-5731] feat: implement assertion without signature

* [PM-5732] feat: finish authenticator assertion implementation

note: CryptoFunctionService still needs Sign implemenation

* [PM-5731] chore: minor clean up

* [PM-5731] feat: scaffold make credential

* [PM-5731] feat: start implementing attestation

* [PM-5731] feat: implement credential exclusion

* [PM-5731] feat: add new credential confirmaiton

* [PM-5731] feat: implement credential creation

* [PM-5731] feat: add user verification checks

* [PM-5731] feat: add unknown error handling

* [PM-5731] chore: clean up unusued params

* [PM-5731] feat: partial attestation implementation

* [PM-5731] feat: implement key generation

* [PM-5731] feat: return public key in DER format

* [PM-5731] feat: implement signing

* [PM-5731] feat: remove logging

* [PM-5731] chore: use primary constructor

* [PM-5731] chore: add Async to method names

* [PM-5731] feat: add support for silent discoverability

* [PM-5731] feat: add support for specifying user presence requirement

* [PM-5731] feat: ensure unlocked vault

* [PM-5731] chore: clean up and refactor assertion tests

* [PM-5731] chore: clean up and refactor attestation tests

* [PM-5731] chore: add user presence todo comment

* [PM-5731] feat: scaffold fido2 client

* PM-5731 Fix build updating discoverable flag

* [PM-5731] fix: failing test

* [PM-5731] feat: add sameOriginWithAncestor and user id length checks

* [PM-5731] feat: add incomplete rpId verification

* [PM-5731] chore: document uri helpers

* [PM-5731] feat: implement fido2 client createCredential

* [PM-5731] feat: implement credential assertion in client

* fix wrong signature format

(cherry picked from commit a1c9ebf01f)

* [PM-5731] fix: issues after cherry-pick

* Fix incompatible GUID conversions

(cherry picked from commit c801b2fc3a)

* [PM-5731] chore: remove default constructor

* [PM-5731] feat: refactor user interface to increase flexibility

* [PM-5731] feat: implement generic assertion user interface class

* [PM-5731] feat: remove ability to make user presence optional

* [PM-5731] chore: remove logging comments

* [PM-5731] feat: add native reprompt support to the authenticator

* [PM-5731] feat: allow pre and post UV

* [PM-5731] chore: add `Async` to method name. Remove `I` from struct

* [PM-5731] fix: discoverable string repr lowercase

* [PM-5731] chore: don't use C# 12 features

* [PM-5731] fix: replace magic strings and numbers with contants and enums

* [PM-5731] fix: use UTC creation date

* [PM-5731] fix: formatting

* [PM-5731] chore: use properties for public fields

* [PM-5731] chore: remove TODO

* [PM-5731] fix: IsValidRpId

---------

Co-authored-by: Federico Maccaroni <fedemkr@gmail.com>
Co-authored-by: mpbw2 <59324545+mpbw2@users.noreply.github.com>
2024-02-21 12:12:52 -03:00

110 lines
4.0 KiB
C#

using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Utilities.Fido2;
using Xunit;
namespace Bit.Core.Test.Utilities.Fido2
{
public class Fido2GetAssertionUserInterfaceTests
{
[Fact]
public async Task PickCredentialAsync_ThrowsNotAllowed_PrePickedCredentialDoesNotMatch()
{
// Arrange
var userInterface = new Fido2GetAssertionUserInterface("cipherId", false, null, null);
// Act & Assert
await Assert.ThrowsAsync<NotAllowedError>(() => userInterface.PickCredentialAsync([CreateCredential("notMatching", false)]));
}
[Fact]
public async Task PickCredentialAsync_ReturnPrePickedCredential_CredentialsMatch()
{
// Arrange
var userInterface = new Fido2GetAssertionUserInterface("cipherId", false, null, null);
// Act
var result = await userInterface.PickCredentialAsync([CreateCredential("cipherId", false), CreateCredential("cipherId2", true)]);
// Assert
Assert.Equal("cipherId", result.CipherId);
Assert.False(result.UserVerified);
}
[Fact]
public async Task PickCredentialAsync_CallsUserVerificationCallback_UserIsAlreadyVerified()
{
// Arrange
var called = false;
var callback = () => { called = true; return Task.FromResult(true); };
var userInterface = new Fido2GetAssertionUserInterface("cipherId", false, null, callback);
// Act
var result = await userInterface.PickCredentialAsync([CreateCredential("cipherId", true), CreateCredential("cipherId2", false)]);
// Assert
Assert.Equal("cipherId", result.CipherId);
Assert.True(result.UserVerified);
Assert.True(called);
}
[Fact]
public async Task PickCredentialAsync_DoesNotCallUserVerificationCallback_UserVerificationIsAlreadyPerformed()
{
// Arrange
var called = false;
var callback = () => { called = true; return Task.FromResult(true); };
var userInterface = new Fido2GetAssertionUserInterface("cipherId2", true, null, callback);
// Act
var result = await userInterface.PickCredentialAsync([CreateCredential("cipherId", true), CreateCredential("cipherId2", false)]);
// Assert
Assert.Equal("cipherId2", result.CipherId);
Assert.True(result.UserVerified);
Assert.False(called);
}
[Fact]
public async Task PickCredentialAsync_DoesNotCallUserVerificationCallback_UserVerificationIsNotRequired()
{
// Arrange
var called = false;
var callback = () => { called = true; return Task.FromResult(true); };
var userInterface = new Fido2GetAssertionUserInterface("cipherId2", false, null, callback);
// Act
var result = await userInterface.PickCredentialAsync([CreateCredential("cipherId", true), CreateCredential("cipherId2", false)]);
// Assert
Assert.Equal("cipherId2", result.CipherId);
Assert.False(result.UserVerified);
Assert.False(called);
}
[Fact]
public async Task EnsureUnlockedVaultAsync_CallsCallback()
{
// Arrange
var called = false;
var callback = () => { called = true; return Task.CompletedTask; };
var userInterface = new Fido2GetAssertionUserInterface("cipherId", false, callback, null);
// Act
await userInterface.EnsureUnlockedVaultAsync();
// Assert
Assert.True(called);
}
private Fido2GetAssertionUserInterfaceCredential CreateCredential(string cipherId, bool requireUserVerification)
{
return new Fido2GetAssertionUserInterfaceCredential
{
CipherId = cipherId,
RequireUserVerification = requireUserVerification
};
}
}
}