Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
import org.elasticsearch.client.security.PutRoleResponse;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.PutUserResponse;
import org.elasticsearch.client.security.QueryApiKeyRequest;
import org.elasticsearch.client.security.QueryApiKeyResponse;

import java.io.IOException;

Expand Down Expand Up @@ -1050,7 +1052,7 @@ public Cancellable createApiKeyAsync(final CreateApiKeyRequest request, final Re
*
* @param request the request to retrieve API key(s)
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the create API key call
* @return the response from the get API key call
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public GetApiKeyResponse getApiKey(final GetApiKeyRequest request, final RequestOptions options) throws IOException {
Expand Down Expand Up @@ -1137,6 +1139,37 @@ public Cancellable grantApiKeyAsync(final GrantApiKeyRequest request, final Requ
CreateApiKeyResponse::fromXContent, listener, emptySet());
}

/**
* Query and retrieve API Key(s) information.<br>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-query-api-key.html">
* the docs</a> for more.
*
* @param request the request to query and retrieve API key(s)
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the query API key call
* @throws IOException in case there is a problem sending the request or parsing back the response
*/
public QueryApiKeyResponse queryApiKey(final QueryApiKeyRequest request, final RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::queryApiKey, options,
QueryApiKeyResponse::fromXContent, emptySet());
}

/**
* Asynchronously query and retrieve API Key(s) information.<br>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-query-api-key.html">
* the docs</a> for more.
*
* @param request the request to query and retrieve API key(s)
* @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
* @return cancellable that may be used to cancel the request
*/
public Cancellable queryApiKeyAsync(final QueryApiKeyRequest request, final RequestOptions options,
final ActionListener<QueryApiKeyResponse> listener) {
return restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::queryApiKey, options,
QueryApiKeyResponse::fromXContent, listener, emptySet());
}

/**
* Get a service account, or list of service accounts synchronously.
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-service-accounts.html">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.elasticsearch.client.security.PutRoleMappingRequest;
import org.elasticsearch.client.security.PutRoleRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.QueryApiKeyRequest;
import org.elasticsearch.client.security.SetUserEnabledRequest;
import org.elasticsearch.common.Strings;

Expand Down Expand Up @@ -346,6 +347,12 @@ static Request invalidateApiKey(final InvalidateApiKeyRequest invalidateApiKeyRe
return request;
}

static Request queryApiKey(final QueryApiKeyRequest queryApiKeyRequest) throws IOException {
final Request request = new Request(HttpGet.METHOD_NAME, "/_security/_query/api_key");
request.setEntity(createEntity(queryApiKeyRequest, REQUEST_BODY_CONTENT_TYPE));
return request;
}

static Request getServiceAccounts(final GetServiceAccountsRequest getServiceAccountsRequest) {
final RequestConverters.EndpointBuilder endpointBuilder = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_security/service");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.client.security;

import org.elasticsearch.client.Validatable;
import org.elasticsearch.client.ValidationException;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.searchafter.SearchAfterBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

public final class QueryApiKeyRequest implements Validatable, ToXContentObject {

@Nullable
private QueryBuilder queryBuilder;
private Integer from;
private Integer size;
@Nullable
private List<FieldSortBuilder> fieldSortBuilders;
@Nullable
private SearchAfterBuilder searchAfterBuilder;

public QueryApiKeyRequest() {
this(null, null, null, null, null);
}

public QueryApiKeyRequest(
@Nullable QueryBuilder queryBuilder,
@Nullable Integer from,
@Nullable Integer size,
@Nullable List<FieldSortBuilder> fieldSortBuilders,
@Nullable SearchAfterBuilder searchAfterBuilder) {
this.queryBuilder = queryBuilder;
this.from = from;
this.size = size;
this.fieldSortBuilders = fieldSortBuilders;
this.searchAfterBuilder = searchAfterBuilder;
}

public QueryBuilder getQueryBuilder() {
return queryBuilder;
}

public int getFrom() {
return from;
}

public int getSize() {
return size;
}

public List<FieldSortBuilder> getFieldSortBuilders() {
return fieldSortBuilders;
}

public SearchAfterBuilder getSearchAfterBuilder() {
return searchAfterBuilder;
}

public QueryApiKeyRequest queryBuilder(QueryBuilder queryBuilder) {
this.queryBuilder = queryBuilder;
return this;
}

public QueryApiKeyRequest from(int from) {
this.from = from;
return this;
}

public QueryApiKeyRequest size(int size) {
this.size = size;
return this;
}

public QueryApiKeyRequest fieldSortBuilders(List<FieldSortBuilder> fieldSortBuilders) {
this.fieldSortBuilders = fieldSortBuilders;
return this;
}

public QueryApiKeyRequest searchAfterBuilder(SearchAfterBuilder searchAfterBuilder) {
this.searchAfterBuilder = searchAfterBuilder;
return this;
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (queryBuilder != null) {
builder.field("query");
queryBuilder.toXContent(builder, params);
}
if (from != null) {
builder.field("from", from);
}
if (size != null) {
builder.field("size", size);
}
if (fieldSortBuilders != null && false == fieldSortBuilders.isEmpty()) {
builder.field("sort", fieldSortBuilders);
}
if (searchAfterBuilder != null) {
builder.array(SearchAfterBuilder.SEARCH_AFTER.getPreferredName(), searchAfterBuilder.getSortValues());
}
return builder.endObject();
}

@Override
public Optional<ValidationException> validate() {
ValidationException validationException = null;
if (from != null && from < 0) {
validationException = addValidationError(validationException, "from must be non-negative");
}
if (size != null && size < 0) {
validationException = addValidationError(validationException, "size must be non-negative");
}
return validationException == null ? Optional.empty() : Optional.of(validationException);
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
QueryApiKeyRequest that = (QueryApiKeyRequest) o;
return Objects.equals(queryBuilder, that.queryBuilder) && Objects.equals(from, that.from) && Objects.equals(
size,
that.size) && Objects.equals(fieldSortBuilders, that.fieldSortBuilders) && Objects.equals(
searchAfterBuilder,
that.searchAfterBuilder);
}

@Override
public int hashCode() {
return Objects.hash(queryBuilder, from, size, fieldSortBuilders, searchAfterBuilder);
}

private ValidationException addValidationError(ValidationException validationException, String message) {
if (validationException == null) {
validationException = new ValidationException();
}
validationException.addValidationError(message);
return validationException;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.client.security;

import org.elasticsearch.client.security.support.ApiKey;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ParseField;
import org.elasticsearch.common.xcontent.XContentParser;

import java.io.IOException;
import java.util.List;

import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;

public final class QueryApiKeyResponse {

private final long total;
private final List<ApiKey> apiKeys;

public QueryApiKeyResponse(long total, List<ApiKey> apiKeys) {
this.total = total;
this.apiKeys = apiKeys;
}

public long getTotal() {
return total;
}

public int getCount() {
return apiKeys.size();
}

public List<ApiKey> getApiKeys() {
return apiKeys;
}

public static QueryApiKeyResponse fromXContent(XContentParser parser) throws IOException {
return PARSER.parse(parser, null);
}

static final ConstructingObjectParser<QueryApiKeyResponse, Void> PARSER = new ConstructingObjectParser<>(
"query_api_key_response",
args -> {
final long total = (long) args[0];
final int count = (int) args[1];
@SuppressWarnings("unchecked")
final List<ApiKey> items = (List<ApiKey>) args[2];
if (count != items.size()) {
throw new IllegalArgumentException("count [" + count + "] is not equal to number of items ["
+ items.size() + "]");
}
return new QueryApiKeyResponse(total, items);
}
);

static {
PARSER.declareLong(constructorArg(), new ParseField("total"));
PARSER.declareInt(constructorArg(), new ParseField("count"));
PARSER.declareObjectArray(optionalConstructorArg(), (p, c) -> ApiKey.fromXContent(p), new ParseField("api_keys"));
}
}
Loading