Skip to content

Commit a671256

Browse files
committed
Use dynamic policy for entitled test plugin (elastic#121852)
Like the plugin being testing, the entitled test plugin needs access to dynamic elements (namely, file paths). This commit dynamically generates the entitlement policy for the entitlted test plugin when it is installed. It also adds using the file entitltlement as an example.
1 parent 77608f0 commit a671256

File tree

6 files changed

+56
-26
lines changed

6 files changed

+56
-26
lines changed

libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.nio.channels.SocketChannel;
4444
import java.nio.channels.spi.SelectorProvider;
4545
import java.nio.charset.Charset;
46+
import java.nio.file.LinkOption;
4647
import java.nio.file.OpenOption;
4748
import java.nio.file.Path;
4849
import java.nio.file.attribute.UserPrincipal;
@@ -452,6 +453,8 @@ public interface EntitlementChecker {
452453
void check$java_util_Scanner$(Class<?> callerClass, File source, Charset charset);
453454

454455
// nio
456+
void check$java_nio_file_Files$$getOwner(Class<?> callerClass, Path path, LinkOption... options);
457+
455458
void check$java_nio_file_Files$$probeContentType(Class<?> callerClass, Path path);
456459

457460
void check$java_nio_file_Files$$setOwner(Class<?> callerClass, Path path, UserPrincipal principal);

libs/entitlement/qa/entitled-plugin/src/main/plugin-metadata/entitlement-policy.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ static void createFileOutputStreamFileWithAppend() throws IOException {
8080
new FileOutputStream(readWriteFile().toFile(), false).close();
8181
}
8282

83+
@EntitlementTest(expectedAccess = PLUGINS)
84+
static void filesGetOwner() throws IOException {
85+
Files.getOwner(readFile());
86+
}
87+
8388
@EntitlementTest(expectedAccess = PLUGINS)
8489
static void filesProbeContentType() throws IOException {
8590
Files.probeContentType(readFile());

libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/AbstractEntitlementsIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import org.elasticsearch.client.Request;
1313
import org.elasticsearch.client.Response;
14+
import org.elasticsearch.entitlement.qa.EntitlementsTestRule.PolicyBuilder;
1415
import org.elasticsearch.test.rest.ESRestTestCase;
1516

1617
import java.io.IOException;
@@ -22,7 +23,7 @@
2223

2324
public abstract class AbstractEntitlementsIT extends ESRestTestCase {
2425

25-
static final EntitlementsTestRule.PolicyBuilder ALLOWED_TEST_ENTITLEMENTS = (builder, tempDir) -> {
26+
static final PolicyBuilder ALLOWED_TEST_ENTITLEMENTS = (builder, tempDir) -> {
2627
builder.value("create_class_loader");
2728
builder.value("set_https_connection_properties");
2829
builder.value("inbound_network");

libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsTestRule.java

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,27 @@
2626
import java.io.UncheckedIOException;
2727
import java.nio.file.Files;
2828
import java.nio.file.Path;
29+
import java.util.List;
30+
import java.util.Map;
2931

3032
class EntitlementsTestRule implements TestRule {
3133

34+
// entitlements that test methods may use, see EntitledActions
35+
private static final PolicyBuilder ENTITLED_POLICY = (builder, tempDir) -> {
36+
builder.value(Map.of("write_system_properties", Map.of("properties", List.of("org.elasticsearch.entitlement.qa.selfTest"))));
37+
builder.value(
38+
Map.of(
39+
"files",
40+
List.of(
41+
Map.of("path", tempDir.resolve("read_dir"), "mode", "read"),
42+
Map.of("path", tempDir.resolve("read_write_dir"), "mode", "read_write"),
43+
Map.of("path", tempDir.resolve("read_file"), "mode", "read"),
44+
Map.of("path", tempDir.resolve("read_write_file"), "mode", "read_write")
45+
)
46+
)
47+
);
48+
};
49+
3250
interface PolicyBuilder {
3351
void build(XContentBuilder builder, Path tempDir) throws IOException;
3452
}
@@ -51,7 +69,7 @@ protected void before() throws Throwable {
5169
}
5270
};
5371
cluster = ElasticsearchCluster.local()
54-
.module("entitled")
72+
.module("entitled", spec -> buildEntitlements(spec, "org.elasticsearch.entitlement.qa.entitled", ENTITLED_POLICY))
5573
.module("entitlement-test-plugin", spec -> setupEntitlements(spec, modular, policyBuilder))
5674
.systemProperty("es.entitlements.enabled", "true")
5775
.systemProperty("es.entitlements.testdir", () -> testDir.getRoot().getAbsolutePath())
@@ -65,29 +83,30 @@ public Statement apply(Statement statement, Description description) {
6583
return ruleChain.apply(statement, description);
6684
}
6785

68-
private void setupEntitlements(PluginInstallSpec spec, boolean modular, PolicyBuilder policyBuilder) {
69-
String moduleName = modular ? "org.elasticsearch.entitlement.qa.test" : "ALL-UNNAMED";
70-
if (policyBuilder != null) {
71-
spec.withEntitlementsOverride(old -> {
72-
try {
73-
try (var builder = YamlXContent.contentBuilder()) {
74-
builder.startObject();
75-
builder.field(moduleName);
76-
builder.startArray();
86+
private void buildEntitlements(PluginInstallSpec spec, String moduleName, PolicyBuilder policyBuilder) {
87+
spec.withEntitlementsOverride(old -> {
88+
try (var builder = YamlXContent.contentBuilder()) {
89+
builder.startObject();
90+
builder.field(moduleName);
91+
builder.startArray();
7792

78-
policyBuilder.build(builder, testDir.getRoot().toPath());
79-
builder.endArray();
80-
builder.endObject();
93+
policyBuilder.build(builder, testDir.getRoot().toPath());
94+
builder.endArray();
95+
builder.endObject();
8196

82-
String policy = Strings.toString(builder);
83-
System.out.println("Using entitlement policy:\n" + policy);
84-
return Resource.fromString(policy);
85-
}
97+
String policy = Strings.toString(builder);
98+
System.out.println("Using entitlement policy for module " + moduleName + ":\n" + policy);
99+
return Resource.fromString(policy);
100+
} catch (IOException e) {
101+
throw new UncheckedIOException(e);
102+
}
103+
});
104+
}
86105

87-
} catch (IOException e) {
88-
throw new UncheckedIOException(e);
89-
}
90-
});
106+
private void setupEntitlements(PluginInstallSpec spec, boolean modular, PolicyBuilder policyBuilder) {
107+
String moduleName = modular ? "org.elasticsearch.entitlement.qa.test" : "ALL-UNNAMED";
108+
if (policyBuilder != null) {
109+
buildEntitlements(spec, moduleName, policyBuilder);
91110
}
92111

93112
if (modular == false) {

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import java.nio.channels.SocketChannel;
4949
import java.nio.channels.spi.SelectorProvider;
5050
import java.nio.charset.Charset;
51+
import java.nio.file.LinkOption;
5152
import java.nio.file.OpenOption;
5253
import java.nio.file.Path;
5354
import java.nio.file.attribute.UserPrincipal;
@@ -889,6 +890,11 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
889890

890891
// nio
891892

893+
@Override
894+
public void check$java_nio_file_Files$$getOwner(Class<?> callerClass, Path path, LinkOption... options) {
895+
policyManager.checkFileRead(callerClass, path);
896+
}
897+
892898
@Override
893899
public void check$java_nio_file_Files$$probeContentType(Class<?> callerClass, Path path) {
894900
policyManager.checkFileRead(callerClass, path);

0 commit comments

Comments
 (0)