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    *     http://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.jetspeed.security;
18  
19  import java.security.AccessControlException;
20  import java.security.AccessController;
21  import java.security.Policy;
22  import java.security.PrivilegedAction;
23  
24  import javax.security.auth.login.LoginContext;
25  import javax.security.auth.login.LoginException;
26  
27  import junit.framework.Test;
28  import junit.framework.TestSuite;
29  
30  import org.apache.jetspeed.security.impl.PassiveCallbackHandler;
31  import org.apache.jetspeed.security.impl.UserPrincipalImpl;
32  import org.apache.jetspeed.security.util.test.AbstractSecurityTestcase;
33  
34  /***
35   * @author <a href="mailto:dlestrat@apache.org">David Le Strat</a>
36   */
37  public class TestRdbmsPolicy extends AbstractSecurityTestcase
38  {
39      /***
40       * <p>
41       * The JAAS login context.
42       * </p>
43       */
44      private LoginContext loginContext = null;
45  
46      /***
47       * @see junit.framework.TestCase#setUp()
48       */
49      public void setUp() throws Exception
50      {
51          super.setUp();
52          initUser();
53  
54          // Let's login in.
55          try
56          {
57              System.out.println("\t\t[TestRdbmsPolicy] Creating login context.");
58              PassiveCallbackHandler pch = new PassiveCallbackHandler("anon", "password");
59              loginContext = new LoginContext("Jetspeed", pch);
60              loginContext.login();
61          }
62          catch (LoginException le)
63          {
64              le.printStackTrace();
65              assertTrue("\t\t[TestRdbmsPolicy] Failed to setup test.", false);
66          }
67  
68      }
69  
70      /***
71       * @see junit.framework.TestCase#tearDown()
72       */
73      public void tearDown() throws Exception
74      {
75  
76          // Logout.
77          try
78          {
79              loginContext.logout();
80          }
81          catch (LoginException le)
82          {
83              le.printStackTrace();
84              assertTrue("\t\t[TestRdbmsPolicy] Failed to tear down test.", false);
85          }
86          destroyUser();
87          super.tearDown();
88      }
89  
90      public static Test suite()
91      {
92          // All methods starting with "test" will be executed in the test suite.
93          return new TestSuite(TestRdbmsPolicy.class);
94      }
95  
96      /***
97       * <p>
98       * Executing this test requires adding an entry to java.policy.
99       * </p>
100      * <p>
101      * A possible entry would be to grant for all principals:
102      * </p>
103      * 
104      * <pre><code>
105      *  grant
106      *  {
107      *      permission org.apache.jetspeed.security.auth.PortletPermission &quot;myportlet&quot;, &quot;view&quot;;
108      *  }
109      * </code></pre>
110      * 
111      * <p>
112      * Such an entry would also test the Rdbms defaulting behavior if no entry is provided in the
113      * database for the tested Subject InternalUserPrincipal.
114      * </p>
115      */
116     /*public void testPermissionWithSubjectInContructor()
117     {
118         // InternalPermission should be granted.
119         PortletPermission perm1 = new PortletPermission("myportlet", "view", loginContext.getSubject());
120         try
121         {
122             AccessController.checkPermission(perm1);
123         }
124         catch (AccessControlException ace)
125         {
126             assertTrue("did not authorize view permission on the portlet.", false);
127         }
128 
129         // InternalPermission should be denied.
130         PortletPermission perm2 = new PortletPermission("myportlet", "edit", loginContext.getSubject());
131         try
132         {
133             AccessController.checkPermission(perm2);
134             assertTrue("did not deny edit permission on the portlet.", false);
135         }
136         catch (AccessControlException ace)
137         {
138         }
139 
140         // Subject is omitted. InternalPermission should be denied.
141         PortletPermission perm3 = new PortletPermission("myportlet", "view");
142         try
143         {
144             AccessController.checkPermission(perm3);
145             // assertTrue("did not deny permission with no subject passed.", false);
146         }
147         catch (AccessControlException ace)
148         {
149         }
150     }*/
151     
152     /***
153      * <p>
154      * Test the policy with the default spring setting where the default underlying policy is not
155      * applied.
156      * </p>
157      */
158     public void testPermissionWithSubjectInAccessControlContext()
159     {
160         
161         // InternalPermission should be granted.
162         try
163         {
164             JSSubject.doAsPrivileged(loginContext.getSubject(), new PrivilegedAction()
165             {
166                 public Object run()
167                 {
168                     PortletPermission perm1 = new PortletPermission("myportlet", "view");
169                     System.out.println("\t\t[TestRdbmsPolicy] Check access control for permission: [myportlet, view]");
170                     System.out.println("\t\t                  with policy: " + Policy.getPolicy().getClass().getName());
171                     AccessController.checkPermission(perm1);
172                     return null;
173                 }
174             }, null);
175         }
176         catch (AccessControlException ace)
177         {
178             assertTrue("did not authorize view permission on the portlet.", false);
179         }
180 
181         // Should be denied.
182         try
183         {
184             JSSubject.doAsPrivileged(loginContext.getSubject(), new PrivilegedAction()
185             {
186                 public Object run()
187                 {
188                     PortletPermission perm2 = new PortletPermission("myportlet", "secure");
189                     System.out.println("\t\t[TestRdbmsPolicy] Check access control for permission: [myportlet, secure]");
190                     System.out.println("\t\t                  with policy: " + Policy.getPolicy().getClass().getName());
191                     AccessController.checkPermission(perm2);
192                     return null;
193                 }
194             }, null);
195             assertTrue("did not deny secure permission on the portlet.", false);
196         }
197         catch (AccessControlException ace)
198         {
199         }
200     }
201     
202     /***
203      * <p>
204      * Test the policy with the default policy being evaluated as well.
205      * </p>
206      */
207     public void testPermissionWithSubjectInAccessControlContextAndDefaultPolicy()
208     {
209         System.out.println("\n\n\t\t[TestRdbmsPolicy] Test with default Policy enabled.");
210         AuthorizationProvider atzProvider = (AuthorizationProvider) ctx.getBean("org.apache.jetspeed.security.AuthorizationProvider");
211         atzProvider.useDefaultPolicy(true);
212         testPermissionWithSubjectInAccessControlContext();
213     }
214 
215     /***
216      * <p>
217      * Initialize user test object.
218      * </p>
219      */
220     protected void initUser()
221     {
222         try
223         {
224             ums.addUser("anon", "password");
225         }
226         catch (SecurityException sex)
227         {
228         }
229         UserPrincipal user = new UserPrincipalImpl("anon");
230         PortletPermission perm1 = new PortletPermission("myportlet", "view");
231         PortletPermission perm2 = new PortletPermission("myportlet", "view, edit");
232         try
233         {
234             pms.addPermission(perm1);
235             pms.addPermission(perm2);
236 
237             pms.grantPermission(user, perm1);
238             pms.grantPermission(user, perm2);
239         }
240         catch (SecurityException sex)
241         {
242             sex.printStackTrace();
243         }
244     }
245 
246     /***
247      * <p>
248      * Destroy user test object.
249      * </p>
250      */
251     protected void destroyUser() throws Exception
252     {
253         ums.removeUser("anon");
254         // Remove permissions.
255         PortletPermission perm1 = new PortletPermission("myportlet", "view");
256         PortletPermission perm2 = new PortletPermission("myportlet", "view, edit");
257         pms.removePermission(perm1);
258         pms.removePermission(perm2);
259     }
260 
261 }