Fixed build failure related to security roles APIs

- roles are now reliably parsed
- in `Put Role` API, added a double check to verify that the role name in the URL matches the role name if the body. Also, if the body doesn't have a role name, the role name in the URL will be used.

Original commit: elastic/x-pack-elasticsearch@5054ce8567
This commit is contained in:
uboness 2016-02-25 01:15:15 -08:00
parent 8ff6b93a3c
commit 266bf09437
8 changed files with 127 additions and 126 deletions

View File

@ -8,7 +8,6 @@ package org.elasticsearch.shield.action.role;
import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException; import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
@ -18,7 +17,7 @@ import org.elasticsearch.shield.authz.RoleDescriptor;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Arrays;
import java.util.List; import java.util.List;
import static org.elasticsearch.action.ValidateActions.addValidationError; import static org.elasticsearch.action.ValidateActions.addValidationError;
@ -29,19 +28,13 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
public class PutRoleRequest extends ActionRequest<PutRoleRequest> implements ToXContent { public class PutRoleRequest extends ActionRequest<PutRoleRequest> implements ToXContent {
private String name; private String name;
private List<String> clusterPriv; private String[] clusterPrivileges;
// List of index names to privileges private List<RoleDescriptor.IndicesPrivileges> indicesPrivileges = new ArrayList<>();
private List<RoleDescriptor.IndicesPrivileges> indices = new ArrayList<>(); private String[] runAs;
private List<String> runAs = new ArrayList<>();
private RoleDescriptor roleDescriptor;
public PutRoleRequest() { public PutRoleRequest() {
} }
public PutRoleRequest(BytesReference source) throws Exception {
this.roleDescriptor = RoleDescriptor.source(source);
}
@Override @Override
public ActionRequestValidationException validate() { public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null; ActionRequestValidationException validationException = null;
@ -51,20 +44,24 @@ public class PutRoleRequest extends ActionRequest<PutRoleRequest> implements ToX
return validationException; return validationException;
} }
public void source(String name, BytesReference source) throws Exception {
RoleDescriptor descriptor = RoleDescriptor.source(name, source);
this.name = descriptor.getName();
this.clusterPrivileges = descriptor.getClusterPrivileges();
this.indicesPrivileges = Arrays.asList(descriptor.getIndicesPrivileges());
this.runAs = descriptor.getRunAs();
}
public void name(String name) { public void name(String name) {
this.name = name; this.name = name;
} }
public void cluster(String clusterPrivilege) { public void cluster(String... clusterPrivileges) {
this.clusterPriv = Collections.singletonList(clusterPrivilege); this.clusterPrivileges = clusterPrivileges;
}
public void cluster(List<String> clusterPrivileges) {
this.clusterPriv = clusterPrivileges;
} }
public void addIndex(String[] indices, String[] privileges, @Nullable String[] fields, @Nullable BytesReference query) { public void addIndex(String[] indices, String[] privileges, @Nullable String[] fields, @Nullable BytesReference query) {
this.indices.add(RoleDescriptor.IndicesPrivileges.builder() this.indicesPrivileges.add(RoleDescriptor.IndicesPrivileges.builder()
.indices(indices) .indices(indices)
.privileges(privileges) .privileges(privileges)
.fields(fields) .fields(fields)
@ -72,7 +69,7 @@ public class PutRoleRequest extends ActionRequest<PutRoleRequest> implements ToX
.build()); .build());
} }
public void runAs(List<String> usernames) { public void runAs(String... usernames) {
this.runAs = usernames; this.runAs = usernames;
} }
@ -80,72 +77,46 @@ public class PutRoleRequest extends ActionRequest<PutRoleRequest> implements ToX
return name; return name;
} }
public List<String> cluster() { public String[] cluster() {
return clusterPriv; return clusterPrivileges;
} }
public List<RoleDescriptor.IndicesPrivileges> indices() { public RoleDescriptor.IndicesPrivileges[] indices() {
return indices; return indicesPrivileges.toArray(new RoleDescriptor.IndicesPrivileges[indicesPrivileges.size()]);
} }
public List<String> runAs() { public String[] runAs() {
return runAs; return runAs;
} }
private RoleDescriptor roleDescriptor() { private RoleDescriptor roleDescriptor() {
if (this.roleDescriptor != null) { return new RoleDescriptor(name, clusterPrivileges,
return this.roleDescriptor; indicesPrivileges.toArray(new RoleDescriptor.IndicesPrivileges[indicesPrivileges.size()]), runAs);
}
this.roleDescriptor = new RoleDescriptor(name, this.clusterPriv.toArray(Strings.EMPTY_ARRAY),
this.indices, this.runAs.toArray(Strings.EMPTY_ARRAY));
return this.roleDescriptor;
} }
@Override @Override
public void readFrom(StreamInput in) throws IOException { public void readFrom(StreamInput in) throws IOException {
super.readFrom(in); super.readFrom(in);
name = in.readString(); name = in.readString();
int clusterSize = in.readVInt(); clusterPrivileges = in.readOptionalStringArray();
List<String> tempCluster = new ArrayList<>(clusterSize);
for (int i = 0; i < clusterSize; i++) {
tempCluster.add(in.readString());
}
clusterPriv = tempCluster;
int indicesSize = in.readVInt(); int indicesSize = in.readVInt();
indices = new ArrayList<>(indicesSize); indicesPrivileges = new ArrayList<>(indicesSize);
for (int i = 0; i < indicesSize; i++) { for (int i = 0; i < indicesSize; i++) {
indices.add(RoleDescriptor.IndicesPrivileges.readIndicesPrivileges(in)); indicesPrivileges.add(RoleDescriptor.IndicesPrivileges.readIndicesPrivileges(in));
}
if (in.readBoolean()) {
int runAsSize = in.readVInt();
runAs = new ArrayList<>(runAsSize);
for (int i = 0; i < runAsSize; i++) {
runAs.add(in.readString());
}
} }
runAs = in.readOptionalStringArray();
} }
@Override @Override
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out); super.writeTo(out);
out.writeString(name); out.writeString(name);
out.writeVInt(clusterPriv.size()); out.writeOptionalStringArray(clusterPrivileges);
for (String cluster : clusterPriv) { out.writeVInt(indicesPrivileges.size());
out.writeString(cluster); for (RoleDescriptor.IndicesPrivileges index : indicesPrivileges) {
}
out.writeVInt(indices.size());
for (RoleDescriptor.IndicesPrivileges index : indices) {
index.writeTo(out); index.writeTo(out);
} }
if (runAs.isEmpty() == false) { out.writeOptionalStringArray(runAs);
out.writeBoolean(true);
out.writeVInt(runAs.size());
for (String runAsUser : runAs) {
out.writeString(runAsUser);
}
} else {
out.writeBoolean(false);
}
} }
@Override @Override

View File

@ -10,8 +10,6 @@ import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.bytes.BytesReference;
import java.util.Arrays;
/** /**
* Builder for requests to add a role to the administrative index * Builder for requests to add a role to the administrative index
*/ */
@ -25,18 +23,23 @@ public class PutRoleRequestBuilder extends ActionRequestBuilder<PutRoleRequest,
super(client, action, new PutRoleRequest()); super(client, action, new PutRoleRequest());
} }
public PutRoleRequestBuilder source(String name, BytesReference source) throws Exception {
request.source(name, source);
return this;
}
public PutRoleRequestBuilder name(String name) { public PutRoleRequestBuilder name(String name) {
request.name(name); request.name(name);
return this; return this;
} }
public PutRoleRequestBuilder cluster(String... cluster) { public PutRoleRequestBuilder cluster(String... clusterPrivileges) {
request.cluster(Arrays.asList(cluster)); request.cluster(clusterPrivileges);
return this; return this;
} }
public PutRoleRequestBuilder runAs(String... runAsUsers) { public PutRoleRequestBuilder runAs(String... runAsUsers) {
request.runAs(Arrays.asList(runAsUsers)); request.runAs(runAsUsers);
return this; return this;
} }

View File

@ -29,14 +29,14 @@ import java.util.List;
public class RoleDescriptor implements ToXContent { public class RoleDescriptor implements ToXContent {
private final String name; private final String name;
private final String[] clusterPattern; private final String[] clusterPrivileges;
private final List<IndicesPrivileges> indicesPrivileges; private final IndicesPrivileges[] indicesPrivileges;
private final String[] runAs; private final String[] runAs;
public RoleDescriptor(String name, String[] clusterPattern, public RoleDescriptor(String name, String[] clusterPrivileges,
List<IndicesPrivileges> indicesPrivileges, String[] runAs) { IndicesPrivileges[] indicesPrivileges, String[] runAs) {
this.name = name; this.name = name;
this.clusterPattern = clusterPattern; this.clusterPrivileges = clusterPrivileges;
this.indicesPrivileges = indicesPrivileges; this.indicesPrivileges = indicesPrivileges;
this.runAs = runAs; this.runAs = runAs;
} }
@ -45,11 +45,11 @@ public class RoleDescriptor implements ToXContent {
return this.name; return this.name;
} }
public String[] getClusterPattern() { public String[] getClusterPrivileges() {
return this.clusterPattern; return this.clusterPrivileges;
} }
public List<IndicesPrivileges> getIndicesPrivileges() { public IndicesPrivileges[] getIndicesPrivileges() {
return this.indicesPrivileges; return this.indicesPrivileges;
} }
@ -149,21 +149,28 @@ public class RoleDescriptor implements ToXContent {
return tempIndices; return tempIndices;
} }
public static RoleDescriptor source(BytesReference source) throws Exception { public static RoleDescriptor source(String name, BytesReference source) throws Exception {
try (XContentParser parser = XContentHelper.createParser(source)) { try (XContentParser parser = XContentHelper.createParser(source)) {
XContentParser.Token token; XContentParser.Token token;
String currentFieldName = null; String currentFieldName = null;
String roleName = null; String roleName = name;
List<IndicesPrivileges> indicesPrivileges = new ArrayList<>(); List<IndicesPrivileges> indicesPrivileges = new ArrayList<>();
List<String> runAsUsers = new ArrayList<>(); List<String> runAsUsers = new ArrayList<>();
List<String> tempClusterPriv = new ArrayList<>(); List<String> clusterPrivileges = new ArrayList<>();
parser.nextToken(); // remove object wrapping parser.nextToken(); // remove object wrapping
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) { if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName(); currentFieldName = parser.currentName();
} else if (token.isValue()) { } else if (token.isValue()) {
if ("name".equals(currentFieldName)) { if ("name".equals(currentFieldName)) {
if (roleName == null) {
// if the role name is not given, we'll parse it from the source
roleName = parser.text(); roleName = parser.text();
} else if (roleName.equals(parser.text()) == false) {
// if the given role name is not the same as the parsed role name, we have inconstency and we need to
// throw an error
throw new ElasticsearchParseException("expected role name [{}] but found [{}] instead", roleName, parser.text());
}
} else { } else {
throw new ElasticsearchParseException("unexpected field in add role request [{}]", currentFieldName); throw new ElasticsearchParseException("unexpected field in add role request [{}]", currentFieldName);
} }
@ -180,7 +187,7 @@ public class RoleDescriptor implements ToXContent {
} else if (token == XContentParser.Token.START_ARRAY && "cluster".equals(currentFieldName)) { } else if (token == XContentParser.Token.START_ARRAY && "cluster".equals(currentFieldName)) {
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
if (token.isValue()) { if (token.isValue()) {
tempClusterPriv.add(parser.text()); clusterPrivileges.add(parser.text());
} else { } else {
throw new ElasticsearchParseException("unexpected value parsing cluster privileges [{}]", token); throw new ElasticsearchParseException("unexpected value parsing cluster privileges [{}]", token);
} }
@ -193,8 +200,9 @@ public class RoleDescriptor implements ToXContent {
if (roleName == null) { if (roleName == null) {
throw new ElasticsearchParseException("field [name] required for role description"); throw new ElasticsearchParseException("field [name] required for role description");
} }
return new RoleDescriptor(roleName, tempClusterPriv.toArray(Strings.EMPTY_ARRAY), return new RoleDescriptor(roleName, clusterPrivileges.toArray(new String[clusterPrivileges.size()]),
indicesPrivileges, runAsUsers.toArray(Strings.EMPTY_ARRAY)); indicesPrivileges.toArray(new IndicesPrivileges[indicesPrivileges.size()]),
runAsUsers.toArray(new String[runAsUsers.size()]));
} }
} }
@ -202,7 +210,7 @@ public class RoleDescriptor implements ToXContent {
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("Role["); StringBuilder sb = new StringBuilder("Role[");
sb.append("name=").append(name); sb.append("name=").append(name);
sb.append(", cluster=[").append(Strings.arrayToCommaDelimitedString(clusterPattern)); sb.append(", cluster=[").append(Strings.arrayToCommaDelimitedString(clusterPrivileges));
sb.append("], indicesPrivileges=["); sb.append("], indicesPrivileges=[");
for (IndicesPrivileges group : indicesPrivileges) { for (IndicesPrivileges group : indicesPrivileges) {
sb.append(group.toString()).append(","); sb.append(group.toString()).append(",");
@ -216,8 +224,8 @@ public class RoleDescriptor implements ToXContent {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
builder.field("name", name); builder.field("name", name);
builder.field("cluster", clusterPattern); builder.field("cluster", clusterPrivileges);
builder.field("indices", indicesPrivileges); builder.field("indices", (Object[]) indicesPrivileges);
if (runAs != null) { if (runAs != null) {
builder.field("run_as", runAs); builder.field("run_as", runAs);
} }
@ -236,17 +244,17 @@ public class RoleDescriptor implements ToXContent {
indicesPrivileges.add(group); indicesPrivileges.add(group);
} }
String[] runAs = in.readStringArray(); String[] runAs = in.readStringArray();
return new RoleDescriptor(name, clusterPattern, indicesPrivileges, runAs); return new RoleDescriptor(name, clusterPattern, indicesPrivileges.toArray(new IndicesPrivileges[indicesPrivileges.size()]), runAs);
} }
public static void writeTo(RoleDescriptor descriptor, StreamOutput out) throws IOException { public static void writeTo(RoleDescriptor descriptor, StreamOutput out) throws IOException {
out.writeString(descriptor.getName()); out.writeString(descriptor.name);
out.writeStringArray(descriptor.getClusterPattern()); out.writeStringArray(descriptor.clusterPrivileges);
out.writeVInt(descriptor.getIndicesPrivileges().size()); out.writeVInt(descriptor.indicesPrivileges.length);
for (IndicesPrivileges group : descriptor.getIndicesPrivileges()) { for (IndicesPrivileges group : descriptor.indicesPrivileges) {
group.writeTo(out); group.writeTo(out);
} }
out.writeStringArray(descriptor.getRunAs()); out.writeStringArray(descriptor.runAs);
} }
public static class IndicesPrivilegesBuilder { public static class IndicesPrivilegesBuilder {

View File

@ -110,7 +110,7 @@ public class ESNativeRolesStore extends AbstractComponent implements RolesStore,
@Nullable @Nullable
private RoleDescriptor transformRole(BytesReference sourceBytes) { private RoleDescriptor transformRole(BytesReference sourceBytes) {
try { try {
return RoleDescriptor.source(sourceBytes); return RoleDescriptor.source(null, sourceBytes);
} catch (Exception e) { } catch (Exception e) {
logger.warn("unable to deserialize role from response", e); logger.warn("unable to deserialize role from response", e);
return null; return null;

View File

@ -68,7 +68,7 @@ public class Role extends GlobalPermission {
private Builder(RoleDescriptor rd) { private Builder(RoleDescriptor rd) {
this.name = rd.getName(); this.name = rd.getName();
this.cluster(ClusterPrivilege.get((new Privilege.Name(rd.getClusterPattern())))); this.cluster(ClusterPrivilege.get((new Privilege.Name(rd.getClusterPrivileges()))));
for (RoleDescriptor.IndicesPrivileges iGroup : rd.getIndicesPrivileges()) { for (RoleDescriptor.IndicesPrivileges iGroup : rd.getIndicesPrivileges()) {
this.add(iGroup.getFields() == null ? null : Arrays.asList(iGroup.getFields()), this.add(iGroup.getFields() == null ? null : Arrays.asList(iGroup.getFields()),
iGroup.getQuery(), iGroup.getQuery(),

View File

@ -169,6 +169,10 @@ public class SecurityClient {
return new PutRoleRequestBuilder(client).name(name); return new PutRoleRequestBuilder(client).name(name);
} }
public PutRoleRequestBuilder preparePutRole(String name, BytesReference source) throws Exception {
return new PutRoleRequestBuilder(client).source(name, source);
}
public void putRole(PutRoleRequest request, ActionListener<PutRoleResponse> listener) { public void putRole(PutRoleRequest request, ActionListener<PutRoleResponse> listener) {
client.execute(PutRoleAction.INSTANCE, request, listener); client.execute(PutRoleAction.INSTANCE, request, listener);
} }

View File

@ -34,7 +34,8 @@ public class RestPutRoleAction extends BaseRestHandler {
@Override @Override
protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception { protected void handleRequest(RestRequest request, final RestChannel channel, Client client) throws Exception {
new SecurityClient(client).preparePutRole(request.param("name")).execute(new RestBuilderListener<PutRoleResponse>(channel) { new SecurityClient(client).preparePutRole(request.param("name"), request.content()).execute(
new RestBuilderListener<PutRoleResponse>(channel) {
@Override @Override
public RestResponse buildResponse(PutRoleResponse putRoleResponse, XContentBuilder builder) throws Exception { public RestResponse buildResponse(PutRoleResponse putRoleResponse, XContentBuilder builder) throws Exception {
return new BytesRestResponse(RestStatus.OK, return new BytesRestResponse(RestStatus.OK,

View File

@ -12,10 +12,8 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.core.Is.is;
public class RoleDescriptorTests extends ESTestCase { public class RoleDescriptorTests extends ESTestCase {
@ -30,13 +28,14 @@ public class RoleDescriptorTests extends ESTestCase {
} }
public void testRDJson() throws Exception { public void testRDJson() throws Exception {
List<RoleDescriptor.IndicesPrivileges> groups = new ArrayList<>(); RoleDescriptor.IndicesPrivileges[] groups = new RoleDescriptor.IndicesPrivileges[] {
groups.add(RoleDescriptor.IndicesPrivileges.builder() RoleDescriptor.IndicesPrivileges.builder()
.indices(new String[] { "i1", "i2" }) .indices(new String[] { "i1", "i2" })
.privileges(new String[] { "read" }) .privileges(new String[] { "read" })
.fields(new String[] { "body", "title" }) .fields(new String[] { "body", "title" })
.query(new BytesArray("{\"query\": {\"match_all\": {}}}")) .query(new BytesArray("{\"query\": {\"match_all\": {}}}"))
.build()); .build()
};
RoleDescriptor d = new RoleDescriptor("test", new String[]{"all", "none"}, groups, new String[]{"sudo"}); RoleDescriptor d = new RoleDescriptor("test", new String[]{"all", "none"}, groups, new String[]{"sudo"});
assertEquals("Role[name=test, cluster=[all,none], indicesPrivileges=[IndicesPrivileges[privileges=[read], indices=[i1,i2], " + assertEquals("Role[name=test, cluster=[all,none], indicesPrivileges=[IndicesPrivileges[privileges=[read], indices=[i1,i2], " +
"fields=[body,title], query={\"query\": {\"match_all\": {}}}],], runAs=[sudo]]", d.toString()); "fields=[body,title], query={\"query\": {\"match_all\": {}}}],], runAs=[sudo]]", d.toString());
@ -53,48 +52,48 @@ public class RoleDescriptorTests extends ESTestCase {
RoleDescriptor rd; RoleDescriptor rd;
try { try {
q = "{}"; q = "{}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
fail("should have failed"); fail("should have failed");
} catch (ElasticsearchParseException e) { } catch (ElasticsearchParseException e) {
// expected // expected
} }
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"]}"; q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
assertEquals("test", rd.getName()); assertEquals("test", rd.getName());
assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPattern()); assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPrivileges());
assertEquals(0, rd.getIndicesPrivileges().size()); assertEquals(0, rd.getIndicesPrivileges().length);
assertArrayEquals(Strings.EMPTY_ARRAY, rd.getRunAs()); assertArrayEquals(Strings.EMPTY_ARRAY, rd.getRunAs());
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"]}"; q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
assertEquals("test", rd.getName()); assertEquals("test", rd.getName());
assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPattern()); assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPrivileges());
assertEquals(0, rd.getIndicesPrivileges().size()); assertEquals(0, rd.getIndicesPrivileges().length);
assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs()); assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs());
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": \"idx1\", " + q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": \"idx1\", " +
"\"privileges\": [\"p1\", \"p2\"]}, {\"names\": \"idx2\", \"privileges\": [\"p3\"], \"fields\": [\"f1\", \"f2\"]}, " + "\"privileges\": [\"p1\", \"p2\"]}, {\"names\": \"idx2\", \"privileges\": [\"p3\"], \"fields\": [\"f1\", \"f2\"]}, " +
"{\"names\": \"idx2\", \"privileges\": [\"p3\"], \"fields\": [\"f1\", \"f2\"], \"query\": \"{\\\"match_all\\\": {}}\"}]}"; "{\"names\": \"idx2\", \"privileges\": [\"p3\"], \"fields\": [\"f1\", \"f2\"], \"query\": \"{\\\"match_all\\\": {}}\"}]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
assertEquals("test", rd.getName()); assertEquals("test", rd.getName());
assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPattern()); assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPrivileges());
assertEquals(3, rd.getIndicesPrivileges().size()); assertEquals(3, rd.getIndicesPrivileges().length);
assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs()); assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs());
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": [\"idx1\",\"idx2\"], " + q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": [\"idx1\",\"idx2\"], " +
"\"privileges\": [\"p1\", \"p2\"]}]}"; "\"privileges\": [\"p1\", \"p2\"]}]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
assertEquals("test", rd.getName()); assertEquals("test", rd.getName());
assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPattern()); assertArrayEquals(new String[]{"a", "b"}, rd.getClusterPrivileges());
assertEquals(1, rd.getIndicesPrivileges().size()); assertEquals(1, rd.getIndicesPrivileges().length);
assertArrayEquals(new String[]{"idx1", "idx2"}, rd.getIndicesPrivileges().get(0).getIndices()); assertArrayEquals(new String[]{"idx1", "idx2"}, rd.getIndicesPrivileges()[0].getIndices());
assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs()); assertArrayEquals(new String[]{"m", "n"}, rd.getRunAs());
try { try {
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": \"idx1,idx2\", " + q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": \"idx1,idx2\", " +
"\"privileges\": [\"p1\", \"p2\"]}]}"; "\"privileges\": [\"p1\", \"p2\"]}]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
fail("should have thrown a parse exception"); fail("should have thrown a parse exception");
} catch (ElasticsearchParseException epe) { } catch (ElasticsearchParseException epe) {
assertTrue(epe.getMessage(), assertTrue(epe.getMessage(),
@ -105,11 +104,26 @@ public class RoleDescriptorTests extends ESTestCase {
// Same, but an array of names // Same, but an array of names
q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": [\"idx1,idx2\"], " + q = "{\"name\": \"test\", \"cluster\":[\"a\", \"b\"], \"run_as\": [\"m\", \"n\"], \"indices\": [{\"names\": [\"idx1,idx2\"], " +
"\"privileges\": [\"p1\", \"p2\"]}]}"; "\"privileges\": [\"p1\", \"p2\"]}]}";
rd = RoleDescriptor.source(new BytesArray(q)); rd = RoleDescriptor.source(null, new BytesArray(q));
fail("should have thrown a parse exception"); fail("should have thrown a parse exception");
} catch (ElasticsearchParseException epe) { } catch (ElasticsearchParseException epe) {
assertTrue(epe.getMessage(), assertTrue(epe.getMessage(),
epe.getMessage().contains("index name [idx1,idx2] may not contain ','")); epe.getMessage().contains("index name [idx1,idx2] may not contain ','"));
} }
// Test given name matches the parsed name
q = "{\"name\": \"foo\"}";
rd = RoleDescriptor.source("foo", new BytesArray(q));
assertThat("foo", is(rd.getName()));
try {
// Test mismatch between given name and parsed name
q = "{\"name\": \"foo\"}";
rd = RoleDescriptor.source("bar", new BytesArray(q));
fail("should have thrown a parse exception");
} catch (ElasticsearchParseException epe) {
assertTrue(epe.getMessage(),
epe.getMessage().contains("expected role name [bar] but found [foo] instead"));
}
} }
} }