< Summary

Information
Class: ProjectTemplate.Infrastructure.Data.Auditing.ApplicationMutationManifestVerifier
Assembly: ProjectTemplate.Infrastructure
File(s): /home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Infrastructure/Data/Auditing/ApplicationMutationManifestVerifier.cs
Line coverage
86%
Covered lines: 19
Uncovered lines: 3
Coverable lines: 22
Total lines: 52
Line coverage: 86.3%
Branch coverage
70%
Covered branches: 7
Total branches: 10
Branch coverage: 70%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%44100%
Verify(...)83.33%6680%

File(s)

/home/runner/work/NetCoreApplicationTemplate/NetCoreApplicationTemplate/src/ProjectTemplate.Infrastructure/Data/Auditing/ApplicationMutationManifestVerifier.cs

#LineLine coverage
 1using System.Security.Cryptography;
 2using ProjectTemplate.Infrastructure.Data.Entities;
 3
 4namespace ProjectTemplate.Infrastructure.Data.Auditing;
 5
 6/// <summary>
 7/// Verifies retained application audit records against a canonical mutation manifest digest.
 8/// </summary>
 209public sealed class ApplicationMutationManifestVerifier(
 2010    IApplicationMutationManifestBuilder manifestBuilder,
 2011    IApplicationMutationManifestHasher manifestHasher)
 12    : IApplicationMutationManifestVerifier
 13{
 2014    private readonly IApplicationMutationManifestBuilder _manifestBuilder =
 2015        manifestBuilder ?? throw new ArgumentNullException(nameof(manifestBuilder));
 2016    private readonly IApplicationMutationManifestHasher _manifestHasher =
 2017        manifestHasher ?? throw new ArgumentNullException(nameof(manifestHasher));
 18
 19    /// <inheritdoc />
 20    public bool Verify(
 21        ApplicationMutationAuditReceipt receipt,
 22        IReadOnlyCollection<AuditRecord> auditRecords)
 23    {
 1824        ArgumentNullException.ThrowIfNull(receipt);
 1825        ArgumentNullException.ThrowIfNull(auditRecords);
 26
 1827        if (!string.Equals(receipt.MutationManifestAlgorithm, _manifestHasher.Algorithm, StringComparison.Ordinal) ||
 1828            auditRecords.Count != receipt.AuditRecordCount ||
 3829            auditRecords.Any(record => !string.Equals(record.MutationBatchId, receipt.MutationBatchId, StringComparison.
 30        {
 231            return false;
 32        }
 33
 1634        ApplicationMutationManifest manifest = _manifestBuilder.Build(auditRecords);
 1635        string actualHash = _manifestHasher.ComputeHash(manifest);
 36
 37        byte[] expectedBytes;
 38        byte[] actualBytes;
 39
 40        try
 41        {
 1642            expectedBytes = Convert.FromHexString(receipt.MutationManifestHash);
 1643            actualBytes = Convert.FromHexString(actualHash);
 1644        }
 045        catch (FormatException)
 46        {
 047            return false;
 48        }
 49
 1650        return CryptographicOperations.FixedTimeEquals(expectedBytes, actualBytes);
 051    }
 52}