View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3.internal.introspection;
18  
19  import static org.junit.jupiter.api.Assertions.assertFalse;
20  import static org.junit.jupiter.api.Assertions.assertNotNull;
21  import static org.junit.jupiter.api.Assertions.assertTrue;
22  
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.Field;
25  import java.lang.reflect.Method;
26  
27  import org.apache.commons.jexl3.annotations.NoJexl;
28  import org.apache.commons.jexl3.introspection.JexlPermissions;
29  import org.junit.jupiter.api.Test;
30  
31  /**
32   * Checks the CacheMap.MethodKey implementation
33   */
34  
35  class NoJexlTest {
36  
37      public static class A {
38          public int i;
39          public A() {}
40          public int method() { return 0; }
41      }
42  
43      public static class A0 extends A implements InterNoJexl0 {
44          @NoJexl public int i0;
45          @NoJexl public A0() {}
46          @Override public int method() { return 1; }
47      }
48  
49      public static class A1 extends A implements InterNoJexl1 {
50          private int i1;
51          @NoJexl public A1() {}
52          @Override public int method() { return 2; }
53      }
54  
55      @NoJexl
56      public static class A2 extends A  {
57          public A2() {}
58          @Override public int method() { return 3; }
59      }
60  
61      protected static class A3 {
62          protected int i3;
63          protected A3() {}
64          int method() { return 4; }
65      }
66  
67      public static class A5 implements InterNoJexl5 {
68          public A5() {}
69          @Override public int method() { return 0; }
70      }
71  
72      @NoJexl
73      public interface InterNoJexl0 {
74          int method();
75      }
76  
77      public interface InterNoJexl1 {
78          @NoJexl
79          int method();
80      }
81  
82      @NoJexl
83      public interface InterNoJexl5 {
84          int method();
85      }
86  
87      @Test
88      void testNoJexlPermissions() throws Exception {
89          final Permissions p = Permissions.Markers.UNRESTRICTED;
90          assertFalse(p.allow((Field) null));
91          assertFalse(p.allow((Package) null));
92          assertFalse(p.allow((Method) null));
93          assertFalse(p.allow((Constructor<?>) null));
94          assertFalse(p.allow((Class<?>) null));
95  
96          assertFalse(p.allow(A2.class));
97          assertTrue(p.allow(A3.class));
98          assertTrue(p.allow(A5.class));
99  
100         final Method mA = A.class.getMethod("method");
101         assertNotNull(mA);
102         final Method mA0 = A0.class.getMethod("method");
103         assertNotNull(mA0);
104         final Method mA1 = A1.class.getMethod("method");
105         assertNotNull(mA1);
106         final Method mA2 = A2.class.getMethod("method");
107         assertNotNull(mA2);
108         final Method mA3 = A2.class.getDeclaredMethod("method");
109         assertNotNull(mA3);
110 
111         assertTrue(p.allow(mA));
112         assertFalse(p.allow(mA0));
113         assertFalse(p.allow(mA1));
114         assertFalse(p.allow(mA2));
115         assertFalse(p.allow(mA3));
116 
117         final Field fA = A.class.getField("i");
118         assertNotNull(fA);
119         assertTrue(p.allow(A.class, fA));
120 
121         final Field fA0 = A0.class.getField("i0");
122         assertNotNull(fA0);
123         assertFalse(p.allow(fA0));
124         final Field fA1 = A1.class.getDeclaredField("i1");
125         assertNotNull(fA1);
126         assertFalse(p.allow(fA0));
127 
128         final Constructor<?> cA = A.class.getConstructor();
129         assertNotNull(cA);
130         assertTrue(p.allow(cA));
131 
132         final Constructor<?> cA0 = A0.class.getConstructor();
133         assertNotNull(cA0);
134         assertFalse(p.allow(cA0));
135 
136         final Constructor<?> cA3 = A3.class.getDeclaredConstructor();
137         assertNotNull(cA3);
138         assertFalse(p.allow(cA3));
139     }
140 
141     @NoJexl
142     interface ProtectedInterface {
143         String protectedOperation();
144     }
145 
146     interface IntermediateInterface extends ProtectedInterface {
147     }
148 
149    public static class HostObject implements IntermediateInterface {
150         public String protectedOperation() {
151             return "protected";
152         }
153         public String unprotectedOperation() {
154             return "unprotected";
155         }
156     }
157 
158     @Test
159     void testNoJexlIntermediate() throws Exception {
160         final JexlPermissions p = Permissions.RESTRICTED.compose("org.apache.commons.jexl3.internal.introspection { +NoJexlTest$HostObject {} }");
161         final Method m0 = HostObject.class.getMethod("unprotectedOperation");
162         assertNotNull(m0);
163         assertTrue(p.allow(m0));
164         final Method m1 = HostObject.class.getMethod("protectedOperation");
165         assertNotNull(m1);
166         assertFalse(p.allow(m1));
167     }
168 }