Disable field stats cache if field level security

Field level security poisons that cache.

Closes elastic/elasticsearch#2528

Original commit: elastic/x-pack-elasticsearch@12ca4a2ef4
This commit is contained in:
Nik Everett 2016-06-15 14:16:39 -04:00
parent f8ba97c42f
commit f92314ba00
7 changed files with 49 additions and 11 deletions

View File

@ -9,6 +9,7 @@ import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.action.filter.ShieldActionFilter;
import org.elasticsearch.shield.action.interceptor.BulkRequestInterceptor;
import org.elasticsearch.shield.action.interceptor.FieldStatsRequestInterceptor;
import org.elasticsearch.shield.action.interceptor.RealtimeRequestInterceptor;
import org.elasticsearch.shield.action.interceptor.RequestInterceptor;
import org.elasticsearch.shield.action.interceptor.SearchRequestInterceptor;
@ -34,5 +35,6 @@ public class ShieldActionModule extends AbstractShieldModule.Node {
multibinder.addBinding().to(SearchRequestInterceptor.class);
multibinder.addBinding().to(UpdateRequestInterceptor.class);
multibinder.addBinding().to(BulkRequestInterceptor.class);
multibinder.addBinding().to(FieldStatsRequestInterceptor.class);
}
}

View File

@ -47,12 +47,14 @@ public abstract class FieldAndDocumentLevelSecurityRequestInterceptor<Request> e
for (String index : indicesRequest.indices()) {
IndicesAccessControl.IndexAccessControl indexAccessControl = indicesAccessControl.getIndexPermissions(index);
if (indexAccessControl != null) {
boolean fls = indexAccessControl.getFields() != null;
boolean dls = indexAccessControl.getQueries() != null;
if (fls || dls) {
logger.debug("intercepted request for index [{}] with field level or document level security enabled, " +
"disabling features", index);
disableFeatures(request);
boolean fieldLevelSecurityEnabled = indexAccessControl.getFields() != null;
boolean documentLevelSecurityEnabled = indexAccessControl.getQueries() != null;
if (fieldLevelSecurityEnabled || documentLevelSecurityEnabled) {
if (logger.isDebugEnabled()) {
logger.debug("intercepted request for index [{}] with field level [{}] or document level [{}] security "
+ "enabled, disabling features", index, fieldLevelSecurityEnabled, documentLevelSecurityEnabled);
}
disableFeatures(request, fieldLevelSecurityEnabled, documentLevelSecurityEnabled);
return;
}
}
@ -62,6 +64,6 @@ public abstract class FieldAndDocumentLevelSecurityRequestInterceptor<Request> e
}
}
protected abstract void disableFeatures(Request request);
protected abstract void disableFeatures(Request request, boolean fieldLevelSecurityEnabled, boolean documentLevelSecurityEnabled);
}

View File

@ -0,0 +1,34 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.shield.action.interceptor;
import org.elasticsearch.action.fieldstats.FieldStatsRequest;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
/**
* Intercepts requests to shards to field level stats and strips fields that the user is not allowed to access from the response.
*/
public class FieldStatsRequestInterceptor extends FieldAndDocumentLevelSecurityRequestInterceptor<FieldStatsRequest> {
@Inject
public FieldStatsRequestInterceptor(Settings settings, ThreadPool threadPool) {
super(settings, threadPool.getThreadContext());
}
@Override
public boolean supports(TransportRequest request) {
return request instanceof FieldStatsRequest;
}
@Override
protected void disableFeatures(FieldStatsRequest request, boolean fieldLevelSecurityEnabled, boolean documentLevelSecurityEnabled) {
if (fieldLevelSecurityEnabled) {
request.setUseCache(false);
}
}
}

View File

@ -23,7 +23,8 @@ public class RealtimeRequestInterceptor extends FieldAndDocumentLevelSecurityReq
}
@Override
protected void disableFeatures(RealtimeRequest realtimeRequest) {
protected void disableFeatures(RealtimeRequest realtimeRequest, boolean fieldLevelSecurityEnabled,
boolean documentLevelSecurityEnabled) {
realtimeRequest.realtime(false);
}

View File

@ -22,7 +22,7 @@ public class SearchRequestInterceptor extends FieldAndDocumentLevelSecurityReque
}
@Override
public void disableFeatures(SearchRequest request) {
public void disableFeatures(SearchRequest request, boolean fieldLevelSecurityEnabled, boolean documentLevelSecurityEnabled) {
request.requestCache(false);
}

View File

@ -28,7 +28,7 @@ public class UpdateRequestInterceptor extends FieldAndDocumentLevelSecurityReque
}
@Override
protected void disableFeatures(UpdateRequest updateRequest) {
protected void disableFeatures(UpdateRequest updateRequest, boolean fieldLevelSecurityEnabled, boolean documentLevelSecurityEnabled) {
throw new ElasticsearchSecurityException("Can't execute an update request if field or document level security is enabled",
RestStatus.BAD_REQUEST);
}

View File

@ -483,7 +483,6 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
}
@AwaitsFix(bugUrl = "https://github.com/elastic/x-plugins/issues/2528")
public void testFieldStatsApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=text", "field2", "type=text", "field3", "type=text")