Skip to content

Commit 03f4c3f

Browse files
authored
Support for JSON arrays, bool, long, and other JSON types. (#11)
* Added support for int, long, and bool JSON types. * JSON array support
1 parent bfebe8d commit 03f4c3f

File tree

2 files changed

+94
-23
lines changed

2 files changed

+94
-23
lines changed

Source/VaultSharp.Extensions.Configuration/VaultConfigurationProvider.cs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ namespace VaultSharp.Extensions.Configuration
22
{
33
using System;
44
using System.Collections.Generic;
5+
using System.Globalization;
56
using System.Threading.Tasks;
67
using Microsoft.Extensions.Configuration;
78
using Microsoft.Extensions.Logging;
@@ -122,31 +123,55 @@ private void SetData<TValue>(IEnumerable<KeyValuePair<string, TValue>> data, str
122123
case string sValue:
123124
this.Set(nestedKey, sValue);
124125
break;
126+
case int intValue:
127+
this.Set(nestedKey, intValue.ToString(CultureInfo.InvariantCulture));
128+
break;
129+
case long longValue:
130+
this.Set(nestedKey, longValue.ToString(CultureInfo.InvariantCulture));
131+
break;
132+
case bool boolValue:
133+
this.Set(nestedKey, boolValue.ToString(CultureInfo.InvariantCulture));
134+
break;
125135
case JToken token:
126136
switch (token.Type)
127137
{
128138
case JTokenType.Object:
129139
this.SetData<JToken?>(token.Value<JObject>(), nestedKey);
130140
break;
131-
case JTokenType.String:
132-
this.Set(nestedKey, token.Value<string>());
133-
break;
134141
case JTokenType.None:
135142
case JTokenType.Array:
136-
case JTokenType.Constructor:
143+
var array = (JArray)token;
144+
for (var i = 0; i < array.Count; i++)
145+
{
146+
if (array[i].Type == JTokenType.Array)
147+
{
148+
this.SetData<JToken?>(array[i].Value<JObject>(), $"{nestedKey}:{i}");
149+
}
150+
else if (array[i].Type == JTokenType.Object)
151+
{
152+
this.SetData<JToken?>(array[i].Value<JObject>(), $"{nestedKey}:{i}");
153+
}
154+
else
155+
{
156+
this.Set($"{nestedKey}:{i}", array[i].Value<string>());
157+
}
158+
}
159+
160+
break;
161+
137162
case JTokenType.Property:
138-
case JTokenType.Comment:
139163
case JTokenType.Integer:
140164
case JTokenType.Float:
141165
case JTokenType.Boolean:
142-
case JTokenType.Null:
143166
case JTokenType.Undefined:
144167
case JTokenType.Date:
145168
case JTokenType.Raw:
146169
case JTokenType.Bytes:
147170
case JTokenType.Guid:
148171
case JTokenType.Uri:
149172
case JTokenType.TimeSpan:
173+
case JTokenType.String:
174+
this.Set(nestedKey, token.Value<string>());
150175
break;
151176
}
152177

Tests/VaultSharp.Extensions.Configuration.Test/IntegrationTests.cs

Lines changed: 63 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,29 +44,54 @@ private TestcontainersContainer PrepareVaultContainer()
4444
return testcontainersBuilder.Build();
4545
}
4646

47-
private async Task LoadDataAsync(Dictionary<string, KeyValuePair<string,string>> values)
47+
private async Task LoadDataAsync(Dictionary<string, IEnumerable<KeyValuePair<string, object>>> values)
4848
{
4949
var authMethod = new TokenAuthMethodInfo("root");
5050

5151
var vaultClientSettings = new VaultClientSettings("http://localhost:8200", authMethod);
5252
IVaultClient vaultClient = new VaultClient(vaultClientSettings);
5353

54-
foreach (var pair in values)
54+
foreach (var sectionPair in values)
5555
{
56-
var data = new Dictionary<string, object>() { [pair.Value.Key] = pair.Value.Value };
57-
await vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(pair.Key, data).ConfigureAwait(false);
56+
var data = new Dictionary<string, object>();
57+
foreach (var pair in sectionPair.Value)
58+
{
59+
data.Add(pair.Key, pair.Value);
60+
}
61+
62+
await vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(sectionPair.Key, data)
63+
.ConfigureAwait(false);
5864
}
5965
}
6066

6167
[Fact]
6268
public async Task Success_SimpleTest_TokenAuth()
6369
{
6470
// arrange
65-
Dictionary<string, KeyValuePair<string, string>> values =
66-
new Dictionary<string, KeyValuePair<string, string>>
71+
var values =
72+
new Dictionary<string, IEnumerable<KeyValuePair<string, object>>>
6773
{
68-
{ "test", new KeyValuePair<string, string>("option1", "value1") },
69-
{ "test/subsection", new KeyValuePair<string, string>("option2", "value2") },
74+
{
75+
"test", new[]
76+
{
77+
new KeyValuePair<string, object>("option1", "value1"),
78+
new KeyValuePair<string, object>("option3", 5),
79+
new KeyValuePair<string, object>("option4", true),
80+
new KeyValuePair<string, object>("option5", new[] {"v1", "v2", "v3"}),
81+
new KeyValuePair<string, object>("option6",
82+
new[]
83+
{
84+
new TestConfigObject() {OptionA = "a1", OptionB = "b1"},
85+
new TestConfigObject() {OptionA = "a2", OptionB = "b2"},
86+
}),
87+
}
88+
},
89+
{
90+
"test/subsection", new[]
91+
{
92+
new KeyValuePair<string, object>("option2", "value2"),
93+
}
94+
},
7095
};
7196

7297
var container = this.PrepareVaultContainer();
@@ -86,6 +111,19 @@ public async Task Success_SimpleTest_TokenAuth()
86111

87112
// assert
88113
configurationRoot.GetValue<string>("option1").Should().Be("value1");
114+
configurationRoot.GetValue<int>("option3").Should().Be(5);
115+
configurationRoot.GetValue<bool>("option4").Should().Be(true);
116+
configurationRoot.GetValue<string>("option5:0").Should().Be("v1");
117+
configurationRoot.GetValue<string>("option5:1").Should().Be("v2");
118+
configurationRoot.GetValue<string>("option5:2").Should().Be("v3");
119+
var t1 = new TestConfigObject();
120+
configurationRoot.Bind("option6:0", t1);
121+
t1.OptionA.Should().Be("a1");
122+
t1.OptionB.Should().Be("b1");
123+
var t2 = new TestConfigObject();
124+
configurationRoot.Bind("option6:1", t2);
125+
t2.OptionA.Should().Be("a2");
126+
t2.OptionB.Should().Be("b2");
89127
configurationRoot.GetSection("subsection").GetValue<string>("option2").Should().Be("value2");
90128
}
91129
finally
@@ -100,11 +138,11 @@ public async Task Success_WatcherTest_TokenAuth()
100138
// arrange
101139
using CancellationTokenSource cts = new CancellationTokenSource();
102140

103-
Dictionary<string, KeyValuePair<string, string>> values =
104-
new Dictionary<string, KeyValuePair<string, string>>
141+
var values =
142+
new Dictionary<string, IEnumerable<KeyValuePair<string, object>>>
105143
{
106-
{ "test", new KeyValuePair<string, string>("option1", "value1") },
107-
{ "test/subsection", new KeyValuePair<string, string>("option2", "value2") },
144+
{"test", new[] {new KeyValuePair<string, object>("option1", "value1"),}},
145+
{"test/subsection", new[] {new KeyValuePair<string, object>("option2", "value2"),}},
108146
};
109147

110148
var container = this.PrepareVaultContainer();
@@ -117,7 +155,8 @@ public async Task Success_WatcherTest_TokenAuth()
117155
// act
118156
ConfigurationBuilder builder = new ConfigurationBuilder();
119157
builder.AddVaultConfiguration(
120-
() => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true, reloadCheckIntervalSeconds: 10),
158+
() => new VaultOptions("http://localhost:8200", "root", reloadOnChange: true,
159+
reloadCheckIntervalSeconds: 10),
121160
"test",
122161
"secret",
123162
this._logger);
@@ -132,11 +171,11 @@ public async Task Success_WatcherTest_TokenAuth()
132171
reloadToken.HasChanged.Should().BeFalse();
133172

134173
// load new data and wait for reload
135-
values = new Dictionary<string, KeyValuePair<string, string>>
174+
values = new Dictionary<string, IEnumerable<KeyValuePair<string, object>>>
136175
{
137-
{ "test", new KeyValuePair<string, string>("option1", "value1_new") },
138-
{ "test/subsection", new KeyValuePair<string, string>("option2", "value2_new") },
139-
{ "test/subsection3", new KeyValuePair<string, string>("option3", "value3_new") },
176+
{"test", new[] {new KeyValuePair<string, object>("option1", "value1_new"),}},
177+
{"test/subsection", new[] {new KeyValuePair<string, object>("option2", "value2_new"),}},
178+
{"test/subsection3", new[] {new KeyValuePair<string, object>("option3", "value3_new"),}},
140179
};
141180
await this.LoadDataAsync(values).ConfigureAwait(false);
142181
await Task.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(true);
@@ -155,4 +194,11 @@ public async Task Success_WatcherTest_TokenAuth()
155194
}
156195
}
157196
}
197+
198+
public class TestConfigObject
199+
{
200+
public string OptionA { get; set; }
201+
202+
public string OptionB { get; set; }
203+
}
158204
}

0 commit comments

Comments
 (0)