KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > groovy > security > SecurityTestSupport


1 package groovy.security;
2
3 import groovy.lang.Binding;
4 import groovy.lang.GroovyClassLoader;
5 import groovy.lang.GroovyCodeSource;
6 import groovy.lang.Script;
7 import groovy.util.GroovyTestCase;
8
9 import java.io.File JavaDoc;
10 import java.io.FileNotFoundException JavaDoc;
11 import java.io.PrintStream JavaDoc;
12 import java.security.AccessControlException JavaDoc;
13 import java.security.AccessController JavaDoc;
14 import java.security.Permission JavaDoc;
15 import java.security.Policy JavaDoc;
16 import java.security.PrivilegedAction JavaDoc;
17 import java.util.Enumeration JavaDoc;
18
19 import junit.framework.TestCase;
20 import junit.framework.TestFailure;
21 import junit.framework.TestResult;
22 import junit.framework.TestSuite;
23 import junit.textui.ResultPrinter;
24
25 import org.codehaus.groovy.runtime.InvokerHelper;
26
27 /**
28  * @author Steve Goetze
29  */

30 public class SecurityTestSupport extends GroovyTestCase {
31
32     private static int counter = 0;
33     private static boolean securityDisabled;
34     private static boolean securityAvailable;
35     private static boolean securityChecked = false;
36
37     static {
38         if (System.getProperty("groovy.security.disabled") != null) {
39             securityAvailable = false;
40             securityDisabled = true;
41         } else {
42             securityDisabled = false;
43             String JavaDoc groovyLibDir = System.getProperty("groovy.lib");
44             if (groovyLibDir == null) {
45                 //Try to find maven repository in the default user.home location
46
groovyLibDir = System.getProperty("user.home") + "/" + ".maven/repository";
47             }
48             if (groovyLibDir == null) {
49                 //Try at user.dir/lib
50
groovyLibDir = "lib";
51             }
52             if (new File JavaDoc(groovyLibDir).exists()) {
53                 securityAvailable = true;
54                 System.setProperty("groovy.lib", groovyLibDir);
55                 System.setProperty("java.security.policy", "=security/groovy.policy");
56             } else {
57                 securityAvailable = false;
58             }
59         }
60     }
61
62     public static boolean isSecurityAvailable() {
63         return securityAvailable;
64     }
65
66     public static boolean isSecurityDisabled() {
67         return securityDisabled;
68     }
69
70     public static void resetSecurityPolicy(String JavaDoc policyFileURL) {
71         System.setProperty("java.security.policy", policyFileURL);
72         Policy.getPolicy().refresh();
73     }
74     
75     protected class SecurityTestResultPrinter extends ResultPrinter {
76         
77         public SecurityTestResultPrinter(PrintStream JavaDoc stream) {
78             super(stream);
79         }
80         public void print(TestResult result) {
81             getWriter().println("Security testing on a groovy test failed:");
82             printErrors(result);
83             printFailures(result);
84             printFooter(result);
85         }
86     };
87
88     protected GroovyClassLoader loader = (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
89         public Object JavaDoc run() {
90             return new GroovyClassLoader(SecurityTestSupport.class.getClassLoader());
91         }
92     });
93     
94     private SecurityManager JavaDoc securityManager;
95     private ClassLoader JavaDoc currentClassLoader;
96
97     public SecurityTestSupport() {
98     }
99     
100     /*
101      * Check SecuritySupport to see if security is properly configured. If not, fail the first
102      * test that runs. All remaining tests will run, but not do any security checking.
103      */

104     private boolean checkSecurity() {
105         if (!securityChecked) {
106             securityChecked = true;
107             if (!isSecurityAvailable()) {
108                 fail("Security is not available - skipping security tests. Ensure that groovy.lib is set and points to the groovy dependency jars.");
109             }
110         }
111         return isSecurityAvailable();
112     }
113
114     //Prepare for each security test. First, check to see if groovy.lib can be determined via
115
//a call to checkSecurity(). If not, fail() the first test. Establish a security manager
116
//and make the GroovyClassLoader the initiating class loader (ala GroovyShell) to compile AND
117
//invoke the test scripts. This handles cases where multiple .groovy scripts are involved in a
118
//test case: a.groovy depends on b.groovy; a.groovy is parsed (and in the process the gcl
119
//loads b.groovy via findClass). Note that b.groovy is only available in the groovy class loader.
120
//See
121
protected void setUp() {
122         if (checkSecurity()) {
123             securityManager = System.getSecurityManager();
124             if (securityManager == null) {
125                 System.setSecurityManager(new SecurityManager JavaDoc());
126             }
127         }
128         currentClassLoader = Thread.currentThread().getContextClassLoader();
129         AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
130             public Object JavaDoc run() {
131                 Thread.currentThread().setContextClassLoader(loader);
132                 return null;
133             }
134         });
135     }
136
137     protected void tearDown() {
138         AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
139             public Object JavaDoc run() {
140                 System.setSecurityManager(securityManager);
141                 Thread.currentThread().setContextClassLoader(currentClassLoader);
142                 return null;
143             }
144         });
145     }
146
147     protected synchronized String JavaDoc generateClassName() {
148         return "testSecurity" + (++counter);
149     }
150
151     /*
152      * Execute the groovy script contained in file. If missingPermission
153      * is non-null, then this invocation expects an AccessControlException with missingPermission
154      * as the reason. If missingPermission is null, the script is expected to execute successfully.
155      */

156     protected Class JavaDoc parseClass(File JavaDoc file) {
157         GroovyCodeSource gcs = null;
158         try {
159             gcs = new GroovyCodeSource(file);
160         } catch (FileNotFoundException JavaDoc fnfe) {
161             fail(fnfe.toString());
162         }
163         return parseClass(gcs);
164     }
165
166     /*
167      * Parse the Groovy code contained in the GroovyCodeSource as a privileged operation (i.e. do not
168      * require the code source to have specific compile time permissions) and return the resulting class.
169      */

170     protected Class JavaDoc parseClass(final GroovyCodeSource gcs) {
171         Class JavaDoc clazz = null;
172         try {
173             clazz = loader.parseClass(gcs);
174         } catch (Exception JavaDoc e) {
175             fail(e.toString());
176         }
177         return clazz;
178     }
179     
180     /*
181      * Parse the script contained in the GroovyCodeSource as a privileged operation (i.e. do not
182      * require the code source to have specific compile time permissions). If the class produced is a
183      * TestCase, run the test in a suite and evaluate against the missingPermission.
184      * Otherwise, run the class as a groovy script and evaluate against the missingPermission.
185      */

186     private void parseAndExecute(final GroovyCodeSource gcs, Permission JavaDoc missingPermission) {
187         Class JavaDoc clazz = null;
188         try {
189             clazz = loader.parseClass(gcs);
190         } catch (Exception JavaDoc e) {
191             fail(e.toString());
192         }
193         if (TestCase.class.isAssignableFrom(clazz)) {
194             executeTest(clazz, missingPermission);
195         } else {
196             executeScript(clazz, missingPermission);
197         }
198     }
199
200     protected void executeTest(Class JavaDoc test, Permission JavaDoc missingPermission) {
201         TestSuite suite = new TestSuite();
202         suite.addTestSuite(test);
203         TestResult result = new TestResult();
204         suite.run(result);
205         if (result.wasSuccessful()) {
206             if (missingPermission == null) {
207                 return;
208             } else {
209                 fail("Security test expected an AccessControlException on " + missingPermission + ", but did not receive one");
210             }
211         } else {
212             if (missingPermission == null) {
213                 new SecurityTestResultPrinter(System.out).print(result);
214                 fail("Security test was expected to run successfully, but failed (results on System.out)");
215             } else {
216                 //There may be more than 1 failure: iterate to ensure that they all match the missingPermission.
217
boolean otherFailure = false;
218                 for (Enumeration JavaDoc e = result.errors(); e.hasMoreElements(); ) {
219                     TestFailure failure = (TestFailure) e.nextElement();
220                     if (failure.thrownException() instanceof AccessControlException JavaDoc) {
221                         AccessControlException JavaDoc ace = (AccessControlException JavaDoc) failure.thrownException();
222                         if (missingPermission.implies(ace.getPermission())) {
223                             continue;
224                         }
225                     }
226                     otherFailure = true;
227                 }
228                 if (otherFailure) {
229                     new SecurityTestResultPrinter(System.out).print(result);
230                     fail("Security test expected an AccessControlException on " + missingPermission + ", but failed for other reasons (results on System.out)");
231                 }
232             }
233         }
234     }
235
236     protected void executeScript(Class JavaDoc scriptClass, Permission JavaDoc missingPermission) {
237         try {
238             Script script = InvokerHelper.createScript(scriptClass, new Binding());
239             script.run();
240             //InvokerHelper.runScript(scriptClass, null);
241
} catch (AccessControlException JavaDoc ace) {
242             if (missingPermission != null && missingPermission.implies(ace.getPermission())) {
243                 return;
244             } else {
245                 fail(ace.toString());
246             }
247         }
248         if (missingPermission != null) {
249             fail("Should catch an AccessControlException");
250         }
251     }
252     
253     /*
254      * Execute the groovy script contained in file. If missingPermission
255      * is non-null, then this invocation expects an AccessControlException with missingPermission
256      * as the reason. If missingPermission is null, the script is expected to execute successfully.
257      */

258     protected void assertExecute(File JavaDoc file, Permission JavaDoc missingPermission) {
259         if (!isSecurityAvailable()) {
260             return;
261         }
262         GroovyCodeSource gcs = null;
263         try {
264             gcs = new GroovyCodeSource(file);
265         } catch (FileNotFoundException JavaDoc fnfe) {
266             fail(fnfe.toString());
267         }
268         parseAndExecute(gcs, missingPermission);
269     }
270     
271     /*
272      * Execute the script represented by scriptStr using the supplied codebase. If missingPermission
273      * is non-null, then this invocation expects an AccessControlException with missingPermission
274      * as the reason. If missingPermission is null, the script is expected to execute successfully.
275      */

276     protected void assertExecute(String JavaDoc scriptStr, String JavaDoc codeBase, Permission JavaDoc missingPermission) {
277         if (!isSecurityAvailable()) {
278             return;
279         }
280         if (codeBase == null) {
281             codeBase = "/groovy/security/test";
282         }
283         parseAndExecute(new GroovyCodeSource(scriptStr, generateClassName(), codeBase), missingPermission);
284     }
285 }
286
Popular Tags