changed the User API
- Now it's more aligned with other APIs in ES (e.g. index template API) - the "get user" API now returns an object as a response. The users are keyed by their username. If none of the requested users is found, an empty object will be returned with a 404 response status. - the body of "put user" request doesn't require "username" anymore (as it's defined as part of the URL) Original commit: elastic/x-pack-elasticsearch@f7c12648b1
This commit is contained in:
parent
1f113e07f4
commit
759d99de9c
|
@ -34,8 +34,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
*/
|
*/
|
||||||
public class ShieldTemplateService extends AbstractComponent implements ClusterStateListener {
|
public class ShieldTemplateService extends AbstractComponent implements ClusterStateListener {
|
||||||
|
|
||||||
public static final String SHIELD_ADMIN_INDEX_NAME = ".security";
|
public static final String SECURITY_INDEX_NAME = ".security";
|
||||||
public static final String SHIELD_TEMPLATE_NAME = "security-index-template";
|
public static final String SECURITY_TEMPLATE_NAME = "security-index-template";
|
||||||
|
|
||||||
private final ThreadPool threadPool;
|
private final ThreadPool threadPool;
|
||||||
private final Provider<InternalClient> clientProvider;
|
private final Provider<InternalClient> clientProvider;
|
||||||
|
@ -52,22 +52,22 @@ public class ShieldTemplateService extends AbstractComponent implements ClusterS
|
||||||
|
|
||||||
private void createShieldTemplate() {
|
private void createShieldTemplate() {
|
||||||
final Client client = clientProvider.get();
|
final Client client = clientProvider.get();
|
||||||
try (InputStream is = getClass().getResourceAsStream("/" + SHIELD_TEMPLATE_NAME + ".json")) {
|
try (InputStream is = getClass().getResourceAsStream("/" + SECURITY_TEMPLATE_NAME + ".json")) {
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
Streams.copy(is, out);
|
Streams.copy(is, out);
|
||||||
final byte[] template = out.toByteArray();
|
final byte[] template = out.toByteArray();
|
||||||
logger.info("--> putting the shield index template");
|
logger.info("--> putting the shield index template");
|
||||||
PutIndexTemplateRequest putTemplateRequest = client.admin().indices()
|
PutIndexTemplateRequest putTemplateRequest = client.admin().indices()
|
||||||
.preparePutTemplate(SHIELD_TEMPLATE_NAME).setSource(template).request();
|
.preparePutTemplate(SECURITY_TEMPLATE_NAME).setSource(template).request();
|
||||||
PutIndexTemplateResponse templateResponse = client.admin().indices().putTemplate(putTemplateRequest).get();
|
PutIndexTemplateResponse templateResponse = client.admin().indices().putTemplate(putTemplateRequest).get();
|
||||||
if (templateResponse.isAcknowledged() == false) {
|
if (templateResponse.isAcknowledged() == false) {
|
||||||
throw new ElasticsearchException("adding template for shield admin index was not acknowledged");
|
throw new ElasticsearchException("adding template for shield admin index was not acknowledged");
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("failed to create shield admin index template [{}]",
|
logger.error("failed to create shield admin index template [{}]",
|
||||||
e, SHIELD_ADMIN_INDEX_NAME);
|
e, SECURITY_INDEX_NAME);
|
||||||
throw new IllegalStateException("failed to create shield admin index template [" +
|
throw new IllegalStateException("failed to create shield admin index template [" +
|
||||||
SHIELD_ADMIN_INDEX_NAME + "]", e);
|
SECURITY_INDEX_NAME + "]", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,13 +80,13 @@ public class ShieldTemplateService extends AbstractComponent implements ClusterS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexRoutingTable shieldIndexRouting = event.state().routingTable().index(SHIELD_ADMIN_INDEX_NAME);
|
IndexRoutingTable shieldIndexRouting = event.state().routingTable().index(SECURITY_INDEX_NAME);
|
||||||
|
|
||||||
if (shieldIndexRouting == null) {
|
if (shieldIndexRouting == null) {
|
||||||
if (event.localNodeMaster()) {
|
if (event.localNodeMaster()) {
|
||||||
ClusterState state = event.state();
|
ClusterState state = event.state();
|
||||||
// TODO for the future need to add some checking in the event the template needs to be updated...
|
// TODO for the future need to add some checking in the event the template needs to be updated...
|
||||||
IndexTemplateMetaData templateMeta = state.metaData().templates().get(SHIELD_TEMPLATE_NAME);
|
IndexTemplateMetaData templateMeta = state.metaData().templates().get(SECURITY_TEMPLATE_NAME);
|
||||||
final boolean createTemplate = (templateMeta == null);
|
final boolean createTemplate = (templateMeta == null);
|
||||||
|
|
||||||
if (createTemplate && templateCreationPending.compareAndSet(false, true)) {
|
if (createTemplate && templateCreationPending.compareAndSet(false, true)) {
|
||||||
|
|
|
@ -158,13 +158,12 @@ public class User implements ToXContent {
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
builder.field(Fields.USERNAME.getPreferredName(), principal());
|
builder.field(Fields.USERNAME.getPreferredName(), username);
|
||||||
builder.array(Fields.ROLES.getPreferredName(), roles());
|
builder.array(Fields.ROLES.getPreferredName(), roles);
|
||||||
builder.field(Fields.FULL_NAME.getPreferredName(), fullName);
|
builder.field(Fields.FULL_NAME.getPreferredName(), fullName);
|
||||||
builder.field(Fields.EMAIL.getPreferredName(), email);
|
builder.field(Fields.EMAIL.getPreferredName(), email);
|
||||||
builder.field(Fields.METADATA.getPreferredName(), metadata);
|
builder.field(Fields.METADATA.getPreferredName(), metadata);
|
||||||
builder.endObject();
|
return builder.endObject();
|
||||||
return builder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User readFrom(StreamInput input) throws IOException {
|
public static User readFrom(StreamInput input) throws IOException {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class XPackUser extends User {
|
||||||
|
|
||||||
// these will be the index permissions required by shield (will uncomment once we optimize watcher permissions)
|
// these will be the index permissions required by shield (will uncomment once we optimize watcher permissions)
|
||||||
|
|
||||||
// .add(IndexPrivilege.ALL, ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
// .add(IndexPrivilege.ALL, ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
// .add(IndexPrivilege.ALL, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
|
// .add(IndexPrivilege.ALL, IndexAuditTrail.INDEX_NAME_PREFIX + "*")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,8 @@ public class PutUserRequestBuilder extends ActionRequestBuilder<PutUserRequest,
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PutUserRequestBuilder source(BytesReference source) throws IOException {
|
public PutUserRequestBuilder source(String username, BytesReference source) throws IOException {
|
||||||
|
username(username);
|
||||||
try (XContentParser parser = XContentHelper.createParser(source)) {
|
try (XContentParser parser = XContentHelper.createParser(source)) {
|
||||||
XContentUtils.verifyObject(parser);
|
XContentUtils.verifyObject(parser);
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
|
@ -73,11 +74,9 @@ public class PutUserRequestBuilder extends ActionRequestBuilder<PutUserRequest,
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, User.Fields.USERNAME)) {
|
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, User.Fields.USERNAME)) {
|
||||||
if (token == XContentParser.Token.VALUE_STRING) {
|
if (username.equals(parser.text()) == false) {
|
||||||
username(parser.text());
|
throw new ElasticsearchParseException("failed to parse user [{}]. username doesn't match user id [{}]",
|
||||||
} else {
|
username, parser.text());
|
||||||
throw new ElasticsearchParseException(
|
|
||||||
"expected field [{}] to be of type string, but found [{}] instead", currentFieldName, token);
|
|
||||||
}
|
}
|
||||||
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, User.Fields.PASSWORD)) {
|
} else if (ParseFieldMatcher.STRICT.match(currentFieldName, User.Fields.PASSWORD)) {
|
||||||
if (token == XContentParser.Token.VALUE_STRING) {
|
if (token == XContentParser.Token.VALUE_STRING) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - perhaps separate indices for users/roles instead of types?
|
// TODO - perhaps separate indices for users/roles instead of types?
|
||||||
public static final String INDEX_USER_TYPE = "user";
|
public static final String USER_DOC_TYPE = "user";
|
||||||
|
|
||||||
// this map contains the mapping for username -> version, which is used when polling the index to easily detect of
|
// this map contains the mapping for username -> version, which is used when polling the index to easily detect of
|
||||||
// any changes that may have been missed since the last update.
|
// any changes that may have been missed since the last update.
|
||||||
|
@ -168,12 +168,13 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
final List<User> users = new ArrayList<>();
|
final List<User> users = new ArrayList<>();
|
||||||
QueryBuilder query;
|
QueryBuilder query;
|
||||||
if (usernames == null || usernames.length == 0) {
|
if (usernames == null || usernames.length == 0) {
|
||||||
query = QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("_type", INDEX_USER_TYPE));
|
query = QueryBuilders.matchAllQuery();
|
||||||
} else {
|
} else {
|
||||||
query = QueryBuilders.boolQuery().filter(QueryBuilders.idsQuery(INDEX_USER_TYPE).addIds(usernames));
|
query = QueryBuilders.boolQuery().filter(QueryBuilders.idsQuery(USER_DOC_TYPE).addIds(usernames));
|
||||||
}
|
}
|
||||||
SearchRequest request = client.prepareSearch(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
SearchRequest request = client.prepareSearch(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setScroll(scrollKeepAlive)
|
.setScroll(scrollKeepAlive)
|
||||||
|
.setTypes(USER_DOC_TYPE)
|
||||||
.setQuery(query)
|
.setQuery(query)
|
||||||
.setSize(scrollSize)
|
.setSize(scrollSize)
|
||||||
.setFetchSource(true)
|
.setFetchSource(true)
|
||||||
|
@ -187,7 +188,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
boolean hasHits = resp.getHits().getHits().length > 0;
|
boolean hasHits = resp.getHits().getHits().length > 0;
|
||||||
if (hasHits) {
|
if (hasHits) {
|
||||||
for (SearchHit hit : resp.getHits().getHits()) {
|
for (SearchHit hit : resp.getHits().getHits()) {
|
||||||
UserAndPassword u = transformUser(hit.getSource());
|
UserAndPassword u = transformUser(hit.getId(), hit.getSource());
|
||||||
if (u != null) {
|
if (u != null) {
|
||||||
users.add(u.user());
|
users.add(u.user());
|
||||||
}
|
}
|
||||||
|
@ -257,12 +258,12 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
|
|
||||||
private void getUserAndPassword(String user, final ActionListener<UserAndPassword> listener) {
|
private void getUserAndPassword(String user, final ActionListener<UserAndPassword> listener) {
|
||||||
try {
|
try {
|
||||||
GetRequest request = client.prepareGet(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME, INDEX_USER_TYPE, user).request();
|
GetRequest request = client.prepareGet(ShieldTemplateService.SECURITY_INDEX_NAME, USER_DOC_TYPE, user).request();
|
||||||
request.indicesOptions().ignoreUnavailable();
|
request.indicesOptions().ignoreUnavailable();
|
||||||
client.get(request, new ActionListener<GetResponse>() {
|
client.get(request, new ActionListener<GetResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(GetResponse getFields) {
|
public void onResponse(GetResponse response) {
|
||||||
listener.onResponse(transformUser(getFields.getSource()));
|
listener.onResponse(transformUser(response.getId(), response.getSource()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -286,24 +287,24 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putUser(final PutUserRequest putUserRequest, final ActionListener<Boolean> listener) {
|
public void putUser(final PutUserRequest request, final ActionListener<Boolean> listener) {
|
||||||
if (state() != State.STARTED) {
|
if (state() != State.STARTED) {
|
||||||
listener.onFailure(new IllegalStateException("user cannot be added as native user service has not been started"));
|
listener.onFailure(new IllegalStateException("user cannot be added as native user service has not been started"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IndexRequest request = client.prepareIndex(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME,
|
IndexRequest indexRequest = client.prepareIndex(ShieldTemplateService.SECURITY_INDEX_NAME, USER_DOC_TYPE, request.username())
|
||||||
INDEX_USER_TYPE, putUserRequest.username())
|
// we still index the username for more intuitive searchability (e.g. using queries like "username: joe")
|
||||||
.setSource(User.Fields.USERNAME.getPreferredName(), putUserRequest.username(),
|
.setSource(User.Fields.USERNAME.getPreferredName(), request.username(),
|
||||||
User.Fields.PASSWORD.getPreferredName(), String.valueOf(putUserRequest.passwordHash()),
|
User.Fields.PASSWORD.getPreferredName(), String.valueOf(request.passwordHash()),
|
||||||
User.Fields.ROLES.getPreferredName(), putUserRequest.roles(),
|
User.Fields.ROLES.getPreferredName(), request.roles(),
|
||||||
User.Fields.FULL_NAME.getPreferredName(), putUserRequest.fullName(),
|
User.Fields.FULL_NAME.getPreferredName(), request.fullName(),
|
||||||
User.Fields.EMAIL.getPreferredName(), putUserRequest.email(),
|
User.Fields.EMAIL.getPreferredName(), request.email(),
|
||||||
User.Fields.METADATA.getPreferredName(), putUserRequest.metadata())
|
User.Fields.METADATA.getPreferredName(), request.metadata())
|
||||||
.request();
|
.request();
|
||||||
|
|
||||||
client.index(request, new ActionListener<IndexResponse>() {
|
client.index(indexRequest, new ActionListener<IndexResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(IndexResponse indexResponse) {
|
public void onResponse(IndexResponse indexResponse) {
|
||||||
// if the document was just created, then we don't need to clear cache
|
// if the document was just created, then we don't need to clear cache
|
||||||
|
@ -312,7 +313,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearRealmCache(putUserRequest.username(), listener, indexResponse.isCreated());
|
clearRealmCache(request.username(), listener, indexResponse.isCreated());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -333,8 +334,8 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DeleteRequest request = client.prepareDelete(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME,
|
DeleteRequest request = client.prepareDelete(ShieldTemplateService.SECURITY_INDEX_NAME,
|
||||||
INDEX_USER_TYPE, deleteUserRequest.username()).request();
|
USER_DOC_TYPE, deleteUserRequest.username()).request();
|
||||||
request.indicesOptions().ignoreUnavailable();
|
request.indicesOptions().ignoreUnavailable();
|
||||||
client.delete(request, new ActionListener<DeleteResponse>() {
|
client.delete(request, new ActionListener<DeleteResponse>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -366,21 +367,21 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterState.metaData().templates().get(ShieldTemplateService.SHIELD_TEMPLATE_NAME) == null) {
|
if (clusterState.metaData().templates().get(ShieldTemplateService.SECURITY_TEMPLATE_NAME) == null) {
|
||||||
logger.debug("native users template [{}] does not exist, so service cannot start",
|
logger.debug("native users template [{}] does not exist, so service cannot start",
|
||||||
ShieldTemplateService.SHIELD_TEMPLATE_NAME);
|
ShieldTemplateService.SECURITY_TEMPLATE_NAME);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexMetaData metaData = clusterState.metaData().index(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
IndexMetaData metaData = clusterState.metaData().index(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
if (metaData == null) {
|
if (metaData == null) {
|
||||||
logger.debug("shield user index [{}] does not exist, so service can start", ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
logger.debug("shield user index [{}] does not exist, so service can start", ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterState.routingTable().index(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME).allPrimaryShardsActive()) {
|
if (clusterState.routingTable().index(ShieldTemplateService.SECURITY_INDEX_NAME).allPrimaryShardsActive()) {
|
||||||
logger.debug("shield user index [{}] all primary shards started, so service can start",
|
logger.debug("shield user index [{}] all primary shards started, so service can start",
|
||||||
ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -472,11 +473,11 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clusterChanged(ClusterChangedEvent event) {
|
public void clusterChanged(ClusterChangedEvent event) {
|
||||||
final boolean exists = event.state().metaData().indices().get(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME) != null;
|
final boolean exists = event.state().metaData().indices().get(ShieldTemplateService.SECURITY_INDEX_NAME) != null;
|
||||||
// make sure all the primaries are active
|
// make sure all the primaries are active
|
||||||
if (exists && event.state().routingTable().index(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME).allPrimaryShardsActive()) {
|
if (exists && event.state().routingTable().index(ShieldTemplateService.SECURITY_INDEX_NAME).allPrimaryShardsActive()) {
|
||||||
logger.debug("shield user index [{}] all primary shards started, so polling can start",
|
logger.debug("shield user index [{}] all primary shards started, so polling can start",
|
||||||
ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
shieldIndexExists = true;
|
shieldIndexExists = true;
|
||||||
} else {
|
} else {
|
||||||
// always set the value - it may have changed...
|
// always set the value - it may have changed...
|
||||||
|
@ -502,12 +503,11 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private UserAndPassword transformUser(Map<String, Object> sourceMap) {
|
private UserAndPassword transformUser(String username, Map<String, Object> sourceMap) {
|
||||||
if (sourceMap == null) {
|
if (sourceMap == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String username = (String) sourceMap.get(User.Fields.USERNAME.getPreferredName());
|
|
||||||
String password = (String) sourceMap.get(User.Fields.PASSWORD.getPreferredName());
|
String password = (String) sourceMap.get(User.Fields.PASSWORD.getPreferredName());
|
||||||
String[] roles = ((List<String>) sourceMap.get(User.Fields.ROLES.getPreferredName())).toArray(Strings.EMPTY_ARRAY);
|
String[] roles = ((List<String>) sourceMap.get(User.Fields.ROLES.getPreferredName())).toArray(Strings.EMPTY_ARRAY);
|
||||||
String fullName = (String) sourceMap.get(User.Fields.FULL_NAME.getPreferredName());
|
String fullName = (String) sourceMap.get(User.Fields.FULL_NAME.getPreferredName());
|
||||||
|
@ -529,7 +529,7 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
}
|
}
|
||||||
if (shieldIndexExists == false) {
|
if (shieldIndexExists == false) {
|
||||||
logger.trace("cannot poll for user changes since shield admin index [{}] does not exist", ShieldTemplateService
|
logger.trace("cannot poll for user changes since shield admin index [{}] does not exist", ShieldTemplateService
|
||||||
.SHIELD_ADMIN_INDEX_NAME);
|
.SECURITY_INDEX_NAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,9 +609,9 @@ public class ESNativeUsersStore extends AbstractComponent implements ClusterStat
|
||||||
final ObjectLongMap<String> map = new ObjectLongHashMap<>();
|
final ObjectLongMap<String> map = new ObjectLongHashMap<>();
|
||||||
SearchResponse response = null;
|
SearchResponse response = null;
|
||||||
try {
|
try {
|
||||||
SearchRequest request = client.prepareSearch(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
SearchRequest request = client.prepareSearch(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setScroll(scrollKeepAlive)
|
.setScroll(scrollKeepAlive)
|
||||||
.setQuery(QueryBuilders.typeQuery(INDEX_USER_TYPE))
|
.setQuery(QueryBuilders.typeQuery(USER_DOC_TYPE))
|
||||||
.setSize(scrollSize)
|
.setSize(scrollSize)
|
||||||
.setVersion(true)
|
.setVersion(true)
|
||||||
.setFetchSource(true)
|
.setFetchSource(true)
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
} else {
|
} else {
|
||||||
query = QueryBuilders.boolQuery().filter(QueryBuilders.idsQuery(INDEX_ROLE_TYPE).addIds(rolesToGet));
|
query = QueryBuilders.boolQuery().filter(QueryBuilders.idsQuery(INDEX_ROLE_TYPE).addIds(rolesToGet));
|
||||||
}
|
}
|
||||||
SearchRequest request = client.prepareSearch(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
SearchRequest request = client.prepareSearch(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setScroll(scrollKeepAlive)
|
.setScroll(scrollKeepAlive)
|
||||||
.setQuery(query)
|
.setQuery(query)
|
||||||
.setSize(scrollSize)
|
.setSize(scrollSize)
|
||||||
|
@ -205,7 +205,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
|
|
||||||
private void executeGetRoleRequest(String role, ActionListener<GetResponse> listener) {
|
private void executeGetRoleRequest(String role, ActionListener<GetResponse> listener) {
|
||||||
try {
|
try {
|
||||||
GetRequest request = client.prepareGet(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME, INDEX_ROLE_TYPE, role).request();
|
GetRequest request = client.prepareGet(ShieldTemplateService.SECURITY_INDEX_NAME, INDEX_ROLE_TYPE, role).request();
|
||||||
request.indicesOptions().ignoreUnavailable();
|
request.indicesOptions().ignoreUnavailable();
|
||||||
client.get(request, listener);
|
client.get(request, listener);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -220,7 +220,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
listener.onResponse(false);
|
listener.onResponse(false);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
DeleteRequest request = client.prepareDelete(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME,
|
DeleteRequest request = client.prepareDelete(ShieldTemplateService.SECURITY_INDEX_NAME,
|
||||||
INDEX_ROLE_TYPE, deleteRoleRequest.role()).request();
|
INDEX_ROLE_TYPE, deleteRoleRequest.role()).request();
|
||||||
request.indicesOptions().ignoreUnavailable();
|
request.indicesOptions().ignoreUnavailable();
|
||||||
client.delete(request, new ActionListener<DeleteResponse>() {
|
client.delete(request, new ActionListener<DeleteResponse>() {
|
||||||
|
@ -294,7 +294,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
listener.onResponse(false);
|
listener.onResponse(false);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
IndexRequest request = client.prepareIndex(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME,
|
IndexRequest request = client.prepareIndex(ShieldTemplateService.SECURITY_INDEX_NAME,
|
||||||
INDEX_ROLE_TYPE, putRoleRequest.name())
|
INDEX_ROLE_TYPE, putRoleRequest.name())
|
||||||
.setSource(putRoleRequest.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS))
|
.setSource(putRoleRequest.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS))
|
||||||
.request();
|
.request();
|
||||||
|
@ -340,9 +340,9 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterState.metaData().templates().get(ShieldTemplateService.SHIELD_TEMPLATE_NAME) == null) {
|
if (clusterState.metaData().templates().get(ShieldTemplateService.SECURITY_TEMPLATE_NAME) == null) {
|
||||||
logger.debug("native roles template [{}] does not exist, so service cannot start",
|
logger.debug("native roles template [{}] does not exist, so service cannot start",
|
||||||
ShieldTemplateService.SHIELD_TEMPLATE_NAME);
|
ShieldTemplateService.SECURITY_TEMPLATE_NAME);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Okay to start...
|
// Okay to start...
|
||||||
|
@ -362,7 +362,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
poller.doRun();
|
poller.doRun();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn("failed to perform initial poll of roles index [{}]. scheduling again in [{}]", e,
|
logger.warn("failed to perform initial poll of roles index [{}]. scheduling again in [{}]", e,
|
||||||
ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME, pollInterval);
|
ShieldTemplateService.SECURITY_INDEX_NAME, pollInterval);
|
||||||
}
|
}
|
||||||
versionChecker = threadPool.scheduleWithFixedDelay(poller, pollInterval);
|
versionChecker = threadPool.scheduleWithFixedDelay(poller, pollInterval);
|
||||||
state.set(State.STARTED);
|
state.set(State.STARTED);
|
||||||
|
@ -426,11 +426,11 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
// TODO abstract this code rather than duplicating...
|
// TODO abstract this code rather than duplicating...
|
||||||
@Override
|
@Override
|
||||||
public void clusterChanged(ClusterChangedEvent event) {
|
public void clusterChanged(ClusterChangedEvent event) {
|
||||||
final boolean exists = event.state().metaData().indices().get(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME) != null;
|
final boolean exists = event.state().metaData().indices().get(ShieldTemplateService.SECURITY_INDEX_NAME) != null;
|
||||||
// make sure all the primaries are active
|
// make sure all the primaries are active
|
||||||
if (exists && event.state().routingTable().index(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME).allPrimaryShardsActive()) {
|
if (exists && event.state().routingTable().index(ShieldTemplateService.SECURITY_INDEX_NAME).allPrimaryShardsActive()) {
|
||||||
logger.debug("shield roles index [{}] all primary shards started, so polling can start",
|
logger.debug("shield roles index [{}] all primary shards started, so polling can start",
|
||||||
ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
shieldIndexExists = true;
|
shieldIndexExists = true;
|
||||||
} else {
|
} else {
|
||||||
// always set the value - it may have changed...
|
// always set the value - it may have changed...
|
||||||
|
@ -460,7 +460,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
}
|
}
|
||||||
if (shieldIndexExists == false) {
|
if (shieldIndexExists == false) {
|
||||||
logger.trace("cannot poll for role changes since shield admin index [{}] does not exist",
|
logger.trace("cannot poll for role changes since shield admin index [{}] does not exist",
|
||||||
ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
|
||||||
// create a copy of the keys in the cache since we will be modifying this list
|
// create a copy of the keys in the cache since we will be modifying this list
|
||||||
final Set<String> existingRoles = new HashSet<>(roleCache.keySet());
|
final Set<String> existingRoles = new HashSet<>(roleCache.keySet());
|
||||||
try {
|
try {
|
||||||
SearchRequest request = client.prepareSearch(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
SearchRequest request = client.prepareSearch(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setScroll(scrollKeepAlive)
|
.setScroll(scrollKeepAlive)
|
||||||
.setQuery(QueryBuilders.typeQuery(INDEX_ROLE_TYPE))
|
.setQuery(QueryBuilders.typeQuery(INDEX_ROLE_TYPE))
|
||||||
.setSize(scrollSize)
|
.setSize(scrollSize)
|
||||||
|
|
|
@ -119,8 +119,8 @@ public class SecurityClient {
|
||||||
|
|
||||||
/** User Management */
|
/** User Management */
|
||||||
|
|
||||||
public GetUsersRequestBuilder prepareGetUsers() {
|
public GetUsersRequestBuilder prepareGetUsers(String... usernames) {
|
||||||
return new GetUsersRequestBuilder(client);
|
return new GetUsersRequestBuilder(client).usernames(usernames);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getUsers(GetUsersRequest request, ActionListener<GetUsersResponse> listener) {
|
public void getUsers(GetUsersRequest request, ActionListener<GetUsersResponse> listener) {
|
||||||
|
@ -136,7 +136,7 @@ public class SecurityClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public PutUserRequestBuilder preparePutUser(String username, BytesReference source) throws IOException {
|
public PutUserRequestBuilder preparePutUser(String username, BytesReference source) throws IOException {
|
||||||
return new PutUserRequestBuilder(client).username(username).source(source);
|
return new PutUserRequestBuilder(client).source(username, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PutUserRequestBuilder preparePutUser(String username, char[] password, String... roles) {
|
public PutUserRequestBuilder preparePutUser(String username, char[] password, String... roles) {
|
||||||
|
|
|
@ -39,17 +39,23 @@ public class RestGetUsersAction extends BaseRestHandler {
|
||||||
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
|
||||||
String[] usernames = request.paramAsStringArray("username", Strings.EMPTY_ARRAY);
|
String[] usernames = request.paramAsStringArray("username", Strings.EMPTY_ARRAY);
|
||||||
|
|
||||||
new SecurityClient(client).prepareGetUsers().usernames(usernames).execute(new RestBuilderListener<GetUsersResponse>(channel) {
|
new SecurityClient(client).prepareGetUsers(usernames).execute(new RestBuilderListener<GetUsersResponse>(channel) {
|
||||||
@Override
|
@Override
|
||||||
public RestResponse buildResponse(GetUsersResponse getUsersResponse, XContentBuilder builder) throws Exception {
|
public RestResponse buildResponse(GetUsersResponse response, XContentBuilder builder) throws Exception {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
builder.field("found", getUsersResponse.hasUsers());
|
for (User user : response.users()) {
|
||||||
builder.startArray("users");
|
builder.field(user.principal(), user);
|
||||||
for (User user : getUsersResponse.users()) {
|
|
||||||
user.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
|
||||||
}
|
}
|
||||||
builder.endArray();
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
|
|
||||||
|
// if the user asked for specific users, but none of them were found
|
||||||
|
// we'll return an empty result and 404 status code
|
||||||
|
if (usernames.length != 0 && response.users().length == 0) {
|
||||||
|
return new BytesRestResponse(RestStatus.NOT_FOUND, builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// either the user asked for all users, or at least one of the users
|
||||||
|
// was found
|
||||||
return new BytesRestResponse(RestStatus.OK, builder);
|
return new BytesRestResponse(RestStatus.OK, builder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class ClearRolesCacheTests extends ShieldIntegTestCase {
|
||||||
logger.debug("--> created role [{}]", role);
|
logger.debug("--> created role [{}]", role);
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
|
|
||||||
// warm up the caches on every node
|
// warm up the caches on every node
|
||||||
for (ESNativeRolesStore rolesStore : internalCluster().getInstances(ESNativeRolesStore.class)) {
|
for (ESNativeRolesStore rolesStore : internalCluster().getInstances(ESNativeRolesStore.class)) {
|
||||||
|
@ -134,7 +134,7 @@ public class ClearRolesCacheTests extends ShieldIntegTestCase {
|
||||||
List<String> toModify = randomSubsetOf(modifiedRolesCount, roles);
|
List<String> toModify = randomSubsetOf(modifiedRolesCount, roles);
|
||||||
logger.debug("--> modifying roles {} to have run_as", toModify);
|
logger.debug("--> modifying roles {} to have run_as", toModify);
|
||||||
for (String role : toModify) {
|
for (String role : toModify) {
|
||||||
UpdateResponse response = client.prepareUpdate().setId(role).setIndex(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME)
|
UpdateResponse response = client.prepareUpdate().setId(role).setIndex(ShieldTemplateService.SECURITY_INDEX_NAME)
|
||||||
.setType(ESNativeRolesStore.INDEX_ROLE_TYPE)
|
.setType(ESNativeRolesStore.INDEX_ROLE_TYPE)
|
||||||
.setDoc("run_as", new String[] { role })
|
.setDoc("run_as", new String[] { role })
|
||||||
.get();
|
.get();
|
||||||
|
@ -177,7 +177,7 @@ public class ClearRolesCacheTests extends ShieldIntegTestCase {
|
||||||
List<RoleDescriptor> foundRoles = securityClient.prepareGetRoles().names(role).get().roles();
|
List<RoleDescriptor> foundRoles = securityClient.prepareGetRoles().names(role).get().roles();
|
||||||
assertThat(foundRoles.size(), is(1));
|
assertThat(foundRoles.size(), is(1));
|
||||||
logger.debug("--> deleting role [{}]", role);
|
logger.debug("--> deleting role [{}]", role);
|
||||||
DeleteResponse response = client.prepareDelete(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME,
|
DeleteResponse response = client.prepareDelete(ShieldTemplateService.SECURITY_INDEX_NAME,
|
||||||
ESNativeRolesStore.INDEX_ROLE_TYPE, role).get();
|
ESNativeRolesStore.INDEX_ROLE_TYPE, role).get();
|
||||||
assertThat(response.isFound(), is(true));
|
assertThat(response.isFound(), is(true));
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
|
|
||||||
public void testGettingUserThatDoesntExist() throws Exception {
|
public void testGettingUserThatDoesntExist() throws Exception {
|
||||||
SecurityClient c = securityClient();
|
SecurityClient c = securityClient();
|
||||||
GetUsersResponse resp = c.prepareGetUsers().usernames("joe").get();
|
GetUsersResponse resp = c.prepareGetUsers("joe").get();
|
||||||
assertFalse("user should not exist", resp.hasUsers());
|
assertFalse("user should not exist", resp.hasUsers());
|
||||||
GetRolesResponse resp2 = c.prepareGetRoles().names("role").get();
|
GetRolesResponse resp2 = c.prepareGetRoles().names("role").get();
|
||||||
assertFalse("role should not exist", resp2.isExists());
|
assertFalse("role should not exist", resp2.isExists());
|
||||||
|
@ -63,9 +63,9 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
logger.error("--> creating user");
|
logger.error("--> creating user");
|
||||||
c.preparePutUser("joe", "s3kirt".toCharArray(), "role1", "user").get();
|
c.preparePutUser("joe", "s3kirt".toCharArray(), "role1", "user").get();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
logger.info("--> retrieving user");
|
logger.info("--> retrieving user");
|
||||||
GetUsersResponse resp = c.prepareGetUsers().usernames("joe").get();
|
GetUsersResponse resp = c.prepareGetUsers("joe").get();
|
||||||
assertTrue("user should exist", resp.hasUsers());
|
assertTrue("user should exist", resp.hasUsers());
|
||||||
User joe = resp.users()[0];
|
User joe = resp.users()[0];
|
||||||
assertEquals(joe.principal(), "joe");
|
assertEquals(joe.principal(), "joe");
|
||||||
|
@ -86,7 +86,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
CollectionUtil.timSort(names);
|
CollectionUtil.timSort(names);
|
||||||
assertArrayEquals(new String[] { "joe", "joe2", "joe3" }, names.toArray(Strings.EMPTY_ARRAY));
|
assertArrayEquals(new String[] { "joe", "joe2", "joe3" }, names.toArray(Strings.EMPTY_ARRAY));
|
||||||
|
|
||||||
GetUsersResponse someUsersResp = c.prepareGetUsers().usernames("joe", "joe3").get();
|
GetUsersResponse someUsersResp = c.prepareGetUsers("joe", "joe3").get();
|
||||||
assertTrue("users should exist", someUsersResp.hasUsers());
|
assertTrue("users should exist", someUsersResp.hasUsers());
|
||||||
assertEquals("should be 2 users returned", 2, someUsersResp.users().length);
|
assertEquals("should be 2 users returned", 2, someUsersResp.users().length);
|
||||||
names = new ArrayList<>(2);
|
names = new ArrayList<>(2);
|
||||||
|
@ -100,7 +100,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
DeleteUserResponse delResp = c.prepareDeleteUser("joe").get();
|
DeleteUserResponse delResp = c.prepareDeleteUser("joe").get();
|
||||||
assertTrue(delResp.found());
|
assertTrue(delResp.found());
|
||||||
logger.info("--> retrieving user");
|
logger.info("--> retrieving user");
|
||||||
resp = c.prepareGetUsers().usernames("joe").get();
|
resp = c.prepareGetUsers("joe").get();
|
||||||
assertFalse("user should not exist after being deleted", resp.hasUsers());
|
assertFalse("user should not exist after being deleted", resp.hasUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
new String[]{"body", "title"}, new BytesArray("{\"query\": {\"match_all\": {}}}"))
|
new String[]{"body", "title"}, new BytesArray("{\"query\": {\"match_all\": {}}}"))
|
||||||
.get();
|
.get();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
logger.info("--> retrieving role");
|
logger.info("--> retrieving role");
|
||||||
GetRolesResponse resp = c.prepareGetRoles().names("test_role").get();
|
GetRolesResponse resp = c.prepareGetRoles().names("test_role").get();
|
||||||
assertTrue("role should exist", resp.isExists());
|
assertTrue("role should exist", resp.isExists());
|
||||||
|
@ -167,9 +167,9 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
||||||
refresh();
|
refresh();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
logger.info("--> retrieving user");
|
logger.info("--> retrieving user");
|
||||||
GetUsersResponse resp = c.prepareGetUsers().usernames("joe").get();
|
GetUsersResponse resp = c.prepareGetUsers("joe").get();
|
||||||
assertTrue("user should exist", resp.hasUsers());
|
assertTrue("user should exist", resp.hasUsers());
|
||||||
|
|
||||||
createIndex("idx");
|
createIndex("idx");
|
||||||
|
@ -189,9 +189,9 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
c.preparePutUser("joe", "s3krit".toCharArray(), ShieldSettingsSource.DEFAULT_ROLE).get();
|
c.preparePutUser("joe", "s3krit".toCharArray(), ShieldSettingsSource.DEFAULT_ROLE).get();
|
||||||
refresh();
|
refresh();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
logger.info("--> retrieving user");
|
logger.info("--> retrieving user");
|
||||||
GetUsersResponse resp = c.prepareGetUsers().usernames("joe").get();
|
GetUsersResponse resp = c.prepareGetUsers("joe").get();
|
||||||
assertTrue("user should exist", resp.hasUsers());
|
assertTrue("user should exist", resp.hasUsers());
|
||||||
assertThat(resp.users()[0].roles(), arrayContaining(ShieldSettingsSource.DEFAULT_ROLE));
|
assertThat(resp.users()[0].roles(), arrayContaining(ShieldSettingsSource.DEFAULT_ROLE));
|
||||||
|
|
||||||
|
@ -225,9 +225,9 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
c.preparePutUser("joe", "s3krit".toCharArray(), ShieldSettingsSource.DEFAULT_ROLE).get();
|
c.preparePutUser("joe", "s3krit".toCharArray(), ShieldSettingsSource.DEFAULT_ROLE).get();
|
||||||
refresh();
|
refresh();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
logger.info("--> retrieving user");
|
logger.info("--> retrieving user");
|
||||||
GetUsersResponse resp = c.prepareGetUsers().usernames("joe").get();
|
GetUsersResponse resp = c.prepareGetUsers("joe").get();
|
||||||
assertTrue("user should exist", resp.hasUsers());
|
assertTrue("user should exist", resp.hasUsers());
|
||||||
assertThat(resp.users()[0].roles(), arrayContaining(ShieldSettingsSource.DEFAULT_ROLE));
|
assertThat(resp.users()[0].roles(), arrayContaining(ShieldSettingsSource.DEFAULT_ROLE));
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
||||||
refresh();
|
refresh();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
|
|
||||||
if (authenticate) {
|
if (authenticate) {
|
||||||
final String token = basicAuthHeaderValue("joe", new SecuredString("s3krit".toCharArray()));
|
final String token = basicAuthHeaderValue("joe", new SecuredString("s3krit".toCharArray()));
|
||||||
|
@ -311,7 +311,7 @@ public class ESNativeTests extends ShieldIntegTestCase {
|
||||||
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
c.preparePutUser("joe", "s3krit".toCharArray(), "test_role").get();
|
||||||
refresh();
|
refresh();
|
||||||
logger.error("--> waiting for .shield index");
|
logger.error("--> waiting for .shield index");
|
||||||
ensureGreen(ShieldTemplateService.SHIELD_ADMIN_INDEX_NAME);
|
ensureGreen(ShieldTemplateService.SECURITY_INDEX_NAME);
|
||||||
|
|
||||||
final String token = basicAuthHeaderValue("joe", new SecuredString("s3krit".toCharArray()));
|
final String token = basicAuthHeaderValue("joe", new SecuredString("s3krit".toCharArray()));
|
||||||
ClusterHealthResponse response = client().filterWithHeader(Collections.singletonMap("Authorization", token)).admin().cluster()
|
ClusterHealthResponse response = client().filterWithHeader(Collections.singletonMap("Authorization", token)).admin().cluster()
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
"paths": [ "/_shield/user/{username}" ],
|
"paths": [ "/_shield/user/{username}" ],
|
||||||
"parts": {
|
"parts": {
|
||||||
"username": {
|
"username": {
|
||||||
"type" : "string",
|
"type" : "list",
|
||||||
"description" : "The username of the User",
|
"description" : "A comma-separated list of usernames",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
username: "joe"
|
username: "joe"
|
||||||
body: >
|
body: >
|
||||||
{
|
{
|
||||||
"username" : "joe",
|
|
||||||
"password" : "s3krit",
|
"password" : "s3krit",
|
||||||
"roles" : [ "admin" ],
|
"roles" : [ "admin" ],
|
||||||
"full_name" : "Bazooka Joe",
|
"full_name" : "Bazooka Joe",
|
||||||
|
@ -33,10 +32,9 @@
|
||||||
- do:
|
- do:
|
||||||
shield.get_user:
|
shield.get_user:
|
||||||
username: "joe"
|
username: "joe"
|
||||||
- match: { found: true }
|
- match: { joe.username: "joe" }
|
||||||
- match: { users.0.username: "joe" }
|
- match: { joe.roles.0: "admin" }
|
||||||
- match: { users.0.roles.0: "admin" }
|
- match: { joe.full_name: "Bazooka Joe" }
|
||||||
- match: { users.0.full_name: "Bazooka Joe" }
|
- match: { joe.email: "joe@bazooka.gum" }
|
||||||
- match: { users.0.email: "joe@bazooka.gum" }
|
- match: { joe.metadata.key1: "val1" }
|
||||||
- match: { users.0.metadata.key1: "val1" }
|
- match: { joe.metadata.key2: "val2" }
|
||||||
- match: { users.0.metadata.key2: "val2" }
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
username: "joe"
|
username: "joe"
|
||||||
body: >
|
body: >
|
||||||
{
|
{
|
||||||
"username": "joe",
|
|
||||||
"password": "s3krit",
|
"password": "s3krit",
|
||||||
"roles" : [ "admin" ]
|
"roles" : [ "admin" ]
|
||||||
}
|
}
|
||||||
|
@ -21,9 +20,8 @@
|
||||||
- do:
|
- do:
|
||||||
shield.get_user:
|
shield.get_user:
|
||||||
username: "joe"
|
username: "joe"
|
||||||
- match: { found: true }
|
- match: { joe.username: "joe" }
|
||||||
- match: { users.0.username: "joe" }
|
- match: { joe.roles.0: "admin" }
|
||||||
- match: { users.0.roles.0: "admin" }
|
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
headers:
|
headers:
|
||||||
|
@ -36,7 +34,6 @@
|
||||||
username: "joe"
|
username: "joe"
|
||||||
body: >
|
body: >
|
||||||
{
|
{
|
||||||
"username" : "joe",
|
|
||||||
"password" : "s3krit2",
|
"password" : "s3krit2",
|
||||||
"roles" : [ "admin", "foo" ],
|
"roles" : [ "admin", "foo" ],
|
||||||
"full_name" : "Bazooka Joe",
|
"full_name" : "Bazooka Joe",
|
||||||
|
@ -51,14 +48,13 @@
|
||||||
- do:
|
- do:
|
||||||
shield.get_user:
|
shield.get_user:
|
||||||
username: "joe"
|
username: "joe"
|
||||||
- match: { found: true }
|
- match: { joe.username: "joe" }
|
||||||
- match: { users.0.username: "joe" }
|
- match: { joe.roles.0: "admin" }
|
||||||
- match: { users.0.roles.0: "admin" }
|
- match: { joe.roles.1: "foo" }
|
||||||
- match: { users.0.roles.1: "foo" }
|
- match: { joe.full_name: "Bazooka Joe" }
|
||||||
- match: { users.0.full_name: "Bazooka Joe" }
|
- match: { joe.email: "joe@bazooka.gum" }
|
||||||
- match: { users.0.email: "joe@bazooka.gum" }
|
- match: { joe.metadata.key1: "val1" }
|
||||||
- match: { users.0.metadata.key1: "val1" }
|
- match: { joe.metadata.key2: "val2" }
|
||||||
- match: { users.0.metadata.key2: "val2" }
|
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
headers:
|
headers:
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
"Get missing user":
|
||||||
|
- do:
|
||||||
|
catch: missing
|
||||||
|
shield.get_user:
|
||||||
|
username: 'foo'
|
||||||
|
|
||||||
|
---
|
||||||
|
"Get missing (multiple) users":
|
||||||
|
- do:
|
||||||
|
catch: missing
|
||||||
|
shield.get_user:
|
||||||
|
username: [ 'foo', 'bar' ]
|
Loading…
Reference in New Issue