From 2999459d577eebb46fe549ebd5211ace941a9cad Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 29 Nov 2018 20:17:20 +0200 Subject: [PATCH 01/21] Put Role request --- .../client/security/PutRoleRequest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java new file mode 100644 index 0000000000000..21f867cd4cd14 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java @@ -0,0 +1,77 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.security; + +import org.elasticsearch.client.Validatable; +import org.elasticsearch.client.security.user.privileges.Role; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Objects; + +/** + * Request object to create or update a role. + */ +public final class PutRoleRequest implements Validatable, ToXContentObject { + + private final Role role; + + public PutRoleRequest(Role role) { + this.role = Objects.requireNonNull(role); + } + + public Role getRole() { + return role; + } + + @Override + public int hashCode() { + return Objects.hash(role); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PutRoleRequest other = (PutRoleRequest) obj; + return Objects.equals(role, other.role); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(Role.APPLICATIONS.getPreferredName(), role.getApplicationResourcePrivileges()); + builder.field(Role.CLUSTER.getPreferredName(), role.getClusterPrivileges()); + builder.field(Role.GLOBAL.getPreferredName(), role.getGlobalApplicationPrivileges()); + builder.field(Role.INDICES.getPreferredName(), role.getIndicesPrivileges()); + builder.field(Role.METADATA.getPreferredName(), role.getMetadata()); + builder.field(Role.RUN_AS.getPreferredName(), role.getRunAsPrivilege()); + return builder.endObject(); + } + +} From 53ad4bb2d7d45144f186f87c3552008ed1d2c9ad Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 29 Nov 2018 21:29:02 +0200 Subject: [PATCH 02/21] RequestConvertTests --- .../client/SecurityRequestConverters.java | 13 +++++++ .../client/security/PutRoleRequest.java | 15 ++++++-- .../client/security/user/privileges/Role.java | 5 +++ .../SecurityRequestConvertersTests.java | 38 +++++++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java index 6485899acf947..355bf66217862 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java @@ -35,6 +35,7 @@ import org.elasticsearch.client.security.InvalidateTokenRequest; import org.elasticsearch.client.security.GetRolesRequest; import org.elasticsearch.client.security.PutRoleMappingRequest; +import org.elasticsearch.client.security.PutRoleRequest; import org.elasticsearch.client.security.HasPrivilegesRequest; import org.elasticsearch.client.security.DisableUserRequest; import org.elasticsearch.client.security.EnableUserRequest; @@ -224,4 +225,16 @@ static Request deletePrivileges(DeletePrivilegesRequest deletePrivilegeRequest) params.withRefreshPolicy(deletePrivilegeRequest.getRefreshPolicy()); return request; } + + static Request putRole(final PutRoleRequest putRoleRequest) throws IOException { + final String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_xpack/security/role") + .addPathPart(putRoleRequest.getRole().getName()) + .build(); + final Request request = new Request(HttpPut.METHOD_NAME, endpoint); + request.setEntity(createEntity(putRoleRequest, REQUEST_BODY_CONTENT_TYPE)); + final RequestConverters.Params params = new RequestConverters.Params(request); + params.withRefreshPolicy(putRoleRequest.getRefreshPolicy()); + return request; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java index 21f867cd4cd14..7a5b20690bb93 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java @@ -21,6 +21,7 @@ import org.elasticsearch.client.Validatable; import org.elasticsearch.client.security.user.privileges.Role; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -33,18 +34,24 @@ public final class PutRoleRequest implements Validatable, ToXContentObject { private final Role role; + private final RefreshPolicy refreshPolicy; - public PutRoleRequest(Role role) { + public PutRoleRequest(Role role, @Nullable final RefreshPolicy refreshPolicy) { this.role = Objects.requireNonNull(role); + this.refreshPolicy = (refreshPolicy == null) ? RefreshPolicy.getDefault() : refreshPolicy; } public Role getRole() { return role; } + public RefreshPolicy getRefreshPolicy() { + return refreshPolicy; + } + @Override public int hashCode() { - return Objects.hash(role); + return Objects.hash(role, refreshPolicy); } @Override @@ -59,7 +66,9 @@ public boolean equals(Object obj) { return false; } final PutRoleRequest other = (PutRoleRequest) obj; - return Objects.equals(role, other.role); + + return (refreshPolicy == other.getRefreshPolicy()) && + Objects.equals(role, other.role); } @Override diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index e332971a512fd..8aeb742427961 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -329,6 +329,9 @@ public static class ClusterPrivilegeName { public static final String MANAGE_PIPELINE = "manage_pipeline"; public static final String MANAGE_CCR = "manage_ccr"; public static final String READ_CCR = "read_ccr"; + public static final String[] ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, + MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT, + MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR }; } /** @@ -349,6 +352,8 @@ public static class IndexPrivilegeName { public static final String CREATE_INDEX = "create_index"; public static final String VIEW_INDEX_METADATA = "view_index_metadata"; public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index"; + public static final String[] ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE, + DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX }; } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java index 110e0cc56c986..3cdb991beb7d2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java @@ -35,12 +35,16 @@ import org.elasticsearch.client.security.ChangePasswordRequest; import org.elasticsearch.client.security.GetRolesRequest; import org.elasticsearch.client.security.PutRoleMappingRequest; +import org.elasticsearch.client.security.PutRoleRequest; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression; import org.elasticsearch.client.security.support.expressiondsl.expressions.AnyRoleMapperExpression; import org.elasticsearch.client.security.support.expressiondsl.fields.FieldRoleMapperExpression; import org.elasticsearch.client.security.user.User; +import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; +import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; +import org.elasticsearch.client.security.user.privileges.Role; import org.elasticsearch.common.Strings; import org.elasticsearch.test.ESTestCase; @@ -50,6 +54,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import static org.elasticsearch.client.RequestConvertersTests.assertToXContentBody; @@ -332,4 +337,37 @@ public void testDeletePrivileges() { assertEquals(expectedParams, request.getParameters()); assertNull(request.getEntity()); } + + public void testPutRole() throws IOException { + final String roleName = randomAlphaOfLengthBetween(4, 7); + final List clusterPrivileges = randomSubsetOf(3, Role.ClusterPrivilegeName.ARRAY); + final Map metadata = Collections.singletonMap(randomAlphaOfLengthBetween(4, 7), randomAlphaOfLengthBetween(4, 7)); + final String[] runAsPrivilege = randomArray(3, String[]::new, () -> randomAlphaOfLength(5)); + final List applicationPrivilegeNames = Arrays.asList(randomArray(1, 3, String[]::new, () -> randomAlphaOfLength(5))); + final List applicationResouceNames = Arrays.asList(randomArray(1, 3, String[]::new, () -> randomAlphaOfLength(5))); + final ApplicationResourcePrivileges applicationResourcePrivilege = new ApplicationResourcePrivileges( + randomAlphaOfLengthBetween(4, 7), applicationPrivilegeNames, applicationResouceNames); + final List indicesName = Arrays.asList(randomArray(1, 3, String[]::new, () -> randomAlphaOfLength(5))); + final List indicesPrivilegeName = Arrays.asList(randomArray(1, 3, String[]::new, () -> randomAlphaOfLength(5))); + final List indicesPrivilegeGrantedName = Arrays.asList(randomArray(3, String[]::new, () -> randomAlphaOfLength(5))); + final List indicesPrivilegeDeniedName = Arrays.asList(randomArray(3, String[]::new, () -> randomAlphaOfLength(5))); + final String indicesPrivilegeQuery = randomAlphaOfLengthBetween(0, 7); + final IndicesPrivileges indicesPrivilege = IndicesPrivileges.builder().indices(indicesName).privileges(indicesPrivilegeName) + .grantedFields(indicesPrivilegeGrantedName).deniedFields(indicesPrivilegeDeniedName).query(indicesPrivilegeQuery).build(); + final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values()); + final Map expectedParams; + if (refreshPolicy != RefreshPolicy.NONE) { + expectedParams = Collections.singletonMap("refresh", refreshPolicy.getValue()); + } else { + expectedParams = Collections.emptyMap(); + } + final Role role = Role.builder().name(roleName).clusterPrivileges(clusterPrivileges).indicesPrivileges(indicesPrivilege) + .applicationResourcePrivileges(applicationResourcePrivilege).runAsPrivilege(runAsPrivilege).metadata(metadata).build(); + final PutRoleRequest putRoleRequest = new PutRoleRequest(role, refreshPolicy); + final Request request = SecurityRequestConverters.putRole(putRoleRequest); + assertEquals(HttpPut.METHOD_NAME, request.getMethod()); + assertEquals("/_xpack/security/role/" + roleName, request.getEndpoint()); + assertEquals(expectedParams, request.getParameters()); + assertToXContentBody(putRoleRequest, request.getEntity()); + } } From 345838ab69a14e2d67e88111929fa65f48b7c370 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 29 Nov 2018 21:47:40 +0200 Subject: [PATCH 03/21] Remove Transient metadata from the Role builder --- .../client/security/user/privileges/Role.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 8aeb742427961..5ab7e4f1cee4d 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -226,7 +226,6 @@ public static final class Builder { private @Nullable Collection applicationResourcePrivileges = null; private @Nullable Collection runAsPrivilege = null; private @Nullable Map metadata = null; - private @Nullable Map transientMetadata = null; private Builder() { } @@ -294,15 +293,9 @@ public Builder metadata(Map metadata) { return this; } - public Builder transientMetadata(Map transientMetadata) { - this.transientMetadata = - Objects.requireNonNull(transientMetadata, "Transient metadata cannot be null. Pass an empty map instead."); - return this; - } - public Role build() { return new Role(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, transientMetadata); + runAsPrivilege, metadata, null); } } From e55ee55292926f5eaff898ef52f6ab35d283b8f0 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Sun, 2 Dec 2018 12:38:16 +0200 Subject: [PATCH 04/21] Revert "Remove Transient metadata from the Role builder" This reverts commit 345838ab69a14e2d67e88111929fa65f48b7c370. --- .../client/security/user/privileges/Role.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 5ab7e4f1cee4d..8aeb742427961 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -226,6 +226,7 @@ public static final class Builder { private @Nullable Collection applicationResourcePrivileges = null; private @Nullable Collection runAsPrivilege = null; private @Nullable Map metadata = null; + private @Nullable Map transientMetadata = null; private Builder() { } @@ -293,9 +294,15 @@ public Builder metadata(Map metadata) { return this; } + public Builder transientMetadata(Map transientMetadata) { + this.transientMetadata = + Objects.requireNonNull(transientMetadata, "Transient metadata cannot be null. Pass an empty map instead."); + return this; + } + public Role build() { return new Role(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, null); + runAsPrivilege, metadata, transientMetadata); } } From d085ef7c92e4b877ce392369d5ddc2f979dda238 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Sun, 2 Dec 2018 13:16:16 +0200 Subject: [PATCH 05/21] Put Role security client and request --- .../elasticsearch/client/SecurityClient.java | 33 ++++++++- .../client/security/PutRoleResponse.java | 70 +++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java index a033ee61f79dc..07e0992a37994 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java @@ -54,6 +54,8 @@ import org.elasticsearch.client.security.InvalidateTokenResponse; import org.elasticsearch.client.security.PutRoleMappingRequest; import org.elasticsearch.client.security.PutRoleMappingResponse; +import org.elasticsearch.client.security.PutRoleRequest; +import org.elasticsearch.client.security.PutRoleResponse; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; @@ -459,7 +461,7 @@ public void getRolesAsync(GetRolesRequest request, RequestOptions options, Actio * * @param request the request with the roles to get * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized - * @return the response from the delete role call + * @return the response from the get roles call * @throws IOException in case there is a problem sending the request or parsing back the response */ public GetRolesResponse getRoles(final GetRolesRequest request, final RequestOptions options) throws IOException { @@ -467,6 +469,35 @@ public GetRolesResponse getRoles(final GetRolesRequest request, final RequestOpt GetRolesResponse::fromXContent, emptySet()); } + /** + * Asynchronously creates or updates a role in the native roles store. + * See + * the docs for more. + * + * @param request the request containing the role to create or update + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public void putRoleAsync(PutRoleRequest request, RequestOptions options, ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::putRole, options, + PutRoleResponse::fromXContent, listener, emptySet()); + } + + /** + * Create or update a role in the native roles store. + * See + * the docs for more. + * + * @param request the request containing the role to create or update + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response from the put role call + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public PutRoleResponse getRoles(final PutRoleRequest request, final RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::putRole, options, + PutRoleResponse::fromXContent, emptySet()); + } + /** * Asynchronously delete a role mapping. * See diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java new file mode 100644 index 0000000000000..d76d60e4db0f4 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.security; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.Objects; + +import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; + +/** + * Response when adding a role to the native roles store. Returns a + * single boolean field for whether the role was created or updated. + */ +public final class PutRoleResponse { + + private final boolean created; + + public PutRoleResponse(boolean created) { + this.created = created; + } + + public boolean isCreated() { + return created; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PutRoleResponse that = (PutRoleResponse) o; + return created == that.created; + } + + @Override + public int hashCode() { + return Objects.hash(created); + } + + private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("put_role_response", + true, args -> new PutRoleResponse((boolean) args[0])); + + static { + PARSER.declareBoolean(constructorArg(), new ParseField("created")); + } + + public static PutRoleResponse fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } +} From 9707795455cb2c406d62500309f388e8a27efc57 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Sun, 2 Dec 2018 13:38:07 +0200 Subject: [PATCH 06/21] Transient metadata --- .../org/elasticsearch/client/security/PutRoleRequest.java | 1 + .../elasticsearch/client/security/user/privileges/Role.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java index 7a5b20690bb93..dc56ccdd6e5aa 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java @@ -79,6 +79,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field(Role.GLOBAL.getPreferredName(), role.getGlobalApplicationPrivileges()); builder.field(Role.INDICES.getPreferredName(), role.getIndicesPrivileges()); builder.field(Role.METADATA.getPreferredName(), role.getMetadata()); + builder.field(Role.TRANSIENT_METADATA.getPreferredName(), role.getTransientMetadata()); builder.field(Role.RUN_AS.getPreferredName(), role.getRunAsPrivilege()); return builder.endObject(); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 8aeb742427961..6d78e0012e143 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -145,6 +145,10 @@ public Map getMetadata() { return metadata; } + public Map getTransientMetadata() { + return transientMetadata; + } + @Override public boolean equals(Object o) { if (this == o) return true; From d087f9874a5ed1c248a8a4c28fbe32bdabd5c756 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Sun, 2 Dec 2018 14:46:16 +0200 Subject: [PATCH 07/21] SecurityDocumentationIT --- .../elasticsearch/client/SecurityClient.java | 2 +- .../client/security/PutRoleResponse.java | 16 ++++- .../SecurityDocumentationIT.java | 69 ++++++++++++++++--- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java index 07e0992a37994..b6c54853c2f04 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java @@ -493,7 +493,7 @@ public void putRoleAsync(PutRoleRequest request, RequestOptions options, ActionL * @return the response from the put role call * @throws IOException in case there is a problem sending the request or parsing back the response */ - public PutRoleResponse getRoles(final PutRoleRequest request, final RequestOptions options) throws IOException { + public PutRoleResponse putRole(final PutRoleRequest request, final RequestOptions options) throws IOException { return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::putRole, options, PutRoleResponse::fromXContent, emptySet()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java index d76d60e4db0f4..b42782b7d9430 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleResponse.java @@ -22,15 +22,18 @@ import org.elasticsearch.common.ParseField; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentParser.Token; import java.io.IOException; import java.util.Objects; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; +import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureFieldName; /** * Response when adding a role to the native roles store. Returns a - * single boolean field for whether the role was created or updated. + * single boolean field for whether the role was created (true) or updated (false). */ public final class PutRoleResponse { @@ -65,6 +68,15 @@ public int hashCode() { } public static PutRoleResponse fromXContent(XContentParser parser) throws IOException { - return PARSER.parse(parser, null); + if (parser.currentToken() == null) { + parser.nextToken(); + } + // parse extraneous wrapper + ensureExpectedToken(Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation); + ensureFieldName(parser, parser.nextToken(), "role"); + parser.nextToken(); + final PutRoleResponse roleResponse = PARSER.parse(parser, null); + ensureExpectedToken(Token.END_OBJECT, parser.nextToken(), parser::getTokenLocation); + return roleResponse; } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 79258b314510c..6fa3169af9484 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -64,6 +64,8 @@ import org.elasticsearch.client.security.InvalidateTokenResponse; import org.elasticsearch.client.security.PutRoleMappingRequest; import org.elasticsearch.client.security.PutRoleMappingResponse; +import org.elasticsearch.client.security.PutRoleRequest; +import org.elasticsearch.client.security.PutRoleResponse; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; import org.elasticsearch.client.security.RefreshPolicy; @@ -1023,18 +1025,63 @@ public void onFailure(Exception e) { } } - // TODO: move all calls to high-level REST client once APIs for adding new role exist - private void addRole(String roleName) throws IOException { - Request addRoleRequest = new Request(HttpPost.METHOD_NAME, "/_xpack/security/role/" + roleName); - try (XContentBuilder builder = jsonBuilder()) { - builder.startObject(); - { - builder.array("cluster", "all"); - } - builder.endObject(); - addRoleRequest.setEntity(new NStringEntity(Strings.toString(builder), ContentType.APPLICATION_JSON)); + public void testPutRole() throws Exception { + RestHighLevelClient client = highLevelClient(); + + { + // tag::put-role-execute + final Role role = Role.builder() + .name("testPutRole") + .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .build(); + final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.NONE); + final PutRoleResponse response = client.security().putRole(request, RequestOptions.DEFAULT); + // end::put-role-execute + // tag::put-role-response + boolean isCreated = response.isCreated(); // <1> + // end::put-role-response + assertTrue(isCreated); + } + + { + final Role role = Role.builder() + .name("testPutRole") + .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .build(); + final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.NONE); + // tag::put-role-execute-listener + ActionListener listener = new ActionListener() { + @Override + public void onResponse(PutRoleResponse response) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + // end::put-role-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::put-role-execute-async + client.security().putRoleAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::put-role-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); } - client().performRequest(addRoleRequest); + } + + private void addRole(String roleName) throws IOException { + final Role role = Role.builder() + .name(roleName) + .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .build(); + final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.IMMEDIATE); + highLevelClient().security().putRole(request, RequestOptions.DEFAULT); } public void testCreateToken() throws Exception { From fcbaad34e438090eb8a7da5c0384019d592cbb8d Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Sun, 2 Dec 2018 23:38:18 +0200 Subject: [PATCH 08/21] IndicesPrivilegesTests --- .../user/privileges/IndicesPrivileges.java | 8 +-- .../client/security/PutRoleRequestTests.java | 27 +++++++++ .../ApplicationResourcePrivilegesTests.java | 10 +++- .../privileges/GlobalPrivilegesTests.java | 30 +++++++--- .../privileges/IndicesPrivilegesTests.java | 58 +++++++++++++++++++ 5 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java index 393b8613f25e7..4282d8219d9d7 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java @@ -58,7 +58,7 @@ public final class IndicesPrivileges implements ToXContentObject { @SuppressWarnings("unchecked") static final ConstructingObjectParser PARSER = - new ConstructingObjectParser<>("indices_privileges", false, constructorObjects -> { + new ConstructingObjectParser<>("indices_privileges", true, constructorObjects -> { int i = 0; final Collection indices = (Collection) constructorObjects[i++]; final Collection privileges = (Collection) constructorObjects[i++]; @@ -73,7 +73,7 @@ public final class IndicesPrivileges implements ToXContentObject { static { @SuppressWarnings("unchecked") final ConstructingObjectParser, Collection>, Void> fls_parser = - new ConstructingObjectParser<>( "field_level_parser", false, constructorObjects -> { + new ConstructingObjectParser<>( "field_level_parser", true, constructorObjects -> { int i = 0; final Collection grantFields = (Collection) constructorObjects[i++]; final Collection exceptFields = (Collection) constructorObjects[i]; @@ -217,12 +217,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.startObject(); builder.field(NAMES.getPreferredName(), indices); builder.field(PRIVILEGES.getPreferredName(), privileges); - if (isUsingFieldLevelSecurity()) { + if (grantedFields != null || deniedFields != null) { builder.startObject(FIELD_PERMISSIONS.getPreferredName()); if (grantedFields != null) { builder.field(GRANT_FIELDS.getPreferredName(), grantedFields); } - if (hasDeniedFields()) { + if (deniedFields != null) { builder.field(EXCEPT_FIELDS.getPreferredName(), deniedFields); } builder.endObject(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java new file mode 100644 index 0000000000000..e988f460528a8 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.security; + +import org.elasticsearch.test.ESTestCase; + +public class PutRoleRequestTests extends ESTestCase { + + +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/ApplicationResourcePrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/ApplicationResourcePrivilegesTests.java index 9575363a40963..29845441a2c05 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/ApplicationResourcePrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/ApplicationResourcePrivilegesTests.java @@ -31,13 +31,17 @@ public class ApplicationResourcePrivilegesTests extends AbstractXContentTestCase { - @Override - protected ApplicationResourcePrivileges createTestInstance() { - return new ApplicationResourcePrivileges(randomAlphaOfLengthBetween(1, 8), + public static ApplicationResourcePrivileges createNewRandom(String name) { + return new ApplicationResourcePrivileges(name, Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8))), Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8)))); } + @Override + protected ApplicationResourcePrivileges createTestInstance() { + return createNewRandom(randomAlphaOfLengthBetween(1, 8)); + } + @Override protected ApplicationResourcePrivileges doParseInstance(XContentParser parser) throws IOException { return ApplicationResourcePrivileges.fromXContent(parser); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java index a9d2702970962..ea1eef3eede6a 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java @@ -36,6 +36,28 @@ public class GlobalPrivilegesTests extends AbstractXContentTestCase privilege = new HashMap<>(); + for (int i = 0; i < randomIntBetween(1, 4); i++) { + if (randomBoolean()) { + privilege.put(randomAlphaOfLength(2) + idCounter++, randomAlphaOfLengthBetween(0, 4)); + } else { + privilege.put(randomAlphaOfLength(2) + idCounter++, Arrays.asList(generateRandomStringArray(4, 4, false))); + } + } + return new GlobalOperationPrivilege(category, randomAlphaOfLength(2) + idCounter++, privilege); + } + + private static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { + return createNewRandom("application"); + } + + public static ApplicationResourcePrivileges createNewRandom() { + return new ApplicationResourcePrivileges(randomAlphaOfLengthBetween(1, 8), + Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8))), + Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8)))); + } + @Override protected GlobalPrivileges createTestInstance() { final List privilegeList = Arrays @@ -85,14 +107,6 @@ public void testSameScopeGlobalOperationPrivilege() { assertThat(e.getMessage(), is("Different privileges for the same category and operation are not permitted")); } - private static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { - final Map privilege = new HashMap<>(); - for (int i = 0; i < randomIntBetween(1, 4); i++) { - privilege.put(randomAlphaOfLength(2) + idCounter++, randomAlphaOfLengthBetween(1, 4)); - } - return new GlobalOperationPrivilege("application", randomAlphaOfLength(2) + idCounter++, privilege); - } - public void testEqualsHashCode() { final List privilegeList = Arrays .asList(randomArray(1, 4, size -> new GlobalOperationPrivilege[size], () -> buildRandomGlobalScopedPrivilege())); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java new file mode 100644 index 0000000000000..ea5ded73bb08b --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java @@ -0,0 +1,58 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.client.security.user.privileges; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.AbstractXContentTestCase; + +import java.io.IOException; + +public class IndicesPrivilegesTests extends AbstractXContentTestCase { + + public static IndicesPrivileges createNewRandom(String query) { + final IndicesPrivileges.Builder indicesPrivilegesBuilder = IndicesPrivileges.builder() + .indices(generateRandomStringArray(4, 4, false, false)) + .privileges(randomSubsetOf(randomIntBetween(1, 4), Role.IndexPrivilegeName.ARRAY)) + .query(query); + if (randomBoolean()) { + indicesPrivilegesBuilder.grantedFields(generateRandomStringArray(4, 4, true)); + } + if (randomBoolean()) { + indicesPrivilegesBuilder.deniedFields(generateRandomStringArray(4, 4, true)); + } + return indicesPrivilegesBuilder.build(); + } + + @Override + protected IndicesPrivileges createTestInstance() { + return createNewRandom( + randomBoolean() ? null : "{ " + randomAlphaOfLengthBetween(1, 4) + " : " + randomAlphaOfLengthBetween(1, 4) + " }"); + } + + @Override + protected IndicesPrivileges doParseInstance(XContentParser parser) throws IOException { + return IndicesPrivileges.fromXContent(parser); + } + + @Override + protected boolean supportsUnknownFields() { + return true; + } +} From e09be4795245929e79a60f99a318a4f05e83fe9e Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Mon, 3 Dec 2018 14:10:58 +0200 Subject: [PATCH 09/21] PutRoleRequestTests --- .../client/security/PutRoleRequest.java | 28 ++++++--- .../client/security/user/privileges/Role.java | 5 +- .../client/security/PutRoleRequestTests.java | 59 ++++++++++++++++++- .../privileges/GlobalPrivilegesTests.java | 13 +--- 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java index dc56ccdd6e5aa..b6a4e4a633ac1 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java @@ -74,13 +74,27 @@ public boolean equals(Object obj) { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Role.APPLICATIONS.getPreferredName(), role.getApplicationResourcePrivileges()); - builder.field(Role.CLUSTER.getPreferredName(), role.getClusterPrivileges()); - builder.field(Role.GLOBAL.getPreferredName(), role.getGlobalApplicationPrivileges()); - builder.field(Role.INDICES.getPreferredName(), role.getIndicesPrivileges()); - builder.field(Role.METADATA.getPreferredName(), role.getMetadata()); - builder.field(Role.TRANSIENT_METADATA.getPreferredName(), role.getTransientMetadata()); - builder.field(Role.RUN_AS.getPreferredName(), role.getRunAsPrivilege()); + if (role.getApplicationResourcePrivileges() != null) { + builder.field(Role.APPLICATIONS.getPreferredName(), role.getApplicationResourcePrivileges()); + } + if (role.getClusterPrivileges() != null) { + builder.field(Role.CLUSTER.getPreferredName(), role.getClusterPrivileges()); + } + if (role.getGlobalApplicationPrivileges() != null) { + builder.field(Role.GLOBAL.getPreferredName(), role.getGlobalApplicationPrivileges()); + } + if (role.getIndicesPrivileges() != null) { + builder.field(Role.INDICES.getPreferredName(), role.getIndicesPrivileges()); + } + if (role.getMetadata() != null) { + builder.field(Role.METADATA.getPreferredName(), role.getMetadata()); + } + if (role.getTransientMetadata() != null) { + builder.field(Role.TRANSIENT_METADATA.getPreferredName(), role.getTransientMetadata()); + } + if (role.getRunAsPrivilege() != null) { + builder.field(Role.RUN_AS.getPreferredName(), role.getRunAsPrivilege()); + } return builder.endObject(); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 6d78e0012e143..bed1f922e06c9 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -34,7 +34,6 @@ import java.util.Objects; import java.util.Set; -import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg; import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg; /** @@ -77,8 +76,8 @@ public final class Role { PARSER.declareFieldArray(optionalConstructorArg(), (parser,c)->ApplicationResourcePrivileges.PARSER.parse(parser,null), APPLICATIONS, ValueType.OBJECT_ARRAY); PARSER.declareStringArray(optionalConstructorArg(), RUN_AS); - PARSER.declareObject(constructorArg(), (parser, c) -> parser.map(), METADATA); - PARSER.declareObject(constructorArg(), (parser, c) -> parser.map(), TRANSIENT_METADATA); + PARSER.declareObject(optionalConstructorArg(), (parser, c) -> parser.map(), METADATA); + PARSER.declareObject(optionalConstructorArg(), (parser, c) -> parser.map(), TRANSIENT_METADATA); } private final String name; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java index e988f460528a8..349b79423071d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java @@ -19,9 +19,64 @@ package org.elasticsearch.client.security; -import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; +import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivilegesTests; +import org.elasticsearch.client.security.user.privileges.GlobalOperationPrivilege; +import org.elasticsearch.client.security.user.privileges.GlobalPrivileges; +import org.elasticsearch.client.security.user.privileges.GlobalPrivilegesTests; +import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; +import org.elasticsearch.client.security.user.privileges.IndicesPrivilegesTests; +import org.elasticsearch.client.security.user.privileges.Role; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.AbstractXContentTestCase; -public class PutRoleRequestTests extends ESTestCase { +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +public class PutRoleRequestTests extends AbstractXContentTestCase { + private static final String roleName = "testRoleName"; + + @Override + protected PutRoleRequest createTestInstance() { + final Role.Builder roleBuilder = Role.builder() + .name(roleName) + .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) + .indicesPrivileges( + randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) + .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, + () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) + .runAsPrivilege(randomArray(3, String[]::new, () -> randomAlphaOfLength(3))); + if (randomBoolean()) { + roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays.asList(randomArray(1, 3, GlobalOperationPrivilege[]::new, + () -> GlobalPrivilegesTests.buildRandomGlobalScopedPrivilege())))); + } + if (randomBoolean()) { + final Map metadata = new HashMap<>(); + for (int i = 0; i < randomInt(3); i++) { + metadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); + } + roleBuilder.metadata(metadata); + } + if (randomBoolean()) { + final Map transientMetadata = new HashMap<>(); + for (int i = 0; i < randomInt(3); i++) { + transientMetadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); + } + roleBuilder.metadata(transientMetadata); + } + return new PutRoleRequest(roleBuilder.build(), null); + } + + @Override + protected PutRoleRequest doParseInstance(XContentParser parser) throws IOException { + return new PutRoleRequest(Role.fromXContent(parser, roleName), null); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java index ea1eef3eede6a..0fd7289aa634d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java @@ -36,7 +36,8 @@ public class GlobalPrivilegesTests extends AbstractXContentTestCase privilege = new HashMap<>(); for (int i = 0; i < randomIntBetween(1, 4); i++) { if (randomBoolean()) { @@ -48,16 +49,6 @@ public static GlobalOperationPrivilege createNewRandom(String category) { return new GlobalOperationPrivilege(category, randomAlphaOfLength(2) + idCounter++, privilege); } - private static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { - return createNewRandom("application"); - } - - public static ApplicationResourcePrivileges createNewRandom() { - return new ApplicationResourcePrivileges(randomAlphaOfLengthBetween(1, 8), - Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8))), - Arrays.asList(randomArray(1, 8, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 8)))); - } - @Override protected GlobalPrivileges createTestInstance() { final List privilegeList = Arrays From 8c8cf33f4926e3171104dd4492cb6d5237ea0d3a Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Mon, 3 Dec 2018 16:57:54 +0200 Subject: [PATCH 10/21] SecurityIT in progress --- .../user/privileges/GlobalPrivileges.java | 2 +- .../org/elasticsearch/client/SecurityIT.java | 70 +++++++++++++++++++ .../SecurityRequestConvertersTests.java | 1 - .../SecurityDocumentationIT.java | 6 -- .../client/security/PutRoleRequestTests.java | 38 +++++----- .../privileges/GlobalPrivilegesTests.java | 11 ++- 6 files changed, 101 insertions(+), 27 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java index 891980765427e..464933542cb7d 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java @@ -49,7 +49,7 @@ public final class GlobalPrivileges implements ToXContentObject { // When categories change, adapting this field should suffice. Categories are NOT // opaque "named_objects", we wish to maintain control over these namespaces - static final List CATEGORIES = Collections.unmodifiableList(Arrays.asList("application")); + public static final List CATEGORIES = Collections.unmodifiableList(Arrays.asList("application")); @SuppressWarnings("unchecked") static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("global_category_privileges", diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java index 27b1d31e6d7d5..ae1cc92c6e0f4 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java @@ -22,12 +22,26 @@ import org.apache.http.client.methods.HttpDelete; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.client.security.AuthenticateResponse; +import org.elasticsearch.client.security.DeleteRoleRequest; +import org.elasticsearch.client.security.DeleteRoleResponse; import org.elasticsearch.client.security.DeleteUserRequest; import org.elasticsearch.client.security.DeleteUserResponse; +import org.elasticsearch.client.security.GetRolesRequest; +import org.elasticsearch.client.security.GetRolesResponse; +import org.elasticsearch.client.security.PutRoleRequest; +import org.elasticsearch.client.security.PutRoleResponse; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.client.security.user.User; +import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; +import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivilegesTests; +import org.elasticsearch.client.security.user.privileges.GlobalOperationPrivilege; +import org.elasticsearch.client.security.user.privileges.GlobalPrivileges; +import org.elasticsearch.client.security.user.privileges.GlobalPrivilegesTests; +import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; +import org.elasticsearch.client.security.user.privileges.IndicesPrivilegesTests; +import org.elasticsearch.client.security.user.privileges.Role; import org.elasticsearch.common.CharArrays; import java.util.Arrays; @@ -38,6 +52,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.contains; public class SecurityIT extends ESRestHighLevelClientTestCase { @@ -93,6 +108,31 @@ public void testAuthenticate() throws Exception { execute(deleteUserRequest, securityClient::deleteUser, securityClient::deleteUserAsync); assertThat(deleteUserResponse2.isAcknowledged(), is(false)); } + + public void testPutRole() throws Exception { + final SecurityClient securityClient = highLevelClient().security(); + // create random role + final Role role = randomRole(randomAlphaOfLength(4)); + final PutRoleRequest putRoleRequest = new PutRoleRequest(role, RefreshPolicy.IMMEDIATE); + + final PutRoleResponse createRoleResponse = execute(putRoleRequest, securityClient::putRole, securityClient::putRoleAsync); + // assert role created + assertThat(createRoleResponse.isCreated(), is(true)); + + final GetRolesRequest getRoleRequest = new GetRolesRequest(role.getName()); + final GetRolesResponse getRoleResponse = securityClient.getRoles(getRoleRequest, RequestOptions.DEFAULT); + // assert role is equal + assertThat(getRoleResponse.getRoles(), contains(role)); + + final PutRoleResponse updateRoleResponse = execute(putRoleRequest, securityClient::putRole, securityClient::putRoleAsync); + // assert role updated + assertThat(updateRoleResponse.isCreated(), is(false)); + + final DeleteRoleRequest deleteRoleRequest = new DeleteRoleRequest(role.getName()); + final DeleteRoleResponse deleteRoleResponse = securityClient.deleteRole(deleteRoleRequest, RequestOptions.DEFAULT); + // assert role deleted + assertThat(deleteRoleResponse.isFound(), is(true)); + } private static User randomUser() { final String username = randomAlphaOfLengthBetween(1, 4); @@ -118,6 +158,36 @@ private static User randomUser(String username) { return new User(username, roles, metadata, fullName, email); } + public static Role randomRole(String roleName) { + final Role.Builder roleBuilder = Role.builder() + .name(roleName) + .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) + .indicesPrivileges( + randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) + .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, + () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase()))) + .runAsPrivilege(randomArray(3, String[]::new, () -> randomAlphaOfLength(3))); + if (randomBoolean()) { + roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays + .asList(GlobalPrivilegesTests.buildRandomGlobalScopedPrivilege(randomFrom(GlobalPrivileges.CATEGORIES), "manage")))); + } + if (randomBoolean()) { + final Map metadata = new HashMap<>(); + for (int i = 0; i < randomInt(3); i++) { + metadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); + } + roleBuilder.metadata(metadata); + } + if (randomBoolean()) { + final Map transientMetadata = new HashMap<>(); + for (int i = 0; i < randomInt(3); i++) { + transientMetadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); + } + roleBuilder.metadata(transientMetadata); + } + return roleBuilder.build(); + } + private static PutUserRequest randomPutUserRequest(boolean enabled) { final User user = randomUser(); return randomPutUserRequest(user, enabled); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java index 3cdb991beb7d2..f41eb578792fd 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java @@ -54,7 +54,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import static org.elasticsearch.client.RequestConvertersTests.assertToXContentBody; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 6fa3169af9484..f11784461acf1 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -19,9 +19,6 @@ package org.elasticsearch.client.documentation; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.nio.entity.NStringEntity; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.LatchedActionListener; @@ -77,9 +74,7 @@ import org.elasticsearch.client.security.user.privileges.Role; import org.elasticsearch.client.security.user.privileges.ApplicationPrivilege; import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; -import org.elasticsearch.common.Strings; import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.rest.RestStatus; import org.hamcrest.Matchers; @@ -98,7 +93,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsInAnyOrder; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java index 349b79423071d..a95c06efe9acd 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.client.security; +import org.elasticsearch.client.SecurityIT; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivilegesTests; import org.elasticsearch.client.security.user.privileges.GlobalOperationPrivilege; @@ -36,22 +37,36 @@ import java.util.Map; public class PutRoleRequestTests extends AbstractXContentTestCase { - + private static final String roleName = "testRoleName"; @Override protected PutRoleRequest createTestInstance() { - final Role.Builder roleBuilder = Role.builder() - .name(roleName) + final Role role = randomRole(roleName); + return new PutRoleRequest(role, null); + } + + @Override + protected PutRoleRequest doParseInstance(XContentParser parser) throws IOException { + return new PutRoleRequest(Role.fromXContent(parser, roleName), null); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } + + private static final Role randomRole(String roleName) { + final Role.Builder roleBuilder = Role.builder().name(roleName) .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) .indicesPrivileges( randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, - () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) + () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase()))) .runAsPrivilege(randomArray(3, String[]::new, () -> randomAlphaOfLength(3))); if (randomBoolean()) { - roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays.asList(randomArray(1, 3, GlobalOperationPrivilege[]::new, - () -> GlobalPrivilegesTests.buildRandomGlobalScopedPrivilege())))); + roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays.asList( + randomArray(1, 3, GlobalOperationPrivilege[]::new, () -> GlobalPrivilegesTests.buildRandomGlobalScopedPrivilege())))); } if (randomBoolean()) { final Map metadata = new HashMap<>(); @@ -67,16 +82,7 @@ protected PutRoleRequest createTestInstance() { } roleBuilder.metadata(transientMetadata); } - return new PutRoleRequest(roleBuilder.build(), null); + return roleBuilder.build(); } - @Override - protected PutRoleRequest doParseInstance(XContentParser parser) throws IOException { - return new PutRoleRequest(Role.fromXContent(parser, roleName), null); - } - - @Override - protected boolean supportsUnknownFields() { - return false; - } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java index 0fd7289aa634d..d7797508b8683 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java @@ -36,8 +36,7 @@ public class GlobalPrivilegesTests extends AbstractXContentTestCase privilege = new HashMap<>(); for (int i = 0; i < randomIntBetween(1, 4); i++) { if (randomBoolean()) { @@ -46,7 +45,13 @@ public static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { privilege.put(randomAlphaOfLength(2) + idCounter++, Arrays.asList(generateRandomStringArray(4, 4, false))); } } - return new GlobalOperationPrivilege(category, randomAlphaOfLength(2) + idCounter++, privilege); + return new GlobalOperationPrivilege(category, operation, privilege); + } + + public static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { + final String categoryParam = randomAlphaOfLength(4); + final String operationParam = randomAlphaOfLength(2) + idCounter++; + return buildRandomGlobalScopedPrivilege(categoryParam, operationParam); } @Override From ff5d788a757af50ff4c27b1da834b57cd0421d62 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Mon, 3 Dec 2018 18:46:42 +0200 Subject: [PATCH 11/21] transient metadata no longer public --- .../client/security/user/privileges/Role.java | 12 +++--------- .../java/org/elasticsearch/client/SecurityIT.java | 2 +- .../client/security/GetRolesResponseTests.java | 14 +------------- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index bed1f922e06c9..4f0311c831064 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -87,6 +87,7 @@ public final class Role { private final Set applicationResourcePrivileges; private final Set runAsPrivilege; private final Map metadata; + // this read only (user face) private final Map transientMetadata; private Role(String name, @Nullable Collection clusterPrivileges, @@ -159,14 +160,13 @@ public boolean equals(Object o) { && indicesPrivileges.equals(that.indicesPrivileges) && applicationResourcePrivileges.equals(that.applicationResourcePrivileges) && runAsPrivilege.equals(that.runAsPrivilege) - && metadata.equals(that.metadata) - && transientMetadata.equals(that.transientMetadata); + && metadata.equals(that.metadata); } @Override public int hashCode() { return Objects.hash(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, transientMetadata); + runAsPrivilege, metadata, null); } @Override @@ -297,12 +297,6 @@ public Builder metadata(Map metadata) { return this; } - public Builder transientMetadata(Map transientMetadata) { - this.transientMetadata = - Objects.requireNonNull(transientMetadata, "Transient metadata cannot be null. Pass an empty map instead."); - return this; - } - public Role build() { return new Role(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, runAsPrivilege, metadata, transientMetadata); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java index ae1cc92c6e0f4..3920bdcd5687e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java @@ -158,7 +158,7 @@ private static User randomUser(String username) { return new User(username, roles, metadata, fullName, email); } - public static Role randomRole(String roleName) { + private static Role randomRole(String roleName) { final Role.Builder roleBuilder = Role.builder() .name(roleName) .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java index 41de52a8cef75..6164dae52db99 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java @@ -92,9 +92,9 @@ public void usedDeprecatedField(String usedName, String replacedWith) { .indicesPrivileges(expectedIndicesPrivileges) .runAsPrivilege("other_user") .metadata(expectedMetadata) - .transientMetadata(expectedTransientMetadata) .build(); assertThat(role, equalTo(expectedRole)); + assertThat(role.getTransientMetadata(), equalTo(expectedTransientMetadata)); } public void testEqualsHashCode() { @@ -107,15 +107,12 @@ public void testEqualsHashCode() { .build(); Map metadata = new HashMap<>(); metadata.put("key", "value"); - Map transientMetadata = new HashMap<>(); - transientMetadata.put("transient_key", "transient_value"); final Role role = Role.builder() .name("role_name") .clusterPrivileges("monitor", "manage", "manage_saml") .indicesPrivileges(indicesPrivileges) .runAsPrivilege("run_as_user") .metadata(metadata) - .transientMetadata(transientMetadata) .build(); roles.add(role); IndicesPrivileges indicesPrivileges2 = new IndicesPrivileges.Builder() @@ -126,15 +123,12 @@ public void testEqualsHashCode() { .build(); Map metadata2 = new HashMap<>(); metadata.put("other_key", "other_value"); - Map transientMetadata2 = new HashMap<>(); - transientMetadata2.put("other_transient_key", "other_transient_value"); final Role role2 = Role.builder() .name("role2_name") .clusterPrivileges("monitor", "manage", "manage_saml") .indicesPrivileges(indicesPrivileges2) .runAsPrivilege("other_run_as_user") .metadata(metadata2) - .transientMetadata(transientMetadata2) .build(); roles.add(role2); final GetRolesResponse getRolesResponse = new GetRolesResponse(roles); @@ -159,15 +153,12 @@ private static GetRolesResponse mutateTestItem(GetRolesResponse original) { .build(); Map metadata = new HashMap(); metadata.put("key", "value"); - Map transientMetadata = new HashMap<>(); - transientMetadata.put("transient_key", "transient_value"); final Role role = Role.builder() .name("role_name") .clusterPrivileges("monitor", "manage", "manage_saml") .indicesPrivileges(indicesPrivileges) .runAsPrivilege("run_as_user") .metadata(metadata) - .transientMetadata(transientMetadata) .build(); roles.add(role); return new GetRolesResponse(roles); @@ -180,15 +171,12 @@ private static GetRolesResponse mutateTestItem(GetRolesResponse original) { .build(); Map metadata = new HashMap(); metadata.put("key", "value"); - Map transientMetadata = new HashMap<>(); - transientMetadata.put("transient_key", "transient_value"); final Role role = Role.builder() .name("role_name") .clusterPrivileges("monitor", "manage", "manage_saml") .indicesPrivileges(indicesPrivileges) .runAsPrivilege("run_as_user") .metadata(metadata) - .transientMetadata(transientMetadata) .build(); List newRoles = original.getRoles().stream().collect(Collectors.toList()); newRoles.remove(0); From e2739307d9028292f61f7b4bead65b3c316f207c Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Tue, 4 Dec 2018 11:48:12 +0200 Subject: [PATCH 12/21] Almost there! --- .../org/elasticsearch/client/SecurityIT.java | 8 +++----- .../client/security/PutRoleRequestTests.java | 6 +++--- .../user/privileges/GlobalPrivilegesTests.java | 17 +++++++++-------- .../user/privileges/IndicesPrivilegesTests.java | 11 +++++++---- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java index 3920bdcd5687e..8b40c80735814 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java @@ -36,8 +36,6 @@ import org.elasticsearch.client.security.user.User; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivilegesTests; -import org.elasticsearch.client.security.user.privileges.GlobalOperationPrivilege; -import org.elasticsearch.client.security.user.privileges.GlobalPrivileges; import org.elasticsearch.client.security.user.privileges.GlobalPrivilegesTests; import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; import org.elasticsearch.client.security.user.privileges.IndicesPrivilegesTests; @@ -48,6 +46,7 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import static org.hamcrest.Matchers.is; @@ -165,11 +164,10 @@ private static Role randomRole(String roleName) { .indicesPrivileges( randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, - () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase()))) + () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase(Locale.ROOT)))) .runAsPrivilege(randomArray(3, String[]::new, () -> randomAlphaOfLength(3))); if (randomBoolean()) { - roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays - .asList(GlobalPrivilegesTests.buildRandomGlobalScopedPrivilege(randomFrom(GlobalPrivileges.CATEGORIES), "manage")))); + roleBuilder.globalApplicationPrivileges(GlobalPrivilegesTests.buildRandomManageApplicationPrivilege()); } if (randomBoolean()) { final Map metadata = new HashMap<>(); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java index a95c06efe9acd..9f34bd550c3d2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java @@ -19,7 +19,6 @@ package org.elasticsearch.client.security; -import org.elasticsearch.client.SecurityIT; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivileges; import org.elasticsearch.client.security.user.privileges.ApplicationResourcePrivilegesTests; import org.elasticsearch.client.security.user.privileges.GlobalOperationPrivilege; @@ -34,6 +33,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.Locale; import java.util.Map; public class PutRoleRequestTests extends AbstractXContentTestCase { @@ -56,13 +56,13 @@ protected boolean supportsUnknownFields() { return false; } - private static final Role randomRole(String roleName) { + private static Role randomRole(String roleName) { final Role.Builder roleBuilder = Role.builder().name(roleName) .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) .indicesPrivileges( randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, - () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase()))) + () -> ApplicationResourcePrivilegesTests.createNewRandom(randomAlphaOfLength(3).toLowerCase(Locale.ROOT)))) .runAsPrivilege(randomArray(3, String[]::new, () -> randomAlphaOfLength(3))); if (randomBoolean()) { roleBuilder.globalApplicationPrivileges(new GlobalPrivileges(Arrays.asList( diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java index d7797508b8683..927372c839e7c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/GlobalPrivilegesTests.java @@ -36,7 +36,14 @@ public class GlobalPrivilegesTests extends AbstractXContentTestCase privilege = new HashMap<>(); + privilege.put("applications", Arrays.asList(generateRandomStringArray(4, 4, false))); + final GlobalOperationPrivilege priv = new GlobalOperationPrivilege("application", "manage", privilege); + return new GlobalPrivileges(Arrays.asList(priv)); + } + + public static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { final Map privilege = new HashMap<>(); for (int i = 0; i < randomIntBetween(1, 4); i++) { if (randomBoolean()) { @@ -45,13 +52,7 @@ public static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege(String c privilege.put(randomAlphaOfLength(2) + idCounter++, Arrays.asList(generateRandomStringArray(4, 4, false))); } } - return new GlobalOperationPrivilege(category, operation, privilege); - } - - public static GlobalOperationPrivilege buildRandomGlobalScopedPrivilege() { - final String categoryParam = randomAlphaOfLength(4); - final String operationParam = randomAlphaOfLength(2) + idCounter++; - return buildRandomGlobalScopedPrivilege(categoryParam, operationParam); + return new GlobalOperationPrivilege(randomFrom(GlobalPrivileges.CATEGORIES), randomAlphaOfLength(2) + idCounter++, privilege); } @Override diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java index ea5ded73bb08b..72c186f9bfb6b 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java @@ -23,6 +23,8 @@ import org.elasticsearch.test.AbstractXContentTestCase; import java.io.IOException; +import java.util.Arrays; +import java.util.List; public class IndicesPrivilegesTests extends AbstractXContentTestCase { @@ -32,10 +34,11 @@ public static IndicesPrivileges createNewRandom(String query) { .privileges(randomSubsetOf(randomIntBetween(1, 4), Role.IndexPrivilegeName.ARRAY)) .query(query); if (randomBoolean()) { - indicesPrivilegesBuilder.grantedFields(generateRandomStringArray(4, 4, true)); - } - if (randomBoolean()) { - indicesPrivilegesBuilder.deniedFields(generateRandomStringArray(4, 4, true)); + final List fields = Arrays.asList(generateRandomStringArray(4, 4, false)); + indicesPrivilegesBuilder.grantedFields(fields); + if (randomBoolean()) { + indicesPrivilegesBuilder.deniedFields(randomSubsetOf(fields)); + } } return indicesPrivilegesBuilder.build(); } From 86941b5e8f6bc7f4b7f10cccac3cc4f7cb9f0e2c Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Tue, 4 Dec 2018 12:34:51 +0200 Subject: [PATCH 13/21] And docs --- .../SecurityDocumentationIT.java | 2 +- .../high-level/security/put-role.asciidoc | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 docs/java-rest/high-level/security/put-role.asciidoc diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index f11784461acf1..628a179ad8aa4 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -1072,7 +1072,7 @@ public void onFailure(Exception e) { private void addRole(String roleName) throws IOException { final Role role = Role.builder() .name(roleName) - .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .clusterPrivileges("all") .build(); final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.IMMEDIATE); highLevelClient().security().putRole(request, RequestOptions.DEFAULT); diff --git a/docs/java-rest/high-level/security/put-role.asciidoc b/docs/java-rest/high-level/security/put-role.asciidoc new file mode 100644 index 0000000000000..436d2d31d3377 --- /dev/null +++ b/docs/java-rest/high-level/security/put-role.asciidoc @@ -0,0 +1,37 @@ + +-- +:api: put-role +:request: PutRoleRequest +:respnse: PutRoleResponse +-- + +[id="{upid}-{api}"] +=== Put Role API + +[id="{upid}-{api}-request"] +==== Put Role Request + +The +{request}+ class is used to create or update a role in the Native Roles +Store. The request contains a single role, which encapsulates privileges over +resources. These roles can be assigned to users using the +<<{upid}-put-role-mapping, Put Role Mapping API>>. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-request] +-------------------------------------------------- + +include::../execution.asciidoc[] + +[id="{upid}-{api}-response"] +==== Put Role Response + +The returned +{response}+ contains a single field, `created`. This field +serves as an indication if the role was created or if an existing entry was +updated. + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests-file}[{api}-response] +-------------------------------------------------- +<1> `created` is a boolean indicating whether the role was created or updated From fa48020f12d2330101ed115e6a250ff66260e2a7 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Tue, 4 Dec 2018 12:44:34 +0200 Subject: [PATCH 14/21] Trimming --- .../elasticsearch/client/security/user/privileges/Role.java | 6 +++--- .../src/test/java/org/elasticsearch/client/SecurityIT.java | 2 +- .../security/user/privileges/IndicesPrivilegesTests.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 4f0311c831064..2d11c454339f8 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -87,7 +87,7 @@ public final class Role { private final Set applicationResourcePrivileges; private final Set runAsPrivilege; private final Map metadata; - // this read only (user face) + // this read only from the client's perspective. The client cannot change this field of a role on the server. private final Map transientMetadata; private Role(String name, @Nullable Collection clusterPrivileges, @@ -166,7 +166,7 @@ public boolean equals(Object o) { @Override public int hashCode() { return Objects.hash(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, null); + runAsPrivilege, metadata); } @Override @@ -350,7 +350,7 @@ public static class IndexPrivilegeName { public static final String VIEW_INDEX_METADATA = "view_index_metadata"; public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index"; public static final String[] ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE, - DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX }; + DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX }; } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java index 8b40c80735814..0bbccd8fbfb7e 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java @@ -107,7 +107,7 @@ public void testAuthenticate() throws Exception { execute(deleteUserRequest, securityClient::deleteUser, securityClient::deleteUserAsync); assertThat(deleteUserResponse2.isAcknowledged(), is(false)); } - + public void testPutRole() throws Exception { final SecurityClient securityClient = highLevelClient().security(); // create random role diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java index 72c186f9bfb6b..7631a0dd3a7a7 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java @@ -56,6 +56,6 @@ protected IndicesPrivileges doParseInstance(XContentParser parser) throws IOExce @Override protected boolean supportsUnknownFields() { - return true; + return false; } } From 730f83537ddc405eca4e245f2c0f24677c612f8e Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Tue, 4 Dec 2018 12:59:25 +0200 Subject: [PATCH 15/21] Unsaved trimming --- .../client/security/user/privileges/IndicesPrivileges.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java index 4282d8219d9d7..188b8b4ea14dc 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/IndicesPrivileges.java @@ -58,7 +58,7 @@ public final class IndicesPrivileges implements ToXContentObject { @SuppressWarnings("unchecked") static final ConstructingObjectParser PARSER = - new ConstructingObjectParser<>("indices_privileges", true, constructorObjects -> { + new ConstructingObjectParser<>("indices_privileges", false, constructorObjects -> { int i = 0; final Collection indices = (Collection) constructorObjects[i++]; final Collection privileges = (Collection) constructorObjects[i++]; @@ -73,7 +73,7 @@ public final class IndicesPrivileges implements ToXContentObject { static { @SuppressWarnings("unchecked") final ConstructingObjectParser, Collection>, Void> fls_parser = - new ConstructingObjectParser<>( "field_level_parser", true, constructorObjects -> { + new ConstructingObjectParser<>( "field_level_parser", false, constructorObjects -> { int i = 0; final Collection grantFields = (Collection) constructorObjects[i++]; final Collection exceptFields = (Collection) constructorObjects[i]; From 302f62bcd06dd1c6e75965542953c0e1adacb8e9 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Wed, 5 Dec 2018 16:59:12 +0200 Subject: [PATCH 16/21] Review --- .../client/security/user/privileges/Role.java | 2 +- .../client/documentation/SecurityDocumentationIT.java | 10 +++++++--- docs/java-rest/high-level/security/put-role.asciidoc | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 2d11c454339f8..20be62b49826e 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -87,7 +87,7 @@ public final class Role { private final Set applicationResourcePrivileges; private final Set runAsPrivilege; private final Map metadata; - // this read only from the client's perspective. The client cannot change this field of a role on the server. + // this is read only from the client's perspective. The client cannot change this field of a role on the server. private final Map transientMetadata; private Role(String name, @Nullable Collection clusterPrivileges, diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 628a179ad8aa4..7d4ab475a22c2 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -1057,15 +1057,19 @@ public void onFailure(Exception e) { }; // end::put-role-execute-listener + // Avoid unused variable warning + assertNotNull(listener); + // Replace the empty listener by a blocking listener in test - final CountDownLatch latch = new CountDownLatch(1); - listener = new LatchedActionListener<>(listener, latch); + final PlainActionFuture future = new PlainActionFuture<>(); + listener = future; // tag::put-role-execute-async client.security().putRoleAsync(request, RequestOptions.DEFAULT, listener); // <1> // end::put-role-execute-async - assertTrue(latch.await(30L, TimeUnit.SECONDS)); + assertNotNull(future.get(30, TimeUnit.SECONDS)); + assertThat(future.get().isCreated(), is(false)); // false because it has already been created by the sync variant } } diff --git a/docs/java-rest/high-level/security/put-role.asciidoc b/docs/java-rest/high-level/security/put-role.asciidoc index 436d2d31d3377..68c1f5d69d470 100644 --- a/docs/java-rest/high-level/security/put-role.asciidoc +++ b/docs/java-rest/high-level/security/put-role.asciidoc @@ -2,7 +2,7 @@ -- :api: put-role :request: PutRoleRequest -:respnse: PutRoleResponse +:response: PutRoleResponse -- [id="{upid}-{api}"] @@ -13,7 +13,7 @@ The +{request}+ class is used to create or update a role in the Native Roles Store. The request contains a single role, which encapsulates privileges over -resources. These roles can be assigned to users using the +resources. A role can be assigned to an user using the <<{upid}-put-role-mapping, Put Role Mapping API>>. ["source","java",subs="attributes,callouts,macros"] From 0499df0acf51fe572de4c2622fb95f9c6b647e9b Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 6 Dec 2018 16:45:59 +0200 Subject: [PATCH 17/21] Pull transient metadata out of Role --- .../client/security/GetRolesResponse.java | 27 ++++++++++++--- .../client/security/PutRoleRequest.java | 3 -- .../user/privileges/GlobalPrivileges.java | 2 +- .../client/security/user/privileges/Role.java | 33 +++++++------------ .../org/elasticsearch/client/SecurityIT.java | 9 +---- .../SecurityRequestConvertersTests.java | 2 +- .../SecurityDocumentationIT.java | 4 +-- .../security/GetRolesResponseTests.java | 30 ++++++++++++----- .../client/security/PutRoleRequestTests.java | 19 +++++------ .../privileges/IndicesPrivilegesTests.java | 2 +- 10 files changed, 70 insertions(+), 61 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java index 91b7527c3235e..4aaf00229e6cf 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java @@ -20,13 +20,16 @@ package org.elasticsearch.client.security; import org.elasticsearch.client.security.user.privileges.Role; +import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParserUtils; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -36,24 +39,37 @@ public final class GetRolesResponse { private final List roles; + private final Map> transientMetadataMap; - public GetRolesResponse(List roles) { + GetRolesResponse(List roles, Map> transientMetadata) { this.roles = Collections.unmodifiableList(roles); + this.transientMetadataMap = Collections.unmodifiableMap(transientMetadata); } public List getRoles() { return roles; } + public Map> getTransientMetadataMap() { + return transientMetadataMap; + } + + public Map getTransientMetadata(String roleName) { + return transientMetadataMap.get(roleName); + } + public static GetRolesResponse fromXContent(XContentParser parser) throws IOException { XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation); final List roles = new ArrayList<>(); + final Map> transientMetadata = new HashMap<>(); XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { XContentParserUtils.ensureExpectedToken(XContentParser.Token.FIELD_NAME, token, parser::getTokenLocation); - roles.add(Role.PARSER.parse(parser, parser.currentName())); + final Tuple> roleAndTransientMetadata = Role.PARSER.parse(parser, parser.currentName()); + roles.add(roleAndTransientMetadata.v1()); + transientMetadata.put(roleAndTransientMetadata.v1().getName(), roleAndTransientMetadata.v2()); } - return new GetRolesResponse(roles); + return new GetRolesResponse(roles, transientMetadata); } @Override @@ -61,11 +77,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GetRolesResponse response = (GetRolesResponse) o; - return Objects.equals(roles, response.roles); + return Objects.equals(roles, response.roles) + && Objects.equals(transientMetadataMap, response.transientMetadataMap); } @Override public int hashCode() { - return Objects.hash(roles); + return Objects.hash(roles, transientMetadataMap); } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java index b6a4e4a633ac1..da9106744bac4 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutRoleRequest.java @@ -89,9 +89,6 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws if (role.getMetadata() != null) { builder.field(Role.METADATA.getPreferredName(), role.getMetadata()); } - if (role.getTransientMetadata() != null) { - builder.field(Role.TRANSIENT_METADATA.getPreferredName(), role.getTransientMetadata()); - } if (role.getRunAsPrivilege() != null) { builder.field(Role.RUN_AS.getPreferredName(), role.getRunAsPrivilege()); } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java index 464933542cb7d..f7f87a33a7fe4 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java @@ -49,7 +49,7 @@ public final class GlobalPrivileges implements ToXContentObject { // When categories change, adapting this field should suffice. Categories are NOT // opaque "named_objects", we wish to maintain control over these namespaces - public static final List CATEGORIES = Collections.unmodifiableList(Arrays.asList("application")); + public static final List CATEGORIES = Collections.singletonList("application"); @SuppressWarnings("unchecked") static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("global_category_privileges", diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index 20be62b49826e..cf417499b4081 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -22,6 +22,7 @@ import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.ObjectParser.ValueType; @@ -50,7 +51,7 @@ public final class Role { public static final ParseField TRANSIENT_METADATA = new ParseField("transient_metadata"); @SuppressWarnings("unchecked") - public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>("role_descriptor", false, + public static final ConstructingObjectParser>, String> PARSER = new ConstructingObjectParser<>("role_descriptor", false, (constructorObjects, roleName) -> { // Don't ignore unknown fields. It is dangerous if the object we parse is also // part of a request that we build later on, and the fields that we now ignore @@ -64,8 +65,10 @@ public final class Role { final Collection runAsPrivilege = (Collection) constructorObjects[i++]; final Map metadata = (Map) constructorObjects[i++]; final Map transientMetadata = (Map) constructorObjects[i]; - return new Role(roleName, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, transientMetadata); + return new Tuple<>( + new Role(roleName, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, + runAsPrivilege, metadata), + transientMetadata != null ? Collections.unmodifiableMap(transientMetadata) : Collections.emptyMap()); }); static { @@ -87,15 +90,12 @@ public final class Role { private final Set applicationResourcePrivileges; private final Set runAsPrivilege; private final Map metadata; - // this is read only from the client's perspective. The client cannot change this field of a role on the server. - private final Map transientMetadata; private Role(String name, @Nullable Collection clusterPrivileges, @Nullable GlobalPrivileges globalApplicationPrivileges, @Nullable Collection indicesPrivileges, @Nullable Collection applicationResourcePrivileges, - @Nullable Collection runAsPrivilege, @Nullable Map metadata, - @Nullable Map transientMetadata) { + @Nullable Collection runAsPrivilege, @Nullable Map metadata) { if (Strings.hasText(name) == false){ throw new IllegalArgumentException("role name must be provided"); } else { @@ -114,7 +114,6 @@ private Role(String name, @Nullable Collection clusterPrivileges, // no run as privileges are granted unless otherwise specified this.runAsPrivilege = Collections.unmodifiableSet(runAsPrivilege != null ? new HashSet<>(runAsPrivilege) : Collections.emptySet()); this.metadata = metadata != null ? Collections.unmodifiableMap(metadata) : Collections.emptyMap(); - this.transientMetadata = transientMetadata != null ? Collections.unmodifiableMap(transientMetadata) : Collections.emptyMap(); } public String getName() { @@ -145,10 +144,6 @@ public Map getMetadata() { return metadata; } - public Map getTransientMetadata() { - return transientMetadata; - } - @Override public boolean equals(Object o) { if (this == o) return true; @@ -203,16 +198,11 @@ public String toString() { sb.append(metadata.toString()); sb.append("], "); } - if (false == transientMetadata.isEmpty()) { - sb.append("TransientMetadata=["); - sb.append(transientMetadata.toString()); - sb.append("] "); - } sb.append("}"); return sb.toString(); } - public static Role fromXContent(XContentParser parser, String name) { + public static Tuple> fromXContent(XContentParser parser, String name) { return PARSER.apply(parser, name); } @@ -229,7 +219,6 @@ public static final class Builder { private @Nullable Collection applicationResourcePrivileges = null; private @Nullable Collection runAsPrivilege = null; private @Nullable Map metadata = null; - private @Nullable Map transientMetadata = null; private Builder() { } @@ -299,7 +288,7 @@ public Builder metadata(Map metadata) { public Role build() { return new Role(name, clusterPrivileges, globalApplicationPrivileges, indicesPrivileges, applicationResourcePrivileges, - runAsPrivilege, metadata, transientMetadata); + runAsPrivilege, metadata); } } @@ -326,7 +315,7 @@ public static class ClusterPrivilegeName { public static final String MANAGE_PIPELINE = "manage_pipeline"; public static final String MANAGE_CCR = "manage_ccr"; public static final String READ_CCR = "read_ccr"; - public static final String[] ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, + public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT, MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR }; } @@ -349,7 +338,7 @@ public static class IndexPrivilegeName { public static final String CREATE_INDEX = "create_index"; public static final String VIEW_INDEX_METADATA = "view_index_metadata"; public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index"; - public static final String[] ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE, + public static final String[] ALL_ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE, DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX }; } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java index 0bbccd8fbfb7e..466cc5b0135dc 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java @@ -160,7 +160,7 @@ private static User randomUser(String username) { private static Role randomRole(String roleName) { final Role.Builder roleBuilder = Role.builder() .name(roleName) - .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) + .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ALL_ARRAY)) .indicesPrivileges( randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, @@ -176,13 +176,6 @@ private static Role randomRole(String roleName) { } roleBuilder.metadata(metadata); } - if (randomBoolean()) { - final Map transientMetadata = new HashMap<>(); - for (int i = 0; i < randomInt(3); i++) { - transientMetadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); - } - roleBuilder.metadata(transientMetadata); - } return roleBuilder.build(); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java index f41eb578792fd..c95a233017a6c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java @@ -339,7 +339,7 @@ public void testDeletePrivileges() { public void testPutRole() throws IOException { final String roleName = randomAlphaOfLengthBetween(4, 7); - final List clusterPrivileges = randomSubsetOf(3, Role.ClusterPrivilegeName.ARRAY); + final List clusterPrivileges = randomSubsetOf(3, Role.ClusterPrivilegeName.ALL_ARRAY); final Map metadata = Collections.singletonMap(randomAlphaOfLengthBetween(4, 7), randomAlphaOfLengthBetween(4, 7)); final String[] runAsPrivilege = randomArray(3, String[]::new, () -> randomAlphaOfLength(5)); final List applicationPrivilegeNames = Arrays.asList(randomArray(1, 3, String[]::new, () -> randomAlphaOfLength(5))); diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 7d4ab475a22c2..5d85cf7f656f3 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -1026,7 +1026,7 @@ public void testPutRole() throws Exception { // tag::put-role-execute final Role role = Role.builder() .name("testPutRole") - .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ALL_ARRAY)) .build(); final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.NONE); final PutRoleResponse response = client.security().putRole(request, RequestOptions.DEFAULT); @@ -1040,7 +1040,7 @@ public void testPutRole() throws Exception { { final Role role = Role.builder() .name("testPutRole") - .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ARRAY)) + .clusterPrivileges(randomSubsetOf(1, Role.ClusterPrivilegeName.ALL_ARRAY)) .build(); final PutRoleRequest request = new PutRoleRequest(role, RefreshPolicy.NONE); // tag::put-role-execute-listener diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java index 6164dae52db99..224b4d59d250d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/GetRolesResponseTests.java @@ -73,6 +73,7 @@ public void usedDeprecatedField(String usedName, String replacedWith) { } }, json))); assertThat(response.getRoles().size(), equalTo(1)); + assertThat(response.getTransientMetadataMap().size(), equalTo(1)); final Role role = response.getRoles().get(0); assertThat(role.getName(), equalTo("my_admin_role")); assertThat(role.getClusterPrivileges().size(), equalTo(1)); @@ -86,6 +87,7 @@ public void usedDeprecatedField(String usedName, String replacedWith) { expectedMetadata.put("version", 1); final Map expectedTransientMetadata = new HashMap<>(); expectedTransientMetadata.put("enabled", true); + assertThat(response.getTransientMetadataMap().get(role.getName()), equalTo(expectedTransientMetadata)); final Role expectedRole = Role.builder() .name("my_admin_role") .clusterPrivileges("all") @@ -94,11 +96,11 @@ public void usedDeprecatedField(String usedName, String replacedWith) { .metadata(expectedMetadata) .build(); assertThat(role, equalTo(expectedRole)); - assertThat(role.getTransientMetadata(), equalTo(expectedTransientMetadata)); } public void testEqualsHashCode() { final List roles = new ArrayList<>(); + final Map> transientMetadataMap = new HashMap<>(); IndicesPrivileges indicesPrivileges = new IndicesPrivileges.Builder() .indices("index1", "index2") .privileges("write", "monitor", "delete") @@ -115,6 +117,9 @@ public void testEqualsHashCode() { .metadata(metadata) .build(); roles.add(role); + Map transientMetadata = new HashMap<>(); + transientMetadata.put("transient_key", "transient_value"); + transientMetadataMap.put(role.getName(), transientMetadata); IndicesPrivileges indicesPrivileges2 = new IndicesPrivileges.Builder() .indices("other_index1", "other_index2") .privileges("write", "monitor", "delete") @@ -131,20 +136,23 @@ public void testEqualsHashCode() { .metadata(metadata2) .build(); roles.add(role2); - final GetRolesResponse getRolesResponse = new GetRolesResponse(roles); - assertNotNull(getRolesResponse); + Map transientMetadata2 = new HashMap<>(); + transientMetadata2.put("other_transient_key", "other_transient_value"); + transientMetadataMap.put(role2.getName(), transientMetadata); + final GetRolesResponse getRolesResponse = new GetRolesResponse(roles, transientMetadataMap); EqualsHashCodeTestUtils.checkEqualsAndHashCode(getRolesResponse, (original) -> { - return new GetRolesResponse(original.getRoles()); + return new GetRolesResponse(original.getRoles(), original.getTransientMetadataMap()); }); EqualsHashCodeTestUtils.checkEqualsAndHashCode(getRolesResponse, (original) -> { - return new GetRolesResponse(original.getRoles()); + return new GetRolesResponse(original.getRoles(), original.getTransientMetadataMap()); }, GetRolesResponseTests::mutateTestItem); } private static GetRolesResponse mutateTestItem(GetRolesResponse original) { + final List roles = new ArrayList<>(); + final Map> transientMetadataMap = new HashMap<>(); if (randomBoolean()) { - final List roles = new ArrayList<>(); IndicesPrivileges indicesPrivileges = new IndicesPrivileges.Builder() .indices("index1", "index2") .privileges("write", "monitor", "delete") @@ -161,7 +169,10 @@ private static GetRolesResponse mutateTestItem(GetRolesResponse original) { .metadata(metadata) .build(); roles.add(role); - return new GetRolesResponse(roles); + Map transientMetadata = new HashMap<>(); + transientMetadata.put("transient_key", "transient_value"); + transientMetadataMap.put(role.getName(), transientMetadata); + return new GetRolesResponse(roles, transientMetadataMap); } else { IndicesPrivileges indicesPrivileges = new IndicesPrivileges.Builder() .indices("index1_changed", "index2") @@ -181,7 +192,10 @@ private static GetRolesResponse mutateTestItem(GetRolesResponse original) { List newRoles = original.getRoles().stream().collect(Collectors.toList()); newRoles.remove(0); newRoles.add(role); - return new GetRolesResponse(newRoles); + Map transientMetadata = new HashMap<>(); + transientMetadata.put("transient_key", "transient_value"); + transientMetadataMap.put(role.getName(), transientMetadata); + return new GetRolesResponse(newRoles, transientMetadataMap); } } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java index 9f34bd550c3d2..32860a807ae67 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/PutRoleRequestTests.java @@ -27,6 +27,7 @@ import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; import org.elasticsearch.client.security.user.privileges.IndicesPrivilegesTests; import org.elasticsearch.client.security.user.privileges.Role; +import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.test.AbstractXContentTestCase; @@ -36,6 +37,9 @@ import java.util.Locale; import java.util.Map; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.empty; + public class PutRoleRequestTests extends AbstractXContentTestCase { private static final String roleName = "testRoleName"; @@ -48,7 +52,9 @@ protected PutRoleRequest createTestInstance() { @Override protected PutRoleRequest doParseInstance(XContentParser parser) throws IOException { - return new PutRoleRequest(Role.fromXContent(parser, roleName), null); + final Tuple> roleAndTransientMetadata = Role.fromXContent(parser, roleName); + assertThat(roleAndTransientMetadata.v2().entrySet(), is(empty())); + return new PutRoleRequest(roleAndTransientMetadata.v1(), null); } @Override @@ -58,7 +64,7 @@ protected boolean supportsUnknownFields() { private static Role randomRole(String roleName) { final Role.Builder roleBuilder = Role.builder().name(roleName) - .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ARRAY)) + .clusterPrivileges(randomSubsetOf(randomInt(3), Role.ClusterPrivilegeName.ALL_ARRAY)) .indicesPrivileges( randomArray(3, IndicesPrivileges[]::new, () -> IndicesPrivilegesTests.createNewRandom(randomAlphaOfLength(3)))) .applicationResourcePrivileges(randomArray(3, ApplicationResourcePrivileges[]::new, @@ -75,14 +81,7 @@ private static Role randomRole(String roleName) { } roleBuilder.metadata(metadata); } - if (randomBoolean()) { - final Map transientMetadata = new HashMap<>(); - for (int i = 0; i < randomInt(3); i++) { - transientMetadata.put(randomAlphaOfLength(3), randomAlphaOfLength(3)); - } - roleBuilder.metadata(transientMetadata); - } - return roleBuilder.build(); + return roleBuilder.build(); } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java index 7631a0dd3a7a7..41442d2a83687 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/user/privileges/IndicesPrivilegesTests.java @@ -31,7 +31,7 @@ public class IndicesPrivilegesTests extends AbstractXContentTestCase fields = Arrays.asList(generateRandomStringArray(4, 4, false)); From 6ae513e46266d23b897ea6ca852bafb4f5e0e4ea Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 6 Dec 2018 16:55:21 +0200 Subject: [PATCH 18/21] Minor left over --- .../org/elasticsearch/client/security/GetRolesResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java index 4aaf00229e6cf..1a937ea5cfeee 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/GetRolesResponse.java @@ -41,9 +41,9 @@ public final class GetRolesResponse { private final List roles; private final Map> transientMetadataMap; - GetRolesResponse(List roles, Map> transientMetadata) { + GetRolesResponse(List roles, Map> transientMetadataMap) { this.roles = Collections.unmodifiableList(roles); - this.transientMetadataMap = Collections.unmodifiableMap(transientMetadata); + this.transientMetadataMap = Collections.unmodifiableMap(transientMetadataMap); } public List getRoles() { From e65f81aff9ce04817aff81d5797f28be414cf1b0 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Thu, 6 Dec 2018 18:45:59 +0200 Subject: [PATCH 19/21] supported-apis --- docs/java-rest/high-level/supported-apis.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index 90df95131e4c7..68b96be5ec094 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -377,6 +377,7 @@ The Java High Level REST Client supports the following Security APIs: * <> * <> * <> +* <<{upid}-put-role>> * <<{upid}-get-roles>> * <> * <<{upid}-clear-roles-cache>> @@ -397,6 +398,7 @@ include::security/delete-user.asciidoc[] include::security/enable-user.asciidoc[] include::security/disable-user.asciidoc[] include::security/change-password.asciidoc[] +include::security/put-role.asciidoc[] include::security/get-roles.asciidoc[] include::security/delete-role.asciidoc[] include::security/delete-privileges.asciidoc[] From 0137e254603897ccee02a551e9849b375c9275ae Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Fri, 7 Dec 2018 12:15:22 +0200 Subject: [PATCH 20/21] Checkstyle --- .../client/security/user/privileges/GlobalPrivileges.java | 3 +-- .../elasticsearch/client/security/user/privileges/Role.java | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java index f7f87a33a7fe4..c1bd5550eca1a 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/GlobalPrivileges.java @@ -26,7 +26,6 @@ import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -134,4 +133,4 @@ public int hashCode() { return Objects.hash(privileges); } -} \ No newline at end of file +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java index cf417499b4081..27af02fdf50db 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java @@ -51,8 +51,8 @@ public final class Role { public static final ParseField TRANSIENT_METADATA = new ParseField("transient_metadata"); @SuppressWarnings("unchecked") - public static final ConstructingObjectParser>, String> PARSER = new ConstructingObjectParser<>("role_descriptor", false, - (constructorObjects, roleName) -> { + public static final ConstructingObjectParser>, String> PARSER = + new ConstructingObjectParser<>("role_descriptor", false, (constructorObjects, roleName) -> { // Don't ignore unknown fields. It is dangerous if the object we parse is also // part of a request that we build later on, and the fields that we now ignore // will end up being implicitly set to null in that request. From 6699ad3925d94a09b24933ba924f48ab4d8228a9 Mon Sep 17 00:00:00 2001 From: Albert Zaharovits Date: Mon, 10 Dec 2018 00:53:50 +0200 Subject: [PATCH 21/21] Checkstyle --- .../client/documentation/SecurityDocumentationIT.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index c06a0dcfb936c..27d8e755e973d 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -24,7 +24,6 @@ import org.elasticsearch.action.LatchedActionListener; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.ESRestHighLevelClientTestCase; -import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.security.AuthenticateResponse; @@ -76,7 +75,6 @@ import org.elasticsearch.client.security.user.privileges.ApplicationPrivilege; import org.elasticsearch.client.security.user.privileges.IndicesPrivileges; import org.elasticsearch.common.util.set.Sets; -import org.elasticsearch.rest.RestStatus; import org.hamcrest.Matchers; import javax.crypto.SecretKeyFactory;