< 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
100%
Covered lines: 22
Uncovered lines: 0
Coverable lines: 22
Total lines: 52
Line coverage: 100%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
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(...)100%66100%

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>
 229public sealed class ApplicationMutationManifestVerifier(
 2210    IApplicationMutationManifestBuilder manifestBuilder,
 2211    IApplicationMutationManifestHasher manifestHasher)
 12    : IApplicationMutationManifestVerifier
 13{
 2214    private readonly IApplicationMutationManifestBuilder _manifestBuilder =
 2215        manifestBuilder ?? throw new ArgumentNullException(nameof(manifestBuilder));
 2216    private readonly IApplicationMutationManifestHasher _manifestHasher =
 2217        manifestHasher ?? throw new ArgumentNullException(nameof(manifestHasher));
 18
 19    /// <inheritdoc />
 20    public bool Verify(
 21        ApplicationMutationAuditReceipt receipt,
 22        IReadOnlyCollection<AuditRecord> auditRecords)
 23    {
 1724        ArgumentNullException.ThrowIfNull(receipt);
 1725        ArgumentNullException.ThrowIfNull(auditRecords);
 26
 1727        if (!string.Equals(receipt.MutationManifestAlgorithm, _manifestHasher.Algorithm, StringComparison.Ordinal) ||
 1728            auditRecords.Count != receipt.AuditRecordCount ||
 1729            auditRecords.Any(record => !string.Equals(record.MutationBatchId, receipt.MutationBatchId, StringComparison.
 30        {
 331            return false;
 32        }
 33
 1434        ApplicationMutationManifest manifest = _manifestBuilder.Build(auditRecords);
 1435        string actualHash = _manifestHasher.ComputeHash(manifest);
 36
 37        byte[] expectedBytes;
 38        byte[] actualBytes;
 39
 40        try
 41        {
 1442            expectedBytes = Convert.FromHexString(receipt.MutationManifestHash);
 1343            actualBytes = Convert.FromHexString(actualHash);
 1344        }
 145        catch (FormatException)
 46        {
 147            return false;
 48        }
 49
 1350        return CryptographicOperations.FixedTimeEquals(expectedBytes, actualBytes);
 151    }
 52}