From d8d5bb36831a332b0422983b6958cdeffdcb25eb Mon Sep 17 00:00:00 2001 From: Areek Zillur Date: Wed, 15 Jun 2016 15:48:21 -0400 Subject: [PATCH 01/11] xpack fixes for elasticsearchelastic/elasticsearch#18732 Original commit: elastic/x-pack-elasticsearch@fdb1cea1db55fb565d8ff0ecc6f6463ca6b1fb30 --- .../accesscontrol/ShieldIndexSearcherWrapperUnitTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapperUnitTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapperUnitTests.java index 15a9de93d97..b32682c9423 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapperUnitTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapperUnitTests.java @@ -36,6 +36,7 @@ import org.apache.lucene.util.FixedBitSet; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.SparseFixedBitSet; import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; @@ -93,7 +94,7 @@ public class ShieldIndexSearcherWrapperUnitTests extends ESTestCase { Collections.emptyMap(), Collections.emptyMap()); SimilarityService similarityService = new SimilarityService(indexSettings, Collections.emptyMap()); mapperService = new MapperService(indexSettings, analysisService, similarityService, - new IndicesModule().getMapperRegistry(), () -> null); + new IndicesModule(new NamedWriteableRegistry()).getMapperRegistry(), () -> null); ShardId shardId = new ShardId(index, 0); licenseState = mock(SecurityLicenseState.class); From 7cb7f85709812bb7cd6b0c1b26d5622ef382ea7d Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Wed, 15 Jun 2016 17:11:34 -0700 Subject: [PATCH 02/11] Remove name() and description() from plugin api This is the xplugins side of elastic/elasticsearchelastic/elasticsearch#18906 Original commit: elastic/x-pack-elasticsearch@b47422fe91b0a260a3dba9e429c3ba559e273bf3 --- .../org/elasticsearch/xpack/graph/Graph.java | 10 ---------- .../xpack/graph/test/GraphTests.java | 9 --------- ...EagerLicenseRegistrationConsumerPlugin.java | 5 ----- .../LazyLicenseRegistrationConsumerPlugin.java | 7 ------- .../consumer/TestConsumerPluginBase.java | 13 ------------- .../marvel/MarvelPluginTests.java | 2 +- .../shield/transport/TransportFilterTests.java | 18 ------------------ .../test/ShieldIntegTestCase.java | 3 ++- .../org/elasticsearch/xpack/XPackPlugin.java | 8 -------- .../script/MockMustacheScriptEngine.java | 5 ----- .../script/SleepScriptEngine.java | 13 ------------- .../actions/ActionErrorIntegrationTests.java | 13 ------------- .../WatcherIndexTemplateRegistryTests.java | 8 -------- 13 files changed, 3 insertions(+), 111 deletions(-) diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java index 9c435dba74f..33f2e6851d6 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java @@ -31,16 +31,6 @@ public class Graph extends Plugin { public Graph(Settings settings) { this.transportClientMode = XPackPlugin.transportClientMode(settings); enabled = enabled(settings); - } - - @Override - public String name() { - return NAME; - } - - @Override - public String description() { - return "Elasticsearch Graph Plugin"; } public static boolean enabled(Settings settings) { diff --git a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java index 9fe576c8dc5..847784d4e4f 100644 --- a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java +++ b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java @@ -347,15 +347,6 @@ public class GraphTests extends ESSingleNodeTestCase { } public static class ScriptedTimeoutPlugin extends Plugin { - @Override - public String name() { - return "test-scripted-graph-timeout"; - } - - @Override - public String description() { - return "Test for scripted timeouts on graph searches"; - } public void onModule(ScriptModule module) { module.registerScript(NativeTestScriptedTimeout.TEST_NATIVE_SCRIPT_TIMEOUT, NativeTestScriptedTimeout.Factory.class); diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/EagerLicenseRegistrationConsumerPlugin.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/EagerLicenseRegistrationConsumerPlugin.java index bd003f279bf..ed07814b408 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/EagerLicenseRegistrationConsumerPlugin.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/EagerLicenseRegistrationConsumerPlugin.java @@ -28,11 +28,6 @@ public class EagerLicenseRegistrationConsumerPlugin extends TestConsumerPluginBa return EagerLicenseRegistrationPluginService.class; } - @Override - protected String pluginName() { - return NAME; - } - @Override public String id() { return EagerLicenseRegistrationPluginService.ID; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/LazyLicenseRegistrationConsumerPlugin.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/LazyLicenseRegistrationConsumerPlugin.java index f8902f0da40..78bc7fb4ad7 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/LazyLicenseRegistrationConsumerPlugin.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/LazyLicenseRegistrationConsumerPlugin.java @@ -16,8 +16,6 @@ import org.elasticsearch.common.settings.Settings; */ public class LazyLicenseRegistrationConsumerPlugin extends TestConsumerPluginBase { - public static String NAME = "test_consumer_plugin_2"; - @Inject public LazyLicenseRegistrationConsumerPlugin(Settings settings) { super(settings); @@ -28,11 +26,6 @@ public class LazyLicenseRegistrationConsumerPlugin extends TestConsumerPluginBas return LazyLicenseRegistrationPluginService.class; } - @Override - protected String pluginName() { - return NAME; - } - @Override public String id() { return LazyLicenseRegistrationPluginService.ID; diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java index 46c50b0375c..7403c63dc45 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java @@ -24,17 +24,6 @@ public abstract class TestConsumerPluginBase extends Plugin { this.isEnabled = TransportClient.CLIENT_TYPE.equals(settings.get(Client.CLIENT_TYPE_SETTING_S.getKey())) == false; } - @Override - public String name() { - return pluginName(); - } - - @Override - public String description() { - return "test licensing consumer plugin"; - } - - @Override public Collection> nodeServices() { Collection> services = new ArrayList<>(); @@ -55,7 +44,5 @@ public abstract class TestConsumerPluginBase extends Plugin { public abstract Class service(); - protected abstract String pluginName(); - public abstract String id(); } diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/MarvelPluginTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/MarvelPluginTests.java index 9e7d39fd542..1353e703af5 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/MarvelPluginTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/MarvelPluginTests.java @@ -79,7 +79,7 @@ public class MarvelPluginTests extends MarvelIntegTestCase { for (PluginInfo plugin : nodeInfo.getPlugins().getPluginInfos()) { assertNotNull(plugin); - if (XPackPlugin.NAME.equals(plugin.getName())) { + if (XPackPlugin.class.getName().equals(plugin.getName())) { found = true; break; } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java index f46f7ab8c41..06f6912c6d7 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java @@ -116,16 +116,6 @@ public class TransportFilterTests extends ESIntegTestCase { } public static class InternalPlugin extends Plugin { - @Override - public String name() { - return "test-transport-filter"; - } - - @Override - public String description() { - return ""; - } - @Override public Collection nodeModules() { return Collections.singletonList(new TestTransportFilterModule()); @@ -289,14 +279,6 @@ public class TransportFilterTests extends ESIntegTestCase { // Sub class the Shield transport to always inject a mock for testing public static class InternalPluginServerTransportService extends ShieldServerTransportService { public static class TestPlugin extends Plugin { - @Override - public String name() { - return "mock-transport-service"; - } - @Override - public String description() { - return "a mock transport service for testing"; - } public void onModule(NetworkModule module) { module.registerTransportService("filter-mock", InternalPluginServerTransportService.class); } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java index c1a09ae3833..97dac80defc 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldIntegTestCase.java @@ -151,7 +151,8 @@ public abstract class ShieldIntegTestCase extends ESIntegTestCase { // assertThat(nodeInfo.getPlugins().getInfos(), hasSize(2)); Collection pluginNames = nodeInfo.getPlugins().getPluginInfos().stream().map(p -> p.getName()).collect(Collectors.toList()); - assertThat("plugin [" + XPackPlugin.NAME + "] not found in [" + pluginNames + "]", pluginNames, hasItem(XPackPlugin.NAME)); + assertThat("plugin [" + xpackPluginClass().getName() + "] not found in [" + pluginNames + "]", pluginNames, + hasItem(xpackPluginClass().getName())); } } diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 456f8db3598..64cb55fdd7f 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -124,14 +124,6 @@ public class XPackPlugin extends Plugin { } } - @Override public String name() { - return NAME; - } - - @Override public String description() { - return "Elastic X-Pack"; - } - // For tests only public Collection> getExtensions() { return Collections.emptyList(); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java index 6430fde4a16..a56e0168fd9 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java @@ -22,11 +22,6 @@ public class MockMustacheScriptEngine extends MockScriptEngine { public static class TestPlugin extends MockScriptEngine.TestPlugin { - @Override - public String name() { - return NAME; - } - public void onModule(ScriptModule module) { module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockMustacheScriptEngine.class, NAME, true)); } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java index c0cf787d7e8..415c655fa09 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java @@ -23,19 +23,6 @@ public class SleepScriptEngine implements ScriptEngineService { public static class TestPlugin extends Plugin { - public TestPlugin() { - } - - @Override - public String name() { - return NAME; - } - - @Override - public String description() { - return "Mock script engine for integration tests"; - } - public void onModule(ScriptModule module) { module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(SleepScriptEngine.class, SleepScriptEngine.NAME, true)); diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/ActionErrorIntegrationTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/ActionErrorIntegrationTests.java index d62df74f188..920a717801a 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/ActionErrorIntegrationTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/actions/ActionErrorIntegrationTests.java @@ -112,19 +112,6 @@ public class ActionErrorIntegrationTests extends AbstractWatcherIntegrationTestC public static class ErrorActionPlugin extends Plugin { - public ErrorActionPlugin() { - } - - @Override - public String name() { - return "error-action"; - } - - @Override - public String description() { - return name(); - } - public void onModule(WatcherActionModule module) { module.registerAction(ErrorAction.TYPE, ErrorAction.Factory.class); } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java index 41d7cbc29ff..47d7301015a 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java @@ -74,14 +74,6 @@ public class WatcherIndexTemplateRegistryTests extends AbstractWatcherIntegratio } public static class SettingTestPlugin extends Plugin { - public String name() { - return "watcher-index-template-registry-settings-plugin"; - } - - @Override - public String description() { - return "installs a setting this test needs"; - } public static final Setting KEY_1 = new Setting<>("index.key1", "", Function.identity(), Setting.Property.IndexScope); From 36ad326483bed89178a30e80909a4d844066ed1a Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 16 Jun 2016 09:35:16 +0200 Subject: [PATCH 03/11] Simplify ScriptModule and script registration elastic/elasticsearchelastic/elasticsearch#18903 (elastic/elasticsearch#2535) follow up PR for elastic/elasticsearchelastic/elasticsearch#18903 Original commit: elastic/x-pack-elasticsearch@d6ab3ab1413d30a48167cc60a940b818160b33c2 --- .../messy/tests/MessyTestUtils.java | 14 +++----------- .../smoketest/WatcherTemplateTests.java | 8 ++------ .../xpack/graph/test/GraphTests.java | 15 ++++++++++++--- .../org/elasticsearch/xpack/XPackPlugin.java | 10 +++++++--- .../org/elasticsearch/xpack/watcher/Watcher.java | 3 --- .../script/MockMustacheScriptEngine.java | 14 +++++++++----- .../elasticsearch/script/SleepScriptEngine.java | 16 ++++++++++------ .../xpack/watcher/test/WatcherTestUtils.java | 2 +- 8 files changed, 44 insertions(+), 38 deletions(-) diff --git a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java index c4bbc2186b9..dee4d8ae66b 100644 --- a/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java +++ b/elasticsearch/qa/messy-test-watcher-with-groovy/src/test/java/org/elasticsearch/messy/tests/MessyTestUtils.java @@ -14,7 +14,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.script.ScriptContextRegistry; import org.elasticsearch.script.ScriptEngineRegistry; -import org.elasticsearch.script.ScriptEngineService; import org.elasticsearch.script.ScriptService; import org.elasticsearch.script.ScriptSettings; import org.elasticsearch.script.groovy.GroovyScriptEngineService; @@ -25,8 +24,7 @@ import org.junit.Ignore; import org.mockito.Mockito; import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.Collections; @Ignore // not a test. @SuppressForbidden(reason = "gradle is broken and tries to run me as a test") @@ -38,19 +36,13 @@ public final class MessyTestUtils { .put("path.home", LuceneTestCase.createTempDir()) .build(); GroovyScriptEngineService groovyScriptEngineService = new GroovyScriptEngineService(settings); - Set engineServiceSet = new HashSet<>(); - engineServiceSet.add(groovyScriptEngineService); - ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry( - Arrays.asList( - new ScriptEngineRegistry.ScriptEngineRegistration(GroovyScriptEngineService.class, GroovyScriptEngineService.NAME) - ) - ); + ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singleton(groovyScriptEngineService)); ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Arrays.asList(ScriptServiceProxy.INSTANCE)); ClusterService clusterService = Mockito.mock(ClusterService.class); Mockito.when(clusterService.state()).thenReturn(ClusterState.builder(new ClusterName("_name")).build()); ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry); - return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), engineServiceSet, + return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), new ResourceWatcherService(settings, tp), scriptEngineRegistry, scriptContextRegistry, scriptSettings), clusterService); } diff --git a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java index efe00900d07..5475529e2d8 100644 --- a/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java +++ b/elasticsearch/qa/smoke-test-watcher-with-mustache/src/test/java/org/elasticsearch/smoketest/WatcherTemplateTests.java @@ -49,18 +49,14 @@ public class WatcherTemplateTests extends ESTestCase { public void init() throws Exception { Settings setting = Settings.builder().put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, true).build(); Environment environment = Mockito.mock(Environment.class); - Set engines = Collections.singleton(new MustacheScriptEngineService(setting)); ResourceWatcherService resourceWatcherService = Mockito.mock(ResourceWatcherService.class); ScriptContextRegistry registry = new ScriptContextRegistry(Collections.singletonList(ScriptServiceProxy.INSTANCE)); ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry( - Arrays.asList( - new ScriptEngineRegistry.ScriptEngineRegistration(MustacheScriptEngineService.class, - MustacheScriptEngineService.NAME) - ) + Collections.singleton(new MustacheScriptEngineService(setting)) ); ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, registry); - ScriptService scriptService = new ScriptService(setting, environment, engines, resourceWatcherService, scriptEngineRegistry, + ScriptService scriptService = new ScriptService(setting, environment, resourceWatcherService, scriptEngineRegistry, registry, scriptSettings); ClusterService clusterService = Mockito.mock(ClusterService.class); Mockito.when(clusterService.state()).thenReturn(ClusterState.builder(new ClusterName("_name")).build()); diff --git a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java index 9fe576c8dc5..9131921669f 100644 --- a/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java +++ b/elasticsearch/x-pack/graph/src/test/java/org/elasticsearch/xpack/graph/test/GraphTests.java @@ -15,6 +15,7 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.ScriptQueryBuilder; import org.elasticsearch.marvel.Monitoring; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.ScriptPlugin; import org.elasticsearch.script.AbstractSearchScript; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.NativeScriptFactory; @@ -34,6 +35,8 @@ import org.elasticsearch.xpack.graph.action.Vertex; import org.elasticsearch.xpack.graph.action.VertexRequest; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.Map; import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS; @@ -346,7 +349,7 @@ public class GraphTests extends ESSingleNodeTestCase { assertThat(why, strongVertex.getWeight(), greaterThan(weakVertex.getWeight())); } - public static class ScriptedTimeoutPlugin extends Plugin { + public static class ScriptedTimeoutPlugin extends Plugin implements ScriptPlugin { @Override public String name() { return "test-scripted-graph-timeout"; @@ -357,8 +360,9 @@ public class GraphTests extends ESSingleNodeTestCase { return "Test for scripted timeouts on graph searches"; } - public void onModule(ScriptModule module) { - module.registerScript(NativeTestScriptedTimeout.TEST_NATIVE_SCRIPT_TIMEOUT, NativeTestScriptedTimeout.Factory.class); + @Override + public List getNativeScripts() { + return Collections.singletonList(new NativeTestScriptedTimeout.Factory()); } } @@ -377,6 +381,11 @@ public class GraphTests extends ESSingleNodeTestCase { public boolean needsScores() { return false; } + + @Override + public String getName() { + return TEST_NATIVE_SCRIPT_TIMEOUT; + } } @Override diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 456f8db3598..17aefe14881 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -22,6 +22,8 @@ import org.elasticsearch.index.IndexModule; import org.elasticsearch.license.plugin.Licensing; import org.elasticsearch.marvel.Monitoring; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.ScriptPlugin; +import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptModule; import org.elasticsearch.shield.Security; import org.elasticsearch.shield.authc.AuthenticationModule; @@ -31,6 +33,7 @@ import org.elasticsearch.xpack.action.TransportXPackInfoAction; import org.elasticsearch.xpack.action.TransportXPackUsageAction; import org.elasticsearch.xpack.action.XPackInfoAction; import org.elasticsearch.xpack.action.XPackUsageAction; +import org.elasticsearch.xpack.common.ScriptServiceProxy; import org.elasticsearch.xpack.common.http.HttpClientModule; import org.elasticsearch.xpack.common.init.LazyInitializationModule; import org.elasticsearch.xpack.common.init.LazyInitializationService; @@ -55,7 +58,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -public class XPackPlugin extends Plugin { +public class XPackPlugin extends Plugin implements ScriptPlugin { public static final String NAME = "x-pack"; @@ -182,8 +185,9 @@ public class XPackPlugin extends Plugin { return builder.build(); } - public void onModule(ScriptModule module) { - watcher.onModule(module); + @Override + public ScriptContext.Plugin getCustomScriptContexts() { + return ScriptServiceProxy.INSTANCE; } public void onModule(SettingsModule module) { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index 2f8b1e1ce2f..50d34f72318 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -140,9 +140,6 @@ public class Watcher { return Settings.EMPTY; } - public void onModule(ScriptModule module) { - module.registerScriptContext(ScriptServiceProxy.INSTANCE); - } public void onModule(SettingsModule module) { for (TemplateConfig templateConfig : WatcherIndexTemplateRegistry.TEMPLATE_CONFIGS) { diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java index 6430fde4a16..31b4f8fb44f 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/MockMustacheScriptEngine.java @@ -5,10 +5,9 @@ */ package org.elasticsearch.script; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.xpack.common.text.DefaultTextTemplateEngine; -import java.util.Collections; -import java.util.List; import java.util.Map; /** @@ -27,10 +26,10 @@ public class MockMustacheScriptEngine extends MockScriptEngine { return NAME; } - public void onModule(ScriptModule module) { - module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(MockMustacheScriptEngine.class, NAME, true)); + @Override + public ScriptEngineService getScriptEngineService(Settings settings) { + return new MockMustacheScriptEngine(); } - } @Override @@ -51,4 +50,9 @@ public class MockMustacheScriptEngine extends MockScriptEngine { return super.compile(name, script, params); } + + @Override + public boolean isInlineScriptEnabled() { + return true; + } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java index c0cf787d7e8..ad593bfe8ac 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/script/SleepScriptEngine.java @@ -6,12 +6,13 @@ package org.elasticsearch.script; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.ScriptPlugin; import org.elasticsearch.search.lookup.SearchLookup; import java.io.IOException; import java.util.Collections; -import java.util.List; import java.util.Map; /** @@ -21,7 +22,7 @@ public class SleepScriptEngine implements ScriptEngineService { public static final String NAME = "sleep"; - public static class TestPlugin extends Plugin { + public static class TestPlugin extends Plugin implements ScriptPlugin { public TestPlugin() { } @@ -36,11 +37,10 @@ public class SleepScriptEngine implements ScriptEngineService { return "Mock script engine for integration tests"; } - public void onModule(ScriptModule module) { - module.addScriptEngine(new ScriptEngineRegistry.ScriptEngineRegistration(SleepScriptEngine.class, - SleepScriptEngine.NAME, true)); + @Override + public ScriptEngineService getScriptEngineService(Settings settings) { + return new SleepScriptEngine(); } - } @Override @@ -92,4 +92,8 @@ public class SleepScriptEngine implements ScriptEngineService { .params(Collections.singletonMap("millis", millis)).build(); } + @Override + public boolean isInlineScriptEnabled() { + return true; + } } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherTestUtils.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherTestUtils.java index e576cfd50ab..f11d07a3f4a 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherTestUtils.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/WatcherTestUtils.java @@ -254,7 +254,7 @@ public final class WatcherTestUtils { ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry); ClusterService clusterService = Mockito.mock(ClusterService.class); Mockito.when(clusterService.state()).thenReturn(ClusterState.builder(new ClusterName("_name")).build()); - return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), Collections.emptySet(), + return ScriptServiceProxy.of(new ScriptService(settings, new Environment(settings), new ResourceWatcherService(settings, tp), scriptEngineRegistry, scriptContextRegistry, scriptSettings), clusterService); } From b2c944a480d6195c395a4731f0015b3f62693959 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 16 Jun 2016 15:53:01 +0200 Subject: [PATCH 04/11] Cut over settings registration to a pull model elastic/elasticsearchelastic/elasticsearch#18890 (elastic/elasticsearch#2538) Followup for elastic/elasticsearchelastic/elasticsearch#18890 Original commit: elastic/x-pack-elasticsearch@a65ee6913f49dfe452c0a57c2e4af389a6a9ede4 --- .../org/elasticsearch/xpack/graph/Graph.java | 13 ++-- .../license/plugin/Licensing.java | 5 +- .../consumer/TestConsumerPluginBase.java | 14 ++--- .../org/elasticsearch/marvel/Monitoring.java | 2 +- .../marvel/MonitoringSettings.java | 32 +++++----- .../org/elasticsearch/shield/Security.java | 63 ++++++++++--------- .../shield/audit/AuditTrailModule.java | 10 +-- .../shield/audit/index/IndexAuditTrail.java | 18 +++--- .../audit/logfile/LoggingAuditTrail.java | 9 +-- .../authc/InternalAuthenticationService.java | 7 ++- .../elasticsearch/shield/authc/Realms.java | 4 +- .../authc/esnative/NativeUsersStore.java | 8 +-- .../authz/InternalAuthorizationService.java | 4 +- .../shield/authz/store/FileRolesStore.java | 4 +- .../shield/authz/store/NativeRolesStore.java | 9 ++- .../shield/crypto/InternalCryptoService.java | 10 +-- .../shield/ssl/SSLConfiguration.java | 38 +++++------ .../shield/transport/filter/IPFilter.java | 16 ++--- .../netty/ShieldNettyHttpServerTransport.java | 9 +-- .../transport/netty/ShieldNettyTransport.java | 21 ++++--- .../shield/user/AnonymousUser.java | 11 +++- .../shield/audit/AuditTrailModuleTests.java | 22 +++---- .../test/SettingsFilterTests.java | 15 +++-- .../org/elasticsearch/xpack/XPackPlugin.java | 44 ++++++++----- .../xpack/notification/Notification.java | 26 ++++---- .../elasticsearch/xpack/watcher/Watcher.java | 45 ++++++------- .../WatcherIndexTemplateRegistryTests.java | 7 ++- 27 files changed, 254 insertions(+), 212 deletions(-) diff --git a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java index 9c435dba74f..b21f1884bc5 100644 --- a/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java +++ b/elasticsearch/x-pack/graph/src/main/java/org/elasticsearch/xpack/graph/Graph.java @@ -20,6 +20,7 @@ import org.elasticsearch.xpack.graph.rest.action.RestGraphAction; import java.util.Collection; import java.util.Collections; +import java.util.List; public class Graph extends Plugin { @@ -69,10 +70,12 @@ public class Graph extends Plugin { if (enabled && transportClientMode == false) { module.registerRestHandler(RestGraphAction.class); } - } - - public void onModule(SettingsModule module) { - module.registerSetting(Setting.boolSetting(XPackPlugin.featureEnabledSetting(NAME), true, Setting.Property.NodeScope)); - } + } + + + @Override + public List> getSettings() { + return Collections.singletonList(Setting.boolSetting(XPackPlugin.featureEnabledSetting(NAME), true, Setting.Property.NodeScope)); + } } diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java index 22c95840dd9..0f52530f74f 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/Licensing.java @@ -28,6 +28,7 @@ import org.elasticsearch.license.plugin.rest.RestPutLicenseAction; import java.util.Collection; import java.util.Collections; +import java.util.List; import static org.elasticsearch.xpack.XPackPlugin.isTribeClientNode; import static org.elasticsearch.xpack.XPackPlugin.isTribeNode; @@ -80,8 +81,8 @@ public class Licensing { return Collections.emptyList(); } - public void onModule(SettingsModule module) { + public List> getSettings() { // TODO convert this wildcard to a real setting - module.registerSetting(Setting.groupSetting("license.", Setting.Property.NodeScope)); + return Collections.singletonList(Setting.groupSetting("license.", Setting.Property.NodeScope)); } } diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java index 46c50b0375c..4261e375d49 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/license/plugin/consumer/TestConsumerPluginBase.java @@ -14,7 +14,9 @@ import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.plugins.Plugin; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.List; public abstract class TestConsumerPluginBase extends Plugin { @@ -44,13 +46,11 @@ public abstract class TestConsumerPluginBase extends Plugin { return services; } - public void onModule(SettingsModule module) { - try { - module.registerSetting(Setting.simpleString("_trial_license_duration_in_seconds", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("_grace_duration_in_seconds", Setting.Property.NodeScope)); - } catch (IllegalArgumentException ex) { - // already loaded - } + @Override + public List> getSettings() { + return Arrays.asList(Setting.simpleString("_trial_license_duration_in_seconds", Setting.Property.NodeScope, + Setting.Property.Shared), Setting.simpleString("_grace_duration_in_seconds", Setting.Property.NodeScope, + Setting.Property.Shared)); } public abstract Class service(); diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/Monitoring.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/Monitoring.java index 8b29f92ffa5..4ec351b8ee6 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/Monitoring.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/Monitoring.java @@ -9,6 +9,7 @@ import org.elasticsearch.action.ActionModule; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.Module; import org.elasticsearch.common.network.NetworkModule; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.marvel.action.MonitoringBulkAction; @@ -80,7 +81,6 @@ public class Monitoring { } public void onModule(SettingsModule module) { - MonitoringSettings.register(module); } public void onModule(ActionModule module) { diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MonitoringSettings.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MonitoringSettings.java index 3ee8afcce21..714f4c9c9ae 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MonitoringSettings.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/MonitoringSettings.java @@ -15,6 +15,7 @@ import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.xpack.XPackPlugin; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -125,22 +126,23 @@ public class MonitoringSettings extends AbstractComponent { public static final Setting EXPORTERS_SETTINGS = groupSetting(key("agent.exporters."), Property.Dynamic, Property.NodeScope); - static void register(SettingsModule module) { - module.registerSetting(INDICES); - module.registerSetting(INTERVAL); - module.registerSetting(INDEX_RECOVERY_TIMEOUT); - module.registerSetting(INDEX_STATS_TIMEOUT); - module.registerSetting(INDICES_STATS_TIMEOUT); - module.registerSetting(INDEX_RECOVERY_ACTIVE_ONLY); - module.registerSetting(COLLECTORS); - module.registerSetting(CLUSTER_STATE_TIMEOUT); - module.registerSetting(CLUSTER_STATS_TIMEOUT); - module.registerSetting(HISTORY_DURATION); - module.registerSetting(EXPORTERS_SETTINGS); - module.registerSetting(ENABLED); + public static List> getSettings() { + return Arrays.asList(INDICES, + INTERVAL, + INDEX_RECOVERY_TIMEOUT, + INDEX_STATS_TIMEOUT, + INDICES_STATS_TIMEOUT, + INDEX_RECOVERY_ACTIVE_ONLY, + COLLECTORS, + CLUSTER_STATE_TIMEOUT, + CLUSTER_STATS_TIMEOUT, + HISTORY_DURATION, + EXPORTERS_SETTINGS, + ENABLED); + } - module.registerSettingsFilter("xpack.monitoring.agent.exporters.*.auth.*"); - module.registerSettingsFilter("xpack.monitoring.agent.exporters.*.ssl.*"); + public static List getSettingsFilter() { + return Arrays.asList("xpack.monitoring.agent.exporters.*.auth.*", "xpack.monitoring.agent.exporters.*.ssl.*"); } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/Security.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/Security.java index 6d63c016a03..aaa68307b1b 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/Security.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/Security.java @@ -18,7 +18,6 @@ import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.index.IndexModule; import org.elasticsearch.shield.action.ShieldActionModule; @@ -188,62 +187,70 @@ public class Security { return settingsBuilder.build(); } - public void onModule(SettingsModule settingsModule) { + public List> getSettings() { + List> settingsList = new ArrayList<>(); // always register for both client and node modes - XPackPlugin.registerFeatureEnabledSettings(settingsModule, NAME, true); - settingsModule.registerSetting(USER_SETTING); + XPackPlugin.addFeatureEnabledSettings(settingsList, NAME, true); + settingsList.add(USER_SETTING); // SSL settings - SSLConfiguration.Global.registerSettings(settingsModule); + SSLConfiguration.Global.addSettings(settingsList); // transport settings - ShieldNettyTransport.registerSettings(settingsModule); + ShieldNettyTransport.addSettings(settingsList); if (transportClientMode) { - return; + return settingsList; } // The following just apply in node mode - XPackPlugin.registerFeatureEnabledSettings(settingsModule, DLS_FLS_FEATURE, true); + XPackPlugin.addFeatureEnabledSettings(settingsList, DLS_FLS_FEATURE, true); // IP Filter settings - IPFilter.registerSettings(settingsModule); + IPFilter.addSettings(settingsList); // audit settings - AuditTrailModule.registerSettings(settingsModule); + AuditTrailModule.addSettings(settingsList); // authentication settings - FileRolesStore.registerSettings(settingsModule); - AnonymousUser.registerSettings(settingsModule); - Realms.registerSettings(settingsModule); - NativeUsersStore.registerSettings(settingsModule); - NativeRolesStore.registerSettings(settingsModule); - InternalAuthenticationService.registerSettings(settingsModule); - InternalAuthorizationService.registerSettings(settingsModule); + FileRolesStore.addSettings(settingsList); + AnonymousUser.addSettings(settingsList); + Realms.addSettings(settingsList); + NativeUsersStore.addSettings(settingsList); + NativeRolesStore.addSettings(settingsList); + InternalAuthenticationService.addSettings(settingsList); + InternalAuthorizationService.addSettings(settingsList); // HTTP settings - ShieldNettyHttpServerTransport.registerSettings(settingsModule); + ShieldNettyHttpServerTransport.addSettings(settingsList); // encryption settings - InternalCryptoService.registerSettings(settingsModule); + InternalCryptoService.addSettings(settingsList); // hide settings - settingsModule.registerSetting(Setting.listSetting(setting("hide_settings"), Collections.emptyList(), Function.identity(), + settingsList.add(Setting.listSetting(setting("hide_settings"), Collections.emptyList(), Function.identity(), Property.NodeScope, Property.Filtered)); + return settingsList; + } + + + public List getSettingsFilter() { + ArrayList settingsFilter = new ArrayList<>(); String[] asArray = settings.getAsArray(setting("hide_settings")); for (String pattern : asArray) { - settingsModule.registerSettingsFilter(pattern); + settingsFilter.add(pattern); } - settingsModule.registerSettingsFilter(setting("authc.realms.*.bind_dn")); - settingsModule.registerSettingsFilter(setting("authc.realms.*.bind_password")); - settingsModule.registerSettingsFilter(setting("authc.realms.*." + SessionFactory.HOSTNAME_VERIFICATION_SETTING)); - settingsModule.registerSettingsFilter(setting("authc.realms.*.truststore.password")); - settingsModule.registerSettingsFilter(setting("authc.realms.*.truststore.path")); - settingsModule.registerSettingsFilter(setting("authc.realms.*.truststore.algorithm")); + settingsFilter.add(setting("authc.realms.*.bind_dn")); + settingsFilter.add(setting("authc.realms.*.bind_password")); + settingsFilter.add(setting("authc.realms.*." + SessionFactory.HOSTNAME_VERIFICATION_SETTING)); + settingsFilter.add(setting("authc.realms.*.truststore.password")); + settingsFilter.add(setting("authc.realms.*.truststore.path")); + settingsFilter.add(setting("authc.realms.*.truststore.algorithm")); // hide settings where we don't define them - they are part of a group... - settingsModule.registerSettingsFilter("transport.profiles.*." + setting("*")); + settingsFilter.add("transport.profiles.*." + setting("*")); + return settingsFilter; } public void onIndexModule(IndexModule module) { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailModule.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailModule.java index f58e0f01b81..1b1a18c0e21 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailModule.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailModule.java @@ -102,10 +102,10 @@ public class AuditTrailModule extends AbstractShieldModule.Node { return false; } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(ENABLED_SETTING); - settingsModule.registerSetting(OUTPUTS_SETTING); - LoggingAuditTrail.registerSettings(settingsModule); - IndexAuditTrail.registerSettings(settingsModule); + public static void addSettings(List> settings) { + settings.add(ENABLED_SETTING); + settings.add(OUTPUTS_SETTING); + LoggingAuditTrail.registerSettings(settings); + IndexAuditTrail.registerSettings(settings); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java index 1e2b4665d66..da8163139b1 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java @@ -877,15 +877,15 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(INDEX_SETTINGS); - settingsModule.registerSetting(EXCLUDE_EVENT_SETTINGS); - settingsModule.registerSetting(INCLUDE_EVENT_SETTINGS); - settingsModule.registerSetting(ROLLOVER_SETTING); - settingsModule.registerSetting(BULK_SIZE_SETTING); - settingsModule.registerSetting(FLUSH_TIMEOUT_SETTING); - settingsModule.registerSetting(QUEUE_SIZE_SETTING); - settingsModule.registerSetting(REMOTE_CLIENT_SETTINGS); + public static void registerSettings(List> settings) { + settings.add(INDEX_SETTINGS); + settings.add(EXCLUDE_EVENT_SETTINGS); + settings.add(INCLUDE_EVENT_SETTINGS); + settings.add(ROLLOVER_SETTING); + settings.add(BULK_SIZE_SETTING); + settings.add(FLUSH_TIMEOUT_SETTING); + settings.add(QUEUE_SIZE_SETTING); + settings.add(REMOTE_CLIENT_SETTINGS); } private class QueueConsumer extends Thread { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java index 92396f02c94..4f4f6942883 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java @@ -35,6 +35,7 @@ import org.elasticsearch.transport.TransportMessage; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.List; import static org.elasticsearch.common.Strings.arrayToCommaDelimitedString; import static org.elasticsearch.shield.audit.AuditUtil.indices; @@ -463,9 +464,9 @@ public class LoggingAuditTrail extends AbstractLifecycleComponent> settings) { + settings.add(HOST_ADDRESS_SETTING); + settings.add(HOST_NAME_SETTING); + settings.add(NODE_NAME_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/InternalAuthenticationService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/InternalAuthenticationService.java index 343b08d50c4..4805354c83e 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/InternalAuthenticationService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/InternalAuthenticationService.java @@ -29,6 +29,7 @@ import org.elasticsearch.transport.TransportMessage; import java.io.IOException; import java.util.Base64; +import java.util.List; import static org.elasticsearch.shield.Security.setting; import static org.elasticsearch.shield.support.Exceptions.authenticationError; @@ -316,9 +317,9 @@ public class InternalAuthenticationService extends AbstractComponent implements return null; } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(SIGN_USER_HEADER); - settingsModule.registerSetting(RUN_AS_ENABLED); + public static void addSettings(List> settings) { + settings.add(SIGN_USER_HEADER); + settings.add(RUN_AS_ENABLED); } // these methods are package private for testing. They are also needed so that a AuditableRequest can be created in tests diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/Realms.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/Realms.java index 604110c6ddc..b2981ec9d1f 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/Realms.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/Realms.java @@ -212,7 +212,7 @@ public class Realms extends AbstractLifecycleComponent implements Iterab } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(REALMS_GROUPS_SETTINGS); + public static void addSettings(List> settingsModule) { + settingsModule.add(REALMS_GROUPS_SETTINGS); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/esnative/NativeUsersStore.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/esnative/NativeUsersStore.java index ce56350aed9..052813d801f 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/esnative/NativeUsersStore.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/esnative/NativeUsersStore.java @@ -867,9 +867,9 @@ public class NativeUsersStore extends AbstractComponent implements ClusterStateL void onUsersChanged(List username); } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(SCROLL_SIZE_SETTING); - settingsModule.registerSetting(SCROLL_KEEP_ALIVE_SETTING); - settingsModule.registerSetting(POLL_INTERVAL_SETTING); + public static void addSettings(List> settings) { + settings.add(SCROLL_SIZE_SETTING); + settings.add(SCROLL_KEEP_ALIVE_SETTING); + settings.add(POLL_INTERVAL_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java index a640b080cf6..ed8e4835333 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java @@ -357,7 +357,7 @@ public class InternalAuthorizationService extends AbstractComponent implements A return authorizationError("action [{}] is unauthorized for user [{}]", action, user.principal()); } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING); + public static void addSettings(List> settings) { + settings.add(ANONYMOUS_AUTHORIZATION_EXCEPTION_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/FileRolesStore.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/FileRolesStore.java index 389c70254e0..19edfa313cb 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/FileRolesStore.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/FileRolesStore.java @@ -260,7 +260,7 @@ public class FileRolesStore extends AbstractLifecycleComponent imple } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(ROLES_FILE_SETTING); + public static void addSettings(List> settings) { + settings.add(ROLES_FILE_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/NativeRolesStore.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/NativeRolesStore.java index 46bfb0c3c71..e977dc77b45 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/NativeRolesStore.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/store/NativeRolesStore.java @@ -31,7 +31,6 @@ import org.elasticsearch.common.inject.Provider; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.util.concurrent.AbstractRunnable; import org.elasticsearch.common.xcontent.ToXContent; @@ -604,9 +603,9 @@ public class NativeRolesStore extends AbstractComponent implements RolesStore, C } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(SCROLL_SIZE_SETTING); - settingsModule.registerSetting(SCROLL_KEEP_ALIVE_SETTING); - settingsModule.registerSetting(POLL_INTERVAL_SETTING); + public static void addSettings(List> settings) { + settings.add(SCROLL_SIZE_SETTING); + settings.add(SCROLL_KEEP_ALIVE_SETTING); + settings.add(POLL_INTERVAL_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java index 30994e722f2..ef96be6b210 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/crypto/InternalCryptoService.java @@ -676,10 +676,10 @@ public class InternalCryptoService extends AbstractLifecycleComponent> settings) { + settings.add(FILE_SETTING); + settings.add(ENCRYPTION_KEY_LENGTH_SETTING); + settings.add(ENCRYPTION_KEY_ALGO_SETTING); + settings.add(ENCRYPTION_ALGO_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ssl/SSLConfiguration.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ssl/SSLConfiguration.java index 2286bff2cbb..cabac13e0f7 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ssl/SSLConfiguration.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/ssl/SSLConfiguration.java @@ -147,25 +147,25 @@ public abstract class SSLConfiguration { static final Setting INCLUDE_JDK_CERTS_SETTING = Setting.boolSetting(globalKey(Custom.INCLUDE_JDK_CERTS_SETTING), true, Property.NodeScope, Property.Filtered); - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(Global.CIPHERS_SETTING); - settingsModule.registerSetting(Global.SUPPORTED_PROTOCOLS_SETTING); - settingsModule.registerSetting(Global.KEYSTORE_PATH_SETTING); - settingsModule.registerSetting(Global.KEYSTORE_PASSWORD_SETTING); - settingsModule.registerSetting(Global.KEYSTORE_ALGORITHM_SETTING); - settingsModule.registerSetting(Global.KEYSTORE_KEY_PASSWORD_SETTING); - settingsModule.registerSetting(Global.KEY_PATH_SETTING); - settingsModule.registerSetting(Global.KEY_PASSWORD_SETTING); - settingsModule.registerSetting(Global.CERT_SETTING); - settingsModule.registerSetting(Global.TRUSTSTORE_PATH_SETTING); - settingsModule.registerSetting(Global.TRUSTSTORE_PASSWORD_SETTING); - settingsModule.registerSetting(Global.TRUSTSTORE_ALGORITHM_SETTING); - settingsModule.registerSetting(Global.PROTOCOL_SETTING); - settingsModule.registerSetting(Global.SESSION_CACHE_SIZE_SETTING); - settingsModule.registerSetting(Global.SESSION_CACHE_TIMEOUT_SETTING); - settingsModule.registerSetting(Global.CA_PATHS_SETTING); - settingsModule.registerSetting(Global.INCLUDE_JDK_CERTS_SETTING); - settingsModule.registerSetting(Global.RELOAD_ENABLED_SETTING); + public static void addSettings(List> settings) { + settings.add(Global.CIPHERS_SETTING); + settings.add(Global.SUPPORTED_PROTOCOLS_SETTING); + settings.add(Global.KEYSTORE_PATH_SETTING); + settings.add(Global.KEYSTORE_PASSWORD_SETTING); + settings.add(Global.KEYSTORE_ALGORITHM_SETTING); + settings.add(Global.KEYSTORE_KEY_PASSWORD_SETTING); + settings.add(Global.KEY_PATH_SETTING); + settings.add(Global.KEY_PASSWORD_SETTING); + settings.add(Global.CERT_SETTING); + settings.add(Global.TRUSTSTORE_PATH_SETTING); + settings.add(Global.TRUSTSTORE_PASSWORD_SETTING); + settings.add(Global.TRUSTSTORE_ALGORITHM_SETTING); + settings.add(Global.PROTOCOL_SETTING); + settings.add(Global.SESSION_CACHE_SIZE_SETTING); + settings.add(Global.SESSION_CACHE_TIMEOUT_SETTING); + settings.add(Global.CA_PATHS_SETTING); + settings.add(Global.INCLUDE_JDK_CERTS_SETTING); + settings.add(Global.RELOAD_ENABLED_SETTING); } private final KeyConfig keyConfig; diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java index b7df9e2234c..ee1724b0f63 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/filter/IPFilter.java @@ -260,13 +260,13 @@ public class IPFilter { updateRules(); } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(ALLOW_BOUND_ADDRESSES_SETTING); - settingsModule.registerSetting(IP_FILTER_ENABLED_SETTING); - settingsModule.registerSetting(IP_FILTER_ENABLED_HTTP_SETTING); - settingsModule.registerSetting(HTTP_FILTER_ALLOW_SETTING); - settingsModule.registerSetting(HTTP_FILTER_DENY_SETTING); - settingsModule.registerSetting(TRANSPORT_FILTER_ALLOW_SETTING); - settingsModule.registerSetting(TRANSPORT_FILTER_DENY_SETTING); + public static void addSettings(List> settings) { + settings.add(ALLOW_BOUND_ADDRESSES_SETTING); + settings.add(IP_FILTER_ENABLED_SETTING); + settings.add(IP_FILTER_ENABLED_HTTP_SETTING); + settings.add(HTTP_FILTER_ALLOW_SETTING); + settings.add(HTTP_FILTER_DENY_SETTING); + settings.add(TRANSPORT_FILTER_ALLOW_SETTING); + settings.add(TRANSPORT_FILTER_DENY_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java index c477f94312c..51545e62a75 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyHttpServerTransport.java @@ -27,6 +27,7 @@ import org.jboss.netty.handler.ssl.SslHandler; import javax.net.ssl.SSLEngine; import java.util.Collections; +import java.util.List; import static org.elasticsearch.http.HttpTransportSettings.SETTING_HTTP_COMPRESSION; import static org.elasticsearch.shield.Security.setting; @@ -128,10 +129,10 @@ public class ShieldNettyHttpServerTransport extends NettyHttpServerTransport { } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(SSL_SETTING); - settingsModule.registerSetting(CLIENT_AUTH_SETTING); - settingsModule.registerSetting(DEPRECATED_SSL_SETTING); + public static void addSettings(List> settings) { + settings.add(SSL_SETTING); + settings.add(CLIENT_AUTH_SETTING); + settings.add(DEPRECATED_SSL_SETTING); } public static void overrideSettings(Settings.Builder settingsBuilder, Settings settings) { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java index d226a5ba4b9..89cf5b1287b 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransport.java @@ -34,6 +34,7 @@ import org.jboss.netty.handler.ssl.SslHandler; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; import java.net.InetSocketAddress; +import java.util.List; import static org.elasticsearch.shield.Security.featureEnabledSetting; import static org.elasticsearch.shield.Security.setting; @@ -249,17 +250,17 @@ public class ShieldNettyTransport extends NettyTransport { } } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(SSL_SETTING); - settingsModule.registerSetting(HOSTNAME_VERIFICATION_SETTING); - settingsModule.registerSetting(HOSTNAME_VERIFICATION_RESOLVE_NAME_SETTING); - settingsModule.registerSetting(CLIENT_AUTH_SETTING); - settingsModule.registerSetting(PROFILE_SSL_SETTING); - settingsModule.registerSetting(PROFILE_CLIENT_AUTH_SETTING); + public static void addSettings(List> settingsModule) { + settingsModule.add(SSL_SETTING); + settingsModule.add(HOSTNAME_VERIFICATION_SETTING); + settingsModule.add(HOSTNAME_VERIFICATION_RESOLVE_NAME_SETTING); + settingsModule.add(CLIENT_AUTH_SETTING); + settingsModule.add(PROFILE_SSL_SETTING); + settingsModule.add(PROFILE_CLIENT_AUTH_SETTING); // deprecated transport settings - settingsModule.registerSetting(DEPRECATED_SSL_SETTING); - settingsModule.registerSetting(DEPRECATED_PROFILE_SSL_SETTING); - settingsModule.registerSetting(DEPRECATED_HOSTNAME_VERIFICATION_SETTING); + settingsModule.add(DEPRECATED_SSL_SETTING); + settingsModule.add(DEPRECATED_PROFILE_SSL_SETTING); + settingsModule.add(DEPRECATED_HOSTNAME_VERIFICATION_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/user/AnonymousUser.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/user/AnonymousUser.java index 818be16d489..55742e31f2b 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/user/AnonymousUser.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/user/AnonymousUser.java @@ -12,6 +12,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.shield.user.User.ReservedUser; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -80,8 +81,12 @@ public class AnonymousUser extends ReservedUser { return roles; } - public static void registerSettings(SettingsModule settingsModule) { - settingsModule.registerSetting(USERNAME_SETTING); - settingsModule.registerSetting(ROLES_SETTING); + public static List> getSettings() { + return Arrays.asList(); + } + + public static void addSettings(List> settingsList) { + settingsList.add(USERNAME_SETTING); + settingsList.add(ROLES_SETTING); } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/audit/AuditTrailModuleTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/audit/AuditTrailModuleTests.java index 46bb410fca3..b7ae372caf7 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/audit/AuditTrailModuleTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/audit/AuditTrailModuleTests.java @@ -11,15 +11,14 @@ import org.elasticsearch.common.inject.Injector; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.network.NetworkService; -import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsModule; -import org.elasticsearch.indices.breaker.CircuitBreakerModule; +import org.elasticsearch.indices.breaker.CircuitBreakerService; +import org.elasticsearch.node.Node; import org.elasticsearch.shield.audit.logfile.LoggingAuditTrail; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.threadpool.ThreadPoolModule; import org.elasticsearch.transport.Transport; import org.elasticsearch.transport.local.LocalTransport; @@ -36,8 +35,7 @@ public class AuditTrailModuleTests extends ESTestCase { .put("client.type", "node") .put(AuditTrailModule.ENABLED_SETTING.getKey(), false) .build(); - SettingsModule settingsModule = new SettingsModule(settings); - settingsModule.registerSetting(AuditTrailModule.ENABLED_SETTING); + SettingsModule settingsModule = new SettingsModule(settings, AuditTrailModule.ENABLED_SETTING); Injector injector = Guice.createInjector(settingsModule, new AuditTrailModule(settings)); AuditTrail auditTrail = injector.getInstance(AuditTrail.class); assertThat(auditTrail, is(AuditTrail.NOOP)); @@ -58,8 +56,7 @@ public class AuditTrailModuleTests extends ESTestCase { .build(); ThreadPool pool = new TestThreadPool("testLogFile"); try { - SettingsModule settingsModule = new SettingsModule(settings); - settingsModule.registerSetting(AuditTrailModule.ENABLED_SETTING); + SettingsModule settingsModule = new SettingsModule(settings, AuditTrailModule.ENABLED_SETTING); Injector injector = Guice.createInjector( settingsModule, new NetworkModule(new NetworkService(settings), settings, false, new NamedWriteableRegistry()) { @@ -69,8 +66,11 @@ public class AuditTrailModuleTests extends ESTestCase { } }, new AuditTrailModule(settings), - new CircuitBreakerModule(settings), - new ThreadPoolModule(pool), + b -> { + b.bind(CircuitBreakerService.class).toInstance(Node.createCircuitBreakerService(settingsModule.getSettings(), + settingsModule.getClusterSettings())); + b.bind(ThreadPool.class).toInstance(pool); + }, new Version.Module(Version.CURRENT) ); AuditTrail auditTrail = injector.getInstance(AuditTrail.class); @@ -90,9 +90,7 @@ public class AuditTrailModuleTests extends ESTestCase { .put(AuditTrailModule.OUTPUTS_SETTING.getKey() , "foo") .put("client.type", "node") .build(); - SettingsModule settingsModule = new SettingsModule(settings); - settingsModule.registerSetting(AuditTrailModule.ENABLED_SETTING); - settingsModule.registerSetting(AuditTrailModule.OUTPUTS_SETTING); + SettingsModule settingsModule = new SettingsModule(settings, AuditTrailModule.ENABLED_SETTING, AuditTrailModule.OUTPUTS_SETTING); try { Guice.createInjector(settingsModule, new AuditTrailModule(settings)); fail("Expect initialization to fail when an unknown audit trail output is configured"); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/SettingsFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/SettingsFilterTests.java index 945472b94c3..767b656b666 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/SettingsFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/SettingsFilterTests.java @@ -15,7 +15,9 @@ import org.elasticsearch.shield.ssl.SSLConfiguration; import org.elasticsearch.xpack.XPackPlugin; import org.hamcrest.Matcher; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.hamcrest.CoreMatchers.nullValue; @@ -85,13 +87,14 @@ public class SettingsFilterTests extends ESTestCase { .build(); XPackPlugin xPackPlugin = new XPackPlugin(settings); - SettingsModule settingsModule = new SettingsModule(settings); + List> settingList = new ArrayList<>(); + settingList.add(Setting.simpleString("foo.bar", Setting.Property.NodeScope)); + settingList.add(Setting.simpleString("foo.baz", Setting.Property.NodeScope)); + settingList.add(Setting.simpleString("bar.baz", Setting.Property.NodeScope)); + settingList.add(Setting.simpleString("baz.foo", Setting.Property.NodeScope)); + settingList.addAll(xPackPlugin.getSettings()); // custom settings, potentially added by a plugin - settingsModule.registerSetting(Setting.simpleString("foo.bar", Setting.Property.NodeScope)); - settingsModule.registerSetting(Setting.simpleString("foo.baz", Setting.Property.NodeScope)); - settingsModule.registerSetting(Setting.simpleString("bar.baz", Setting.Property.NodeScope)); - settingsModule.registerSetting(Setting.simpleString("baz.foo", Setting.Property.NodeScope)); - xPackPlugin.onModule(settingsModule); + SettingsModule settingsModule = new SettingsModule(settings, settingList, xPackPlugin.getSettingsFilter()); Injector injector = Guice.createInjector(settingsModule); SettingsFilter settingsFilter = injector.getInstance(SettingsFilter.class); diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index 17aefe14881..66d5a20b1f4 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -21,6 +21,7 @@ import org.elasticsearch.env.Environment; import org.elasticsearch.index.IndexModule; import org.elasticsearch.license.plugin.Licensing; import org.elasticsearch.marvel.Monitoring; +import org.elasticsearch.marvel.MonitoringSettings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ScriptPlugin; import org.elasticsearch.script.ScriptContext; @@ -28,7 +29,6 @@ import org.elasticsearch.script.ScriptModule; import org.elasticsearch.shield.Security; import org.elasticsearch.shield.authc.AuthenticationModule; import org.elasticsearch.threadpool.ExecutorBuilder; -import org.elasticsearch.threadpool.ThreadPoolModule; import org.elasticsearch.xpack.action.TransportXPackInfoAction; import org.elasticsearch.xpack.action.TransportXPackUsageAction; import org.elasticsearch.xpack.action.XPackInfoAction; @@ -190,22 +190,34 @@ public class XPackPlugin extends Plugin implements ScriptPlugin { return ScriptServiceProxy.INSTANCE; } - public void onModule(SettingsModule module) { + @Override + public List> getSettings() { + ArrayList> settings = new ArrayList<>(); + settings.addAll(notification.getSettings()); + settings.addAll(security.getSettings()); + settings.addAll(MonitoringSettings.getSettings()); + settings.addAll(watcher.getSettings()); + settings.addAll(graph.getSettings()); + settings.addAll(licensing.getSettings()); // we add the `xpack.version` setting to all internal indices - module.registerSetting(Setting.simpleString("index.xpack.version", Setting.Property.IndexScope)); + settings.add(Setting.simpleString("index.xpack.version", Setting.Property.IndexScope)); // http settings - module.registerSetting(Setting.simpleString("xpack.http.default_read_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.http.default_connection_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.groupSetting("xpack.http.ssl.", Setting.Property.NodeScope)); - module.registerSetting(Setting.groupSetting("xpack.http.proxy.", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.http.default_read_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.http.default_connection_timeout", Setting.Property.NodeScope)); + settings.add(Setting.groupSetting("xpack.http.ssl.", Setting.Property.NodeScope)); + settings.add(Setting.groupSetting("xpack.http.proxy.", Setting.Property.NodeScope)); + return settings; + } - notification.onModule(module); - security.onModule(module); - monitoring.onModule(module); - watcher.onModule(module); - graph.onModule(module); - licensing.onModule(module); + @Override + public List getSettingsFilter() { + List filters = new ArrayList<>(); + filters.addAll(notification.getSettingsFilter()); + filters.addAll(security.getSettingsFilter()); + filters.addAll(MonitoringSettings.getSettingsFilter()); + filters.addAll(graph.getSettingsFilter()); + return filters; } @Override @@ -309,9 +321,9 @@ public class XPackPlugin extends Plugin implements ScriptPlugin { * * {@code ".enabled": true | false} */ - public static void registerFeatureEnabledSettings(SettingsModule settingsModule, String featureName, boolean defaultValue) { - settingsModule.registerSetting(Setting.boolSetting(featureEnabledSetting(featureName), defaultValue, Setting.Property.NodeScope)); - settingsModule.registerSetting(Setting.boolSetting(legacyFeatureEnabledSetting(featureName), + public static void addFeatureEnabledSettings(List> settingsList, String featureName, boolean defaultValue) { + settingsList.add(Setting.boolSetting(featureEnabledSetting(featureName), defaultValue, Setting.Property.NodeScope)); + settingsList.add(Setting.boolSetting(legacyFeatureEnabledSetting(featureName), defaultValue, Setting.Property.NodeScope)); } diff --git a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/notification/Notification.java b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/notification/Notification.java index a1d2e67b6fc..755b18098ae 100644 --- a/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/notification/Notification.java +++ b/elasticsearch/x-pack/src/main/java/org/elasticsearch/xpack/notification/Notification.java @@ -36,18 +36,22 @@ public class Notification { this.transportClient = "transport".equals(settings.get(Client.CLIENT_TYPE_SETTING_S.getKey())); } - public void onModule(SettingsModule module) { - module.registerSetting(InternalSlackService.SLACK_ACCOUNT_SETTING); - module.registerSetting(InternalEmailService.EMAIL_ACCOUNT_SETTING); - module.registerSetting(InternalHipChatService.HIPCHAT_ACCOUNT_SETTING); - module.registerSetting(InternalPagerDutyService.PAGERDUTY_ACCOUNT_SETTING); + public List> getSettings() { + return Arrays.asList(InternalSlackService.SLACK_ACCOUNT_SETTING, + InternalEmailService.EMAIL_ACCOUNT_SETTING, + InternalHipChatService.HIPCHAT_ACCOUNT_SETTING, + InternalPagerDutyService.PAGERDUTY_ACCOUNT_SETTING); + } - module.registerSettingsFilter("xpack.notification.email.account.*.smtp.password"); - module.registerSettingsFilter("xpack.notification.slack.account.*.url"); - module.registerSettingsFilter("xpack.notification.pagerduty.account.*.url"); - module.registerSettingsFilter("xpack.notification.pagerduty." + PagerDutyAccount.SERVICE_KEY_SETTING); - module.registerSettingsFilter("xpack.notification.pagerduty.account.*." + PagerDutyAccount.SERVICE_KEY_SETTING); - module.registerSettingsFilter("xpack.notification.hipchat.account.*.auth_token"); + public List getSettingsFilter() { + ArrayList settingsFilter = new ArrayList<>(); + settingsFilter.add("xpack.notification.email.account.*.smtp.password"); + settingsFilter.add("xpack.notification.slack.account.*.url"); + settingsFilter.add("xpack.notification.pagerduty.account.*.url"); + settingsFilter.add("xpack.notification.pagerduty." + PagerDutyAccount.SERVICE_KEY_SETTING); + settingsFilter.add("xpack.notification.pagerduty.account.*." + PagerDutyAccount.SERVICE_KEY_SETTING); + settingsFilter.add("xpack.notification.hipchat.account.*.auth_token"); + return settingsFilter; } public Collection> nodeServices() { diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java index 50d34f72318..aaaa604764f 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/xpack/watcher/Watcher.java @@ -19,12 +19,10 @@ import org.elasticsearch.common.network.NetworkModule; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.script.ScriptModule; import org.elasticsearch.threadpool.ExecutorBuilder; import org.elasticsearch.threadpool.FixedExecutorBuilder; -import org.elasticsearch.threadpool.ThreadPoolModule; import org.elasticsearch.xpack.XPackPlugin; import org.elasticsearch.xpack.common.init.LazyInitializationModule; import org.elasticsearch.xpack.watcher.actions.WatcherActionModule; @@ -141,29 +139,31 @@ public class Watcher { } - public void onModule(SettingsModule module) { + public List> getSettings() { + List> settings = new ArrayList<>(); for (TemplateConfig templateConfig : WatcherIndexTemplateRegistry.TEMPLATE_CONFIGS) { - module.registerSetting(templateConfig.getSetting()); + settings.add(templateConfig.getSetting()); } - module.registerSetting(INDEX_WATCHER_VERSION_SETTING); - module.registerSetting(INDEX_WATCHER_TEMPLATE_VERSION_SETTING); - module.registerSetting(Setting.intSetting("xpack.watcher.execution.scroll.size", 0, Setting.Property.NodeScope)); - module.registerSetting(Setting.intSetting("xpack.watcher.watch.scroll.size", 0, Setting.Property.NodeScope)); - module.registerSetting(Setting.boolSetting(XPackPlugin.featureEnabledSetting(Watcher.NAME), true, Setting.Property.NodeScope)); - module.registerSetting(ENCRYPT_SENSITIVE_DATA_SETTING); + settings.add(INDEX_WATCHER_VERSION_SETTING); + settings.add(INDEX_WATCHER_TEMPLATE_VERSION_SETTING); + settings.add(Setting.intSetting("xpack.watcher.execution.scroll.size", 0, Setting.Property.NodeScope)); + settings.add(Setting.intSetting("xpack.watcher.watch.scroll.size", 0, Setting.Property.NodeScope)); + settings.add(Setting.boolSetting(XPackPlugin.featureEnabledSetting(Watcher.NAME), true, Setting.Property.NodeScope)); + settings.add(ENCRYPT_SENSITIVE_DATA_SETTING); - module.registerSetting(Setting.simpleString("xpack.watcher.internal.ops.search.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.internal.ops.bulk.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.internal.ops.index.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.execution.default_throttle_period", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.actions.index.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.index.rest.direct_access", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.trigger.schedule.engine", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.input.search.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.transform.search.default_timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.trigger.schedule.ticker.tick_interval", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.execution.scroll.timeout", Setting.Property.NodeScope)); - module.registerSetting(Setting.simpleString("xpack.watcher.start_immediately", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.internal.ops.search.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.internal.ops.bulk.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.internal.ops.index.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.execution.default_throttle_period", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.actions.index.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.index.rest.direct_access", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.trigger.schedule.engine", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.input.search.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.transform.search.default_timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.trigger.schedule.ticker.tick_interval", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.execution.scroll.timeout", Setting.Property.NodeScope)); + settings.add(Setting.simpleString("xpack.watcher.start_immediately", Setting.Property.NodeScope)); + return settings; } public List> getExecutorBuilders(final Settings settings) { @@ -279,4 +279,5 @@ public class Watcher { "[.watcher-history-YYYY.MM.dd] are allowed to be created", value); } + } diff --git a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java index 41d7cbc29ff..1db1130953f 100644 --- a/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java +++ b/elasticsearch/x-pack/watcher/src/test/java/org/elasticsearch/xpack/watcher/support/WatcherIndexTemplateRegistryTests.java @@ -15,6 +15,8 @@ import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; import java.util.function.Function; import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST; @@ -85,8 +87,9 @@ public class WatcherIndexTemplateRegistryTests extends AbstractWatcherIntegratio public static final Setting KEY_1 = new Setting<>("index.key1", "", Function.identity(), Setting.Property.IndexScope); - public void onModule(SettingsModule module) { - module.registerSetting(KEY_1); + @Override + public List> getSettings() { + return Collections.singletonList(KEY_1); } } } From e07d73e91cd06cc98bdb63c0694e3be2163de49d Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Thu, 3 Mar 2016 10:57:00 -0600 Subject: [PATCH 05/11] monitoring ui: add overall and plugin statuses to ops data Original commit: elastic/x-pack-elasticsearch@9dff2cf9aed6e61d1271ece2eee2625b8a029d26 --- .../x-pack/marvel/src/main/resources/monitoring-data.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elasticsearch/x-pack/marvel/src/main/resources/monitoring-data.json b/elasticsearch/x-pack/marvel/src/main/resources/monitoring-data.json index 26a45831a3b..c4b45cd5cce 100644 --- a/elasticsearch/x-pack/marvel/src/main/resources/monitoring-data.json +++ b/elasticsearch/x-pack/marvel/src/main/resources/monitoring-data.json @@ -20,4 +20,4 @@ "enabled": false } } -} \ No newline at end of file +} From f231341f903960889cc96b1309319996852409af Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Tue, 7 Jun 2016 17:48:28 -0700 Subject: [PATCH 06/11] monitoring ui: add heap.size_limit to Kibana stats Original commit: elastic/x-pack-elasticsearch@c74e90c34e63efe27e7bf77f1cd0296ecc7bbb49 --- .../x-pack/marvel/src/main/resources/monitoring-kibana.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elasticsearch/x-pack/marvel/src/main/resources/monitoring-kibana.json b/elasticsearch/x-pack/marvel/src/main/resources/monitoring-kibana.json index 6abe689028d..e814260533c 100644 --- a/elasticsearch/x-pack/marvel/src/main/resources/monitoring-kibana.json +++ b/elasticsearch/x-pack/marvel/src/main/resources/monitoring-kibana.json @@ -136,6 +136,9 @@ }, "used_in_bytes": { "type": "float" + }, + "size_limit": { + "type": "float" } } }, From 27958cc708ac3caafbd76f9339a9bd1b5e6fa760 Mon Sep 17 00:00:00 2001 From: jaymode Date: Thu, 16 Jun 2016 13:18:35 -0400 Subject: [PATCH 07/11] security: add charset to the WWW-Authenticate header The WWW-Authenticate header can optionally specify the charset that the server uses after decoding credentials. If this is not specified, most clients will limit the available characters to ISO-8859-1, which causes issues for certain characters. See RFC 7617 Closes elastic/elasticsearch#2290 Original commit: elastic/x-pack-elasticsearch@44411eebe7f33323b0672b834a5e151a6fef403e --- .../java/org/elasticsearch/shield/support/Exceptions.java | 4 ++-- .../java/org/elasticsearch/shield/test/ShieldAssertions.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Exceptions.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Exceptions.java index caac6700b01..349a6b70285 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Exceptions.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Exceptions.java @@ -19,13 +19,13 @@ public class Exceptions { public static ElasticsearchSecurityException authenticationError(String msg, Throwable cause, Object... args) { ElasticsearchSecurityException e = new ElasticsearchSecurityException(msg, RestStatus.UNAUTHORIZED, cause, args); - e.addHeader("WWW-Authenticate", "Basic realm=\"" + Security.NAME + "\""); + e.addHeader("WWW-Authenticate", "Basic realm=\"" + Security.NAME + "\" charset=\"UTF-8\""); return e; } public static ElasticsearchSecurityException authenticationError(String msg, Object... args) { ElasticsearchSecurityException e = new ElasticsearchSecurityException(msg, RestStatus.UNAUTHORIZED, args); - e.addHeader("WWW-Authenticate", "Basic realm=\"" + Security.NAME + "\""); + e.addHeader("WWW-Authenticate", "Basic realm=\"" + Security.NAME + "\" charset=\"UTF-8\""); return e; } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/test/ShieldAssertions.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/test/ShieldAssertions.java index d7c311e12b4..e2018815c6c 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/test/ShieldAssertions.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/test/ShieldAssertions.java @@ -21,6 +21,6 @@ public class ShieldAssertions { assertThat(e.status(), is(RestStatus.UNAUTHORIZED)); assertThat(e.getHeaderKeys(), hasSize(1)); assertThat(e.getHeader("WWW-Authenticate"), notNullValue()); - assertThat(e.getHeader("WWW-Authenticate"), contains("Basic realm=\"" + Security.NAME + "\"")); + assertThat(e.getHeader("WWW-Authenticate"), contains("Basic realm=\"" + Security.NAME + "\" charset=\"UTF-8\"")); } } From eeb964c8869284cfe97543ae9ee5f99c86eb8f1c Mon Sep 17 00:00:00 2001 From: jaymode Date: Wed, 27 Apr 2016 11:49:13 -0400 Subject: [PATCH 08/11] security: default role checks authenticating realm This change makes the default role check the authenticating realm when authorizing a request for the current user (or run as user) where the user is trying to change their own password. We need to do this, otherwise we open up the potential of a user in one realm changing the password of a user in another realm. As part of this work, the authentication service has been refactored and simplified. A new object, Authentication, is now returned when authenticating. Currently, this object contains the user, authenticating realm information, and if it is a run as request the information of the realm that looked up the user. Closes elastic/elasticsearch#2089 Original commit: elastic/x-pack-elasticsearch@3fd9c37a166905e10249832abbfbd3eae4f168e3 --- .../shield/authz/AuthorizationUtilsTests.java | 12 +- .../elasticsearch/shield/InternalClient.java | 2 +- .../elasticsearch/shield/SecurityContext.java | 26 +- .../action/filter/ShieldActionFilter.java | 19 +- .../shield/audit/AuditTrail.java | 6 + .../shield/audit/AuditTrailService.java | 9 + .../shield/audit/index/IndexAuditTrail.java | 35 +- .../audit/logfile/LoggingAuditTrail.java | 11 + .../shield/authc/Authentication.java | 186 +++++ .../shield/authc/AuthenticationService.java | 12 +- .../authc/InternalAuthenticationService.java | 642 ++++++++---------- .../shield/authz/AuthorizationService.java | 9 +- .../shield/authz/AuthorizationUtils.java | 5 +- .../authz/InternalAuthorizationService.java | 98 +-- .../authz/permission/ClusterPermission.java | 12 +- .../shield/authz/permission/DefaultRole.java | 45 +- .../transport/ClientTransportFilter.java | 2 +- .../transport/ServerTransportFilter.java | 6 +- .../filter/ShieldActionFilterTests.java | 23 +- .../InternalAuthenticationServiceTests.java | 396 +++++------ .../InternalAuthorizationServiceTests.java | 68 +- .../authz/permission/DefaultRoleTests.java | 128 +++- .../authz/permission/KibanaRoleTests.java | 20 +- .../authz/permission/KibanaUserRoleTests.java | 20 +- .../authz/permission/SuperuserRoleTests.java | 17 +- .../shield/rest/ShieldRestFilterTests.java | 6 +- .../transport/ClientTransportFilterTests.java | 2 +- .../transport/ServerTransportFilterTests.java | 14 +- 28 files changed, 1074 insertions(+), 757 deletions(-) create mode 100644 elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authc/Authentication.java diff --git a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/shield/authz/AuthorizationUtilsTests.java b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/shield/authz/AuthorizationUtilsTests.java index a27290ca161..cdff7aa1e87 100644 --- a/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/shield/authz/AuthorizationUtilsTests.java +++ b/elasticsearch/x-pack/license-plugin/src/test/java/org/elasticsearch/shield/authz/AuthorizationUtilsTests.java @@ -7,9 +7,10 @@ package org.elasticsearch.shield.authz; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.shield.authc.Authentication; +import org.elasticsearch.shield.authc.Authentication.RealmRef; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; -import org.elasticsearch.shield.authc.InternalAuthenticationService; import org.elasticsearch.test.ESTestCase; import org.junit.Before; @@ -33,21 +34,24 @@ public class AuthorizationUtilsTests extends ESTestCase { public void testSystemUserSwitchWithNullorSystemUser() { if (randomBoolean()) { - threadContext.putTransient(InternalAuthenticationService.USER_KEY, SystemUser.INSTANCE); + threadContext.putTransient(Authentication.AUTHENTICATION_KEY, + new Authentication(SystemUser.INSTANCE, new RealmRef("test", "test", "foo"), null)); } assertThat(AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, "internal:something"), is(true)); } public void testSystemUserSwitchWithNonSystemUser() { User user = new User(randomAsciiOfLength(6), new String[] {}); - threadContext.putTransient(InternalAuthenticationService.USER_KEY, user); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication); threadContext.putTransient(InternalAuthorizationService.ORIGINATING_ACTION_KEY, randomFrom("indices:foo", "cluster:bar")); assertThat(AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, "internal:something"), is(true)); } public void testSystemUserSwitchWithNonSystemUserAndInternalAction() { User user = new User(randomAsciiOfLength(6), new String[] {}); - threadContext.putTransient(InternalAuthenticationService.USER_KEY, user); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication); threadContext.putTransient(InternalAuthorizationService.ORIGINATING_ACTION_KEY, randomFrom("internal:foo/bar")); assertThat(AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, "internal:something"), is(false)); } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/InternalClient.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/InternalClient.java index f939ceb022f..f5f889737ea 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/InternalClient.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/InternalClient.java @@ -62,7 +62,7 @@ public abstract class InternalClient extends FilterClient { try (ThreadContext.StoredContext ctx = threadPool().getThreadContext().stashContext()) { try { - authcService.attachUserHeaderIfMissing(XPackUser.INSTANCE); + authcService.attachUserIfMissing(XPackUser.INSTANCE); } catch (IOException ioe) { throw new ElasticsearchException("failed to attach internal user to request", ioe); } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/SecurityContext.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/SecurityContext.java index e065e0ca983..4a5e82ead7c 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/SecurityContext.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/SecurityContext.java @@ -8,6 +8,7 @@ package org.elasticsearch.shield; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.authc.AuthenticationService; import org.elasticsearch.shield.user.User; import org.elasticsearch.threadpool.ThreadPool; @@ -26,6 +27,12 @@ public interface SecurityContext { User getUser(); + Authentication getAuthentication(); + + default boolean hasAuthentication() { + return getAuthentication() != null; + } + class Insecure implements SecurityContext { public static final Insecure INSTANCE = new Insecure(); @@ -51,6 +58,11 @@ public interface SecurityContext { public User getUser() { return null; } + + @Override + public Authentication getAuthentication() { + return null; + } } class Secure implements SecurityContext { @@ -82,14 +94,20 @@ public interface SecurityContext { @Override public User getUser() { - return authcService.getCurrentUser(); + Authentication authentication = authcService.getCurrentAuthentication(); + return authentication == null ? null : authentication.getUser(); + } + + @Override + public Authentication getAuthentication() { + return authcService.getCurrentAuthentication(); } private void setUser(User user) { try { - authcService.attachUserHeaderIfMissing(user); - } catch (IOException e) { - throw new ElasticsearchException("failed to attach watcher user to request", e); + authcService.attachUserIfMissing(user); + } catch (IOException | IllegalArgumentException e) { + throw new ElasticsearchException("failed to attach user to request", e); } } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/filter/ShieldActionFilter.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/filter/ShieldActionFilter.java index 81466d9583f..4ff41b15cd0 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/filter/ShieldActionFilter.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/filter/ShieldActionFilter.java @@ -20,13 +20,14 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.license.plugin.core.LicenseUtils; import org.elasticsearch.shield.Security; +import org.elasticsearch.shield.SecurityContext; import org.elasticsearch.shield.action.ShieldActionMapper; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.action.interceptor.RequestInterceptor; import org.elasticsearch.shield.audit.AuditTrail; import org.elasticsearch.shield.authc.AuthenticationService; -import org.elasticsearch.shield.authc.InternalAuthenticationService; import org.elasticsearch.shield.authz.AuthorizationService; import org.elasticsearch.shield.authz.AuthorizationUtils; import org.elasticsearch.shield.authz.privilege.HealthAndStatsPrivilege; @@ -58,11 +59,13 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte private final Set requestInterceptors; private final SecurityLicenseState licenseState; private final ThreadContext threadContext; + private final SecurityContext securityContext; @Inject public ShieldActionFilter(Settings settings, AuthenticationService authcService, AuthorizationService authzService, CryptoService cryptoService, AuditTrail auditTrail, SecurityLicenseState licenseState, - ShieldActionMapper actionMapper, Set requestInterceptors, ThreadPool threadPool) { + ShieldActionMapper actionMapper, Set requestInterceptors, ThreadPool threadPool, + SecurityContext securityContext) { super(settings); this.authcService = authcService; this.authzService = authzService; @@ -72,6 +75,7 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte this.licenseState = licenseState; this.requestInterceptors = requestInterceptors; this.threadContext = threadPool.getThreadContext(); + this.securityContext = securityContext; } @Override @@ -91,8 +95,7 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte // only restore the context if it is not empty. This is needed because sometimes a response is sent to the user // and then a cleanup action is executed (like for search without a scroll) final ThreadContext.StoredContext original = threadContext.newStoredContext(); - final boolean restoreOriginalContext = threadContext.getHeader(InternalAuthenticationService.USER_KEY) != null || - threadContext.getTransient(InternalAuthenticationService.USER_KEY) != null; + final boolean restoreOriginalContext = securityContext.hasAuthentication(); try { if (licenseState.authenticationAndAuthorizationEnabled()) { if (AuthorizationUtils.shouldReplaceUserWithSystem(threadContext, action)) { @@ -133,9 +136,11 @@ public class ShieldActionFilter extends AbstractComponent implements ActionFilte the {@link Rest} filter and the {@link ServerTransport} filter respectively), it's safe to assume a system user here if a request is not associated with any other user. */ - String shieldAction = actionMapper.action(action, request); - User user = authcService.authenticate(shieldAction, request, SystemUser.INSTANCE); - authzService.authorize(user, shieldAction, request); + final String shieldAction = actionMapper.action(action, request); + Authentication authentication = authcService.authenticate(shieldAction, request, SystemUser.INSTANCE); + assert authentication != null; + authzService.authorize(authentication, shieldAction, request); + final User user = authentication.getUser(); request = unsign(user, shieldAction, request); /* diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrail.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrail.java index a6efbc13cea..196570f4fe6 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrail.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrail.java @@ -94,6 +94,10 @@ public interface AuditTrail { @Override public void runAsDenied(User user, String action, TransportMessage message) { } + + @Override + public void runAsDenied(User user, RestRequest request) { + } }; String name(); @@ -131,4 +135,6 @@ public interface AuditTrail { void runAsGranted(User user, String action, TransportMessage message); void runAsDenied(User user, String action, TransportMessage message); + + void runAsDenied(User user, RestRequest request); } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailService.java index c806f511fec..d717811c1fd 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/AuditTrailService.java @@ -188,4 +188,13 @@ public class AuditTrailService extends AbstractComponent implements AuditTrail { } } } + + @Override + public void runAsDenied(User user, RestRequest request) { + if (securityLicenseState.auditingEnabled()) { + for (AuditTrail auditTrail : auditTrails) { + auditTrail.runAsDenied(user, request); + } + } + } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java index da8163139b1..e7b70374089 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/index/IndexAuditTrail.java @@ -512,7 +512,7 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl public void runAsGranted(User user, String action, TransportMessage message) { if (events.contains(RUN_AS_GRANTED)) { try { - enqueue(message("run_as_granted", action, user, null, message), "access_granted"); + enqueue(message("run_as_granted", action, user, null, message), "run_as_granted"); } catch (Exception e) { logger.warn("failed to index audit event: [run_as_granted]", e); } @@ -523,7 +523,18 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl public void runAsDenied(User user, String action, TransportMessage message) { if (events.contains(RUN_AS_DENIED)) { try { - enqueue(message("run_as_denied", action, user, null, message), "access_granted"); + enqueue(message("run_as_denied", action, user, null, message), "run_as_denied"); + } catch (Exception e) { + logger.warn("failed to index audit event: [run_as_denied]", e); + } + } + } + + @Override + public void runAsDenied(User user, RestRequest request) { + if (events.contains(RUN_AS_DENIED)) { + try { + enqueue(message("run_as_denied", user, request), "run_as_denied"); } catch (Exception e) { logger.warn("failed to index audit event: [run_as_denied]", e); } @@ -620,6 +631,26 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail, Cl return msg.end(); } + private Message message(String type, User user, RestRequest request) throws Exception { + + Message msg = new Message().start(); + common("rest", type, msg.builder); + + msg.builder.field(Field.PRINCIPAL, user.principal()); + msg.builder.field(Field.REQUEST_BODY, restRequestContent(request)); + msg.builder.field(Field.ORIGIN_TYPE, "rest"); + SocketAddress address = request.getRemoteAddress(); + if (address instanceof InetSocketAddress) { + msg.builder.field(Field.ORIGIN_ADDRESS, NetworkAddress.format(((InetSocketAddress) request.getRemoteAddress()) + .getAddress())); + } else { + msg.builder.field(Field.ORIGIN_ADDRESS, address); + } + msg.builder.field(Field.URI, request.uri()); + + return msg.end(); + } + private Message message(String layer, String type, InetAddress originAddress, String profile, ShieldIpFilterRule rule) throws IOException { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java index 4f4f6942883..5df0f9f2d5e 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/audit/logfile/LoggingAuditTrail.java @@ -384,6 +384,17 @@ public class LoggingAuditTrail extends AbstractLifecycleComponent - * The order by which the realms are checked is defined in {@link Realms}. - * - * @param request the request to authenticate - * @param fallbackUser The user to assume if there is not other user attached to the message - * @return The authenticated user - * @throws ElasticsearchSecurityException If none of the configured realms successfully authenticated the - * request - */ - User authenticateWithRealms(AuditableRequest request, User fallbackUser) throws ElasticsearchSecurityException { - AuthenticationToken token; - try { - token = token(request); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("failed to extract token from request: [{}]", e, request); - } else { - logger.warn("failed to extract token from request: [{}]", request, e.getMessage()); - } - throw request.exceptionProcessingRequest(e); + Authenticator createAuthenticator(RestRequest request) { + return new Authenticator(request); + } + + Authenticator createAuthenticator(String action, TransportMessage message, User fallbackUser) { + return new Authenticator(action, message, fallbackUser); + } + + class Authenticator { + + private final AuditableRequest request; + private final User fallbackUser; + + private RealmRef authenticatedBy = null; + private RealmRef lookedupBy = null; + + Authenticator(RestRequest request) { + this.request = new Rest(request); + this.fallbackUser = null; } - if (token == null) { - if (fallbackUser != null) { - return fallbackUser; + Authenticator(String action, TransportMessage message, User fallbackUser) { + this.request = new Transport(action, message); + this.fallbackUser = fallbackUser; + } + + Authentication authenticate() throws IOException, IllegalArgumentException { + Authentication existing = getCurrentAuthentication(); + if (existing != null) { + return existing; } - if (AnonymousUser.enabled()) { - return AnonymousUser.INSTANCE; + + AuthenticationToken token = extractToken(); + if (token == null) { + return handleNullToken(); + } + + User user = authenticateToken(token); + if (user == null) { + throw handleNullUser(token); + } + user = lookupRunAsUserIfNecessary(user, token); + + final Authentication authentication = new Authentication(user, authenticatedBy, lookedupBy); + authentication.writeToContext(threadContext, cryptoService, signUserHeader); + return authentication; + } + + Authentication getCurrentAuthentication() { + Authentication authentication; + try { + authentication = Authentication.readFromContext(threadContext, cryptoService, signUserHeader); + } catch (Exception e) { + throw request.tamperedRequest(); + } + + // make sure this isn't a rest request since we don't allow authentication to be read via a HTTP request... + if (authentication != null && request instanceof Rest) { + throw request.tamperedRequest(); + } + return authentication; + } + + AuthenticationToken extractToken() { + AuthenticationToken token = null; + try { + for (Realm realm : realms) { + token = realm.token(threadContext); + if (token != null) { + logger.trace("realm [{}] resolved authentication token [{}] from [{}]", realm, token.principal(), request); + break; + } + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.debug("failed to extract token from request: [{}]", e, request); + } else { + logger.warn("failed to extract token from request: [{}]", request, e.getMessage()); + } + throw request.exceptionProcessingRequest(e, null); + } + return token; + } + + Authentication handleNullToken() throws IOException { + Authentication authentication = null; + if (fallbackUser != null) { + RealmRef authenticatedBy = new RealmRef("__fallback", "__fallback", nodeName); + authentication = new Authentication(fallbackUser, authenticatedBy, null); + } else if (AnonymousUser.enabled()) { + RealmRef authenticatedBy = new RealmRef("__anonymous", "__anonymous", nodeName); + authentication = new Authentication(AnonymousUser.INSTANCE, authenticatedBy, null); + } + + if (authentication != null) { + authentication.writeToContext(threadContext, cryptoService, signUserHeader); + return authentication; } throw request.anonymousAccessDenied(); } - User user; - try { - user = authenticate(request, token); - } catch (Exception e) { - if (logger.isDebugEnabled()) { + User authenticateToken(AuthenticationToken token) { + User user = null; + try { + for (Realm realm : realms) { + if (realm.supports(token)) { + user = realm.authenticate(token); + if (user != null) { + authenticatedBy = new RealmRef(realm.name(), realm.type(), nodeName); + break; + } + request.realmAuthenticationFailed(token, realm.name()); + } + } + } catch (Exception e) { logger.debug("authentication failed for principal [{}], [{}]", e, request); + throw request.exceptionProcessingRequest(e, token); + } finally { + token.clearCredentials(); } - throw request.exceptionProcessingRequest(e, token); + return user; } - if (user == null) { - throw request.failedAuthentication(token); + ElasticsearchSecurityException handleNullUser(AuthenticationToken token) { + throw request.authenticationFailed(token); } - if (runAsEnabled) { + boolean shouldTryToRunAs(User authenticatedUser, AuthenticationToken token) { + if (runAsEnabled == false) { + return false; + } + String runAsUsername = threadContext.getHeader(RUN_AS_USER_HEADER); - if (runAsUsername != null) { - if (runAsUsername.isEmpty()) { - logger.warn("user [{}] attempted to runAs with an empty username", user.principal()); - throw request.failedAuthentication(token); - } - User runAsUser; - try { - runAsUser = lookupUser(runAsUsername); - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("lookup of run as user failed for principal [{}], [{}], run as username [{}]", e, - token.principal(), request, runAsUsername); + if (runAsUsername == null) { + return false; + } + + if (runAsUsername.isEmpty()) { + logger.debug("user [{}] attempted to runAs with an empty username", authenticatedUser.principal()); + throw request.runAsDenied(new User(authenticatedUser.principal(), authenticatedUser.roles(), + new User(runAsUsername, Strings.EMPTY_ARRAY)), token); + } + return true; + } + + User lookupRunAsUserIfNecessary(User authenticatedUser, AuthenticationToken token) { + User user = authenticatedUser; + if (shouldTryToRunAs(user, token) == false) { + return user; + } + + final String runAsUsername = threadContext.getHeader(RUN_AS_USER_HEADER); + try { + for (Realm realm : realms) { + if (realm.userLookupSupported()) { + User runAsUser = realm.lookupUser(runAsUsername); + if (runAsUser != null) { + lookedupBy = new RealmRef(realm.name(), realm.type(), nodeName); + user = new User(user.principal(), user.roles(), runAsUser); + return user; + } } - throw request.exceptionProcessingRequest(e, token); } - // wrap in a try catch because the user constructor could throw an exception if we are trying to runAs the system user - try { - if (runAsUser != null) { - user = new User(user.principal(), user.roles(), runAsUser); - } else { - // the requested run as user does not exist, but we don't throw an error here otherwise this could let - // information leak about users in the system... instead we'll just let the authz service fail throw an - // authorization error - user = new User(user.principal(), user.roles(), new User(runAsUsername, Strings.EMPTY_ARRAY)); - } - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.debug("user creation failed for principal [{}], [{}], run as username [{}]", e, token.principal(), - request, runAsUsername); - } - throw request.exceptionProcessingRequest(e, token); - } + // the requested run as user does not exist, but we don't throw an error here otherwise this could let + // information leak about users in the system... instead we'll just let the authz service fail throw an + // authorization error + user = new User(user.principal(), user.roles(), new User(runAsUsername, Strings.EMPTY_ARRAY)); + } catch (Exception e) { + logger.debug("run as failed for principal [{}], [{}], run as username [{}]", e, token.principal(), request, runAsUsername); + throw request.exceptionProcessingRequest(e, token); } + return user; } - return user; - } - User authenticate(AuditableRequest request, AuthenticationToken token) throws ElasticsearchSecurityException { - assert token != null : "cannot authenticate null tokens"; - try { - for (Realm realm : realms) { - if (realm.supports(token)) { - User user = realm.authenticate(token); - if (user != null) { - return user; - } - request.authenticationFailed(token, realm.name()); - } - } - request.authenticationFailed(token); - return null; - } finally { - token.clearCredentials(); - } - } + abstract class AuditableRequest { - AuthenticationToken token(AuditableRequest request) throws ElasticsearchSecurityException { - for (Realm realm : realms) { - AuthenticationToken token = realm.token(threadContext); - if (token != null) { - request.tokenResolved(realm.name(), token); - return token; - } - } - return null; - } + abstract void realmAuthenticationFailed(AuthenticationToken token, String realm); - User lookupUser(String username) { - for (Realm realm : realms) { - if (realm.userLookupSupported()) { - User user = realm.lookupUser(username); - if (user != null) { - return user; + abstract ElasticsearchSecurityException tamperedRequest(); + + abstract ElasticsearchSecurityException exceptionProcessingRequest(Exception e, @Nullable AuthenticationToken token); + + abstract ElasticsearchSecurityException authenticationFailed(AuthenticationToken token); + + abstract ElasticsearchSecurityException anonymousAccessDenied(); + + abstract ElasticsearchSecurityException runAsDenied(User user, AuthenticationToken token); + } + + class Transport extends AuditableRequest { + + private final String action; + private final TransportMessage message; + + Transport(String action, TransportMessage message) { + this.action = action; + this.message = message; + } + + @Override + void realmAuthenticationFailed(AuthenticationToken token, String realm) { + auditTrail.authenticationFailed(realm, token, action, message); + } + + @Override + ElasticsearchSecurityException tamperedRequest() { + auditTrail.tamperedRequest(action, message); + return new ElasticsearchSecurityException("failed to verify signed authentication information"); + } + + @Override + ElasticsearchSecurityException exceptionProcessingRequest(Exception e, @Nullable AuthenticationToken token) { + if (token != null) { + auditTrail.authenticationFailed(token, action, message); + } else { + auditTrail.authenticationFailed(action, message); } + return failureHandler.exceptionProcessingRequest(message, action, e, threadContext); + } + + @Override + ElasticsearchSecurityException authenticationFailed(AuthenticationToken token) { + auditTrail.authenticationFailed(token, action, message); + return failureHandler.failedAuthentication(message, token, action, threadContext); + } + + @Override + ElasticsearchSecurityException anonymousAccessDenied() { + auditTrail.anonymousAccessDenied(action, message); + return failureHandler.missingToken(message, action, threadContext); + } + + @Override + ElasticsearchSecurityException runAsDenied(User user, AuthenticationToken token) { + auditTrail.runAsDenied(user, action, message); + return failureHandler.failedAuthentication(message, token, action, threadContext); + } + + public String toString() { + return "transport request action [" + action + "]"; + } + } + + class Rest extends AuditableRequest { + + private final RestRequest request; + + Rest(RestRequest request) { + this.request = request; + } + + @Override + void realmAuthenticationFailed(AuthenticationToken token, String realm) { + auditTrail.authenticationFailed(realm, token, request); + } + + @Override + ElasticsearchSecurityException tamperedRequest() { + auditTrail.tamperedRequest(request); + return new ElasticsearchSecurityException("rest request attempted to inject a user"); + } + + @Override + ElasticsearchSecurityException exceptionProcessingRequest(Exception e, @Nullable AuthenticationToken token) { + if (token != null) { + auditTrail.authenticationFailed(token, request); + } else { + auditTrail.authenticationFailed(request); + } + return failureHandler.exceptionProcessingRequest(request, e, threadContext); + } + + @Override + ElasticsearchSecurityException authenticationFailed(AuthenticationToken token) { + auditTrail.authenticationFailed(token, request); + return failureHandler.failedAuthentication(request, token, threadContext); + } + + @Override + ElasticsearchSecurityException anonymousAccessDenied() { + auditTrail.anonymousAccessDenied(request); + return failureHandler.missingToken(request, threadContext); + } + + @Override + ElasticsearchSecurityException runAsDenied(User user, AuthenticationToken token) { + auditTrail.runAsDenied(user, request); + return failureHandler.failedAuthentication(request, token, threadContext); + } + + public String toString() { + return "rest request uri [" + request.uri() + "]"; } } - return null; } public static void addSettings(List> settings) { settings.add(SIGN_USER_HEADER); settings.add(RUN_AS_ENABLED); } - - // these methods are package private for testing. They are also needed so that a AuditableRequest can be created in tests - AuditableRequest newRequest(String action, TransportMessage message) { - return new Transport(action, message); - } - - AuditableRequest newRequest(RestRequest request) { - return new Rest(request); - } - - abstract class AuditableRequest { - - abstract void authenticationFailed(AuthenticationToken token); - - abstract void authenticationFailed(AuthenticationToken token, String realm); - - abstract void tamperedRequest(); - - abstract void tokenResolved(String realm, AuthenticationToken token); - - abstract ElasticsearchSecurityException exceptionProcessingRequest(Exception e); - - abstract ElasticsearchSecurityException exceptionProcessingRequest(Exception e, AuthenticationToken token); - - abstract ElasticsearchSecurityException failedAuthentication(AuthenticationToken token); - - abstract ElasticsearchSecurityException anonymousAccessDenied(); - } - - class Transport extends AuditableRequest { - - private final String action; - private final TransportMessage message; - - Transport(String action, TransportMessage message) { - this.action = action; - this.message = message; - } - - @Override - void authenticationFailed(AuthenticationToken token) { - auditTrail.authenticationFailed(token, action, message); - } - - @Override - void authenticationFailed(AuthenticationToken token, String realm) { - auditTrail.authenticationFailed(realm, token, action, message); - } - - @Override - void tamperedRequest() { - auditTrail.tamperedRequest(action, message); - } - - @Override - void tokenResolved(String realm, AuthenticationToken token) { - logger.trace("realm [{}] resolved authentication token [{}] from transport request with action [{}]", - realm, token.principal(), action); - } - - @Override - ElasticsearchSecurityException exceptionProcessingRequest(Exception e) { - auditTrail.authenticationFailed(action, message); - return failureHandler.exceptionProcessingRequest(message, action, e, threadContext); - } - - @Override - ElasticsearchSecurityException exceptionProcessingRequest(Exception e, AuthenticationToken token) { - authenticationFailed(token); - return failureHandler.exceptionProcessingRequest(message, action, e, threadContext); - } - - ElasticsearchSecurityException failedAuthentication(AuthenticationToken token) { - auditTrail.authenticationFailed(token, action, message); - return failureHandler.failedAuthentication(message, token, action, threadContext); - } - - @Override - ElasticsearchSecurityException anonymousAccessDenied() { - auditTrail.anonymousAccessDenied(action, message); - return failureHandler.missingToken(message, action, threadContext); - } - - public String toString() { - return "transport action [" + action + "]"; - } - } - - class Rest extends AuditableRequest { - - private final RestRequest request; - - Rest(RestRequest request) { - this.request = request; - } - - @Override - void authenticationFailed(AuthenticationToken token) { - auditTrail.authenticationFailed(token, request); - } - - @Override - void authenticationFailed(AuthenticationToken token, String realm) { - auditTrail.authenticationFailed(realm, token, request); - } - - @Override - void tamperedRequest() { - auditTrail.tamperedRequest(request); - } - - @Override - void tokenResolved(String realm, AuthenticationToken token) { - logger.trace("realm [{}] resolved authentication token [{}] from rest request with uri [{}]", - realm, token.principal(), request.uri()); - } - - @Override - ElasticsearchSecurityException exceptionProcessingRequest(Exception e) { - auditTrail.authenticationFailed(request); - return failureHandler.exceptionProcessingRequest(request, e, threadContext); - } - - @Override - ElasticsearchSecurityException exceptionProcessingRequest(Exception e, AuthenticationToken token) { - authenticationFailed(token); - return failureHandler.exceptionProcessingRequest(request, e, threadContext); - } - - ElasticsearchSecurityException failedAuthentication(AuthenticationToken token) { - auditTrail.authenticationFailed(token, request); - return failureHandler.failedAuthentication(request, token, threadContext); - } - - @Override - ElasticsearchSecurityException anonymousAccessDenied() { - auditTrail.anonymousAccessDenied(request); - return failureHandler.missingToken(request, threadContext); - } - - public String toString() { - return "rest uri [" + request.uri() + "]"; - } - } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationService.java index e914791de99..0804b9b658e 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationService.java @@ -6,6 +6,7 @@ package org.elasticsearch.shield.authz; import org.elasticsearch.ElasticsearchSecurityException; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.user.User; import org.elasticsearch.transport.TransportRequest; @@ -29,11 +30,11 @@ public interface AuthorizationService { * have the appropriate privileges for this action/request, an {@link ElasticsearchSecurityException} * will be thrown. * - * @param user The user - * @param action The action - * @param request The request + * @param authentication The authentication information + * @param action The action + * @param request The request * @throws ElasticsearchSecurityException If the given user is no allowed to execute the given request */ - void authorize(User user, String action, TransportRequest request) throws ElasticsearchSecurityException; + void authorize(Authentication authentication, String action, TransportRequest request) throws ElasticsearchSecurityException; } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationUtils.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationUtils.java index f8db520203a..cbd67e982eb 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationUtils.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/AuthorizationUtils.java @@ -6,6 +6,7 @@ package org.elasticsearch.shield.authz; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.authc.InternalAuthenticationService; @@ -44,8 +45,8 @@ public final class AuthorizationUtils { return false; } - User user = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - if (user == null || SystemUser.is(user)) { + Authentication authentication = threadContext.getTransient(Authentication.AUTHENTICATION_KEY); + if (authentication == null || SystemUser.is(authentication.getUser())) { return true; } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java index ed8e4835333..a01029475e1 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/InternalAuthorizationService.java @@ -23,11 +23,11 @@ import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting.Property; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.settings.SettingsModule; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.search.action.SearchTransportService; import org.elasticsearch.shield.ShieldTemplateService; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; @@ -140,32 +140,32 @@ public class InternalAuthorizationService extends AbstractComponent implements A } @Override - public void authorize(User user, String action, TransportRequest request) throws ElasticsearchSecurityException { + public void authorize(Authentication authentication, String action, TransportRequest request) throws ElasticsearchSecurityException { // prior to doing any authorization lets set the originating action in the context only setOriginatingAction(action); - User effectiveUser = user; // first we need to check if the user is the system. If it is, we'll just authorize the system access - if (SystemUser.is(user)) { - if (SystemUser.isAuthorized(action)) { + if (SystemUser.is(authentication.getRunAsUser())) { + if (SystemUser.isAuthorized(action) && SystemUser.is(authentication.getUser())) { setIndicesAccessControl(IndicesAccessControl.ALLOW_ALL); - grant(user, action, request); + grant(authentication, action, request); return; } - throw denial(user, action, request); + throw denial(authentication, action, request); } - GlobalPermission permission = permission(user.roles()); + // get the roles of the authenticated user, which may be different than the effective + GlobalPermission permission = permission(authentication.getUser().roles()); - final boolean isRunAs = user.runAs() != null; + final boolean isRunAs = authentication.getUser() != authentication.getRunAsUser(); // permission can be null as it might be that the user's role // is unknown if (permission == null || permission.isEmpty()) { if (isRunAs) { // the request is a run as request so we should call the specific audit event for a denied run as attempt - throw denyRunAs(user, action, request); + throw denyRunAs(authentication, action, request); } else { - throw denial(user, action, request); + throw denial(authentication, action, request); } } @@ -173,18 +173,17 @@ public class InternalAuthorizationService extends AbstractComponent implements A if (isRunAs) { // first we must authorize for the RUN_AS action RunAsPermission runAs = permission.runAs(); - if (runAs != null && runAs.check(user.runAs().principal())) { - grantRunAs(user, action, request); - permission = permission(user.runAs().roles()); + if (runAs != null && runAs.check(authentication.getRunAsUser().principal())) { + grantRunAs(authentication, action, request); + permission = permission(authentication.getRunAsUser().roles()); // permission can be null as it might be that the user's role // is unknown if (permission == null || permission.isEmpty()) { - throw denial(user, action, request); + throw denial(authentication, action, request); } - effectiveUser = user.runAs(); } else { - throw denyRunAs(user, action, request); + throw denyRunAs(authentication, action, request); } } @@ -193,17 +192,17 @@ public class InternalAuthorizationService extends AbstractComponent implements A if (ClusterPrivilege.ACTION_MATCHER.test(action)) { ClusterPermission cluster = permission.cluster(); // we use the effectiveUser for permission checking since we are running as a user! - if (cluster != null && cluster.check(action, request, effectiveUser)) { + if (cluster != null && cluster.check(action, request, authentication)) { setIndicesAccessControl(IndicesAccessControl.ALLOW_ALL); - grant(user, action, request); + grant(authentication, action, request); return; } - throw denial(user, action, request); + throw denial(authentication, action, request); } // ok... this is not a cluster action, let's verify it's an indices action if (!IndexPrivilege.ACTION_MATCHER.test(action)) { - throw denial(user, action, request); + throw denial(authentication, action, request); } // some APIs are indices requests that are not actually associated with indices. For example, @@ -217,33 +216,34 @@ public class InternalAuthorizationService extends AbstractComponent implements A //note that clear scroll shard level actions can originate from a clear scroll all, which doesn't require any //indices permission as it's categorized under cluster. This is why the scroll check is performed //even before checking if the user has any indices permission. - grant(user, action, request); + grant(authentication, action, request); return; } assert false : "only scroll related requests are known indices api that don't support retrieving the indices they relate to"; - throw denial(user, action, request); + throw denial(authentication, action, request); } if (permission.indices() == null || permission.indices().isEmpty()) { - throw denial(user, action, request); + throw denial(authentication, action, request); } ClusterState clusterState = clusterService.state(); - Set indexNames = resolveIndices(user, action, request, clusterState); + Set indexNames = resolveIndices(authentication, action, request, clusterState); assert !indexNames.isEmpty() : "every indices request needs to have its indices set thus the resolved indices must not be empty"; MetaData metaData = clusterState.metaData(); IndicesAccessControl indicesAccessControl = permission.authorize(action, indexNames, metaData); if (!indicesAccessControl.isGranted()) { - throw denial(user, action, request); + throw denial(authentication, action, request); } else if (indicesAccessControl.getIndexPermissions(ShieldTemplateService.SECURITY_INDEX_NAME) != null && indicesAccessControl.getIndexPermissions(ShieldTemplateService.SECURITY_INDEX_NAME).isGranted() - && XPackUser.is(user) == false + && XPackUser.is(authentication.getRunAsUser()) == false && MONITOR_INDEX_PREDICATE.test(action) == false) { // only the XPackUser is allowed to work with this index, but we should allow indices monitoring actions through for debugging // purposes. These monitor requests also sometimes resolve indices concretely and then requests them - logger.debug("user [{}] attempted to directly perform [{}] against the security index [{}]", user.principal(), action, - ShieldTemplateService.SECURITY_INDEX_NAME); - throw denial(user, action, request); + // FIXME its not just the XPackUser. We said the elastic user and superusers could access this! + logger.debug("user [{}] attempted to directly perform [{}] against the security index [{}]", + authentication.getRunAsUser().principal(), action, ShieldTemplateService.SECURITY_INDEX_NAME); + throw denial(authentication, action, request); } else { setIndicesAccessControl(indicesAccessControl); } @@ -259,14 +259,14 @@ public class InternalAuthorizationService extends AbstractComponent implements A } indicesAccessControl = permission.authorize("indices:admin/aliases", aliasesAndIndices, metaData); if (!indicesAccessControl.isGranted()) { - throw denial(user, "indices:admin/aliases", request); + throw denial(authentication, "indices:admin/aliases", request); } // no need to re-add the indicesAccessControl in the context, // because the create index call doesn't do anything FLS or DLS } } - grant(user, action, request); + grant(authentication, action, request); } private void setIndicesAccessControl(IndicesAccessControl accessControl) { @@ -304,15 +304,15 @@ public class InternalAuthorizationService extends AbstractComponent implements A return roles.build(); } - private Set resolveIndices(User user, String action, TransportRequest request, ClusterState clusterState) { + private Set resolveIndices(Authentication authentication, String action, TransportRequest request, ClusterState clusterState) { MetaData metaData = clusterState.metaData(); for (IndicesAndAliasesResolver resolver : indicesAndAliasesResolvers) { if (resolver.requestType().isInstance(request)) { - return resolver.resolve(user, action, request, metaData); + return resolver.resolve(authentication.getRunAsUser(), action, request, metaData); } } assert false : "we should be able to resolve indices for any known request that requires indices privileges"; - throw denial(user, action, request); + throw denial(authentication, action, request); } private static boolean isScrollRelatedAction(String action) { @@ -325,34 +325,36 @@ public class InternalAuthorizationService extends AbstractComponent implements A action.equals(SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME); } - private ElasticsearchSecurityException denial(User user, String action, TransportRequest request) { - auditTrail.accessDenied(user, action, request); - return denialException(user, action); + private ElasticsearchSecurityException denial(Authentication authentication, String action, TransportRequest request) { + auditTrail.accessDenied(authentication.getUser(), action, request); + return denialException(authentication, action); } - private ElasticsearchSecurityException denyRunAs(User user, String action, TransportRequest request) { - auditTrail.runAsDenied(user, action, request); - return denialException(user, action); + private ElasticsearchSecurityException denyRunAs(Authentication authentication, String action, TransportRequest request) { + auditTrail.runAsDenied(authentication.getUser(), action, request); + return denialException(authentication, action); } - private void grant(User user, String action, TransportRequest request) { - auditTrail.accessGranted(user, action, request); + private void grant(Authentication authentication, String action, TransportRequest request) { + auditTrail.accessGranted(authentication.getUser(), action, request); } - private void grantRunAs(User user, String action, TransportRequest request) { - auditTrail.runAsGranted(user, action, request); + private void grantRunAs(Authentication authentication, String action, TransportRequest request) { + auditTrail.runAsGranted(authentication.getUser(), action, request); } - private ElasticsearchSecurityException denialException(User user, String action) { + private ElasticsearchSecurityException denialException(Authentication authentication, String action) { + final User user = authentication.getUser(); // Special case for anonymous user if (AnonymousUser.enabled() && AnonymousUser.is(user)) { if (anonymousAuthzExceptionEnabled == false) { throw authcFailureHandler.authenticationRequired(action, threadContext); } } - if (user.runAs() != null) { + // check for run as + if (user != authentication.getRunAsUser()) { return authorizationError("action [{}] is unauthorized for user [{}] run as [{}]", action, user.principal(), - user.runAs().principal()); + authentication.getRunAsUser().principal()); } return authorizationError("action [{}] is unauthorized for user [{}]", action, user.principal()); } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/ClusterPermission.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/ClusterPermission.java index 91370ba9f45..e9f8b715642 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/ClusterPermission.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/ClusterPermission.java @@ -5,8 +5,8 @@ */ package org.elasticsearch.shield.authz.permission; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.authz.privilege.ClusterPrivilege; -import org.elasticsearch.shield.user.User; import org.elasticsearch.transport.TransportRequest; import java.util.List; @@ -17,13 +17,13 @@ import java.util.function.Predicate; */ public interface ClusterPermission extends Permission { - boolean check(String action, TransportRequest request, User user); + boolean check(String action, TransportRequest request, Authentication authentication); public static class Core implements ClusterPermission { public static final Core NONE = new Core(ClusterPrivilege.NONE) { @Override - public boolean check(String action, TransportRequest request, User user) { + public boolean check(String action, TransportRequest request, Authentication authentication) { return false; } @@ -46,7 +46,7 @@ public interface ClusterPermission extends Permission { } @Override - public boolean check(String action, TransportRequest request, User user) { + public boolean check(String action, TransportRequest request, Authentication authentication) { return predicate.test(action); } @@ -65,7 +65,7 @@ public interface ClusterPermission extends Permission { } @Override - public boolean check(String action, TransportRequest request, User user) { + public boolean check(String action, TransportRequest request, Authentication authentication) { if (globals == null) { return false; } @@ -73,7 +73,7 @@ public interface ClusterPermission extends Permission { if (global == null || global.cluster() == null) { throw new RuntimeException(); } - if (global.cluster().check(action, request, user)) { + if (global.cluster().check(action, request, authentication)) { return true; } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/DefaultRole.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/DefaultRole.java index 80bf9874a06..b8e495b1cf2 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/DefaultRole.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/DefaultRole.java @@ -5,7 +5,9 @@ */ package org.elasticsearch.shield.authz.permission; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; +import org.elasticsearch.shield.authc.esnative.NativeRealm; +import org.elasticsearch.shield.authc.esnative.ReservedRealm; import org.elasticsearch.shield.action.user.AuthenticateAction; import org.elasticsearch.shield.action.user.ChangePasswordAction; import org.elasticsearch.shield.action.user.UserRequest; @@ -40,18 +42,47 @@ public class DefaultRole extends Role { } @Override - public boolean check(String action, TransportRequest request, User user) { - final boolean actionAllowed = super.check(action, request, user); + public boolean check(String action, TransportRequest request, Authentication authentication) { + final boolean actionAllowed = super.check(action, request, authentication); if (actionAllowed) { - assert request instanceof UserRequest; + if (request instanceof UserRequest == false) { + assert false : "right now only a user request should be allowed"; + return false; + } UserRequest userRequest = (UserRequest) request; String[] usernames = userRequest.usernames(); - assert usernames != null && usernames.length == 1; + if (usernames == null || usernames.length != 1 || usernames[0] == null) { + assert false : "this role should only be used for actions to apply to a single user"; + return false; + } final String username = usernames[0]; - assert username != null; - return user.principal().equals(username); + final boolean sameUsername = authentication.getRunAsUser().principal().equals(username); + if (sameUsername && ChangePasswordAction.NAME.equals(action)) { + return checkChangePasswordAction(authentication); + } + + assert AuthenticateAction.NAME.equals(action) || sameUsername == false; + return sameUsername; } return false; } } + + static boolean checkChangePasswordAction(Authentication authentication) { + // we need to verify that this user was authenticated by or looked up by a realm type that support password changes + // otherwise we open ourselves up to issues where a user in a different realm could be created with the same username + // and do malicious things + final boolean isRunAs = authentication.getUser() != authentication.getRunAsUser(); + final String realmType; + if (isRunAs) { + realmType = authentication.getLookedUpBy().getType(); + } else { + realmType = authentication.getAuthenticatedBy().getType(); + } + + assert realmType != null; + // ensure the user was authenticated by a realm that we can change a password for. The native realm is an internal realm and right + // now only one can exist in the realm configuration - if this changes we should update this check + return ReservedRealm.TYPE.equals(realmType) || NativeRealm.TYPE.equals(realmType); + } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ClientTransportFilter.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ClientTransportFilter.java index 540319bfbca..a3d6a0006b1 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ClientTransportFilter.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ClientTransportFilter.java @@ -56,7 +56,7 @@ public interface ClientTransportFilter { the system user will be attached. There cannot be a request outgoing from this node that is not associated with a user. */ - authcService.attachUserHeaderIfMissing(SystemUser.INSTANCE); + authcService.attachUserIfMissing(SystemUser.INSTANCE); } } } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ServerTransportFilter.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ServerTransportFilter.java index eb22fa17821..4fa06c75a59 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ServerTransportFilter.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ServerTransportFilter.java @@ -8,7 +8,7 @@ package org.elasticsearch.shield.transport; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.action.ShieldActionMapper; import org.elasticsearch.shield.authc.AuthenticationService; import org.elasticsearch.shield.authc.pki.PkiRealm; @@ -101,8 +101,8 @@ public interface ServerTransportFilter { } } - User user = authcService.authenticate(shieldAction, request, null); - authzService.authorize(user, shieldAction, request); + Authentication authentication = authcService.authenticate(shieldAction, request, null); + authzService.authorize(authentication, shieldAction, request); } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/action/filter/ShieldActionFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/action/filter/ShieldActionFilterTests.java index 7dd5690a5f5..7bebea884c3 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/action/filter/ShieldActionFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/action/filter/ShieldActionFilterTests.java @@ -12,7 +12,10 @@ import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.action.support.ActionFilterChain; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.shield.SecurityContext; import org.elasticsearch.shield.action.ShieldActionMapper; +import org.elasticsearch.shield.authc.Authentication; +import org.elasticsearch.shield.authc.Authentication.RealmRef; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.audit.AuditTrail; @@ -62,7 +65,7 @@ public class ShieldActionFilterTests extends ESTestCase { ThreadPool threadPool = mock(ThreadPool.class); when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY)); filter = new ShieldActionFilter(Settings.EMPTY, authcService, authzService, cryptoService, auditTrail, securityLicenseState, - new ShieldActionMapper(), new HashSet<>(), threadPool); + new ShieldActionMapper(), new HashSet<>(), threadPool, mock(SecurityContext.class)); } public void testApply() throws Exception { @@ -71,10 +74,11 @@ public class ShieldActionFilterTests extends ESTestCase { ActionFilterChain chain = mock(ActionFilterChain.class); Task task = mock(Task.class); User user = new User("username", "r1", "r2"); - when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(user); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication); doReturn(request).when(spy(filter)).unsign(user, "_action", request); filter.apply(task, "_action", request, listener, chain); - verify(authzService).authorize(user, "_action", request); + verify(authzService).authorize(authentication, "_action", request); verify(chain).proceed(eq(task), eq("_action"), eq(request), isA(ShieldActionFilter.SigningListener.class)); } @@ -85,8 +89,9 @@ public class ShieldActionFilterTests extends ESTestCase { RuntimeException exception = new RuntimeException("process-error"); Task task = mock(Task.class); User user = new User("username", "r1", "r2"); - when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(user); - doThrow(exception).when(authzService).authorize(user, "_action", request); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication); + doThrow(exception).when(authzService).authorize(authentication, "_action", request); filter.apply(task, "_action", request, listener, chain); verify(listener).onFailure(exception); verifyNoMoreInteractions(chain); @@ -98,12 +103,13 @@ public class ShieldActionFilterTests extends ESTestCase { ActionFilterChain chain = mock(ActionFilterChain.class); User user = mock(User.class); Task task = mock(Task.class); - when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(user); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication); when(cryptoService.signed("signed_scroll_id")).thenReturn(true); when(cryptoService.unsignAndVerify("signed_scroll_id")).thenReturn("scroll_id"); filter.apply(task, "_action", request, listener, chain); assertThat(request.scrollId(), equalTo("scroll_id")); - verify(authzService).authorize(user, "_action", request); + verify(authzService).authorize(authentication, "_action", request); verify(chain).proceed(eq(task), eq("_action"), eq(request), isA(ShieldActionFilter.SigningListener.class)); } @@ -114,7 +120,8 @@ public class ShieldActionFilterTests extends ESTestCase { IllegalArgumentException sigException = new IllegalArgumentException("bad bad boy"); User user = mock(User.class); Task task = mock(Task.class); - when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(user); + Authentication authentication = new Authentication(user, new RealmRef("test", "test", "foo"), null); + when(authcService.authenticate("_action", request, SystemUser.INSTANCE)).thenReturn(authentication); when(cryptoService.signed("scroll_id")).thenReturn(true); doThrow(sigException).when(cryptoService).unsignAndVerify("scroll_id"); filter.apply(task, "_action", request, listener, chain); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authc/InternalAuthenticationServiceTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authc/InternalAuthenticationServiceTests.java index c21233e739e..1869972c94e 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authc/InternalAuthenticationServiceTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authc/InternalAuthenticationServiceTests.java @@ -7,7 +7,6 @@ package org.elasticsearch.shield.authc; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.Version; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; @@ -15,7 +14,8 @@ import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.env.Environment; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.shield.authc.InternalAuthenticationService.AuditableRequest; +import org.elasticsearch.shield.authc.Authentication.RealmRef; +import org.elasticsearch.shield.authc.InternalAuthenticationService.Authenticator; import org.elasticsearch.shield.SecurityLicenseState.EnabledRealmType; import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.SystemUser; @@ -32,17 +32,14 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportMessage; import org.junit.After; import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.ExpectedException; +import java.io.IOException; import java.util.Arrays; -import java.util.Base64; import java.util.Collections; import static org.elasticsearch.shield.support.Exceptions.authenticationError; import static org.elasticsearch.test.ShieldTestsUtils.assertAuthenticationException; import static org.hamcrest.Matchers.arrayContaining; -import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -50,11 +47,10 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -66,9 +62,6 @@ import static org.mockito.Mockito.when; */ public class InternalAuthenticationServiceTests extends ESTestCase { - @Rule - public ExpectedException thrown = ExpectedException.none(); - InternalAuthenticationService service; TransportMessage message; RestRequest restRequest; @@ -88,10 +81,15 @@ public class InternalAuthenticationServiceTests extends ESTestCase { message = new InternalMessage(); restRequest = new FakeRestRequest(); firstRealm = mock(Realm.class); - when(firstRealm.name()).thenReturn("file"); + when(firstRealm.type()).thenReturn("file"); + when(firstRealm.name()).thenReturn("file_realm"); secondRealm = mock(Realm.class); - when(secondRealm.name()).thenReturn("second"); - Settings settings = Settings.builder().put("path.home", createTempDir()).build(); + when(secondRealm.type()).thenReturn("second"); + when(secondRealm.name()).thenReturn("second_realm"); + Settings settings = Settings.builder() + .put("path.home", createTempDir()) + .put("node.name", "authc_test") + .build(); SecurityLicenseState shieldLicenseState = mock(SecurityLicenseState.class); when(shieldLicenseState.enabledRealmType()).thenReturn(EnabledRealmType.ALL); when(shieldLicenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); @@ -113,7 +111,8 @@ public class InternalAuthenticationServiceTests extends ESTestCase { threadContext = new ThreadContext(Settings.EMPTY); controller = mock(RestController.class); when(threadPool.getThreadContext()).thenReturn(threadContext); - service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, + when(cryptoService.sign(any(String.class))).thenReturn("_signed_auth"); + service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); } @@ -127,17 +126,21 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.token(threadContext)).thenReturn(null); when(secondRealm.token(threadContext)).thenReturn(token); - AuthenticationToken result = service.token(service.newRequest("_action", message)); + Authenticator authenticator = service.createAuthenticator("_action", message, null); + AuthenticationToken result = authenticator.extractToken(); assertThat(result, notNullValue()); assertThat(result, is(token)); verifyZeroInteractions(auditTrail); } public void testTokenMissing() throws Exception { - AuthenticationToken token = service.token(service.newRequest("_action", message)); + Authenticator authenticator = service.createAuthenticator("_action", message, null); + AuthenticationToken token = authenticator.extractToken(); assertThat(token, nullValue()); + ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, authenticator::handleNullToken); + assertThat(e.getMessage(), containsString("missing authentication token")); + verify(auditTrail).anonymousAccessDenied("_action", message); verifyNoMoreInteractions(auditTrail); - assertThat(threadContext.getTransient(InternalAuthenticationService.TOKEN_KEY), nullValue()); } @SuppressWarnings("unchecked") @@ -147,20 +150,20 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.authenticate(token)).thenReturn(null); // first fails when(secondRealm.supports(token)).thenReturn(true); when(secondRealm.authenticate(token)).thenReturn(user); + if (randomBoolean()) { + when(firstRealm.token(threadContext)).thenReturn(token); + } else { + when(secondRealm.token(threadContext)).thenReturn(token); + } - service = spy(service); - doReturn(token).when(service).token(any(AuditableRequest.class)); - - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user, null))).thenReturn("_encoded_user"); - - User result = service.authenticate("_action", message, null); + Authentication result = service.authenticate("_action", message, null); assertThat(result, notNullValue()); - assertThat(result, is(user)); - verify(auditTrail).authenticationFailed("file", token, "_action", message); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, notNullValue()); - assertThat(user1, sameInstance(user)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_encoded_user")); + assertThat(result.getUser(), is(user)); + assertThat(result.getLookedUpBy(), is(nullValue())); + assertThat(result.getAuthenticatedBy(), is(notNullValue())); // TODO implement equals + verify(auditTrail).authenticationFailed(firstRealm.name(), token, "_action", message); + verify(cryptoService).sign(any(String.class)); + assertThreadContextContainsAuthentication(result); } public void testAuthenticateFirstNotSupportingSecondSucceeds() throws Exception { @@ -168,36 +171,28 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.supports(token)).thenReturn(false); when(secondRealm.supports(token)).thenReturn(true); when(secondRealm.authenticate(token)).thenReturn(user); + when(secondRealm.token(threadContext)).thenReturn(token); - service = spy(service); - doReturn(token).when(service).token(any(AuditableRequest.class)); - - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user, null))).thenReturn("_encoded_user"); - - User result = service.authenticate("_action", message, null); + Authentication result = service.authenticate("_action", message, null); assertThat(result, notNullValue()); - assertThat(result, is(user)); + assertThat(result.getUser(), is(user)); verifyZeroInteractions(auditTrail); verify(firstRealm, never()).authenticate(token); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, notNullValue()); - assertThat(user1, is((Object) user)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_encoded_user")); + assertThreadContextContainsAuthentication(result); } public void testAuthenticateCached() throws Exception { - User user = new User("_username", "r1"); - threadContext.putTransient(InternalAuthenticationService.USER_KEY, user); - User result = service.authenticate("_action", message, null); + final Authentication authentication = new Authentication(new User("_username", "r1"), new RealmRef("test", "cached", "foo"), null); + authentication.writeToContext(threadContext, cryptoService, true); + + Authentication result = service.authenticate("_action", message, null); + assertThat(result, notNullValue()); - assertThat(result, is(user)); + assertThat(result, is(authentication)); verifyZeroInteractions(auditTrail); verifyZeroInteractions(firstRealm); verifyZeroInteractions(secondRealm); - verifyZeroInteractions(cryptoService); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, notNullValue()); - assertThat(user1, is(user)); + verify(cryptoService).sign(any(String.class)); } public void testAuthenticateNonExistentRestRequestUserThrowsAuthenticationException() throws Exception { @@ -214,36 +209,30 @@ public class InternalAuthenticationServiceTests extends ESTestCase { public void testTokenRestMissing() throws Exception { when(firstRealm.token(threadContext)).thenReturn(null); when(secondRealm.token(threadContext)).thenReturn(null); - AuthenticationToken token = service.token(service.newRequest(restRequest)); + + Authenticator authenticator = service.createAuthenticator(restRequest); + AuthenticationToken token = authenticator.extractToken(); + assertThat(token, nullValue()); } - public void testEncodeDecodeUser() throws Exception { - User user = new User("username", "r1", "r2", "r3"); - String text = InternalAuthenticationService.encodeUser(user, null); - User user2 = InternalAuthenticationService.decodeUser(text); - assertThat(user, equalTo(user2)); - - text = InternalAuthenticationService.encodeUser(SystemUser.INSTANCE, null); - user2 = InternalAuthenticationService.decodeUser(text); - assertThat(SystemUser.INSTANCE, sameInstance(user2)); - } - - public void testUserHeader() throws Exception { + public void authenticationInContextAndHeader() throws Exception { User user = new User("_username", "r1"); when(firstRealm.token(threadContext)).thenReturn(token); when(firstRealm.supports(token)).thenReturn(true); when(firstRealm.authenticate(token)).thenReturn(user); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user, null))).thenReturn("_signed_user"); - service = spy(service); - AuditableRequest request = service.newRequest("_action", message); - doReturn(token).when(service).token(request); - User result = service.authenticate("_action", message, null); + + Authentication result = service.authenticate("_action", message, null); + assertThat(result, notNullValue()); - assertThat(result, is(user)); - String userStr = threadContext.getHeader(InternalAuthenticationService.USER_KEY); + assertThat(result.getUser(), is(user)); + + String userStr = threadContext.getHeader(Authentication.AUTHENTICATION_KEY); assertThat(userStr, notNullValue()); - assertThat(userStr, equalTo("_signed_user")); + assertThat(userStr, equalTo("_signed_auth")); + + Authentication ctxAuth = threadContext.getTransient(Authentication.AUTHENTICATION_KEY); + assertThat(ctxAuth, is(result)); } public void testAuthenticateTransportAnonymous() throws Exception { @@ -276,38 +265,24 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.token(threadContext)).thenReturn(null); when(secondRealm.token(threadContext)).thenReturn(null); User user1 = new User("username", "r1", "r2"); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user"); - User user2 = service.authenticate("_action", message, user1); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance(user2)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_signed_user")); + + Authentication result = service.authenticate("_action", message, user1); + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance(user1)); + assertThreadContextContainsAuthentication(result); } - public void testAuthenticateTransportSuccessNoFallback() throws Exception { - User user1 = new User("username", "r1", "r2"); + public void testAuthenticateTransportSuccess() throws Exception { + User user = new User("username", "r1", "r2"); + User fallback = randomBoolean() ? SystemUser.INSTANCE : null; when(firstRealm.token(threadContext)).thenReturn(token); when(firstRealm.supports(token)).thenReturn(true); - when(firstRealm.authenticate(token)).thenReturn(user1); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user"); - User user2 = service.authenticate("_action", message, null); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance(user2)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo("_signed_user")); - } + when(firstRealm.authenticate(token)).thenReturn(user); - public void testAuthenticateTransportSuccessWithFallback() throws Exception { - User user1 = new User("username", "r1", "r2"); - when(firstRealm.token(threadContext)).thenReturn(token); - when(firstRealm.supports(token)).thenReturn(true); - when(firstRealm.authenticate(token)).thenReturn(user1); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user"); - User user2 = service.authenticate("_action", message, SystemUser.INSTANCE); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance((Object) user2)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_signed_user")); + Authentication result = service.authenticate("_action", message, fallback); + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance(user)); + assertThreadContextContainsAuthentication(result); } public void testAuthenticateRestSuccess() throws Exception { @@ -315,10 +290,10 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.token(threadContext)).thenReturn(token); when(firstRealm.supports(token)).thenReturn(true); when(firstRealm.authenticate(token)).thenReturn(user1); - User user2 = service.authenticate(restRequest); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance(user2)); + Authentication result = service.authenticate(restRequest); + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance(user1)); + assertThreadContextContainsAuthentication(result); } public void testAutheticateTransportContextAndHeader() throws Exception { @@ -326,12 +301,10 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.token(threadContext)).thenReturn(token); when(firstRealm.supports(token)).thenReturn(true); when(firstRealm.authenticate(token)).thenReturn(user1); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user1, null))).thenReturn("_signed_user"); - User user2 = service.authenticate("_action", message, SystemUser.INSTANCE); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance(user2)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_signed_user")); + Authentication authentication = service.authenticate("_action", message, SystemUser.INSTANCE); + assertThat(authentication, notNullValue()); + assertThat(authentication.getUser(), sameInstance(user1)); + assertThreadContextContainsAuthentication(authentication); reset(firstRealm); // checking authentication from the context @@ -341,10 +314,10 @@ public class InternalAuthenticationServiceTests extends ESTestCase { service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - threadContext1.putTransient(InternalAuthenticationService.USER_KEY, - threadContext.getTransient(InternalAuthenticationService.USER_KEY)); - User user = service.authenticate("_action", message1, SystemUser.INSTANCE); - assertThat(user, sameInstance(user1)); + threadContext1.putTransient(Authentication.AUTHENTICATION_KEY, threadContext.getTransient(Authentication.AUTHENTICATION_KEY)); + threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY)); + Authentication ctxAuth = service.authenticate("_action", message1, SystemUser.INSTANCE); + assertThat(ctxAuth, sameInstance(authentication)); verifyZeroInteractions(firstRealm); reset(firstRealm); @@ -354,8 +327,8 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(threadPool.getThreadContext()).thenReturn(threadContext1); service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - threadContext1.putHeader(InternalAuthenticationService.USER_KEY, threadContext.getHeader(InternalAuthenticationService.USER_KEY)); - when(cryptoService.unsignAndVerify("_signed_user")).thenReturn(InternalAuthenticationService.encodeUser(user1, null)); + threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY)); + when(cryptoService.unsignAndVerify("_signed_auth")).thenReturn(authentication.encode()); BytesStreamOutput output = new BytesStreamOutput(); threadContext1.writeTo(output); @@ -366,12 +339,13 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(threadPool.getThreadContext()).thenReturn(threadContext1); service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - user = service.authenticate("_action", new InternalMessage(), SystemUser.INSTANCE); - assertThat(user, equalTo(user1)); + Authentication result = service.authenticate("_action", new InternalMessage(), SystemUser.INSTANCE); + assertThat(result, notNullValue()); + assertThat(result.getUser(), equalTo(user1)); verifyZeroInteractions(firstRealm); } - public void testAutheticateTransportContextAndHeaderNoSigning() throws Exception { + public void testAuthenticateTransportContextAndHeaderNoSigning() throws Exception { Settings settings = Settings.builder().put(InternalAuthenticationService.SIGN_USER_HEADER.getKey(), false).build(); service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); @@ -380,12 +354,10 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.supports(token)).thenReturn(true); when(firstRealm.token(threadContext)).thenReturn(token); when(firstRealm.authenticate(token)).thenReturn(user1); - User user2 = service.authenticate("_action", message, SystemUser.INSTANCE); - assertThat(user1, sameInstance(user2)); - User user3 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user3, sameInstance(user2)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), - equalTo((Object) InternalAuthenticationService.encodeUser(user1, null))); + Authentication authentication = service.authenticate("_action", message, SystemUser.INSTANCE); + assertThat(authentication, notNullValue()); + assertThat(authentication.getUser(), sameInstance(user1)); + assertThreadContextContainsAuthentication(authentication, false); reset(firstRealm); // checking authentication from the context @@ -394,17 +366,16 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(threadPool.getThreadContext()).thenReturn(threadContext1); service = new InternalAuthenticationService(Settings.EMPTY, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - threadContext1.putTransient(InternalAuthenticationService.USER_KEY, - threadContext.getTransient(InternalAuthenticationService.USER_KEY)); - User user = service.authenticate("_action", message1, SystemUser.INSTANCE); - assertThat(user, sameInstance(user1)); + threadContext1.putTransient(Authentication.AUTHENTICATION_KEY, threadContext.getTransient(Authentication.AUTHENTICATION_KEY)); + threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY)); + Authentication ctxAuth = service.authenticate("_action", message1, SystemUser.INSTANCE); + assertThat(ctxAuth, sameInstance(authentication)); verifyZeroInteractions(firstRealm); reset(firstRealm); - // checking authentication from the user header threadContext1 = new ThreadContext(Settings.EMPTY); - threadContext1.putHeader(InternalAuthenticationService.USER_KEY, threadContext.getHeader(InternalAuthenticationService.USER_KEY)); + threadContext1.putHeader(Authentication.AUTHENTICATION_KEY, threadContext.getHeader(Authentication.AUTHENTICATION_KEY)); BytesStreamOutput output = new BytesStreamOutput(); threadContext1.writeTo(output); @@ -415,8 +386,9 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(threadPool.getThreadContext()).thenReturn(threadContext1); service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - user = service.authenticate("_action", new InternalMessage(), SystemUser.INSTANCE); - assertThat(user, equalTo(user1)); + Authentication result = service.authenticate("_action", new InternalMessage(), SystemUser.INSTANCE); + assertThat(result, notNullValue()); + assertThat(result.getUser(), equalTo(user1)); verifyZeroInteractions(firstRealm); verifyZeroInteractions(cryptoService); @@ -424,8 +396,8 @@ public class InternalAuthenticationServiceTests extends ESTestCase { public void testAuthenticateTamperedUser() throws Exception { InternalMessage message = new InternalMessage(); - threadContext.putHeader(InternalAuthenticationService.USER_KEY, "_signed_user"); - when(cryptoService.unsignAndVerify("_signed_user")).thenThrow( + threadContext.putHeader(Authentication.AUTHENTICATION_KEY, "_signed_auth"); + when(cryptoService.unsignAndVerify("_signed_auth")).thenThrow( randomFrom(new RuntimeException(), new IllegalArgumentException(), new IllegalStateException())); try { @@ -444,23 +416,26 @@ public class InternalAuthenticationServiceTests extends ESTestCase { } else { user = new User("username", "r1", "r2"); } - assertThat(threadContext.getTransient(InternalAuthenticationService.USER_KEY), nullValue()); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), nullValue()); - when(cryptoService.sign(InternalAuthenticationService.encodeUser(user, null))).thenReturn("_signed_user"); - service.attachUserHeaderIfMissing(user); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance((Object) user)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo((Object) "_signed_user")); + assertThat(threadContext.getTransient(Authentication.AUTHENTICATION_KEY), nullValue()); + assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), nullValue()); + service.attachUserIfMissing(user); + + Authentication authentication = threadContext.getTransient(Authentication.AUTHENTICATION_KEY); + assertThat(authentication, notNullValue()); + assertThat(authentication.getUser(), sameInstance((Object) user)); + assertThat(authentication.getLookedUpBy(), nullValue()); + assertThat(authentication.getAuthenticatedBy().getName(), is("__attach")); + assertThat(authentication.getAuthenticatedBy().getType(), is("__attach")); + assertThat(authentication.getAuthenticatedBy().getNodeName(), is("authc_test")); + assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) "_signed_auth")); } public void testAttachIfMissingExists() throws Exception { - User user = new User("username", "r1", "r2"); - threadContext.putTransient(InternalAuthenticationService.USER_KEY, user); - threadContext.putHeader(InternalAuthenticationService.USER_KEY, "_signed_user"); - service.attachUserHeaderIfMissing(new User("username2", "r3", "r4")); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance(user)); - assertThat(threadContext.getHeader(InternalAuthenticationService.USER_KEY), equalTo("_signed_user")); + Authentication authentication = new Authentication(new User("username", "r1", "r2"), new RealmRef("test", "test", "foo"), null); + threadContext.putTransient(Authentication.AUTHENTICATION_KEY, authentication); + threadContext.putHeader(Authentication.AUTHENTICATION_KEY, "_signed_auth"); + service.attachUserIfMissing(new User("username2", "r3", "r4")); + assertThreadContextContainsAuthentication(authentication); } public void testAnonymousUserRest() throws Exception { @@ -474,16 +449,13 @@ public class InternalAuthenticationServiceTests extends ESTestCase { AnonymousUser.initialize(settings); service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - RestRequest request = new FakeRestRequest(); - User user = service.authenticate(request); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, notNullValue()); - assertThat(user1, sameInstance((Object) user)); - assertThat(user, notNullValue()); - assertThat(user.principal(), equalTo(username)); - assertThat(user.roles(), arrayContainingInAnyOrder("r1", "r2", "r3")); + Authentication result = service.authenticate(request); + + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance((Object) AnonymousUser.INSTANCE)); + assertThreadContextContainsAuthentication(result); } public void testAnonymousUserTransportNoDefaultUser() throws Exception { @@ -493,13 +465,12 @@ public class InternalAuthenticationServiceTests extends ESTestCase { AnonymousUser.initialize(settings); service = new InternalAuthenticationService(settings, realms, auditTrail, cryptoService, new DefaultAuthenticationFailureHandler(), threadPool, controller); - InternalMessage message = new InternalMessage(); - User user = service.authenticate("_action", message, null); - assertThat(user, notNullValue()); - assertThat(user.principal(), equalTo(AnonymousUser.DEFAULT_ANONYMOUS_USERNAME)); - assertThat(user.roles(), arrayContainingInAnyOrder("r1", "r2", "r3")); + Authentication result = service.authenticate("_action", message, null); + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance(AnonymousUser.INSTANCE)); + assertThreadContextContainsAuthentication(result); } public void testAnonymousUserTransportWithDefaultUser() throws Exception { @@ -512,9 +483,10 @@ public class InternalAuthenticationServiceTests extends ESTestCase { InternalMessage message = new InternalMessage(); - User user = service.authenticate("_action", message, SystemUser.INSTANCE); - assertThat(user, notNullValue()); - assertThat(user, sameInstance(SystemUser.INSTANCE)); + Authentication result = service.authenticate("_action", message, SystemUser.INSTANCE); + assertThat(result, notNullValue()); + assertThat(result.getUser(), sameInstance(SystemUser.INSTANCE)); + assertThreadContextContainsAuthentication(result); } public void testRealmTokenThrowingException() throws Exception { @@ -638,7 +610,14 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(secondRealm.lookupUser("run_as")).thenReturn(new User("looked up user", new String[]{"some role"})); when(secondRealm.userLookupSupported()).thenReturn(true); - User authenticated = service.authenticate("_action", message, null); + Authentication result; + if (randomBoolean()) { + result = service.authenticate("_action", message, null); + } else { + result = service.authenticate(restRequest); + } + assertThat(result, notNullValue()); + User authenticated = result.getUser(); assertThat(SystemUser.is(authenticated), is(false)); assertThat(authenticated.runAs(), is(notNullValue())); @@ -646,29 +625,7 @@ public class InternalAuthenticationServiceTests extends ESTestCase { assertThat(authenticated.roles(), arrayContaining("user")); assertThat(authenticated.runAs().principal(), is("looked up user")); assertThat(authenticated.runAs().roles(), arrayContaining("some role")); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance(authenticated)); - } - - public void testRunAsLookupSameRealmRest() throws Exception { - AuthenticationToken token = mock(AuthenticationToken.class); - threadContext.putHeader(InternalAuthenticationService.RUN_AS_USER_HEADER, "run_as"); - when(secondRealm.token(threadContext)).thenReturn(token); - when(secondRealm.supports(token)).thenReturn(true); - when(secondRealm.authenticate(token)).thenReturn(new User("lookup user", new String[]{"user"})); - when(secondRealm.lookupUser("run_as")).thenReturn(new User("looked up user", new String[]{"some role"})); - when(secondRealm.userLookupSupported()).thenReturn(true); - - User authenticated = service.authenticate(restRequest); - - assertThat(SystemUser.is(authenticated), is(false)); - assertThat(authenticated.runAs(), is(notNullValue())); - assertThat(authenticated.principal(), is("lookup user")); - assertThat(authenticated.roles(), arrayContaining("user")); - assertThat(authenticated.runAs().principal(), is("looked up user")); - assertThat(authenticated.runAs().roles(), arrayContaining("some role")); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance(authenticated)); + assertThreadContextContainsAuthentication(result); } public void testRunAsLookupDifferentRealm() throws Exception { @@ -681,7 +638,14 @@ public class InternalAuthenticationServiceTests extends ESTestCase { when(firstRealm.lookupUser("run_as")).thenReturn(new User("looked up user", new String[]{"some role"})); when(firstRealm.userLookupSupported()).thenReturn(true); - User authenticated = service.authenticate("_action", message, null); + Authentication result; + if (randomBoolean()) { + result = service.authenticate("_action", message, null); + } else { + result = service.authenticate(restRequest); + } + assertThat(result, notNullValue()); + User authenticated = result.getUser(); assertThat(SystemUser.is(authenticated), is(false)); assertThat(authenticated.runAs(), is(notNullValue())); @@ -689,74 +653,60 @@ public class InternalAuthenticationServiceTests extends ESTestCase { assertThat(authenticated.roles(), arrayContaining("user")); assertThat(authenticated.runAs().principal(), is("looked up user")); assertThat(authenticated.runAs().roles(), arrayContaining("some role")); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance(authenticated)); - } - - public void testRunAsLookupDifferentRealmRest() throws Exception { - AuthenticationToken token = mock(AuthenticationToken.class); - threadContext.putHeader(InternalAuthenticationService.RUN_AS_USER_HEADER, "run_as"); - when(secondRealm.token(threadContext)).thenReturn(token); - when(secondRealm.supports(token)).thenReturn(true); - when(secondRealm.authenticate(token)).thenReturn(new User("lookup user", new String[]{"user"})); - when(firstRealm.lookupUser("run_as")).thenReturn(new User("looked up user", new String[]{"some role"})); - when(firstRealm.userLookupSupported()).thenReturn(true); - - User authenticated = service.authenticate(restRequest); - - assertThat(SystemUser.is(authenticated), is(false)); - assertThat(authenticated.runAs(), is(notNullValue())); - assertThat(authenticated.principal(), is("lookup user")); - assertThat(authenticated.roles(), arrayContaining("user")); - assertThat(authenticated.runAs().principal(), is("looked up user")); - assertThat(authenticated.runAs().roles(), arrayContaining("some role")); - User user1 = threadContext.getTransient(InternalAuthenticationService.USER_KEY); - assertThat(user1, sameInstance(authenticated)); + assertThreadContextContainsAuthentication(result); } public void testRunAsWithEmptyRunAsUsernameRest() throws Exception { AuthenticationToken token = mock(AuthenticationToken.class); + User user = new User("lookup user", new String[]{"user"}); threadContext.putHeader(InternalAuthenticationService.RUN_AS_USER_HEADER, ""); when(secondRealm.token(threadContext)).thenReturn(token); when(secondRealm.supports(token)).thenReturn(true); - when(secondRealm.authenticate(token)).thenReturn(new User("lookup user", new String[]{"user"})); + when(secondRealm.authenticate(token)).thenReturn(user); when(secondRealm.userLookupSupported()).thenReturn(true); try { service.authenticate(restRequest); fail("exception should be thrown"); } catch (ElasticsearchException e) { - verify(auditTrail).authenticationFailed(token, restRequest); + verify(auditTrail).runAsDenied(any(User.class), eq(restRequest)); verifyNoMoreInteractions(auditTrail); } } public void testRunAsWithEmptyRunAsUsername() throws Exception { AuthenticationToken token = mock(AuthenticationToken.class); + User user = new User("lookup user", new String[]{"user"}); threadContext.putHeader(InternalAuthenticationService.RUN_AS_USER_HEADER, ""); when(secondRealm.token(threadContext)).thenReturn(token); when(secondRealm.supports(token)).thenReturn(true); - when(secondRealm.authenticate(token)).thenReturn(new User("lookup user", new String[]{"user"})); + when(secondRealm.authenticate(token)).thenReturn(user); when(secondRealm.userLookupSupported()).thenReturn(true); try { service.authenticate("_action", message, null); fail("exception should be thrown"); } catch (ElasticsearchException e) { - verify(auditTrail).authenticationFailed(token, "_action", message); + verify(auditTrail).runAsDenied(any(User.class), eq("_action"), eq(message)); verifyNoMoreInteractions(auditTrail); } } - public void testVersionWrittenWithUser() throws Exception { - User user = new User("username", "r1", "r2", "r3"); - String text = InternalAuthenticationService.encodeUser(user, null); - - StreamInput input = StreamInput.wrap(Base64.getDecoder().decode(text)); - Version version = Version.readVersion(input); - assertThat(version, is(Version.CURRENT)); - } - private static class InternalMessage extends TransportMessage { } + + void assertThreadContextContainsAuthentication(Authentication authentication) throws IOException { + assertThreadContextContainsAuthentication(authentication, true); + } + + void assertThreadContextContainsAuthentication(Authentication authentication, boolean sign) throws IOException { + Authentication contextAuth = threadContext.getTransient(Authentication.AUTHENTICATION_KEY); + assertThat(contextAuth, notNullValue()); + assertThat(contextAuth, is(authentication)); + if (sign) { + assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) "_signed_auth")); + } else { + assertThat(threadContext.getHeader(Authentication.AUTHENTICATION_KEY), equalTo((Object) authentication.encode())); + } + } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java index 69b07d08634..b242a89f710 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java @@ -56,6 +56,8 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.search.action.SearchTransportService; import org.elasticsearch.shield.ShieldTemplateService; +import org.elasticsearch.shield.authc.Authentication; +import org.elasticsearch.shield.authc.Authentication.RealmRef; import org.elasticsearch.shield.user.AnonymousUser; import org.elasticsearch.shield.user.SystemUser; import org.elasticsearch.shield.user.User; @@ -123,10 +125,10 @@ public class InternalAuthorizationServiceTests extends ESTestCase { TransportRequest request = mock(TransportRequest.class); // A failure would throw an exception - internalAuthorizationService.authorize(SystemUser.INSTANCE, "indices:monitor/whatever", request); + internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:monitor/whatever", request); verify(auditTrail).accessGranted(SystemUser.INSTANCE, "indices:monitor/whatever", request); - internalAuthorizationService.authorize(SystemUser.INSTANCE, "internal:whatever", request); + internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "internal:whatever", request); verify(auditTrail).accessGranted(SystemUser.INSTANCE, "internal:whatever", request); verifyNoMoreInteractions(auditTrail); } @@ -134,7 +136,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { public void testIndicesActionsAreNotAuthorized() { TransportRequest request = mock(TransportRequest.class); try { - internalAuthorizationService.authorize(SystemUser.INSTANCE, "indices:", request); + internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:", request); fail("action beginning with indices should have failed"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, @@ -147,7 +149,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { public void testClusterAdminActionsAreNotAuthorized() { TransportRequest request = mock(TransportRequest.class); try { - internalAuthorizationService.authorize(SystemUser.INSTANCE, "cluster:admin/whatever", request); + internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/whatever", request); fail("action beginning with cluster:admin/whatever should have failed"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, @@ -160,7 +162,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { public void testClusterAdminSnapshotStatusActionIsNotAuthorized() { TransportRequest request = mock(TransportRequest.class); try { - internalAuthorizationService.authorize(SystemUser.INSTANCE, "cluster:admin/snapshot/status", request); + internalAuthorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/snapshot/status", request); fail("action beginning with cluster:admin/snapshot/status should have failed"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" + @@ -174,7 +176,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { TransportRequest request = new SearchRequest(); User user = new User("test user"); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("user without roles should be denied"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]")); @@ -187,7 +189,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { TransportRequest request = new SearchRequest(); User user = new User("test user", "non-existent-role"); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("user with unknown role only should have been denied"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]")); @@ -202,7 +204,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build()); try { - internalAuthorizationService.authorize(user, "whatever", request); + internalAuthorizationService.authorize(createAuthentication(user), "whatever", request); fail("non indices and non cluster requests should be denied"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [whatever] is unauthorized for user [test user]")); @@ -217,7 +219,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(rolesStore.role("no_indices")).thenReturn(Role.builder("no_indices").cluster(ClusterPrivilege.action("")).build()); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("user only has cluster roles so indices requests should fail"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]")); @@ -231,28 +233,29 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build()); ClearScrollRequest clearScrollRequest = new ClearScrollRequest(); - internalAuthorizationService.authorize(user, ClearScrollAction.NAME, clearScrollRequest); + internalAuthorizationService.authorize(createAuthentication(user), ClearScrollAction.NAME, clearScrollRequest); verify(auditTrail).accessGranted(user, ClearScrollAction.NAME, clearScrollRequest); SearchScrollRequest searchScrollRequest = new SearchScrollRequest(); - internalAuthorizationService.authorize(user, SearchScrollAction.NAME, searchScrollRequest); + internalAuthorizationService.authorize(createAuthentication(user), SearchScrollAction.NAME, searchScrollRequest); verify(auditTrail).accessGranted(user, SearchScrollAction.NAME, searchScrollRequest); // We have to use a mock request for other Scroll actions as the actual requests are package private to SearchTransportService TransportRequest request = mock(TransportRequest.class); - internalAuthorizationService.authorize(user, SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request); + internalAuthorizationService + .authorize(createAuthentication(user), SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request); verify(auditTrail).accessGranted(user, SearchTransportService.CLEAR_SCROLL_CONTEXTS_ACTION_NAME, request); - internalAuthorizationService.authorize(user, SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request); verify(auditTrail).accessGranted(user, SearchTransportService.FETCH_ID_SCROLL_ACTION_NAME, request); - internalAuthorizationService.authorize(user, SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request); verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_FETCH_SCROLL_ACTION_NAME, request); - internalAuthorizationService.authorize(user, SearchTransportService.QUERY_SCROLL_ACTION_NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.QUERY_SCROLL_ACTION_NAME, request); verify(auditTrail).accessGranted(user, SearchTransportService.QUERY_SCROLL_ACTION_NAME, request); - internalAuthorizationService.authorize(user, SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request); verify(auditTrail).accessGranted(user, SearchTransportService.FREE_CONTEXT_SCROLL_ACTION_NAME, request); verifyNoMoreInteractions(auditTrail); } @@ -266,7 +269,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("indices request for b should be denied since there is no such index"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]")); @@ -287,7 +290,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA); try { - internalAuthorizationService.authorize(user, CreateIndexAction.NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request); fail("indices creation request with alias should be denied since user does not have permission to alias"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, @@ -308,7 +311,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(clusterService.state()).thenReturn(state); when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA); - internalAuthorizationService.authorize(user, CreateIndexAction.NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request); verify(auditTrail).accessGranted(user, CreateIndexAction.NAME, request); verifyNoMoreInteractions(auditTrail); @@ -364,7 +367,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA); try { - internalAuthorizationService.authorize(AnonymousUser.INSTANCE, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(AnonymousUser.INSTANCE), "indices:a", request); fail("indices request for b should be denied since there is no such index"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, @@ -395,7 +398,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA); try { - internalAuthorizationService.authorize(anonymousUser, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(anonymousUser), "indices:a", request); fail("indices request for b should be denied since there is no such index"); } catch (ElasticsearchSecurityException e) { assertAuthenticationException(e, containsString("action [indices:a] requires authentication")); @@ -411,7 +414,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { User user = new User("test user", null, new User("run as me", new String[] { "admin" })); assertThat(user.runAs(), is(notNullValue())); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("user without roles should be denied for run as"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]")); @@ -431,7 +434,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { .build()); try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("user without roles should be denied for run as"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]")); @@ -465,7 +468,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { } try { - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); fail("the run as user's role doesn't exist so they should not get authorized"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]")); @@ -496,7 +499,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { .add(IndexPrivilege.ALL, "b") .build()); - internalAuthorizationService.authorize(user, "indices:a", request); + internalAuthorizationService.authorize(createAuthentication(user), "indices:a", request); verify(auditTrail).runAsGranted(user, "indices:a", request); verify(auditTrail).accessGranted(user, "indices:a", request); verifyNoMoreInteractions(auditTrail); @@ -533,7 +536,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { String action = requestTuple.v1(); TransportRequest request = requestTuple.v2(); try { - internalAuthorizationService.authorize(user, action, request); + internalAuthorizationService.authorize(createAuthentication(user), action, request); fail("only the xpack user can execute operation [" + action + "] against the internal index"); } catch (ElasticsearchSecurityException e) { assertAuthorizationException(e, containsString("action [" + action + "] is unauthorized for user [all_access_user]")); @@ -544,12 +547,12 @@ public class InternalAuthorizationServiceTests extends ESTestCase { // we should allow waiting for the health of the index or any index if the user has this permission ClusterHealthRequest request = new ClusterHealthRequest(ShieldTemplateService.SECURITY_INDEX_NAME); - internalAuthorizationService.authorize(user, ClusterHealthAction.NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request); verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request); // multiple indices request = new ClusterHealthRequest(ShieldTemplateService.SECURITY_INDEX_NAME, "foo", "bar"); - internalAuthorizationService.authorize(user, ClusterHealthAction.NAME, request); + internalAuthorizationService.authorize(createAuthentication(user), ClusterHealthAction.NAME, request); verify(auditTrail).accessGranted(user, ClusterHealthAction.NAME, request); } @@ -580,7 +583,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { for (Tuple requestTuple : requests) { String action = requestTuple.v1(); TransportRequest request = requestTuple.v2(); - internalAuthorizationService.authorize(user, action, request); + internalAuthorizationService.authorize(createAuthentication(user), action, request); verify(auditTrail).accessGranted(user, action, request); } } @@ -612,8 +615,13 @@ public class InternalAuthorizationServiceTests extends ESTestCase { for (Tuple requestTuple : requests) { String action = requestTuple.v1(); TransportRequest request = requestTuple.v2(); - internalAuthorizationService.authorize(XPackUser.INSTANCE, action, request); + internalAuthorizationService.authorize(createAuthentication(XPackUser.INSTANCE), action, request); verify(auditTrail).accessGranted(XPackUser.INSTANCE, action, request); } } + + private Authentication createAuthentication(User user) { + RealmRef lookedUpBy = user.runAs() == null ? null : new RealmRef("looked", "up", "by"); + return new Authentication(user, new RealmRef("test", "test", "foo"), lookedUpBy); + } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/DefaultRoleTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/DefaultRoleTests.java index 5e7f52ed623..fad804c08aa 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/DefaultRoleTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/DefaultRoleTests.java @@ -12,6 +12,14 @@ import org.elasticsearch.client.Client; import org.elasticsearch.license.plugin.action.get.GetLicenseAction; import org.elasticsearch.shield.action.user.AuthenticateRequestBuilder; import org.elasticsearch.shield.action.user.ChangePasswordRequestBuilder; +import org.elasticsearch.shield.authc.Authentication; +import org.elasticsearch.shield.authc.Authentication.RealmRef; +import org.elasticsearch.shield.authc.activedirectory.ActiveDirectoryRealm; +import org.elasticsearch.shield.authc.esnative.NativeRealm; +import org.elasticsearch.shield.authc.esnative.ReservedRealm; +import org.elasticsearch.shield.authc.file.FileRealm; +import org.elasticsearch.shield.authc.ldap.LdapRealm; +import org.elasticsearch.shield.authc.pki.PkiRealm; import org.elasticsearch.shield.user.User; import org.elasticsearch.shield.action.user.AuthenticateAction; import org.elasticsearch.shield.action.user.AuthenticateRequest; @@ -28,7 +36,11 @@ import java.util.Iterator; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; /** * Unit tests for the {@link DefaultRole} @@ -51,9 +63,16 @@ public class DefaultRoleTests extends ESTestCase { new ChangePasswordRequestBuilder(mock(Client.class)).username(user.principal()).request() : new AuthenticateRequestBuilder(mock(Client.class)).username(user.principal()).request(); final String action = changePasswordRequest ? ChangePasswordAction.NAME : AuthenticateAction.NAME; - assertThat(request, instanceOf(UserRequest.class)); + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(user); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authenticatedBy.getType()) + .thenReturn(changePasswordRequest ? randomFrom(ReservedRealm.TYPE, NativeRealm.TYPE) : randomAsciiOfLengthBetween(4, 12)); - assertThat(DefaultRole.INSTANCE.cluster().check(action, request, user), is(true)); + assertThat(request, instanceOf(UserRequest.class)); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(true)); } public void testDefaultRoleDoesNotAllowNonMatchingUsername() { @@ -64,19 +83,33 @@ public class DefaultRoleTests extends ESTestCase { new ChangePasswordRequestBuilder(mock(Client.class)).username(username).request() : new AuthenticateRequestBuilder(mock(Client.class)).username(username).request(); final String action = changePasswordRequest ? ChangePasswordAction.NAME : AuthenticateAction.NAME; - assertThat(request, instanceOf(UserRequest.class)); + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(user); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authenticatedBy.getType()) + .thenReturn(changePasswordRequest ? randomFrom(ReservedRealm.TYPE, NativeRealm.TYPE) : randomAsciiOfLengthBetween(4, 12)); - assertThat(DefaultRole.INSTANCE.cluster().check(action, request, user), is(false)); + assertThat(request, instanceOf(UserRequest.class)); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); final User user2 = new User("admin", new String[] { "bar" }, user); + when(authentication.getUser()).thenReturn(user2); + when(authentication.getRunAsUser()).thenReturn(user); + final RealmRef lookedUpBy = mock(RealmRef.class); + when(authentication.getLookedUpBy()).thenReturn(lookedUpBy); + when(lookedUpBy.getType()) + .thenReturn(changePasswordRequest ? randomFrom(ReservedRealm.TYPE, NativeRealm.TYPE) : randomAsciiOfLengthBetween(4, 12)); + // this should still fail since the username is still different + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); + if (request instanceof ChangePasswordRequest) { ((ChangePasswordRequest)request).username("joe"); } else { ((AuthenticateRequest)request).username("joe"); } - // run as should not be checked by this role, it is up to the caller to provide the correct user - assertThat(DefaultRole.INSTANCE.cluster().check(action, request, user2), is(false)); - assertThat(DefaultRole.INSTANCE.cluster().check(action, request, user), is(true)); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(true)); } public void testDefaultRoleDoesNotAllowOtherActions() { @@ -84,8 +117,85 @@ public class DefaultRoleTests extends ESTestCase { final TransportRequest request = mock(TransportRequest.class); final String action = randomFrom(PutUserAction.NAME, DeleteUserAction.NAME, ClusterHealthAction.NAME, ClusterStateAction.NAME, ClusterStatsAction.NAME, GetLicenseAction.NAME); + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(randomBoolean() ? user : new User("runAs")); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authenticatedBy.getType()) + .thenReturn(randomAsciiOfLengthBetween(4, 12)); - assertThat(DefaultRole.INSTANCE.cluster().check(action, request, user), is(false)); - verifyZeroInteractions(user, request); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); + verifyZeroInteractions(user, request, authentication); + } + + public void testDefaultRoleWithRunAsChecksAuthenticatedBy() { + final String username = "joe"; + final User runAs = new User(username); + final User user = new User("admin", new String[] { "bar" }, runAs); + final boolean changePasswordRequest = randomBoolean(); + final TransportRequest request = changePasswordRequest ? + new ChangePasswordRequestBuilder(mock(Client.class)).username(username).request() : + new AuthenticateRequestBuilder(mock(Client.class)).username(username).request(); + final String action = changePasswordRequest ? ChangePasswordAction.NAME : AuthenticateAction.NAME; + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + final RealmRef lookedUpBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(runAs); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authentication.getLookedUpBy()).thenReturn(lookedUpBy); + when(lookedUpBy.getType()) + .thenReturn(changePasswordRequest ? randomFrom(ReservedRealm.TYPE, NativeRealm.TYPE) : randomAsciiOfLengthBetween(4, 12)); + + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(true)); + + when(authentication.getRunAsUser()).thenReturn(user); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); + } + + public void testDefaultRoleDoesNotAllowChangePasswordForOtherRealms() { + final User user = new User("joe"); + final ChangePasswordRequest request = new ChangePasswordRequestBuilder(mock(Client.class)).username(user.principal()).request(); + final String action = ChangePasswordAction.NAME; + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(user); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authenticatedBy.getType()).thenReturn(randomFrom(LdapRealm.TYPE, FileRealm.TYPE, ActiveDirectoryRealm.TYPE, PkiRealm.TYPE, + randomAsciiOfLengthBetween(4, 12))); + + assertThat(request, instanceOf(UserRequest.class)); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); + verify(authenticatedBy).getType(); + verify(authentication, times(2)).getRunAsUser(); + verify(authentication).getUser(); + verify(authentication).getAuthenticatedBy(); + verifyNoMoreInteractions(authenticatedBy, authentication); + } + + public void testDefaultRoleDoesNotAllowChangePasswordForLookedUpByOtherRealms() { + final User runAs = new User("joe"); + final User user = new User("admin", new String[] { "bar" }, runAs); + final ChangePasswordRequest request = new ChangePasswordRequestBuilder(mock(Client.class)).username(runAs.principal()).request(); + final String action = ChangePasswordAction.NAME; + final Authentication authentication = mock(Authentication.class); + final RealmRef authenticatedBy = mock(RealmRef.class); + final RealmRef lookedUpBy = mock(RealmRef.class); + when(authentication.getUser()).thenReturn(user); + when(authentication.getRunAsUser()).thenReturn(runAs); + when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy); + when(authentication.getLookedUpBy()).thenReturn(lookedUpBy); + when(lookedUpBy.getType()).thenReturn(randomFrom(LdapRealm.TYPE, FileRealm.TYPE, ActiveDirectoryRealm.TYPE, PkiRealm.TYPE, + randomAsciiOfLengthBetween(4, 12))); + + assertThat(request, instanceOf(UserRequest.class)); + assertThat(DefaultRole.INSTANCE.cluster().check(action, request, authentication), is(false)); + verify(authentication).getLookedUpBy(); + verify(authentication, times(2)).getRunAsUser(); + verify(authentication).getUser(); + verify(lookedUpBy).getType(); + verifyNoMoreInteractions(authentication, lookedUpBy, authenticatedBy); } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaRoleTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaRoleTests.java index 6aefb0b1f5e..f199c3008b7 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaRoleTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaRoleTests.java @@ -17,14 +17,14 @@ import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateActio import org.elasticsearch.action.delete.DeleteAction; import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.marvel.action.MonitoringBulkAction; -import org.elasticsearch.shield.user.KibanaUser; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.TransportRequest; import java.util.Arrays; import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; /** * Tests for the kibana role @@ -32,15 +32,15 @@ import static org.hamcrest.Matchers.is; public class KibanaRoleTests extends ESTestCase { public void testCluster() { - final User user = KibanaUser.INSTANCE; final TransportRequest request = new TransportRequest.Empty(); - assertThat(KibanaRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, user), is(true)); - assertThat(KibanaRole.INSTANCE.cluster().check(ClusterStateAction.NAME, request, user), is(true)); - assertThat(KibanaRole.INSTANCE.cluster().check(ClusterStatsAction.NAME, request, user), is(true)); - assertThat(KibanaRole.INSTANCE.cluster().check(MonitoringBulkAction.NAME, request, user), is(true)); - assertThat(KibanaRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, user), is(false)); - assertThat(KibanaRole.INSTANCE.cluster().check(ClusterRerouteAction.NAME, request, user), is(false)); - assertThat(KibanaRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, user), is(false)); + final Authentication authentication = mock(Authentication.class); + assertThat(KibanaRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(KibanaRole.INSTANCE.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); + assertThat(KibanaRole.INSTANCE.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); + assertThat(KibanaRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); + assertThat(KibanaRole.INSTANCE.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false)); + assertThat(KibanaRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(false)); + assertThat(KibanaRole.INSTANCE.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(true)); } public void testRunAs() { diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaUserRoleTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaUserRoleTests.java index ccdf3b4fdc8..89021551d05 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaUserRoleTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/KibanaUserRoleTests.java @@ -19,27 +19,27 @@ import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.search.MultiSearchAction; import org.elasticsearch.action.search.SearchAction; import org.elasticsearch.marvel.action.MonitoringBulkAction; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.transport.TransportRequest; import java.util.Arrays; import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; public class KibanaUserRoleTests extends ESTestCase { public void testCluster() { - final User user = new User("joe"); + final Authentication authentication = mock(Authentication.class); final TransportRequest request = new TransportRequest.Empty(); - assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, user), is(true)); - assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterStateAction.NAME, request, user), is(true)); - assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterStatsAction.NAME, request, user), is(true)); - assertThat(KibanaUserRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, user), is(false)); - assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterRerouteAction.NAME, request, user), is(false)); - assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, user), is(false)); - - assertThat(KibanaUserRole.INSTANCE.cluster().check(MonitoringBulkAction.NAME, request, user), is(false)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterStateAction.NAME, request, authentication), is(true)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterStatsAction.NAME, request, authentication), is(true)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(false)); + assertThat(KibanaUserRole.INSTANCE.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(false)); } public void testRunAs() { diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/SuperuserRoleTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/SuperuserRoleTests.java index 5b94d3eaf29..cd47c9e1bee 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/SuperuserRoleTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/SuperuserRoleTests.java @@ -20,6 +20,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.shield.action.role.PutRoleAction; import org.elasticsearch.shield.action.user.PutUserAction; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.authz.accesscontrol.IndicesAccessControl.IndexAccessControl; import org.elasticsearch.shield.user.User; import org.elasticsearch.test.ESTestCase; @@ -28,6 +29,8 @@ import org.elasticsearch.transport.TransportRequest; import java.util.Map; import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * Tests for the superuser role @@ -36,14 +39,16 @@ public class SuperuserRoleTests extends ESTestCase { public void testCluster() { final User user = new User("joe", SuperuserRole.NAME); + final Authentication authentication = mock(Authentication.class); + when(authentication.getUser()).thenReturn(user); final TransportRequest request = new TransportRequest.Empty(); - assertThat(SuperuserRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, user), is(true)); - assertThat(SuperuserRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, user), is(true)); - assertThat(SuperuserRole.INSTANCE.cluster().check(PutUserAction.NAME, request, user), is(true)); - assertThat(SuperuserRole.INSTANCE.cluster().check(PutRoleAction.NAME, request, user), is(true)); - assertThat(SuperuserRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, user), is(true)); - assertThat(SuperuserRole.INSTANCE.cluster().check("internal:admin/foo", request, user), is(false)); + assertThat(SuperuserRole.INSTANCE.cluster().check(ClusterHealthAction.NAME, request, authentication), is(true)); + assertThat(SuperuserRole.INSTANCE.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication), is(true)); + assertThat(SuperuserRole.INSTANCE.cluster().check(PutUserAction.NAME, request, authentication), is(true)); + assertThat(SuperuserRole.INSTANCE.cluster().check(PutRoleAction.NAME, request, authentication), is(true)); + assertThat(SuperuserRole.INSTANCE.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(true)); + assertThat(SuperuserRole.INSTANCE.cluster().check("internal:admin/foo", request, authentication), is(false)); } public void testIndices() { diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/rest/ShieldRestFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/rest/ShieldRestFilterTests.java index 59ae9601bf7..fac9f00da77 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/rest/ShieldRestFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/rest/ShieldRestFilterTests.java @@ -12,7 +12,7 @@ import org.elasticsearch.rest.RestChannel; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestFilterChain; import org.elasticsearch.rest.RestRequest; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.authc.AuthenticationService; import org.elasticsearch.shield.SecurityLicenseState; import org.elasticsearch.test.ESTestCase; @@ -52,8 +52,8 @@ public class ShieldRestFilterTests extends ESTestCase { public void testProcess() throws Exception { RestRequest request = mock(RestRequest.class); - User user = new User("_user", "r1"); - when(authcService.authenticate(request)).thenReturn(user); + Authentication authentication = mock(Authentication.class); + when(authcService.authenticate(request)).thenReturn(authentication); filter.process(request, channel, chain); verify(chain).continueProcessing(request, channel); verifyZeroInteractions(channel); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ClientTransportFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ClientTransportFilterTests.java index 19eb7ed089e..89e8fe15e5c 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ClientTransportFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ClientTransportFilterTests.java @@ -30,6 +30,6 @@ public class ClientTransportFilterTests extends ESTestCase { public void testOutbound() throws Exception { TransportRequest request = mock(TransportRequest.class); filter.outbound("_action", request); - verify(authcService).attachUserHeaderIfMissing(SystemUser.INSTANCE); + verify(authcService).attachUserIfMissing(SystemUser.INSTANCE); } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ServerTransportFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ServerTransportFilterTests.java index 715df3c07e0..9cd88467b32 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ServerTransportFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/ServerTransportFilterTests.java @@ -8,7 +8,7 @@ package org.elasticsearch.shield.transport; import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.shield.user.User; +import org.elasticsearch.shield.authc.Authentication; import org.elasticsearch.shield.action.ShieldActionMapper; import org.elasticsearch.shield.authc.AuthenticationService; import org.elasticsearch.shield.authz.AuthorizationService; @@ -48,10 +48,10 @@ public class ServerTransportFilterTests extends ESTestCase { public void testInbound() throws Exception { TransportRequest request = mock(TransportRequest.class); - User user = mock(User.class); - when(authcService.authenticate("_action", request, null)).thenReturn(user); + Authentication authentication = mock(Authentication.class); + when(authcService.authenticate("_action", request, null)).thenReturn(authentication); filter.inbound("_action", request, channel); - verify(authzService).authorize(user, "_action", request); + verify(authzService).authorize(authentication, "_action", request); } public void testInboundAuthenticationException() throws Exception { @@ -68,9 +68,9 @@ public class ServerTransportFilterTests extends ESTestCase { public void testInboundAuthorizationException() throws Exception { TransportRequest request = mock(TransportRequest.class); - User user = mock(User.class); - when(authcService.authenticate("_action", request, null)).thenReturn(user); - doThrow(authorizationError("authz failed")).when(authzService).authorize(user, "_action", request); + Authentication authentication = mock(Authentication.class); + when(authcService.authenticate("_action", request, null)).thenReturn(authentication); + doThrow(authorizationError("authz failed")).when(authzService).authorize(authentication, "_action", request); try { filter.inbound("_action", request, channel); fail("expected filter inbound to throw an authorization exception on authorization error"); From 568bf49578cc3f951d35e2cebc45fda9b935ac4a Mon Sep 17 00:00:00 2001 From: Areek Zillur Date: Fri, 17 Jun 2016 10:32:28 -0400 Subject: [PATCH 09/11] add rollover to known actions Original commit: elastic/x-pack-elasticsearch@296e4ea4c21fe076b834ad40c6898545c09549b4 --- .../src/test/resources/org/elasticsearch/transport/actions | 1 + 1 file changed, 1 insertion(+) diff --git a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/transport/actions b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/transport/actions index 1952eec4478..a96611f6b02 100644 --- a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/transport/actions +++ b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/transport/actions @@ -44,6 +44,7 @@ indices:admin/refresh indices:admin/settings/update indices:admin/shards/search_shards indices:admin/shrink +indices:admin/rollover indices:admin/template/delete indices:admin/template/get indices:admin/template/put From 5e300fc1e42f44df4ddf853acde20e51acaa2b61 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Fri, 17 Jun 2016 17:07:22 +0200 Subject: [PATCH 10/11] Cleanup ClusterService dependencies and detached from Guice (elastic/elasticsearch#2542) followup for elastic/elasticsearchelastic/elasticsearch#18941 Original commit: elastic/x-pack-elasticsearch@6b8680b5e91b1a0cafe50d7aa8e8451e0467d206 --- .../license/plugin/core/LicensesService.java | 2 +- .../agent/collector/cluster/ClusterStatsCollector.java | 6 ++---- .../marvel/action/TransportMonitoringBulkActionTests.java | 8 ++++---- .../collector/cluster/ClusterStatsCollectorTests.java | 3 +-- .../marvel/agent/exporter/ExportersTests.java | 6 ++++-- .../agent/resolver/cluster/ClusterInfoResolverTests.java | 5 +++-- .../agent/resolver/cluster/ClusterStatsResolverTests.java | 4 ++-- .../action/realm/TransportClearRealmCacheAction.java | 7 +++---- .../action/role/TransportClearRolesCacheAction.java | 7 +++---- .../shield/transport/ShieldClientTransportService.java | 5 ++--- .../shield/transport/ShieldServerTransportService.java | 4 +--- .../shield/transport/TransportFilterTests.java | 4 ++-- 12 files changed, 28 insertions(+), 33 deletions(-) diff --git a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java index 4368267727b..3438fdbda8d 100644 --- a/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java +++ b/elasticsearch/x-pack/license-plugin/src/main/java/org/elasticsearch/license/plugin/core/LicensesService.java @@ -415,7 +415,7 @@ public class LicensesService extends AbstractLifecycleComponent long issueDate = System.currentTimeMillis(); License.Builder specBuilder = License.builder() .uid(UUID.randomUUID().toString()) - .issuedTo(clusterService.state().getClusterName().value()) + .issuedTo(clusterService.getClusterName().value()) .maxNodes(trialLicenseMaxNodes) .issueDate(issueDate) .expiryDate(issueDate + trialLicenseDuration.getMillis()); diff --git a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollector.java b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollector.java index 96ea090dcf4..cff6259308a 100644 --- a/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollector.java +++ b/elasticsearch/x-pack/marvel/src/main/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollector.java @@ -41,17 +41,15 @@ public class ClusterStatsCollector extends AbstractCollector {}); clusterService.start(); - transportService = new TransportService(Settings.EMPTY, transport, threadPool, clusterService.state().getClusterName()); + transportService = new TransportService(clusterService.getSettings(), transport, threadPool); transportService.start(); transportService.acceptIncomingRequests(); exportService = new CapturingExporters(); diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollectorTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollectorTests.java index 84d2bbe2e5f..25f47c6a74d 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollectorTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/collector/cluster/ClusterStatsCollectorTests.java @@ -134,8 +134,7 @@ public class ClusterStatsCollectorTests extends AbstractCollectorTestCase { internalCluster().getInstance(MonitoringSettings.class, nodeId), internalCluster().getInstance(MonitoringLicensee.class, nodeId), securedClient(nodeId), - internalCluster().getInstance(LicensesManagerService.class, nodeId), - internalCluster().getInstance(ClusterName.class, nodeId)); + internalCluster().getInstance(LicensesManagerService.class, nodeId)); } private void assertCanCollect(AbstractCollector collector, Class... classes) { diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java index 7ed76f5c9f8..c9c2ef39aba 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/exporter/ExportersTests.java @@ -223,7 +223,8 @@ public class ExportersTests extends ESTestCase { DiscoveryNodes nodes = mock(DiscoveryNodes.class); when(nodes.isLocalNodeElectedMaster()).thenReturn(true); - when(clusterService.state()).thenReturn(ClusterState.builder(ClusterName.DEFAULT).nodes(nodes).build()); + when(clusterService.state()).thenReturn(ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)) + .nodes(nodes).build()); ExportBulk bulk = exporters.openBulk(); assertThat(bulk, notNullValue()); @@ -247,7 +248,8 @@ public class ExportersTests extends ESTestCase { DiscoveryNodes nodes = mock(DiscoveryNodes.class); when(nodes.isLocalNodeElectedMaster()).thenReturn(false); - when(clusterService.state()).thenReturn(ClusterState.builder(ClusterName.DEFAULT).nodes(nodes).build()); + when(clusterService.state()).thenReturn(ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)) + .nodes(nodes).build()); ExportBulk bulk = exporters.openBulk(); assertThat(bulk, notNullValue()); diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterInfoResolverTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterInfoResolverTests.java index 514f75351fa..d0982ec6705 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterInfoResolverTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterInfoResolverTests.java @@ -9,6 +9,7 @@ import org.elasticsearch.Version; import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.DummyTransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentType; @@ -45,8 +46,8 @@ public class ClusterInfoResolverTests extends MonitoringIndexNameResolverTestCas doc.setVersion(randomFrom(Version.V_2_0_0, Version.CURRENT).toString()); doc.setLicense(licenseBuilder.build()); doc.setClusterName(randomAsciiOfLength(5)); - doc.setClusterStats(new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.DEFAULT, - randomAsciiOfLength(5), Collections.emptyList(), Collections.emptyList())); + doc.setClusterStats(new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.CLUSTER_NAME_SETTING + .getDefault(Settings.EMPTY), randomAsciiOfLength(5), Collections.emptyList(), Collections.emptyList())); return doc; } catch (Exception e) { throw new IllegalStateException("Failed to generated random ClusterInfoMarvelDoc", e); diff --git a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterStatsResolverTests.java b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterStatsResolverTests.java index 80beba90765..5aafcd04f46 100644 --- a/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterStatsResolverTests.java +++ b/elasticsearch/x-pack/marvel/src/test/java/org/elasticsearch/marvel/agent/resolver/cluster/ClusterStatsResolverTests.java @@ -97,8 +97,8 @@ public class ClusterStatsResolverTests extends MonitoringIndexNameResolverTestCa emptyMap(), emptySet(), Version.CURRENT), ClusterHealthStatus.GREEN, randomNodeInfo(), randomNodeStats(), randomShardStats()) ); - return new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.DEFAULT, UUID.randomUUID().toString(), - responses, Collections.emptyList()); + return new ClusterStatsResponse(Math.abs(randomLong()), ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY), + UUID.randomUUID().toString(), responses, Collections.emptyList()); } /** diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/realm/TransportClearRealmCacheAction.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/realm/TransportClearRealmCacheAction.java index c2a4c81a63b..99d8dc32889 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/realm/TransportClearRealmCacheAction.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/realm/TransportClearRealmCacheAction.java @@ -9,7 +9,6 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.TransportNodesAction; -import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; @@ -31,11 +30,11 @@ public class TransportClearRealmCacheAction extends TransportNodesAction responses, List failures) { - return new ClearRealmCacheResponse(clusterName, responses, failures); + return new ClearRealmCacheResponse(clusterService.getClusterName(), responses, failures); } @Override diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/role/TransportClearRolesCacheAction.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/role/TransportClearRolesCacheAction.java index 0d1498ac9ff..b029b6de167 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/role/TransportClearRolesCacheAction.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/action/role/TransportClearRolesCacheAction.java @@ -8,7 +8,6 @@ package org.elasticsearch.shield.action.role; import org.elasticsearch.action.FailedNodeException; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.nodes.TransportNodesAction; -import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.common.inject.Inject; @@ -28,10 +27,10 @@ public class TransportClearRolesCacheAction extends TransportNodesAction responses, List failures) { - return new ClearRolesCacheResponse(clusterName, responses, failures); + return new ClearRolesCacheResponse(clusterService.getClusterName(), responses, failures); } @Override diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldClientTransportService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldClientTransportService.java index c4320ab973e..73dede2f854 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldClientTransportService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldClientTransportService.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.shield.transport; -import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; @@ -24,8 +23,8 @@ public class ShieldClientTransportService extends TransportService { @Inject public ShieldClientTransportService(Settings settings, Transport transport, ThreadPool threadPool, - ClusterName clusterName, ClientTransportFilter clientFilter) { - super(settings, transport, threadPool, clusterName); + ClientTransportFilter clientFilter) { + super(settings, transport, threadPool); this.clientFilter = clientFilter; } diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java index 8f5baa4ae33..918bc6e7a8e 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/transport/ShieldServerTransportService.java @@ -5,7 +5,6 @@ */ package org.elasticsearch.shield.transport; -import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; @@ -56,13 +55,12 @@ public class ShieldServerTransportService extends TransportService { @Inject public ShieldServerTransportService(Settings settings, Transport transport, ThreadPool threadPool, - ClusterName clusterName, AuthenticationService authcService, AuthorizationService authzService, ShieldActionMapper actionMapper, ClientTransportFilter clientTransportFilter, SecurityLicenseState licenseState) { - super(settings, transport, threadPool, clusterName); + super(settings, transport, threadPool); this.authcService = authcService; this.authzService = authzService; this.actionMapper = actionMapper; diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java index 06f6912c6d7..e711500990f 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/transport/TransportFilterTests.java @@ -290,9 +290,9 @@ public class TransportFilterTests extends ESIntegTestCase { @Inject public InternalPluginServerTransportService(Settings settings, Transport transport, ThreadPool threadPool, - ClusterName clusterName, AuthenticationService authcService, AuthorizationService authzService, + AuthenticationService authcService, AuthorizationService authzService, ShieldActionMapper actionMapper, ClientTransportFilter clientTransportFilter) { - super(settings, transport, threadPool, clusterName, authcService, authzService, actionMapper, clientTransportFilter, + super(settings, transport, threadPool, authcService, authzService, actionMapper, clientTransportFilter, mock(SecurityLicenseState.class)); when(licenseState.authenticationAndAuthorizationEnabled()).thenReturn(true); } From dd7a43a93fa236e2cabe9cb48c29e8fa04853593 Mon Sep 17 00:00:00 2001 From: jaymode Date: Wed, 15 Jun 2016 15:44:30 -0400 Subject: [PATCH 11/11] security: optimize field level security for match all fields This commit handles the use of `*` as a field in a role as effectively disabling field level security. We do this to take advantage of caches that we disable when field level security is active. See elastic/elasticsearch#2407 Original commit: elastic/x-pack-elasticsearch@d96e18d57c2baddb6648ec81ff8aa50a4e7143f4 --- .../shield/authz/permission/IndicesPermission.java | 6 +++++- .../authz/accesscontrol/IndicesPermissionTests.java | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/IndicesPermission.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/IndicesPermission.java index 3fab48e5d34..81d76b02592 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/IndicesPermission.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/permission/IndicesPermission.java @@ -163,7 +163,11 @@ public interface IndicesPermission extends Permission, Iterable roleFields = rolesFieldsByIndex.get(index); if (roleFields != null) { - roleFields = unmodifiableSet(roleFields); + if (roleFields.contains("*")) { + roleFields = null; + } else { + roleFields = unmodifiableSet(roleFields); + } } indexPermissions.put(index, new IndicesAccessControl.IndexAccessControl(entry.getValue(), roleFields, roleQueries)); } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesPermissionTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesPermissionTests.java index f4d1f2b9332..bdecc86d919 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesPermissionTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesPermissionTests.java @@ -19,7 +19,9 @@ import org.elasticsearch.shield.authz.privilege.IndexPrivilege; import org.elasticsearch.test.ESTestCase; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Set; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.notNullValue; @@ -72,6 +74,16 @@ public class IndicesPermissionTests extends ESTestCase { assertThat(permissions.getIndexPermissions("_index").getFields().iterator().next(), equalTo("_field")); assertThat(permissions.getIndexPermissions("_index").getQueries().size(), equalTo(1)); assertThat(permissions.getIndexPermissions("_index").getQueries().iterator().next(), equalTo(query)); + + // match all fields + List allFields = randomFrom(Collections.singletonList("*"), Arrays.asList("foo", "*"), + Arrays.asList(randomAsciiOfLengthBetween(1, 10), "*")); + role = Role.builder("_role").add(allFields, query, IndexPrivilege.ALL, "_alias").build(); + permissions = role.authorize(SearchAction.NAME, Sets.newHashSet("_alias"), md); + assertThat(permissions.getIndexPermissions("_index"), notNullValue()); + assertThat(permissions.getIndexPermissions("_index").getFields(), nullValue()); + assertThat(permissions.getIndexPermissions("_index").getQueries().size(), equalTo(1)); + assertThat(permissions.getIndexPermissions("_index").getQueries().iterator().next(), equalTo(query)); } }