Skip to content

Commit

Permalink
Fix GetRoleMappings when multiple distinguished names returned (#5271)
Browse files Browse the repository at this point in the history
* Fix deserialisation of multiple dns
* Support serialisation
  • Loading branch information
stevejgordon authored Jan 15, 2021
1 parent b2a0705 commit c1316d3
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.Collections.Generic;

namespace Nest
{
public class DistinguishedNameRule : FieldRuleBase
{
public DistinguishedNameRule(string name) => DistinguishedName = name;

public DistinguishedNameRule(IEnumerable<string> names) => DistinguishedNames = names;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ protected string DistinguishedName
set => BackingDictionary.Add("dn", value);
}

[IgnoreDataMember]
protected IEnumerable<string> DistinguishedNames
{
get => BackingDictionary.TryGetValue("dn", out var o) ? (IEnumerable<string>)o : null;
set => BackingDictionary.Add("dn", value);
}

[IgnoreDataMember]
protected IEnumerable<string> Groups
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using System.Collections.Generic;
using Elasticsearch.Net.Utf8Json;
using Elasticsearch.Net.Utf8Json.Formatters;
using Elasticsearch.Net.Utf8Json.Internal;


Expand Down Expand Up @@ -41,6 +43,13 @@ public FieldRuleBase Deserialize(ref JsonReader reader, IJsonFormatterResolver f
fieldRule = new UsernameRule(username);
break;
case 1:
if (reader.GetCurrentJsonToken() == JsonToken.BeginArray)
{
var fm = formatterResolver.GetFormatter<IEnumerable<string>>();
var dns = fm.Deserialize(ref reader, formatterResolver);
fieldRule = new DistinguishedNameRule(dns);
break;
}
var dn = reader.ReadString();
fieldRule = new DistinguishedNameRule(dn);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ private RoleMappingRulesDescriptor Add(RoleMappingRuleBase m)
return this;
}

public RoleMappingRulesDescriptor DistinguishedName(IEnumerable<string> names) => Add(new DistinguishedNameRule(names));

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

public RoleMappingRulesDescriptor Username(string username) => Add(new UsernameRule(username));
Expand Down
66 changes: 66 additions & 0 deletions tests/Tests.Reproduce/GitHubIssue5270.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
using Elasticsearch.Net;
using FluentAssertions;
using Nest;

namespace Tests.Reproduce
{
public class GitHubIssue5270
{
private static readonly byte[] ResponseBytes = Encoding.UTF8.GetBytes(@"{
""test admin role mapping"" : {
""enabled"" : true,
""roles"" : [
""apm_user""
],
""rules"" : {
""any"" : [
{
""field"" : {
""dn"" : [
""CN=Bloggs Joe abcdef01,OU=Users,OU=_Central,OU=S1000,OU=SG001,DC=ad001,DC=example,DC=net"",
""cn=bloggs joe abcdef02,ou=usersfunctional,ou=_central,ou=accadm,OU=SG001,DC=ad001,DC=example,DC=net""
]
}
}
]
},
""metadata"" : { }
}
}");

[U]
public async Task GetRoleMappings()
{
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
var settings = new ConnectionSettings(pool, new InMemoryConnection(ResponseBytes));
var client = new ElasticClient(settings);

// ReSharper disable once MethodHasAsyncOverload
var roleResponse = client.Security.GetRoleMapping();
roleResponse.RoleMappings.Count.Should().Be(1);
Assert(roleResponse);

roleResponse = await client.Security.GetRoleMappingAsync();
roleResponse.RoleMappings.Count.Should().Be(1);
Assert(roleResponse);
}

private static void Assert(GetRoleMappingResponse roleResponse) =>
roleResponse.RoleMappings["test admin role mapping"]
.Rules.Should()
.BeAssignableTo<AnyRoleMappingRule>()
.Subject.Any.First()
.Should()
.BeAssignableTo<FieldRoleMappingRule>()
.Subject.Field.Should()
.BeAssignableTo<DistinguishedNameRule>()
.Subject["dn"].Should().BeAssignableTo<IEnumerable<string>>()
.Subject.Count().Should().Be(2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using System.Collections.Generic;
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
using Elasticsearch.Net;
using Nest;
using Tests.Core.ManagedElasticsearch.Clusters;
using Tests.Framework.EndpointTests;
using Tests.Framework.EndpointTests.TestState;

namespace Tests.XPack.Security.RoleMapping
{
[SkipVersion("<5.5.0", "Does not exist in earlier versions")]
public class DistinguishedNamesRoleMappingsTests
: ApiTestBase<XPackCluster, PutRoleMappingResponse, IPutRoleMappingRequest, PutRoleMappingDescriptor, PutRoleMappingRequest>
{
public DistinguishedNamesRoleMappingsTests(XPackCluster cluster, EndpointUsage usage) : base(cluster, usage) { }

protected override HttpMethod HttpMethod => HttpMethod.PUT;
protected override string UrlPath => "/_security/role_mapping/name";
protected override bool SupportsDeserialization => false;

protected override object ExpectJson => new
{
enabled = true,
roles = new[] { "user_role" },
rules = new
{
any = new object[]
{
new
{
field = new {
dn = new [] {
"a",
"b"
}
}
}
}
}
};

protected override PutRoleMappingRequest Initializer { get; } = new("name")
{
Enabled = true,
Roles = new List<string> { "user_role" },
Rules = new AnyRoleMappingRule(new DistinguishedNameRule(new List<string>
{
"a", "b"
}))
};

protected override PutRoleMappingDescriptor NewDescriptor() => new("name");

protected override Func<PutRoleMappingDescriptor, IPutRoleMappingRequest> Fluent =>
d => d.Enabled().Roles("user_role").Rules(r => r.Any(a => a.DistinguishedName(new List<string> { "a", "b" })));

protected override LazyResponses ClientUsage() => Calls(
(client, f) => client.Security.PutRoleMapping("name", f),
(client, f) => client.Security.PutRoleMappingAsync("name", f),
(client, r) => client.Security.PutRoleMapping(r),
(client, r) => client.Security.PutRoleMappingAsync(r));
}
}

0 comments on commit c1316d3

Please sign in to comment.