Skip to content

Commit

Permalink
[HLRC] Add support for get application privileges API (#35556)
Browse files Browse the repository at this point in the history
This commits adds support for the Get Application Privileges
API to the HLRC

Relates: #29827
  • Loading branch information
jkakavas committed Nov 21, 2018
1 parent 48f9c0d commit cedd02b
Show file tree
Hide file tree
Showing 12 changed files with 972 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EmptyResponse;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.GetPrivilegesRequest;
import org.elasticsearch.client.security.GetPrivilegesResponse;
import org.elasticsearch.client.security.GetRoleMappingsRequest;
import org.elasticsearch.client.security.GetRoleMappingsResponse;
import org.elasticsearch.client.security.GetSslCertificatesRequest;
Expand Down Expand Up @@ -505,10 +507,47 @@ public void invalidateTokenAsync(InvalidateTokenRequest request, RequestOptions
InvalidateTokenResponse::fromXContent, listener, emptySet());
}

/**
* Synchronously get application privilege(s).
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-privileges.html">
* the docs</a> for more.
*
* @param request {@link GetPrivilegesRequest} with the application name and the privilege name.
* If no application name is provided, information about all privileges for all applications is retrieved.
* If no privilege name is provided, information about all privileges of the specified application is retrieved.
* @param options the request options (e.g. headers), use
* {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the get privileges call
* @throws IOException in case there is a problem sending the request or
* parsing back the response
*/
public GetPrivilegesResponse getPrivileges(final GetPrivilegesRequest request, final RequestOptions options) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::getPrivileges,
options, GetPrivilegesResponse::fromXContent, emptySet());
}

/**
* Asynchronously get application privilege(s).
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-privileges.html">
* the docs</a> for more.
*
* @param request {@link GetPrivilegesRequest} with the application name and the privilege name.
* If no application name is provided, information about all privileges for all applications is retrieved.
* If no privilege name is provided, information about all privileges of the specified application is retrieved.
* @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 getPrivilegesAsync(final GetPrivilegesRequest request, final RequestOptions options,
final ActionListener<GetPrivilegesResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::getPrivileges,
options, GetPrivilegesResponse::fromXContent, listener, emptySet());
}

/**
* Removes application privilege(s)
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-privilege.html">
* the docs</a> for more.
*
* @param request the request with the application privilege to delete
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
* @return the response from the delete application privilege call
Expand All @@ -523,12 +562,13 @@ public DeletePrivilegesResponse deletePrivileges(DeletePrivilegesRequest request
* Asynchronously removes an application privilege
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-privilege.html">
* the docs</a> for more.
* @param request the request with the application privilege to delete
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
*
* @param request the request with the application privilege to delete
* @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 deletePrivilegesAsync(DeletePrivilegesRequest request, RequestOptions options,
ActionListener<DeletePrivilegesResponse> listener) {
ActionListener<DeletePrivilegesResponse> listener) {
restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::deletePrivileges, options,
DeletePrivilegesResponse::fromXContent, listener, singleton(404));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@
import org.elasticsearch.client.security.ClearRolesCacheRequest;
import org.elasticsearch.client.security.CreateTokenRequest;
import org.elasticsearch.client.security.DeletePrivilegesRequest;
import org.elasticsearch.client.security.GetPrivilegesRequest;
import org.elasticsearch.client.security.DeleteRoleMappingRequest;
import org.elasticsearch.client.security.DeleteRoleRequest;
import org.elasticsearch.client.security.InvalidateTokenRequest;
import org.elasticsearch.client.security.PutRoleMappingRequest;
import org.elasticsearch.client.security.HasPrivilegesRequest;
import org.elasticsearch.client.security.DisableUserRequest;
import org.elasticsearch.client.security.EnableUserRequest;
import org.elasticsearch.client.security.GetRoleMappingsRequest;
import org.elasticsearch.client.security.InvalidateTokenRequest;
import org.elasticsearch.client.security.PutRoleMappingRequest;
import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.SetUserEnabledRequest;
import org.elasticsearch.common.Strings;
Expand Down Expand Up @@ -181,6 +182,15 @@ static Request invalidateToken(InvalidateTokenRequest invalidateTokenRequest) th
return request;
}

static Request getPrivileges(GetPrivilegesRequest getPrivilegesRequest) {
String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_xpack/security/privilege")
.addPathPart(getPrivilegesRequest.getApplicationName())
.addCommaSeparatedPathParts(getPrivilegesRequest.getPrivilegeNames())
.build();
return new Request(HttpGet.METHOD_NAME, endpoint);
}

static Request deletePrivileges(DeletePrivilegesRequest deletePrivilegeRequest) {
String endpoint = new RequestConverters.EndpointBuilder()
.addPathPartAsIs("_xpack/security/privilege")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.util.CollectionUtils;

import java.util.Arrays;
import java.util.Objects;

/**
* Request object to get application privilege(s)
*/
public final class GetPrivilegesRequest implements Validatable {
private final String applicationName;
private final String[] privilegeNames;

public GetPrivilegesRequest(@Nullable final String applicationName, @Nullable final String... privilegeNames) {
if ((CollectionUtils.isEmpty(privilegeNames) == false) && Strings.isNullOrEmpty(applicationName)) {
throw new IllegalArgumentException("privilege cannot be specified when application is missing");
}
this.applicationName = applicationName;
this.privilegeNames = privilegeNames;
}

/**
* Constructs a {@link GetPrivilegesRequest} to request all the privileges defined for all applications
*/
public static GetPrivilegesRequest getAllPrivileges() {
return new GetPrivilegesRequest(null);
}

/**
* Constructs a {@link GetPrivilegesRequest} to request all the privileges defined for the specified {@code applicationName}
*
* @param applicationName the name of the application for which the privileges are requested
*/
public static GetPrivilegesRequest getApplicationPrivileges(String applicationName) {
if (Strings.isNullOrEmpty(applicationName)) {
throw new IllegalArgumentException("application name is required");
}
return new GetPrivilegesRequest(applicationName);
}

/**
* @return the name of the application for which to return certain privileges
*/
public String getApplicationName() {
return applicationName;
}

/**
* @return an array of privilege names to return or null if all should be returned
*/
public String[] getPrivilegeNames() {
return privilegeNames;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GetPrivilegesRequest that = (GetPrivilegesRequest) o;
return Objects.equals(applicationName, that.applicationName) &&
Arrays.equals(privilegeNames, that.privilegeNames);
}

@Override
public int hashCode() {
int result = Objects.hash(applicationName);
result = 31 * result + Arrays.hashCode(privilegeNames);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -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.security.user.privileges.ApplicationPrivilege;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParserUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
* Get application privileges response
*/
public final class GetPrivilegesResponse {

private Set<ApplicationPrivilege> privileges;

public Set<ApplicationPrivilege> getPrivileges() {
return privileges;
}

public GetPrivilegesResponse(Collection<ApplicationPrivilege> privileges) {
this.privileges = Collections.unmodifiableSet(new HashSet<>(privileges));
}

public static GetPrivilegesResponse fromXContent(XContentParser parser) throws IOException {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
List<ApplicationPrivilege> privileges = new ArrayList<>();
XContentParser.Token token;
while ((token = parser.nextToken()) != null) {
if (token == XContentParser.Token.FIELD_NAME) {
XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser::getTokenLocation);
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
privileges.add(ApplicationPrivilege.PARSER.parse(parser, null));
}
}
}
return new GetPrivilegesResponse(new HashSet<>(privileges));
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GetPrivilegesResponse that = (GetPrivilegesResponse) o;
return Objects.equals(privileges, that.privileges);
}

@Override
public int hashCode() {
return Objects.hash(privileges);
}
}
Loading

0 comments on commit cedd02b

Please sign in to comment.