1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.File;
26 import java.io.FileReader;
27 import java.lang.reflect.Constructor;
28 import java.util.Collections;
29
30 import org.apache.commons.jexl3.introspection.JexlPermissions;
31 import org.junit.jupiter.api.Test;
32
33 import com.google.gson.Gson;
34
35
36
37
38 class ComposePermissionsTest extends JexlTestCase {
39 static final String SAMPLE_JSON = "src/test/scripts/sample.json";
40
41
42
43
44 public ComposePermissionsTest() {
45 super("PermissionsTest");
46 }
47
48 void runComposePermissions(final JexlPermissions p) throws Exception {
49 final String check = "http://example.com/content.jpg";
50 final File jsonFile = new File(SAMPLE_JSON);
51 final Gson gson = new Gson();
52 final Object json;
53 try (final FileReader reader = new FileReader(jsonFile)) {
54 json = gson.fromJson(reader, Object.class);
55 assertNotNull(json);
56 }
57
58
59 final JexlEngine j0 = createEngine(false, p);
60 final JexlScript s0 = j0.createScript("json.pageInfo.pagePic", "json");
61 final Object r0 = s0.execute(null, json);
62 assertEquals(check, r0);
63
64
65 JexlEngine j1 = createEngine(false, p.compose("com.google.gson.internal {}"));
66 final JexlScript s1 = j1.createScript("json.pageInfo.pagePic", "json");
67 JexlException.Property xproperty = assertThrows(JexlException.Property.class, () -> s1.execute(null, json));
68 assertEquals("pageInfo", xproperty.getProperty());
69
70
71 j1 = createEngine(false, p.compose("com.google.gson.internal { LinkedTreeMap {} }"));
72 final JexlScript s2 = j1.createScript("json.pageInfo.pagePic", "json");
73 xproperty = assertThrows(JexlException.Property.class, () -> s2.execute(null, json));
74 assertEquals("pageInfo", xproperty.getProperty());
75
76
77 j1 = createEngine(false, JexlPermissions.RESTRICTED.compose("com.google.gson.internal +{}"));
78 final JexlScript s3 = j1.createScript("json.pageInfo.pagePic", "json");
79 final Object r3 = s3.execute(null, json);
80 assertEquals(check, r3);
81 }
82
83 @Test
84 void testComposePermissions() throws Exception {
85 runComposePermissions(JexlPermissions.UNRESTRICTED);
86 }
87
88 @Test
89 void testComposePreservesBaseDenials() throws Exception {
90
91
92 final Constructor<?> pbCtor = ProcessBuilder.class.getConstructor(String[].class);
93 assertFalse(JexlPermissions.RESTRICTED.allow(pbCtor));
94 assertFalse(JexlPermissions.RESTRICTED.allow(ProcessBuilder.class));
95 final JexlPermissions composed = JexlPermissions.RESTRICTED.compose("java.math +{}");
96 assertFalse(composed.allow(pbCtor));
97 assertFalse(composed.allow(ProcessBuilder.class));
98 assertFalse(composed.allow(Runtime.class));
99
100 final JexlPermissions pkgDeny = JexlPermissions.parse("java.lang.*", "java.net {}");
101 assertFalse(pkgDeny.allow(java.net.URI.class));
102 final JexlPermissions pkgDenyComposed = pkgDeny.compose("java.math +{}");
103 assertFalse(pkgDenyComposed.allow(java.net.URI.class));
104 }
105
106 @Test
107 void testComposePreservesBaseAllows() throws Exception {
108
109
110 final Constructor<?> swCtor = java.io.StringWriter.class.getConstructor();
111 assertTrue(JexlPermissions.RESTRICTED.allow(swCtor));
112 assertTrue(JexlPermissions.RESTRICTED.allow(java.io.StringWriter.class));
113 final JexlPermissions composed = JexlPermissions.RESTRICTED.compose("java.math +{}");
114 assertTrue(composed.allow(swCtor));
115 assertTrue(composed.allow(java.io.StringWriter.class));
116 }
117
118 @Test
119 void testComposePreservesPackageDenialWithException() throws Exception {
120
121
122 final JexlPermissions base = JexlPermissions.parse("java.lang.*", "java.net {}");
123
124 assertFalse(base.allow(java.net.URI.class));
125 assertFalse(base.allow(java.net.URL.class));
126
127
128 final JexlPermissions withException = base.compose("java.net { +URI {} }");
129 assertTrue(withException.allow(java.net.URI.class));
130 assertFalse(withException.allow(java.net.URL.class));
131
132
133 final JexlPermissions withException2 = withException.compose("java.math +{}");
134 assertTrue(withException2.allow(java.net.URI.class));
135 assertFalse(withException2.allow(java.net.URL.class));
136
137
138 final JexlPermissions restrictedPlus = JexlPermissions.RESTRICTED.compose("java.lang { +ProcessHandle { Info {} } }");
139 assertFalse(restrictedPlus.allow(Thread.class));
140 assertFalse(restrictedPlus.allow(Runtime.class));
141 }
142
143 @Test
144 void testComposePermissions1() throws Exception {
145 runComposePermissions(new JexlPermissions.Delegate(JexlPermissions.UNRESTRICTED) {
146 @Override
147 public String toString() {
148 return "delegate:" + base.toString();
149 }
150 });
151 }
152
153 @Test
154 void testComposePermissions2() throws Exception {
155 runComposePermissions(new JexlPermissions.ClassPermissions(JexlPermissions.UNRESTRICTED, Collections.emptySet()));
156 }
157 }