-
Notifications
You must be signed in to change notification settings - Fork 727
/
FakeRedactor.cs
94 lines (77 loc) · 3.25 KB
/
FakeRedactor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Globalization;
#if NET8_0_OR_GREATER
using System.Text;
#endif
using System.Threading;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Options;
using Microsoft.Shared.Diagnostics;
namespace Microsoft.Extensions.Compliance.Testing;
/// <summary>
/// Redactor designed for use in tests.
/// </summary>
public class FakeRedactor : Redactor
{
#if NET8_0_OR_GREATER
private readonly CompositeFormat _format;
#else
private readonly string _format;
#endif
private int _redactedSoFar;
/// <summary>
/// Gets the collector of redaction events.
/// </summary>
public FakeRedactionCollector EventCollector { get; }
/// <summary>
/// Initializes a new instance of the <see cref="FakeRedactor"/> class.
/// </summary>
/// <param name="options">The options to control the redactor's behavior.</param>
/// <param name="collector">Collects info about redacted values.</param>
public FakeRedactor(IOptions<FakeRedactorOptions>? options = null, FakeRedactionCollector? collector = null)
{
var opt = options ?? Microsoft.Extensions.Options.Options.Create(new FakeRedactorOptions());
IValidateOptions<FakeRedactorOptions> validator = new FakeRedactorOptionsAutoValidator();
var r = validator.Validate(nameof(options), opt.Value);
if (r.Succeeded)
{
validator = new FakeRedactorOptionsCustomValidator();
r = validator.Validate(nameof(options), opt.Value);
}
if (r.Failed)
{
Throw.ArgumentException(nameof(options), r.ToString());
}
EventCollector = collector ?? new FakeRedactionCollector();
#if NET8_0_OR_GREATER
_format = CompositeFormat.Parse(opt.Value.RedactionFormat);
#else
_format = opt.Value.RedactionFormat;
#endif
}
/// <summary>
/// Initializes a new instance of the <see cref="FakeRedactor"/> class.
/// </summary>
/// <param name="options">The options to control behavior of redactor.</param>
/// <param name="collector">Collects info about redacted values.</param>
/// <returns>New instance of <see cref="FakeRedactor"/>.</returns>
public static FakeRedactor Create(FakeRedactorOptions? options = null, FakeRedactionCollector? collector = null) => new(Options.Options.Create(options ?? new FakeRedactorOptions()), collector);
/// <inheritdoc/>
public override int Redact(ReadOnlySpan<char> source, Span<char> destination)
{
var sourceString = source.ToString();
var str = string.Format(CultureInfo.InvariantCulture, _format, sourceString);
Throw.IfBufferTooSmall(destination.Length, str.Length, nameof(destination));
str.AsSpan().CopyTo(destination);
var order = Interlocked.Increment(ref _redactedSoFar);
EventCollector.Append(new RedactedData(sourceString, destination.Slice(0, str.Length).ToString(), order));
return str.Length;
}
/// <inheritdoc/>
public override int GetRedactedLength(ReadOnlySpan<char> input)
{
return string.Format(CultureInfo.InvariantCulture, _format, input.ToString()).Length;
}
}