Skip to content

Commit 3252dc5

Browse files
bizybotYogesh Gaikwad
authored and
Yogesh Gaikwad
committed
[HLRC] Add support for get role mappings API (#34637)
This commit adds support for get role mappings API in HLRC.
1 parent fee7a42 commit 3252dc5

13 files changed

+845
-0
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.elasticsearch.client.security.DisableUserRequest;
3030
import org.elasticsearch.client.security.EmptyResponse;
3131
import org.elasticsearch.client.security.EnableUserRequest;
32+
import org.elasticsearch.client.security.GetRoleMappingsRequest;
33+
import org.elasticsearch.client.security.GetRoleMappingsResponse;
3234
import org.elasticsearch.client.security.GetSslCertificatesRequest;
3335
import org.elasticsearch.client.security.GetSslCertificatesResponse;
3436
import org.elasticsearch.client.security.PutUserRequest;
@@ -112,6 +114,40 @@ public void putRoleMappingAsync(final PutRoleMappingRequest request, final Reque
112114
PutRoleMappingResponse::fromXContent, listener, emptySet());
113115
}
114116

117+
/**
118+
* Synchronously get role mapping(s).
119+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-role-mapping.html">
120+
* the docs</a> for more.
121+
*
122+
* @param request {@link GetRoleMappingsRequest} with role mapping name(s).
123+
* If no role mapping name is provided then retrieves all role mappings.
124+
* @param options the request options (e.g. headers), use
125+
* {@link RequestOptions#DEFAULT} if nothing needs to be customized
126+
* @return the response from the get role mapping call
127+
* @throws IOException in case there is a problem sending the request or
128+
* parsing back the response
129+
*/
130+
public GetRoleMappingsResponse getRoleMappings(final GetRoleMappingsRequest request, final RequestOptions options) throws IOException {
131+
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::getRoleMappings,
132+
options, GetRoleMappingsResponse::fromXContent, emptySet());
133+
}
134+
135+
/**
136+
* Asynchronously get role mapping(s).
137+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-role-mapping.html">
138+
* the docs</a> for more.
139+
*
140+
* @param request {@link GetRoleMappingsRequest} with role mapping name(s).
141+
* If no role mapping name is provided then retrieves all role mappings.
142+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
143+
* @param listener the listener to be notified upon request completion
144+
*/
145+
public void getRoleMappingsAsync(final GetRoleMappingsRequest request, final RequestOptions options,
146+
final ActionListener<GetRoleMappingsResponse> listener) {
147+
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::getRoleMappings,
148+
options, GetRoleMappingsResponse::fromXContent, listener, emptySet());
149+
}
150+
115151
/**
116152
* Enable a native realm or built-in user synchronously.
117153
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html">

client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.client;
2121

22+
import org.apache.http.client.methods.HttpGet;
2223
import org.apache.http.client.methods.HttpDelete;
2324
import org.apache.http.client.methods.HttpPost;
2425
import org.apache.http.client.methods.HttpPut;
@@ -28,9 +29,11 @@
2829
import org.elasticsearch.client.security.PutRoleMappingRequest;
2930
import org.elasticsearch.client.security.DisableUserRequest;
3031
import org.elasticsearch.client.security.EnableUserRequest;
32+
import org.elasticsearch.client.security.GetRoleMappingsRequest;
3133
import org.elasticsearch.client.security.ChangePasswordRequest;
3234
import org.elasticsearch.client.security.PutUserRequest;
3335
import org.elasticsearch.client.security.SetUserEnabledRequest;
36+
import org.elasticsearch.common.Strings;
3437

3538
import java.io.IOException;
3639

@@ -78,6 +81,15 @@ static Request putRoleMapping(final PutRoleMappingRequest putRoleMappingRequest)
7881
return request;
7982
}
8083

84+
static Request getRoleMappings(final GetRoleMappingsRequest getRoleMappingRequest) throws IOException {
85+
RequestConverters.EndpointBuilder builder = new RequestConverters.EndpointBuilder();
86+
builder.addPathPartAsIs("_xpack/security/role_mapping");
87+
if (getRoleMappingRequest.getRoleMappingNames().size() > 0) {
88+
builder.addPathPart(Strings.collectionToCommaDelimitedString(getRoleMappingRequest.getRoleMappingNames()));
89+
}
90+
return new Request(HttpGet.METHOD_NAME, builder.build());
91+
}
92+
8193
static Request enableUser(EnableUserRequest enableUserRequest) {
8294
return setUserEnabled(enableUserRequest);
8395
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.security;
21+
22+
import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
23+
import org.elasticsearch.client.security.support.expressiondsl.parser.RoleMapperExpressionParser;
24+
import org.elasticsearch.common.ParseField;
25+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
26+
import org.elasticsearch.common.xcontent.ObjectParser;
27+
import org.elasticsearch.common.xcontent.XContentParser;
28+
29+
import java.util.Collections;
30+
import java.util.List;
31+
import java.util.Map;
32+
33+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
34+
35+
/**
36+
* A representation of a single role-mapping.
37+
*
38+
* @see RoleMapperExpression
39+
* @see RoleMapperExpressionParser
40+
*/
41+
public final class ExpressionRoleMapping {
42+
43+
@SuppressWarnings("unchecked")
44+
static final ConstructingObjectParser<ExpressionRoleMapping, String> PARSER = new ConstructingObjectParser<>("role-mapping", true,
45+
(args, name) -> new ExpressionRoleMapping(name, (RoleMapperExpression) args[0], (List<String>) args[1],
46+
(Map<String, Object>) args[2], (boolean) args[3]));
47+
48+
static {
49+
PARSER.declareField(constructorArg(), (parser, context) -> RoleMapperExpressionParser.fromXContent(parser), Fields.RULES,
50+
ObjectParser.ValueType.OBJECT);
51+
PARSER.declareStringArray(constructorArg(), Fields.ROLES);
52+
PARSER.declareField(constructorArg(), XContentParser::map, Fields.METADATA, ObjectParser.ValueType.OBJECT);
53+
PARSER.declareBoolean(constructorArg(), Fields.ENABLED);
54+
}
55+
56+
private final String name;
57+
private final RoleMapperExpression expression;
58+
private final List<String> roles;
59+
private final Map<String, Object> metadata;
60+
private final boolean enabled;
61+
62+
/**
63+
* Constructor for role mapping
64+
*
65+
* @param name role mapping name
66+
* @param expr {@link RoleMapperExpression} Expression used for role mapping
67+
* @param roles list of roles to be associated with the user
68+
* @param metadata metadata that helps to identify which roles are assigned
69+
* to the user
70+
* @param enabled a flag when {@code true} signifies the role mapping is active
71+
*/
72+
public ExpressionRoleMapping(final String name, final RoleMapperExpression expr, final List<String> roles,
73+
final Map<String, Object> metadata, boolean enabled) {
74+
this.name = name;
75+
this.expression = expr;
76+
this.roles = Collections.unmodifiableList(roles);
77+
this.metadata = (metadata == null) ? Collections.emptyMap() : Collections.unmodifiableMap(metadata);
78+
this.enabled = enabled;
79+
}
80+
81+
public String getName() {
82+
return name;
83+
}
84+
85+
public RoleMapperExpression getExpression() {
86+
return expression;
87+
}
88+
89+
public List<String> getRoles() {
90+
return roles;
91+
}
92+
93+
public Map<String, Object> getMetadata() {
94+
return metadata;
95+
}
96+
97+
public boolean isEnabled() {
98+
return enabled;
99+
}
100+
101+
@Override
102+
public int hashCode() {
103+
final int prime = 31;
104+
int result = 1;
105+
result = prime * result + (enabled ? 1231 : 1237);
106+
result = prime * result + ((expression == null) ? 0 : expression.hashCode());
107+
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
108+
result = prime * result + ((name == null) ? 0 : name.hashCode());
109+
result = prime * result + ((roles == null) ? 0 : roles.hashCode());
110+
return result;
111+
}
112+
113+
@Override
114+
public boolean equals(Object obj) {
115+
if (this == obj)
116+
return true;
117+
if (obj == null)
118+
return false;
119+
if (getClass() != obj.getClass())
120+
return false;
121+
final ExpressionRoleMapping other = (ExpressionRoleMapping) obj;
122+
if (enabled != other.enabled)
123+
return false;
124+
if (expression == null) {
125+
if (other.expression != null)
126+
return false;
127+
} else if (!expression.equals(other.expression))
128+
return false;
129+
if (metadata == null) {
130+
if (other.metadata != null)
131+
return false;
132+
} else if (!metadata.equals(other.metadata))
133+
return false;
134+
if (name == null) {
135+
if (other.name != null)
136+
return false;
137+
} else if (!name.equals(other.name))
138+
return false;
139+
if (roles == null) {
140+
if (other.roles != null)
141+
return false;
142+
} else if (!roles.equals(other.roles))
143+
return false;
144+
return true;
145+
}
146+
147+
public interface Fields {
148+
ParseField ROLES = new ParseField("roles");
149+
ParseField ENABLED = new ParseField("enabled");
150+
ParseField RULES = new ParseField("rules");
151+
ParseField METADATA = new ParseField("metadata");
152+
}
153+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.security;
21+
22+
import org.elasticsearch.client.Validatable;
23+
import org.elasticsearch.common.util.set.Sets;
24+
25+
import java.util.Collections;
26+
import java.util.Objects;
27+
import java.util.Set;
28+
29+
/**
30+
* Request object to get role mappings
31+
*/
32+
public final class GetRoleMappingsRequest implements Validatable {
33+
private final Set<String> roleMappingNames;
34+
35+
public GetRoleMappingsRequest(final String... roleMappingNames) {
36+
if (roleMappingNames != null) {
37+
this.roleMappingNames = Collections.unmodifiableSet(Sets.newHashSet(roleMappingNames));
38+
} else {
39+
this.roleMappingNames = Collections.emptySet();
40+
}
41+
}
42+
43+
public Set<String> getRoleMappingNames() {
44+
return roleMappingNames;
45+
}
46+
47+
@Override
48+
public int hashCode() {
49+
return Objects.hash(roleMappingNames);
50+
}
51+
52+
@Override
53+
public boolean equals(Object obj) {
54+
if (this == obj) {
55+
return true;
56+
}
57+
if (obj == null) {
58+
return false;
59+
}
60+
if (getClass() != obj.getClass()) {
61+
return false;
62+
}
63+
final GetRoleMappingsRequest other = (GetRoleMappingsRequest) obj;
64+
65+
return Objects.equals(roleMappingNames, other.roleMappingNames);
66+
}
67+
68+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.security;
21+
22+
import org.elasticsearch.common.xcontent.XContentParser;
23+
import org.elasticsearch.common.xcontent.XContentParserUtils;
24+
25+
import java.io.IOException;
26+
import java.util.ArrayList;
27+
import java.util.Collections;
28+
import java.util.List;
29+
30+
/**
31+
* Get role mappings response
32+
*/
33+
public final class GetRoleMappingsResponse {
34+
35+
private final List<ExpressionRoleMapping> mappings;
36+
37+
public GetRoleMappingsResponse(List<ExpressionRoleMapping> mappings) {
38+
this.mappings = Collections.unmodifiableList(mappings);
39+
}
40+
41+
public List<ExpressionRoleMapping> getMappings() {
42+
return mappings;
43+
}
44+
45+
@Override
46+
public boolean equals(Object o) {
47+
if (this == o) return true;
48+
if (o == null || getClass() != o.getClass()) return false;
49+
final GetRoleMappingsResponse that = (GetRoleMappingsResponse) o;
50+
return this.mappings.equals(that.mappings);
51+
}
52+
53+
@Override
54+
public int hashCode() {
55+
return mappings.hashCode();
56+
}
57+
58+
public static GetRoleMappingsResponse fromXContent(XContentParser parser) throws IOException {
59+
final List<ExpressionRoleMapping> roleMappings = new ArrayList<>();
60+
61+
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
62+
XContentParser.Token token;
63+
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
64+
XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation);
65+
roleMappings.add(ExpressionRoleMapping.PARSER.parse(parser, parser.currentName()));
66+
}
67+
68+
return new GetRoleMappingsResponse(roleMappings);
69+
}
70+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/security/support/expressiondsl/parser/RoleMapperExpressionParser.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,18 @@
4545
public final class RoleMapperExpressionParser {
4646
public static final ParseField FIELD = new ParseField("field");
4747

48+
public static RoleMapperExpression fromXContent(final XContentParser parser) throws IOException {
49+
return new RoleMapperExpressionParser().parse("rules", parser);
50+
}
51+
52+
/**
53+
* This function exists to be compatible with
54+
* {@link org.elasticsearch.common.xcontent.ContextParser#parse(XContentParser, Object)}
55+
*/
56+
public static RoleMapperExpression parseObject(XContentParser parser, String id) throws IOException {
57+
return new RoleMapperExpressionParser().parse(id, parser);
58+
}
59+
4860
/**
4961
* @param name The name of the expression tree within its containing object.
5062
* Used to provide descriptive error messages.

0 commit comments

Comments
 (0)