Skip to content

Commit d3ead91

Browse files
committed
Merge branch 'master' into feature-jindex-master
2 parents 518f8b9 + f1f3b28 commit d3ead91

File tree

164 files changed

+2641
-1191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

164 files changed

+2641
-1191
lines changed

buildSrc/src/main/resources/checkstyle_suppressions.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,13 @@
6262
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]snapshots[/\\]SnapshotShardsService.java" checks="LineLength" />
6363
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]snapshots[/\\]SnapshotsService.java" checks="LineLength" />
6464
<suppress files="server[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]threadpool[/\\]ThreadPool.java" checks="LineLength" />
65-
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]VersionTests.java" checks="LineLength" />
6665
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]aliases[/\\]IndexAliasesIT.java" checks="LineLength" />
6766
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]deps[/\\]joda[/\\]SimpleJodaTests.java" checks="LineLength" />
6867
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]env[/\\]EnvironmentTests.java" checks="LineLength" />
6968
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]env[/\\]NodeEnvironmentTests.java" checks="LineLength" />
7069
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]explain[/\\]ExplainActionIT.java" checks="LineLength" />
7170
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]get[/\\]GetActionIT.java" checks="LineLength" />
7271
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]indexing[/\\]IndexActionIT.java" checks="LineLength" />
73-
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]indexlifecycle[/\\]IndexLifecycleActionIT.java" checks="LineLength" />
7472
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]monitor[/\\]jvm[/\\]JvmGcMonitorServiceSettingsTests.java" checks="LineLength" />
7573
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]plugins[/\\]PluginsServiceTests.java" checks="LineLength" />
7674
<suppress files="server[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]recovery[/\\]FullRollingRestartIT.java" checks="LineLength" />

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import org.elasticsearch.client.security.GetSslCertificatesResponse;
5151
import org.elasticsearch.client.security.GetUserPrivilegesRequest;
5252
import org.elasticsearch.client.security.GetUserPrivilegesResponse;
53+
import org.elasticsearch.client.security.GetUsersRequest;
54+
import org.elasticsearch.client.security.GetUsersResponse;
5355
import org.elasticsearch.client.security.HasPrivilegesRequest;
5456
import org.elasticsearch.client.security.HasPrivilegesResponse;
5557
import org.elasticsearch.client.security.InvalidateTokenRequest;
@@ -81,6 +83,33 @@ public final class SecurityClient {
8183
this.restHighLevelClient = restHighLevelClient;
8284
}
8385

86+
/**
87+
* Get a user, or list of users, in the native realm synchronously.
88+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-user.html">
89+
* the docs</a> for more information.
90+
* @param request the request with the user's name
91+
* @param options the request options (e.g., headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
92+
* @return the response from the get users call
93+
* @throws IOException in case there is a problem sending the request or parsing back the response
94+
*/
95+
public GetUsersResponse getUsers(GetUsersRequest request, RequestOptions options) throws IOException {
96+
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::getUsers, options,
97+
GetUsersResponse::fromXContent, emptySet());
98+
}
99+
100+
/**
101+
* Get a user, or list of users, in the native realm asynchronously.
102+
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-user.html">
103+
* the docs</a> for more information.
104+
* @param request the request with the user's name
105+
* @param options the request options (e.g., headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
106+
* @param listener the listener to be notified upon request completion
107+
*/
108+
public void getUsersAsync(GetUsersRequest request, RequestOptions options, ActionListener<GetUsersResponse> listener) {
109+
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::getUsers, options,
110+
GetUsersResponse::fromXContent, listener, emptySet());
111+
}
112+
84113
/**
85114
* Create/update a user in the native realm synchronously.
86115
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-users.html">

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.elasticsearch.client.security.GetPrivilegesRequest;
3737
import org.elasticsearch.client.security.GetRoleMappingsRequest;
3838
import org.elasticsearch.client.security.GetRolesRequest;
39+
import org.elasticsearch.client.security.GetUsersRequest;
3940
import org.elasticsearch.client.security.HasPrivilegesRequest;
4041
import org.elasticsearch.client.security.InvalidateTokenRequest;
4142
import org.elasticsearch.client.security.PutPrivilegesRequest;
@@ -67,6 +68,15 @@ static Request changePassword(ChangePasswordRequest changePasswordRequest) throw
6768
return request;
6869
}
6970

71+
static Request getUsers(GetUsersRequest getUsersRequest) {
72+
RequestConverters.EndpointBuilder builder = new RequestConverters.EndpointBuilder()
73+
.addPathPartAsIs("_security/user");
74+
if (getUsersRequest.getUsernames().size() > 0) {
75+
builder.addPathPart(Strings.collectionToCommaDelimitedString(getUsersRequest.getUsernames()));
76+
}
77+
return new Request(HttpGet.METHOD_NAME, builder.build());
78+
}
79+
7080
static Request putUser(PutUserRequest putUserRequest) throws IOException {
7181
String endpoint = new RequestConverters.EndpointBuilder()
7282
.addPathPartAsIs("_security/user")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client.security;
20+
21+
import org.elasticsearch.client.Validatable;
22+
import org.elasticsearch.common.util.set.Sets;
23+
24+
import java.util.Collections;
25+
import java.util.Objects;
26+
import java.util.Set;
27+
28+
/**
29+
* Request object to retrieve users from the native realm
30+
*/
31+
public class GetUsersRequest implements Validatable {
32+
private final Set<String> usernames;
33+
34+
public GetUsersRequest(final String... usernames) {
35+
if (usernames != null) {
36+
this.usernames = Collections.unmodifiableSet(Sets.newHashSet(usernames));
37+
} else {
38+
this.usernames = Collections.emptySet();
39+
}
40+
}
41+
42+
public Set<String> getUsernames() {
43+
return usernames;
44+
}
45+
46+
@Override
47+
public boolean equals(Object o) {
48+
if (this == o) return true;
49+
if (!(o instanceof GetUsersRequest)) return false;
50+
GetUsersRequest that = (GetUsersRequest) o;
51+
return Objects.equals(usernames, that.usernames);
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return Objects.hash(usernames);
57+
}
58+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.elasticsearch.client.security;
20+
21+
import org.elasticsearch.client.security.user.User;
22+
import org.elasticsearch.common.Nullable;
23+
import org.elasticsearch.common.ParseField;
24+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
25+
import org.elasticsearch.common.xcontent.XContentParser;
26+
import org.elasticsearch.common.xcontent.XContentParser.Token;
27+
import org.elasticsearch.common.xcontent.XContentParserUtils;
28+
29+
import java.io.IOException;
30+
import java.util.Collection;
31+
import java.util.Collections;
32+
import java.util.HashSet;
33+
import java.util.Map;
34+
import java.util.Objects;
35+
import java.util.Set;
36+
37+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
38+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
39+
40+
/**
41+
* Response when requesting zero or more users.
42+
* Returns a List of {@link User} objects
43+
*/
44+
public class GetUsersResponse {
45+
private final Set<User> users;
46+
private final Set<User> enabledUsers;
47+
48+
public GetUsersResponse(Set<User> users, Set<User> enabledUsers) {
49+
this.users = Collections.unmodifiableSet(users);
50+
this.enabledUsers = Collections.unmodifiableSet(enabledUsers);
51+
}
52+
53+
public Set<User> getUsers() {
54+
return users;
55+
}
56+
57+
public Set<User> getEnabledUsers() {
58+
return enabledUsers;
59+
}
60+
61+
public static GetUsersResponse fromXContent(XContentParser parser) throws IOException {
62+
XContentParserUtils.ensureExpectedToken(Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
63+
final Set<User> users = new HashSet<>();
64+
final Set<User> enabledUsers = new HashSet<>();
65+
Token token;
66+
while ((token = parser.nextToken()) != Token.END_OBJECT) {
67+
XContentParserUtils.ensureExpectedToken(Token.FIELD_NAME, token, parser::getTokenLocation);
68+
ParsedUser parsedUser = USER_PARSER.parse(parser, parser.currentName());
69+
users.add(parsedUser.user);
70+
if (parsedUser.enabled) {
71+
enabledUsers.add(parsedUser.user);
72+
}
73+
}
74+
return new GetUsersResponse(users, enabledUsers);
75+
}
76+
77+
@Override
78+
public boolean equals(Object o) {
79+
if (this == o) return true;
80+
if (!(o instanceof GetUsersResponse)) return false;
81+
GetUsersResponse that = (GetUsersResponse) o;
82+
return Objects.equals(users, that.users);
83+
}
84+
85+
@Override
86+
public int hashCode() {
87+
return Objects.hash(users);
88+
}
89+
90+
public static final ParseField USERNAME = new ParseField("username");
91+
public static final ParseField ROLES = new ParseField("roles");
92+
public static final ParseField FULL_NAME = new ParseField("full_name");
93+
public static final ParseField EMAIL = new ParseField("email");
94+
public static final ParseField METADATA = new ParseField("metadata");
95+
public static final ParseField ENABLED = new ParseField("enabled");
96+
97+
@SuppressWarnings("unchecked")
98+
public static final ConstructingObjectParser<ParsedUser, String> USER_PARSER = new ConstructingObjectParser<>("user_info",
99+
(constructorObjects) -> {
100+
int i = 0;
101+
final String username = (String) constructorObjects[i++];
102+
final Collection<String> roles = (Collection<String>) constructorObjects[i++];
103+
final Map<String, Object> metadata = (Map<String, Object>) constructorObjects[i++];
104+
final Boolean enabled = (Boolean) constructorObjects[i++];
105+
final String fullName = (String) constructorObjects[i++];
106+
final String email = (String) constructorObjects[i++];
107+
return new ParsedUser(username, roles, metadata, enabled, fullName, email);
108+
});
109+
110+
static {
111+
USER_PARSER.declareString(constructorArg(), USERNAME);
112+
USER_PARSER.declareStringArray(constructorArg(), ROLES);
113+
USER_PARSER.declareObject(constructorArg(), (parser, c) -> parser.map(), METADATA);
114+
USER_PARSER.declareBoolean(constructorArg(), ENABLED);
115+
USER_PARSER.declareStringOrNull(optionalConstructorArg(), FULL_NAME);
116+
USER_PARSER.declareStringOrNull(optionalConstructorArg(), EMAIL);
117+
}
118+
119+
protected static final class ParsedUser {
120+
protected User user;
121+
protected boolean enabled;
122+
123+
public ParsedUser(String username, Collection<String> roles, Map<String, Object> metadata, Boolean enabled,
124+
@Nullable String fullName, @Nullable String email) {
125+
String checkedUsername = username = Objects.requireNonNull(username, "`username` is required, cannot be null");
126+
Collection<String> checkedRoles = Collections.unmodifiableSet(new HashSet<>(
127+
Objects.requireNonNull(roles, "`roles` is required, cannot be null. Pass an empty Collection instead.")));
128+
Map<String, Object> checkedMetadata = Collections
129+
.unmodifiableMap(Objects.requireNonNull(metadata, "`metadata` is required, cannot be null. Pass an empty map instead."));
130+
this.user = new User(checkedUsername, checkedRoles, checkedMetadata, fullName, email);
131+
this.enabled = enabled;
132+
}
133+
}
134+
}

client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/User.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.Objects;
3030
import java.util.Set;
3131

32-
3332
/**
3433
* A user to be utilized with security APIs.
3534
* Can be an existing authenticated user or it can be a new user to be enrolled to the native realm.

client/rest-high-level/src/main/java/org/elasticsearch/client/security/user/privileges/Role.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,11 @@ public static class ClusterPrivilegeName {
315315
public static final String MANAGE_PIPELINE = "manage_pipeline";
316316
public static final String MANAGE_CCR = "manage_ccr";
317317
public static final String READ_CCR = "read_ccr";
318+
public static final String MANAGE_ILM = "manage_ilm";
319+
public static final String READ_ILM = "read_ilm";
318320
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE,
319321
MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT,
320-
MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR };
322+
MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR, MANAGE_ILM, READ_ILM };
321323
}
322324

323325
/**
@@ -338,8 +340,9 @@ public static class IndexPrivilegeName {
338340
public static final String CREATE_INDEX = "create_index";
339341
public static final String VIEW_INDEX_METADATA = "view_index_metadata";
340342
public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index";
343+
public static final String MANAGE_ILM = "manage_ilm";
341344
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE,
342-
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX };
345+
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX, MANAGE_ILM };
343346
}
344347

345348
}

client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityIT.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.elasticsearch.client.security.DeleteUserResponse;
2929
import org.elasticsearch.client.security.GetRolesRequest;
3030
import org.elasticsearch.client.security.GetRolesResponse;
31+
import org.elasticsearch.client.security.GetUsersRequest;
32+
import org.elasticsearch.client.security.GetUsersResponse;
3133
import org.elasticsearch.client.security.PutRoleRequest;
3234
import org.elasticsearch.client.security.PutRoleResponse;
3335
import org.elasticsearch.client.security.PutUserRequest;
@@ -42,6 +44,7 @@
4244
import org.elasticsearch.client.security.user.privileges.Role;
4345
import org.elasticsearch.common.CharArrays;
4446

47+
import java.util.ArrayList;
4548
import java.util.Arrays;
4649
import java.util.Base64;
4750
import java.util.HashMap;
@@ -74,6 +77,22 @@ public void testPutUser() throws Exception {
7477
highLevelClient().getLowLevelClient().performRequest(deleteUserRequest);
7578
}
7679

80+
public void testGetUser() throws Exception {
81+
final SecurityClient securityClient = highLevelClient().security();
82+
// create user
83+
final PutUserRequest putUserRequest = randomPutUserRequest(randomBoolean());
84+
final PutUserResponse putUserResponse = execute(putUserRequest, securityClient::putUser, securityClient::putUserAsync);
85+
// assert user created
86+
assertThat(putUserResponse.isCreated(), is(true));
87+
// get user
88+
final GetUsersRequest getUsersRequest = new GetUsersRequest(putUserRequest.getUser().getUsername());
89+
final GetUsersResponse getUsersResponse = execute(getUsersRequest, securityClient::getUsers, securityClient::getUsersAsync);
90+
// assert user was correctly retrieved
91+
ArrayList<User> users = new ArrayList<>();
92+
users.addAll(getUsersResponse.getUsers());
93+
assertThat(users.get(0), is(putUserRequest.getUser()));
94+
}
95+
7796
public void testAuthenticate() throws Exception {
7897
final SecurityClient securityClient = highLevelClient().security();
7998
// test fixture: put enabled user
@@ -89,6 +108,15 @@ public void testAuthenticate() throws Exception {
89108
assertThat(authenticateResponse.getUser(), is(putUserRequest.getUser()));
90109
assertThat(authenticateResponse.enabled(), is(true));
91110

111+
// get user
112+
final GetUsersRequest getUsersRequest =
113+
new GetUsersRequest(putUserRequest.getUser().getUsername());
114+
final GetUsersResponse getUsersResponse =
115+
execute(getUsersRequest, securityClient::getUsers, securityClient::getUsersAsync);
116+
ArrayList<User> users = new ArrayList<>();
117+
users.addAll(getUsersResponse.getUsers());
118+
assertThat(users.get(0), is(putUserRequest.getUser()));
119+
92120
// delete user
93121
final DeleteUserRequest deleteUserRequest =
94122
new DeleteUserRequest(putUserRequest.getUser().getUsername(), putUserRequest.getRefreshPolicy());

client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.elasticsearch.client.security.GetPrivilegesRequest;
3535
import org.elasticsearch.client.security.GetRoleMappingsRequest;
3636
import org.elasticsearch.client.security.GetRolesRequest;
37+
import org.elasticsearch.client.security.GetUsersRequest;
3738
import org.elasticsearch.client.security.PutPrivilegesRequest;
3839
import org.elasticsearch.client.security.PutRoleMappingRequest;
3940
import org.elasticsearch.client.security.PutRoleRequest;
@@ -101,6 +102,21 @@ public void testDeleteUser() {
101102
assertNull(request.getEntity());
102103
}
103104

105+
public void testGetUsers() {
106+
final String[] users = randomArray(0, 5, String[]::new, () -> randomAlphaOfLength(5));
107+
GetUsersRequest getUsersRequest = new GetUsersRequest(users);
108+
Request request = SecurityRequestConverters.getUsers(getUsersRequest);
109+
assertEquals(HttpGet.METHOD_NAME, request.getMethod());
110+
if (users.length == 0) {
111+
assertEquals("/_security/user", request.getEndpoint());
112+
} else {
113+
assertEquals("/_security/user/" + Strings.collectionToCommaDelimitedString(getUsersRequest.getUsernames()),
114+
request.getEndpoint());
115+
}
116+
assertNull(request.getEntity());
117+
assertEquals(Collections.emptyMap(), request.getParameters());
118+
}
119+
104120
public void testPutRoleMapping() throws IOException {
105121
final String username = randomAlphaOfLengthBetween(4, 7);
106122
final String rolename = randomAlphaOfLengthBetween(4, 7);

0 commit comments

Comments
 (0)