Skip to content

Commit 10612d0

Browse files
Add support for properties containing destructured objects
1 parent 748536a commit 10612d0

File tree

4 files changed

+123
-21
lines changed

4 files changed

+123
-21
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog for Serilog.Enrichers.Sensitive
22

3+
## 1.4.0
4+
5+
- Add support for masking destructured objects
6+
37
## 1.3.0
48

59
- Add the default enricher logo to package [#5](https://github.com/serilog-contrib/Serilog.Enrichers.Sensitive/issues/5)

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>1.3.0.0</Version>
3+
<Version>1.4.0.0</Version>
44
<Authors>Sander van Vliet, Huibert Jan Nieuwkamer, Scott Toberman</Authors>
55
<Company>Codenizer BV</Company>
66
<Copyright>2022 Sander van Vliet</Copyright>

src/Serilog.Enrichers.Sensitive/SensitiveDataEnricher.cs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5-
using System.Threading.Tasks;
65
using Serilog.Core;
76
using Serilog.Events;
87
using Serilog.Parsing;
@@ -35,7 +34,7 @@ public SensitiveDataEnricher(
3534
{
3635
throw new ArgumentNullException("mask", "The mask must be a non-empty string");
3736
}
38-
37+
3938
_maskingMode = enricherOptions.Mode;
4039
_maskValue = enricherOptions.MaskValue;
4140
_maskProperties = enricherOptions.MaskProperties ?? new List<string>();
@@ -49,7 +48,7 @@ public SensitiveDataEnricher(
4948
}
5049

5150
public SensitiveDataEnricher(
52-
MaskingMode maskingMode,
51+
MaskingMode maskingMode,
5352
IEnumerable<IMaskingOperator> maskingOperators,
5453
string mask = DefaultMaskValue)
5554
: this(options =>
@@ -71,29 +70,50 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
7170

7271
foreach (var property in logEvent.Properties.ToList())
7372
{
74-
if (_excludeProperties.Contains(property.Key, StringComparer.InvariantCultureIgnoreCase))
75-
{
76-
continue;
77-
}
78-
79-
if (_maskProperties.Contains(property.Key, StringComparer.InvariantCultureIgnoreCase))
80-
{
81-
logEvent.AddOrUpdateProperty(
82-
new LogEventProperty(
83-
property.Key,
84-
new ScalarValue(_maskValue)));
85-
}
86-
else if (property.Value is ScalarValue scalar && scalar.Value is string stringValue)
87-
{
88-
logEvent.AddOrUpdateProperty(
73+
var maskedValue = MaskProperty(property);
74+
75+
logEvent
76+
.AddOrUpdateProperty(
8977
new LogEventProperty(
9078
property.Key,
91-
new ScalarValue(ReplaceSensitiveDataFromString(stringValue))));
92-
}
79+
maskedValue));
9380
}
9481
}
9582
}
9683

84+
private LogEventPropertyValue MaskProperty(KeyValuePair<string, LogEventPropertyValue> property)
85+
{
86+
if (_excludeProperties.Contains(property.Key, StringComparer.InvariantCultureIgnoreCase))
87+
{
88+
return property.Value;
89+
}
90+
91+
if (_maskProperties.Contains(property.Key, StringComparer.InvariantCultureIgnoreCase))
92+
{
93+
return new ScalarValue(_maskValue);
94+
}
95+
96+
if (property.Value is ScalarValue scalar && scalar.Value is string stringValue)
97+
{
98+
return new ScalarValue(ReplaceSensitiveDataFromString(stringValue));
99+
}
100+
if (property.Value is StructureValue structureValue)
101+
{
102+
var propList = new List<LogEventProperty>();
103+
104+
foreach (var prop in structureValue.Properties)
105+
{
106+
var maskedValue = MaskProperty(new KeyValuePair<string, LogEventPropertyValue>(prop.Name, prop.Value));
107+
108+
propList.Add(new LogEventProperty(prop.Name, maskedValue));
109+
}
110+
111+
return new StructureValue(propList);
112+
}
113+
114+
return property.Value;
115+
}
116+
97117
private string ReplaceSensitiveDataFromString(string input)
98118
{
99119
foreach (var maskingOperator in _maskingOperators)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System.Collections.Generic;
2+
using Serilog.Core;
3+
using Serilog.Sinks.InMemory;
4+
using Serilog.Sinks.InMemory.Assertions;
5+
using Xunit;
6+
7+
namespace Serilog.Enrichers.Sensitive.Tests.Unit
8+
{
9+
public class WhenMaskingDestructuredObject
10+
{
11+
private readonly InMemorySink _sink;
12+
private readonly Logger _logger;
13+
14+
public WhenMaskingDestructuredObject()
15+
{
16+
_sink = new InMemorySink();
17+
18+
_logger = new LoggerConfiguration()
19+
.WriteTo.Sink(_sink)
20+
.Enrich.WithSensitiveDataMasking(options =>
21+
{
22+
options.MaskProperties.Add("TestProperty");
23+
options.MaskingOperators = new List<IMaskingOperator> { new EmailAddressMaskingOperator() };
24+
})
25+
.CreateLogger();
26+
}
27+
28+
[Fact]
29+
public void GivenLogMessageWithDestructuredObjectPropertyThatHasSensitiveData_SensitiveDataIsMasked()
30+
{
31+
var testObject = new TestObject();
32+
33+
_logger.Information("Test message {@TestObject}", testObject);
34+
35+
_sink
36+
.Should()
37+
.HaveMessage("Test message {@TestObject}")
38+
.Appearing()
39+
.Once()
40+
.WithProperty("TestObject")
41+
.HavingADestructuredObject()
42+
.WithProperty("TestProperty")
43+
.WithValue("***MASKED***");
44+
}
45+
46+
[Fact]
47+
public void GivenLogMessageWithDestructuredObjectPropertyThatHasSensitiveDataInNestedProperty_SensitiveDataIsMasked()
48+
{
49+
var testObject = new TestObject();
50+
51+
_logger.Information("Test message {@TestObject}", testObject);
52+
53+
_sink
54+
.Should()
55+
.HaveMessage("Test message {@TestObject}")
56+
.Appearing()
57+
.Once()
58+
.WithProperty("TestObject")
59+
.HavingADestructuredObject()
60+
.WithProperty("Nested")
61+
.HavingADestructuredObject()
62+
.WithProperty("TestProperty")
63+
.WithValue("***MASKED***");
64+
}
65+
}
66+
67+
public class TestObject
68+
{
69+
public string TestProperty { get; set; } = "[email protected]";
70+
71+
public NestedTestObject Nested { get; set; } = new NestedTestObject();
72+
}
73+
74+
public class NestedTestObject
75+
{
76+
public string TestProperty { get; set; } = "[email protected]";
77+
}
78+
}

0 commit comments

Comments
 (0)