org.elasticsearch.client.security.user.privileges.AbstractIndicesPrivileges Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch-rest-high-level-client Show documentation
Show all versions of elasticsearch-rest-high-level-client Show documentation
Elasticsearch subproject :client:rest-high-level
/*
* 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.user.privileges;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.xcontent.ConstructingObjectParser;
import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import static org.elasticsearch.xcontent.ConstructingObjectParser.optionalConstructorArg;
public abstract class AbstractIndicesPrivileges {
static final ParseField NAMES = new ParseField("names");
static final ParseField ALLOW_RESTRICTED_INDICES = new ParseField("allow_restricted_indices");
static final ParseField PRIVILEGES = new ParseField("privileges");
static final ParseField FIELD_PERMISSIONS = new ParseField("field_security");
static final ParseField QUERY = new ParseField("query");
protected final Set indices;
protected final Set privileges;
protected final boolean allowRestrictedIndices;
AbstractIndicesPrivileges(Collection indices, Collection privileges, boolean allowRestrictedIndices) {
if (null == indices || indices.isEmpty()) {
throw new IllegalArgumentException("indices privileges must refer to at least one index name or index name pattern");
}
if (null == privileges || privileges.isEmpty()) {
throw new IllegalArgumentException("indices privileges must define at least one privilege");
}
this.indices = Collections.unmodifiableSet(new HashSet<>(indices));
this.privileges = Collections.unmodifiableSet(new HashSet<>(privileges));
this.allowRestrictedIndices = allowRestrictedIndices;
}
/**
* The indices names covered by the privileges.
*/
public Set getIndices() {
return this.indices;
}
/**
* The privileges acting over indices. There is a canonical predefined set of
* such privileges, but the {@code String} datatype allows for flexibility in defining
* finer grained privileges.
*/
public Set getPrivileges() {
return this.privileges;
}
/**
* True if the privileges cover restricted internal indices too. Certain indices are reserved for internal services and should be
* transparent to ordinary users. For that matter, when granting privileges, you also have to toggle this flag to confirm that all
* indices, including restricted ones, are in the scope of this permission. By default this is false.
*/
public boolean allowRestrictedIndices() {
return this.allowRestrictedIndices;
}
/**
* If {@code true} some documents might not be visible. Only the documents
* matching {@code query} will be readable.
*/
public abstract boolean isUsingDocumentLevelSecurity();
/**
* If {@code true} some document fields might not be visible.
*/
public abstract boolean isUsingFieldLevelSecurity();
public static class FieldSecurity implements ToXContentObject {
static final ParseField GRANT_FIELDS = new ParseField("grant");
static final ParseField EXCEPT_FIELDS = new ParseField("except");
private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
FIELD_PERMISSIONS.getPreferredName(),
true,
FieldSecurity::buildObjectFromParserArgs
);
@SuppressWarnings("unchecked")
private static FieldSecurity buildObjectFromParserArgs(Object[] args) {
return new FieldSecurity((Collection) args[0], (Collection) args[1]);
}
static {
PARSER.declareStringArray(optionalConstructorArg(), GRANT_FIELDS);
PARSER.declareStringArray(optionalConstructorArg(), EXCEPT_FIELDS);
}
static FieldSecurity parse(XContentParser parser, Void context) throws IOException {
return PARSER.parse(parser, context);
}
// null or singleton '*' means all fields are granted, empty means no fields are granted
private final Set grantedFields;
// null or empty means no fields are denied
private final Set deniedFields;
FieldSecurity(Collection grantedFields, Collection deniedFields) {
// unspecified granted fields means no restriction
this.grantedFields = grantedFields == null ? null : Collections.unmodifiableSet(new HashSet<>(grantedFields));
// unspecified denied fields means no restriction
this.deniedFields = deniedFields == null ? null : Collections.unmodifiableSet(new HashSet<>(deniedFields));
}
/**
* The document fields that can be read or queried. Can be null, in this case
* all the document's fields are granted access to. Can also be empty, in which
* case no fields are granted access to.
*/
public Set getGrantedFields() {
return grantedFields;
}
/**
* The document fields that cannot be accessed or queried. Can be null or empty,
* in which case no fields are denied.
*/
public Set getDeniedFields() {
return deniedFields;
}
public boolean isUsingFieldLevelSecurity() {
return limitsGrantedFields() || hasDeniedFields();
}
private boolean hasDeniedFields() {
return deniedFields != null && false == deniedFields.isEmpty();
}
private boolean limitsGrantedFields() {
// we treat just '*' as no FLS since that's what the UI defaults to
if (grantedFields == null || (grantedFields.size() == 1 && grantedFields.iterator().next().equals("*"))) {
return false;
}
return true;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (grantedFields == null) {
// The role parser will reject a field_security object that doesn't have a "granted" field
builder.field(GRANT_FIELDS.getPreferredName(), Collections.singletonList("*"));
} else {
builder.field(GRANT_FIELDS.getPreferredName(), grantedFields);
}
if (deniedFields != null) {
builder.field(EXCEPT_FIELDS.getPreferredName(), deniedFields);
}
return builder.endObject();
}
@Override
public String toString() {
try {
return XContentHelper.toXContent(this, XContentType.JSON, true).utf8ToString();
} catch (IOException e) {
throw new UncheckedIOException("Unexpected", e);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final FieldSecurity that = (FieldSecurity) o;
return Objects.equals(this.grantedFields, that.grantedFields) && Objects.equals(this.deniedFields, that.deniedFields);
}
@Override
public int hashCode() {
return Objects.hash(grantedFields, deniedFields);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy