1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.taglibs.authz;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.Authentication;
21  import org.acegisecurity.GrantedAuthority;
22  import org.acegisecurity.MockAclManager;
23  import org.acegisecurity.MockApplicationContext;
24  
25  import org.acegisecurity.acl.AclEntry;
26  import org.acegisecurity.acl.AclManager;
27  import org.acegisecurity.acl.basic.MockAclObjectIdentity;
28  import org.acegisecurity.acl.basic.SimpleAclEntry;
29  
30  import org.acegisecurity.context.SecurityContextHolder;
31  
32  import org.acegisecurity.providers.TestingAuthenticationToken;
33  
34  import org.springframework.context.ApplicationContext;
35  import org.springframework.context.ConfigurableApplicationContext;
36  
37  import javax.servlet.jsp.JspException;
38  import javax.servlet.jsp.PageContext;
39  import javax.servlet.jsp.tagext.Tag;
40  
41  
42  /**
43   * Tests {@link AclTag}.
44   *
45   * @author Ben Alex
46   * @version $Id: AclTagTests.java 1496 2006-05-23 13:38:33Z benalex $
47   */
48  public class AclTagTests extends TestCase {
49      //~ Instance fields ================================================================================================
50  
51      private final MyAclTag aclTag = new MyAclTag();
52  
53      //~ Methods ========================================================================================================
54  
55      public void testInclusionDeniedWhenAclManagerUnawareOfObject()
56          throws JspException {
57          Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {});
58          SecurityContextHolder.getContext().setAuthentication(auth);
59  
60          aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString());
61          aclTag.setDomainObject(new Integer(54));
62          assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
63  
64          SecurityContextHolder.getContext().setAuthentication(null);
65      }
66  
67      public void testInclusionDeniedWhenNoListOfPermissionsGiven()
68          throws JspException {
69          Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {});
70          SecurityContextHolder.getContext().setAuthentication(auth);
71  
72          aclTag.setHasPermission(null);
73          aclTag.setDomainObject("object1");
74          assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
75  
76          SecurityContextHolder.getContext().setAuthentication(null);
77      }
78  
79      public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions()
80          throws JspException {
81          Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {});
82          SecurityContextHolder.getContext().setAuthentication(auth);
83  
84          aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
85          assertEquals(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ),
86              aclTag.getHasPermission());
87          aclTag.setDomainObject("object1");
88          assertEquals("object1", aclTag.getDomainObject());
89          assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
90  
91          SecurityContextHolder.getContext().setAuthentication(null);
92      }
93  
94      public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions()
95          throws JspException {
96          Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {});
97          SecurityContextHolder.getContext().setAuthentication(auth);
98  
99          aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString());
100         aclTag.setDomainObject("object1");
101         assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
102 
103         SecurityContextHolder.getContext().setAuthentication(null);
104     }
105 
106     public void testInclusionDeniedWhenSecurityContextEmpty()
107         throws JspException {
108         SecurityContextHolder.getContext().setAuthentication(null);
109 
110         aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString());
111         aclTag.setDomainObject("object1");
112         assertEquals(Tag.SKIP_BODY, aclTag.doStartTag());
113 
114         SecurityContextHolder.getContext().setAuthentication(null);
115     }
116 
117     public void testInclusionPermittedWhenDomainObjectIsNull()
118         throws JspException {
119         aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString());
120         aclTag.setDomainObject(null);
121         assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
122     }
123 
124     public void testJspExceptionThrownIfHasPermissionNotValidFormat()
125         throws JspException {
126         Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {});
127         SecurityContextHolder.getContext().setAuthentication(auth);
128 
129         aclTag.setHasPermission("0,5, 6"); // shouldn't be any space
130 
131         try {
132             aclTag.doStartTag();
133             fail("Should have thrown JspException");
134         } catch (JspException expected) {
135             assertTrue(true);
136         }
137 
138         SecurityContextHolder.getContext().setAuthentication(null);
139     }
140 
141     public void testOperationWhenPrincipalHoldsPermissionOfMultipleList()
142         throws JspException {
143         Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {});
144         SecurityContextHolder.getContext().setAuthentication(auth);
145 
146         aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
147         aclTag.setDomainObject("object1");
148         assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
149 
150         SecurityContextHolder.getContext().setAuthentication(null);
151     }
152 
153     public void testOperationWhenPrincipalHoldsPermissionOfSingleList()
154         throws JspException {
155         Authentication auth = new TestingAuthenticationToken("marissa", "koala", new GrantedAuthority[] {});
156         SecurityContextHolder.getContext().setAuthentication(auth);
157 
158         aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString());
159         aclTag.setDomainObject("object1");
160         assertEquals(Tag.EVAL_BODY_INCLUDE, aclTag.doStartTag());
161 
162         SecurityContextHolder.getContext().setAuthentication(null);
163     }
164 
165     //~ Inner Classes ==================================================================================================
166 
167     private class MockAclEntry implements AclEntry {
168         // just so AclTag iterates some different types of AclEntrys
169     }
170 
171     private class MyAclTag extends AclTag {
172         protected ApplicationContext getContext(PageContext pageContext) {
173             ConfigurableApplicationContext context = MockApplicationContext.getContext();
174 
175             // Create an AclManager
176             AclManager aclManager = new MockAclManager("object1", "marissa",
177                     new AclEntry[] {
178                         new MockAclEntry(),
179                         new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.ADMINISTRATION),
180                         new SimpleAclEntry("marissa", new MockAclObjectIdentity(), null, SimpleAclEntry.READ)
181                     });
182 
183             // Register the AclManager into our ApplicationContext
184             context.getBeanFactory().registerSingleton("aclManager", aclManager);
185 
186             return context;
187         }
188     }
189 }