Skip to content

Commit 3bac7e7

Browse files
committed
add IT tests for always allowed with no policy; add test functions with Environment
1 parent b9a9784 commit 3bac7e7

File tree

5 files changed

+152
-14
lines changed

5 files changed

+152
-14
lines changed

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/EntitlementTestPlugin.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,28 @@
1515
import org.elasticsearch.common.settings.IndexScopedSettings;
1616
import org.elasticsearch.common.settings.Settings;
1717
import org.elasticsearch.common.settings.SettingsFilter;
18+
import org.elasticsearch.env.Environment;
1819
import org.elasticsearch.features.NodeFeature;
1920
import org.elasticsearch.plugins.ActionPlugin;
2021
import org.elasticsearch.plugins.Plugin;
2122
import org.elasticsearch.rest.RestController;
2223
import org.elasticsearch.rest.RestHandler;
2324

25+
import java.util.Collection;
2426
import java.util.List;
2527
import java.util.function.Predicate;
2628
import java.util.function.Supplier;
2729

2830
public class EntitlementTestPlugin extends Plugin implements ActionPlugin {
31+
32+
private Environment environment;
33+
34+
@Override
35+
public Collection<?> createComponents(PluginServices services) {
36+
environment = services.environment();
37+
return super.createComponents(services);
38+
}
39+
2940
@Override
3041
public List<RestHandler> getRestHandlers(
3142
final Settings settings,
@@ -38,6 +49,6 @@ public List<RestHandler> getRestHandlers(
3849
final Supplier<DiscoveryNodes> nodesInCluster,
3950
Predicate<NodeFeature> clusterSupportsFeature
4051
) {
41-
return List.of(new RestEntitlementsCheckAction());
52+
return List.of(new RestEntitlementsCheckAction(environment));
4253
}
4354
}

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/FileCheckActions.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.elasticsearch.core.CheckedRunnable;
1313
import org.elasticsearch.core.SuppressForbidden;
1414
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
15+
import org.elasticsearch.env.Environment;
1516

1617
import java.io.File;
1718
import java.io.FileDescriptor;
@@ -22,9 +23,11 @@
2223
import java.io.FileWriter;
2324
import java.io.IOException;
2425
import java.io.RandomAccessFile;
26+
import java.net.URISyntaxException;
2527
import java.net.http.HttpRequest;
2628
import java.net.http.HttpResponse;
2729
import java.nio.charset.StandardCharsets;
30+
import java.nio.file.Files;
2831
import java.nio.file.Path;
2932
import java.nio.file.Paths;
3033
import java.security.GeneralSecurityException;
@@ -41,6 +44,7 @@
4144
import static java.util.zip.ZipFile.OPEN_DELETE;
4245
import static java.util.zip.ZipFile.OPEN_READ;
4346
import static org.elasticsearch.entitlement.qa.entitled.EntitledActions.createTempFileForWrite;
47+
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_ALLOWED;
4448
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
4549
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
4650

@@ -563,5 +567,29 @@ static void httpResponseBodySubscribersOfFile_FileOpenOptions_readOnly() {
563567
HttpResponse.BodySubscribers.ofFile(readFile(), CREATE, WRITE);
564568
}
565569

570+
@EntitlementTest(expectedAccess = ALWAYS_ALLOWED)
571+
static void readAccessConfigDirectory(Environment environment) {
572+
Files.exists(environment.configDir());
573+
}
574+
575+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
576+
static void writeAccessConfigDirectory(Environment environment) throws IOException {
577+
var file = environment.configDir().resolve("to_create");
578+
Files.createFile(file);
579+
}
580+
581+
@EntitlementTest(expectedAccess = ALWAYS_ALLOWED)
582+
static void readAccessSourcePath() throws URISyntaxException {
583+
var sourcePath = Paths.get(EntitlementTestPlugin.class.getProtectionDomain().getCodeSource().getLocation().toURI());
584+
Files.exists(sourcePath);
585+
}
586+
587+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
588+
static void writeAccessSourcePath() throws IOException, URISyntaxException {
589+
var sourcePath = Paths.get(EntitlementTestPlugin.class.getProtectionDomain().getCodeSource().getLocation().toURI());
590+
var file = sourcePath.getParent().resolve("to_create");
591+
Files.createFile(file);
592+
}
593+
566594
private FileCheckActions() {}
567595
}

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
import org.elasticsearch.client.internal.node.NodeClient;
1313
import org.elasticsearch.common.Strings;
14+
import org.elasticsearch.core.CheckedConsumer;
1415
import org.elasticsearch.core.CheckedRunnable;
1516
import org.elasticsearch.core.SuppressForbidden;
17+
import org.elasticsearch.env.Environment;
1618
import org.elasticsearch.logging.LogManager;
1719
import org.elasticsearch.logging.Logger;
1820
import org.elasticsearch.rest.BaseRestHandler;
@@ -68,20 +70,24 @@
6870
public class RestEntitlementsCheckAction extends BaseRestHandler {
6971
private static final Logger logger = LogManager.getLogger(RestEntitlementsCheckAction.class);
7072

71-
record CheckAction(CheckedRunnable<Exception> action, EntitlementTest.ExpectedAccess expectedAccess, Integer fromJavaVersion) {
73+
record CheckAction(
74+
CheckedConsumer<Environment, Exception> action,
75+
EntitlementTest.ExpectedAccess expectedAccess,
76+
Integer fromJavaVersion
77+
) {
7278
/**
7379
* These cannot be granted to plugins, so our test plugins cannot test the "allowed" case.
7480
*/
7581
static CheckAction deniedToPlugins(CheckedRunnable<Exception> action) {
76-
return new CheckAction(action, SERVER_ONLY, null);
82+
return new CheckAction(env -> action.run(), SERVER_ONLY, null);
7783
}
7884

7985
static CheckAction forPlugins(CheckedRunnable<Exception> action) {
80-
return new CheckAction(action, PLUGINS, null);
86+
return new CheckAction(env -> action.run(), PLUGINS, null);
8187
}
8288

8389
static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
84-
return new CheckAction(action, ALWAYS_DENIED, null);
90+
return new CheckAction(env -> action.run(), ALWAYS_DENIED, null);
8591
}
8692
}
8793

@@ -128,7 +134,7 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
128134
entry("responseCache_setDefault", alwaysDenied(RestEntitlementsCheckAction::setDefaultResponseCache)),
129135
entry(
130136
"createInetAddressResolverProvider",
131-
new CheckAction(VersionSpecificNetworkChecks::createInetAddressResolverProvider, SERVER_ONLY, 18)
137+
new CheckAction(env -> VersionSpecificNetworkChecks.createInetAddressResolverProvider(), SERVER_ONLY, 18)
132138
),
133139
entry("createURLStreamHandlerProvider", alwaysDenied(RestEntitlementsCheckAction::createURLStreamHandlerProvider)),
134140
entry("createURLWithURLStreamHandler", alwaysDenied(RestEntitlementsCheckAction::createURLWithURLStreamHandler)),
@@ -204,6 +210,12 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
204210
.filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion())
205211
.collect(Collectors.toUnmodifiableMap(Entry::getKey, Entry::getValue));
206212

213+
private final Environment environment;
214+
215+
public RestEntitlementsCheckAction(Environment environment) {
216+
this.environment = environment;
217+
}
218+
207219
@SuppressForbidden(reason = "Need package private methods so we don't have to make them all public")
208220
private static Method[] getDeclaredMethods(Class<?> clazz) {
209221
return clazz.getDeclaredMethods();
@@ -219,13 +231,10 @@ private static Stream<Entry<String, CheckAction>> getTestEntries(Class<?> action
219231
if (Modifier.isStatic(method.getModifiers()) == false) {
220232
throw new AssertionError("Entitlement test method [" + method + "] must be static");
221233
}
222-
if (method.getParameterTypes().length != 0) {
223-
throw new AssertionError("Entitlement test method [" + method + "] must not have parameters");
224-
}
225-
226-
CheckedRunnable<Exception> runnable = () -> {
234+
final CheckedConsumer<Environment, Exception> call = createConsumerForMethod(method);
235+
CheckedConsumer<Environment, Exception> runnable = env -> {
227236
try {
228-
method.invoke(null);
237+
call.accept(env);
229238
} catch (IllegalAccessException e) {
230239
throw new AssertionError(e);
231240
} catch (InvocationTargetException e) {
@@ -242,6 +251,17 @@ private static Stream<Entry<String, CheckAction>> getTestEntries(Class<?> action
242251
return entries.stream();
243252
}
244253

254+
private static CheckedConsumer<Environment, Exception> createConsumerForMethod(Method method) {
255+
Class<?>[] parameters = method.getParameterTypes();
256+
if (parameters.length == 0) {
257+
return env -> method.invoke(null);
258+
}
259+
if (parameters.length == 1 && parameters[0].equals(Environment.class)) {
260+
return env -> method.invoke(null, env);
261+
}
262+
throw new AssertionError("Entitlement test method [" + method + "] must have no parameters or 1 parameter (Environment)");
263+
}
264+
245265
private static void createURLStreamHandlerProvider() {
246266
var x = new URLStreamHandlerProvider() {
247267
@Override
@@ -405,6 +425,14 @@ public static Set<String> getCheckActionsAllowedInPlugins() {
405425
.collect(Collectors.toSet());
406426
}
407427

428+
public static Set<String> getAlwaysAllowedCheckActions() {
429+
return checkActions.entrySet()
430+
.stream()
431+
.filter(kv -> kv.getValue().expectedAccess().equals(ALWAYS_ALLOWED))
432+
.map(Entry::getKey)
433+
.collect(Collectors.toSet());
434+
}
435+
408436
public static Set<String> getDeniableCheckActions() {
409437
return checkActions.entrySet()
410438
.stream()
@@ -437,10 +465,9 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli
437465

438466
return channel -> {
439467
logger.info("Calling check action [{}]", actionName);
440-
checkAction.action().run();
468+
checkAction.action().accept(environment);
441469
logger.debug("Check action [{}] returned", actionName);
442470
channel.sendResponse(new RestResponse(RestStatus.OK, Strings.format("Succesfully executed action [%s]", actionName)));
443471
};
444472
}
445-
446473
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.qa;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.Name;
13+
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
14+
15+
import org.elasticsearch.entitlement.qa.test.RestEntitlementsCheckAction;
16+
import org.junit.ClassRule;
17+
18+
public class EntitlementsAlwaysAllowedIT extends AbstractEntitlementsIT {
19+
20+
@ClassRule
21+
public static EntitlementsTestRule testRule = new EntitlementsTestRule(true, null);
22+
23+
public EntitlementsAlwaysAllowedIT(@Name("actionName") String actionName) {
24+
super(actionName, true);
25+
}
26+
27+
@ParametersFactory
28+
public static Iterable<Object[]> data() {
29+
return RestEntitlementsCheckAction.getAlwaysAllowedCheckActions().stream().map(action -> new Object[] { action }).toList();
30+
}
31+
32+
@Override
33+
protected String getTestRestCluster() {
34+
return testRule.cluster.getHttpAddresses();
35+
}
36+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.qa;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.Name;
13+
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
14+
15+
import org.elasticsearch.entitlement.qa.test.RestEntitlementsCheckAction;
16+
import org.junit.ClassRule;
17+
18+
public class EntitlementsAlwaysAllowedNonModularIT extends AbstractEntitlementsIT {
19+
20+
@ClassRule
21+
public static EntitlementsTestRule testRule = new EntitlementsTestRule(false, null);
22+
23+
public EntitlementsAlwaysAllowedNonModularIT(@Name("actionName") String actionName) {
24+
super(actionName, true);
25+
}
26+
27+
@ParametersFactory
28+
public static Iterable<Object[]> data() {
29+
return RestEntitlementsCheckAction.getAlwaysAllowedCheckActions().stream().map(action -> new Object[] { action }).toList();
30+
}
31+
32+
@Override
33+
protected String getTestRestCluster() {
34+
return testRule.cluster.getHttpAddresses();
35+
}
36+
}

0 commit comments

Comments
 (0)