Skip to content

Commit 0f3d571

Browse files
authored
Fix username rule when returned as array (#6110)
1 parent 2f82491 commit 0f3d571

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

src/Nest/XPack/Security/RoleMapping/Rules/Field/FieldRuleBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ protected string Username
5959
set => BackingDictionary.Add("username", value);
6060
}
6161

62+
[IgnoreDataMember]
63+
protected IEnumerable<string> Usernames
64+
{
65+
get => BackingDictionary.TryGetValue("username", out var o) ? (IEnumerable<string>)o : null;
66+
set => BackingDictionary.Add("username", value);
67+
}
68+
6269
public static AnyRoleMappingRule operator |(FieldRuleBase leftContainer, FieldRuleBase rightContainer) =>
6370
new AnyRoleMappingRule(new FieldRoleMappingRule(leftContainer), new FieldRoleMappingRule(rightContainer));
6471

src/Nest/XPack/Security/RoleMapping/Rules/Field/FieldRuleBaseFormatter.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ public FieldRuleBase Deserialize(ref JsonReader reader, IJsonFormatterResolver f
3939
switch (value)
4040
{
4141
case 0:
42+
if (reader.GetCurrentJsonToken() == JsonToken.BeginArray)
43+
{
44+
var fm = formatterResolver.GetFormatter<IEnumerable<string>>();
45+
var dns = fm.Deserialize(ref reader, formatterResolver);
46+
fieldRule = new UsernameRule(dns);
47+
break;
48+
}
4249
var username = reader.ReadString();
4350
fieldRule = new UsernameRule(username);
4451
break;

src/Nest/XPack/Security/RoleMapping/Rules/Field/UsernameRule.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information
44

5+
using System.Collections.Generic;
6+
57
namespace Nest
68
{
79
public class UsernameRule : FieldRuleBase
810
{
911
public UsernameRule(string username) => Username = username;
12+
13+
public UsernameRule(IEnumerable<string> usernames) => Usernames = usernames;
1014
}
1115
}

src/Nest/XPack/Security/RoleMapping/Rules/Role/RoleMappingRulesDescriptor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ private RoleMappingRulesDescriptor Add(RoleMappingRuleBase m)
2424

2525
public RoleMappingRulesDescriptor DistinguishedName(string name) => Add(new DistinguishedNameRule(name));
2626

27+
public RoleMappingRulesDescriptor Username(IEnumerable<string> usernames) => Add(new UsernameRule(usernames));
28+
2729
public RoleMappingRulesDescriptor Username(string username) => Add(new UsernameRule(username));
2830

2931
public RoleMappingRulesDescriptor Groups(params string[] groups) => Add(new GroupsRule(groups));

tests/Tests.Reproduce/GitHubIssue5270.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,58 @@ private static void Assert(GetRoleMappingResponse roleResponse) =>
6767
.Subject["dn"].Should().BeAssignableTo<IEnumerable<string>>()
6868
.Subject.Count().Should().Be(2);
6969
}
70+
71+
public class GitHubIssue5270PartTwo
72+
{
73+
private static readonly byte[] ResponseBytes = Encoding.UTF8.GetBytes(@"{
74+
""test admin role mapping"" : {
75+
""enabled"" : true,
76+
""roles"" : [
77+
""apm_user""
78+
],
79+
""rules"" : {
80+
""any"" : [
81+
{
82+
""field"" : {
83+
""username"" : [
84+
""admin1"",
85+
""admin2""
86+
]
87+
}
88+
}
89+
]
90+
},
91+
""metadata"" : { }
92+
}
93+
}");
94+
95+
[U]
96+
public async Task GetRoleMappings()
97+
{
98+
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
99+
var settings = new ConnectionSettings(pool, new InMemoryConnection(ResponseBytes));
100+
var client = new ElasticClient(settings);
101+
102+
// ReSharper disable once MethodHasAsyncOverload
103+
var roleResponse = client.Security.GetRoleMapping();
104+
roleResponse.RoleMappings.Count.Should().Be(1);
105+
Assert(roleResponse);
106+
107+
roleResponse = await client.Security.GetRoleMappingAsync();
108+
roleResponse.RoleMappings.Count.Should().Be(1);
109+
Assert(roleResponse);
110+
}
111+
112+
private static void Assert(GetRoleMappingResponse roleResponse) =>
113+
roleResponse.RoleMappings["test admin role mapping"]
114+
.Rules.Should()
115+
.BeAssignableTo<AnyRoleMappingRule>()
116+
.Subject.Any.First()
117+
.Should()
118+
.BeAssignableTo<FieldRoleMappingRule>()
119+
.Subject.Field.Should()
120+
.BeAssignableTo<UsernameRule>()
121+
.Subject["username"].Should().BeAssignableTo<IEnumerable<string>>()
122+
.Subject.Count().Should().Be(2);
123+
}
70124
}

0 commit comments

Comments
 (0)