Skip to content

Commit 57e4029

Browse files
Use a prooper structure for configuring
1 parent 89c0115 commit 57e4029

11 files changed

+125
-74
lines changed
Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,58 @@
1-
namespace Serilog.Enrichers.Sensitive;
1+
using System;
22

3-
public class MaskOptions
3+
namespace Serilog.Enrichers.Sensitive;
4+
5+
public class MaskOptions : IEquatable<MaskOptions>
46
{
5-
public static readonly MaskOptions Default= new();
7+
public static readonly MaskOptions Default = new();
68
public const int NotSet = -1;
79
public int ShowFirst { get; set; } = NotSet;
810
public int ShowLast { get; set; } = NotSet;
911
public bool PreserveLength { get; set; } = true;
1012

13+
public bool Equals(MaskOptions? other)
14+
{
15+
if (other is null)
16+
{
17+
return false;
18+
}
19+
20+
if (ReferenceEquals(this, other))
21+
{
22+
return true;
23+
}
24+
25+
return ShowFirst == other.ShowFirst && ShowLast == other.ShowLast && PreserveLength == other.PreserveLength;
26+
}
27+
28+
public override bool Equals(object? obj)
29+
{
30+
if (obj is null)
31+
{
32+
return false;
33+
}
34+
35+
if (ReferenceEquals(this, obj))
36+
{
37+
return true;
38+
}
39+
40+
if (obj.GetType() != GetType())
41+
{
42+
return false;
43+
}
44+
45+
return Equals((MaskOptions)obj);
46+
}
47+
48+
public override int GetHashCode()
49+
{
50+
unchecked
51+
{
52+
var hashCode = ShowFirst;
53+
hashCode = (hashCode * 397) ^ ShowLast;
54+
hashCode = (hashCode * 397) ^ PreserveLength.GetHashCode();
55+
return hashCode;
56+
}
57+
}
1158
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Serilog.Enrichers.Sensitive;
2+
3+
public class MaskProperty
4+
{
5+
public string Name { get; set; }
6+
public MaskOptions Options { get; set; } = new();
7+
8+
public static MaskProperty WithDefaults(string propertyName)
9+
{
10+
return new MaskProperty { Name = propertyName };
11+
}
12+
}

src/Serilog.Enrichers.Sensitive/MaskPropertyCollection.cs

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/Serilog.Enrichers.Sensitive/SensitiveDataEnricher.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal class SensitiveDataEnricher : ILogEventEnricher
1818
private readonly FieldInfo _messageTemplateBackingField;
1919
private readonly List<IMaskingOperator> _maskingOperators;
2020
private readonly string _maskValue;
21-
private readonly MaskPropertyCollection _maskProperties;
21+
private readonly List<MaskProperty> _maskProperties;
2222
private readonly List<string> _excludeProperties;
2323

2424
public SensitiveDataEnricher(SensitiveDataEnricherOptions options)
@@ -33,7 +33,7 @@ public SensitiveDataEnricher(
3333
MaskingMode.Globally,
3434
DefaultMaskValue,
3535
DefaultOperators.Select(o => o.GetType().AssemblyQualifiedName),
36-
_maskProperties != null ? string.Join(",", _maskProperties) : null,
36+
_maskProperties,
3737
new List<string>());
3838

3939
if (options != null)
@@ -114,21 +114,22 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
114114
return (false, null);
115115
}
116116

117-
if(_maskProperties.TryGetProperty(property.Key, out var options))
117+
var matchingProperty = _maskProperties.SingleOrDefault(p => p.Name.Equals(property.Key, StringComparison.OrdinalIgnoreCase));
118+
if(matchingProperty != null)
118119
{
119-
if (options == MaskOptions.Default)
120+
if (matchingProperty.Options == MaskOptions.Default)
120121
{
121122
return (true, new ScalarValue(_maskValue));
122123
}
123124

124125
switch (property.Value)
125126
{
126127
case ScalarValue { Value: string stringValue }:
127-
return (true, new ScalarValue(MaskWithOptions(_maskValue, options, stringValue)));
128-
case ScalarValue { Value: Uri uriValue } when options is UriMaskOptions uriMaskOptions:
128+
return (true, new ScalarValue(MaskWithOptions(_maskValue, matchingProperty.Options, stringValue)));
129+
case ScalarValue { Value: Uri uriValue } when matchingProperty.Options is UriMaskOptions uriMaskOptions:
129130
return (true, new ScalarValue(MaskWithUriOptions(_maskValue, uriMaskOptions, uriValue)));
130131
case ScalarValue { Value: Uri uriValue }:
131-
return (true, new ScalarValue(MaskWithOptions(_maskValue, options, uriValue.ToString())));
132+
return (true, new ScalarValue(MaskWithOptions(_maskValue, matchingProperty.Options, uriValue.ToString())));
132133
}
133134
}
134135

src/Serilog.Enrichers.Sensitive/SensitiveDataEnricherOptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ public SensitiveDataEnricherOptions(
1818
MaskingMode mode = MaskingMode.Globally,
1919
string maskValue = SensitiveDataEnricher.DefaultMaskValue,
2020
IEnumerable<string>? maskingOperators = null,
21-
string? maskProperties = null,
21+
List<MaskProperty>? maskProperties = null,
2222
IEnumerable<string>? excludeProperties = null,
2323
// ReSharper disable once UnusedParameter.Local as this only exists to support JSON configuration, see the Operators property below
2424
IEnumerable<string>? operators = null)
2525
{
2626
Mode = mode;
2727
MaskValue = maskValue;
2828
MaskingOperators = maskingOperators == null ? new List<IMaskingOperator>() : ResolveMaskingOperators(maskingOperators);
29-
MaskProperties = maskProperties == null ? new MaskPropertyCollection() : MaskPropertyCollection.From(maskProperties?.Split(',') ?? []);
29+
MaskProperties = maskProperties == null ? new List<MaskProperty>() : maskProperties.ToList();
3030
ExcludeProperties = excludeProperties?.ToList() ?? new List<string>();
3131
}
3232

@@ -90,7 +90,7 @@ private static List<IMaskingOperator> ResolveMaskingOperators(IEnumerable<string
9090
/// The list of properties that should always be masked regardless of whether they match the pattern of any of the masking operators
9191
/// </summary>
9292
/// <remarks>The property name is case-insensitive, when the property is present on the log message it will always be masked even if it is empty</remarks>
93-
public MaskPropertyCollection MaskProperties { get; set; } = new();
93+
public List<MaskProperty> MaskProperties { get; set; } = new();
9494
/// <summary>
9595
/// The list of properties that should never be masked
9696
/// </summary>

test/Serilog.Enrichers.Sensitive.Tests.Unit/WhenConfiguringFromJson.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ public void ReproCaseIssue25()
5252
.WithProperty("secret")
5353
.WithValue("**SECRET**");
5454
}
55+
56+
[Fact]
57+
public void GivenMaskPropertyWithSpecificOptions_OptionsAreApplied()
58+
{
59+
var configuration = new ConfigurationBuilder()
60+
.AddJsonFile("enricher-config.json")
61+
.Build();
62+
63+
var inMemorySink = new InMemorySink();
64+
65+
var logger = new LoggerConfiguration()
66+
.ReadFrom.Configuration(configuration)
67+
.WriteTo.Sink(inMemorySink)
68+
.CreateLogger();
69+
70+
logger.Information("A test message {propwithoptions}", "1234567890");
71+
72+
inMemorySink
73+
.Should()
74+
.HaveMessage("A test message {propwithoptions}")
75+
.Appearing().Once()
76+
.WithProperty("propwithoptions")
77+
.WithValue("123*******");
78+
}
5579
}
5680

5781
public class MyTestMaskingOperator : IMaskingOperator

test/Serilog.Enrichers.Sensitive.Tests.Unit/WhenMaskingDestructuredObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public WhenMaskingDestructuredObject()
2424
.Enrich.WithSensitiveDataMasking(options =>
2525
{
2626
options.MaskingOperators = new List<IMaskingOperator> { new EmailAddressMaskingOperator() };
27-
options.MaskProperties.Add("SensitiveProperty");
27+
options.MaskProperties.Add(MaskProperty.WithDefaults("SensitiveProperty"));
2828
})
2929
.CreateLogger();
3030
}

test/Serilog.Enrichers.Sensitive.Tests.Unit/WhenMaskingSensitiveDataBasedOnPropertyName.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public void GivenLogMessageHasSpecificProperty_PropertyValueIsMasked()
1414
var logger = new LoggerConfiguration()
1515
.Enrich.WithSensitiveDataMasking(options =>
1616
{
17-
options.MaskProperties.Add("Email");
17+
options.MaskProperties.Add(MaskProperty.WithDefaults("Email"));
1818
})
1919
.WriteTo.Sink(inMemorySink)
2020
.CreateLogger();
@@ -38,7 +38,7 @@ public void GivenLogMessageHasSpecificPropertyAndLogMessageHasPropertyButLowerCa
3838
var logger = new LoggerConfiguration()
3939
.Enrich.WithSensitiveDataMasking(options =>
4040
{
41-
options.MaskProperties.Add("Email");
41+
options.MaskProperties.Add(MaskProperty.WithDefaults("Email"));
4242
})
4343
.WriteTo.Sink(inMemorySink)
4444
.CreateLogger();
@@ -86,7 +86,7 @@ public void GivenLogMessageHasSpecificPropertyAndPropertyIsExcludedAndAlsoInclud
8686
var logger = new LoggerConfiguration()
8787
.Enrich.WithSensitiveDataMasking(options =>
8888
{
89-
options.MaskProperties.Add("Email");
89+
options.MaskProperties.Add(MaskProperty.WithDefaults("Email"));
9090
options.ExcludeProperties.Add("Email");
9191
})
9292
.WriteTo.Sink(inMemorySink)

test/Serilog.Enrichers.Sensitive.Tests.Unit/WhenMaskingWithOptions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void GivenMaskOptionsWithInputShorterThanNumberOfCharactersThatShouldBeSh
2525
var inMemorySink = new InMemorySink();
2626
var logger = new LoggerConfiguration()
2727
.Enrich.WithSensitiveDataMasking(
28-
options => options.MaskProperties.Add("Prop", new MaskOptions{ ShowFirst = showFirst, ShowLast = showLast, PreserveLength = preserveLength}))
28+
options => options.MaskProperties.Add(new MaskProperty { Name = "Prop", Options = new MaskOptions{ ShowFirst = showFirst, ShowLast = showLast, PreserveLength = preserveLength}}))
2929
.WriteTo.Sink(inMemorySink)
3030
.CreateLogger();
3131

@@ -52,13 +52,13 @@ public void GivenUriMaskOptions(bool showScheme, bool showHost, bool showPath, b
5252
var inMemorySink = new InMemorySink();
5353
var logger = new LoggerConfiguration()
5454
.Enrich.WithSensitiveDataMasking(
55-
options => options.MaskProperties.Add("Prop", new UriMaskOptions
55+
options => options.MaskProperties.Add(new MaskProperty { Name ="Prop", Options = new UriMaskOptions
5656
{
5757
ShowScheme = showScheme,
5858
ShowHost = showHost,
5959
ShowPath = showPath,
6060
ShowQueryString = showQuery
61-
}))
61+
}}))
6262
.WriteTo.Sink(inMemorySink)
6363
.CreateLogger();
6464

test/Serilog.Enrichers.Sensitive.Tests.Unit/enricher-config.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@
99
"Args": {
1010
"options": {
1111
"MaskValue": "**SECRET**",
12-
"MaskProperties": "secret"
12+
"MaskProperties": [
13+
{ "Name": "secret"},
14+
{ "Name": "propwithoptions",
15+
"Options": {
16+
"ShowFirst": 3
17+
}
18+
}
19+
]
1320
}
1421
}
1522
}

0 commit comments

Comments
 (0)