1   /* Copyright 2004, 2005 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.acl.basic.jdbc;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.PopulatedDatabase;
21  import org.acegisecurity.acl.basic.AclObjectIdentity;
22  import org.acegisecurity.acl.basic.BasicAclEntry;
23  import org.acegisecurity.acl.basic.NamedEntityObjectIdentity;
24  import org.acegisecurity.acl.basic.SimpleAclEntry;
25  
26  import org.springframework.dao.DataIntegrityViolationException;
27  import org.springframework.dao.DataRetrievalFailureException;
28  
29  import org.springframework.jdbc.object.MappingSqlQuery;
30  
31  import java.sql.ResultSet;
32  import java.sql.SQLException;
33  
34  
35  /***
36   * Tests {@link JdbcExtendedDaoImpl}.
37   *
38   * @author Ben Alex
39   * @version $Id: JdbcExtendedDaoImplTests.java,v 1.3 2005/11/17 00:56:48 benalex Exp $
40   */
41  public class JdbcExtendedDaoImplTests extends TestCase {
42      //~ Static fields/initializers =============================================
43  
44      public static final String OBJECT_IDENTITY = "org.acegisecurity.acl.DomainObject";
45  
46      //~ Constructors ===========================================================
47  
48      public JdbcExtendedDaoImplTests() {
49          super();
50      }
51  
52      public JdbcExtendedDaoImplTests(String arg0) {
53          super(arg0);
54      }
55  
56      //~ Methods ================================================================
57  
58      public final void setUp() throws Exception {
59          super.setUp();
60      }
61  
62      public static void main(String[] args) {
63          junit.textui.TestRunner.run(JdbcExtendedDaoImplTests.class);
64      }
65  
66      public void testChangeMask() throws Exception {
67          JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
68          AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
69                  "204");
70          AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
71                  "1");
72  
73          // Create a BasicAclEntry for this AclObjectIdentity
74          SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity,
75                  parentIdentity, SimpleAclEntry.CREATE);
76          dao.create(simpleAcl1);
77  
78          // Create another BasicAclEntry for this AclObjectIdentity
79          SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity,
80                  parentIdentity, SimpleAclEntry.READ);
81          dao.create(simpleAcl2);
82  
83          // Check creation was successful
84          BasicAclEntry[] acls = dao.getAcls(identity);
85          assertEquals(2, acls.length);
86          assertEquals(SimpleAclEntry.CREATE, acls[0].getMask());
87          assertEquals(SimpleAclEntry.READ, acls[1].getMask());
88  
89          // Attempt to change mask
90          dao.changeMask(identity, "marissa",
91              new Integer(SimpleAclEntry.ADMINISTRATION));
92          dao.changeMask(identity, "scott", new Integer(SimpleAclEntry.NOTHING));
93          acls = dao.getAcls(identity);
94          assertEquals(2, acls.length);
95          assertEquals("marissa", acls[0].getRecipient());
96          assertEquals(SimpleAclEntry.ADMINISTRATION, acls[0].getMask());
97          assertEquals("scott", acls[1].getRecipient());
98          assertEquals(SimpleAclEntry.NOTHING, acls[1].getMask());
99      }
100 
101     public void testChangeMaskThrowsExceptionWhenExistingRecordNotFound()
102         throws Exception {
103         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
104         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
105                 "205");
106         AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
107                 "1");
108 
109         // Create at least one record for this AclObjectIdentity
110         SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity,
111                 parentIdentity, SimpleAclEntry.CREATE);
112         dao.create(simpleAcl1);
113 
114         // Attempt to change mask, but for a recipient we don't have
115         try {
116             dao.changeMask(identity, "scott",
117                 new Integer(SimpleAclEntry.ADMINISTRATION));
118             fail("Should have thrown DataRetrievalFailureException");
119         } catch (DataRetrievalFailureException expected) {
120             assertTrue(true);
121         }
122     }
123 
124     public void testConvertAclObjectIdentity() throws Exception {
125         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
126 
127         try {
128             dao.convertAclObjectIdentityToString(new AclObjectIdentity() {
129                     // not a NamedEntityObjectIdentity
130                 });
131             fail("Should have thrown IllegalArgumentException");
132         } catch (IllegalArgumentException expected) {
133             assertTrue(true);
134         }
135     }
136 
137     public void testCreationOfIdentityThenAclInSeparateInvocations()
138         throws Exception {
139         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
140         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
141                 "206");
142         AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
143                 "1");
144 
145         // Create just the object identity (NB: recipient and mask is null)
146         SimpleAclEntry simpleAcl1 = new SimpleAclEntry();
147         simpleAcl1.setAclObjectIdentity(identity);
148         simpleAcl1.setAclObjectParentIdentity(parentIdentity);
149         dao.create(simpleAcl1);
150 
151         // Delete it
152         dao.delete(identity);
153     }
154 
155     public void testDeletionOfAllRecipients() throws Exception {
156         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
157         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
158                 "203");
159 
160         // Create a BasicAclEntry for this AclObjectIdentity
161         SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity,
162                 null, SimpleAclEntry.CREATE);
163         dao.create(simpleAcl1);
164 
165         // Create another BasicAclEntry for this AclObjectIdentity
166         SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity, null,
167                 SimpleAclEntry.READ);
168         dao.create(simpleAcl2);
169 
170         // Check creation was successful
171         BasicAclEntry[] acls = dao.getAcls(identity);
172         assertEquals(2, acls.length);
173 
174         // Attempt deletion and check delete successful
175         dao.delete(identity);
176         assertNull(dao.getAcls(identity));
177     }
178 
179     public void testDeletionOfSpecificRecipient() throws Exception {
180         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
181         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
182                 "202");
183         AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
184                 "1");
185 
186         // Create a BasicAclEntry for this AclObjectIdentity
187         SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity,
188                 parentIdentity, SimpleAclEntry.CREATE);
189         dao.create(simpleAcl1);
190 
191         // Create another BasicAclEntry for this AclObjectIdentity
192         SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity,
193                 parentIdentity, SimpleAclEntry.READ);
194         dao.create(simpleAcl2);
195 
196         // Check creation was successful
197         BasicAclEntry[] acls = dao.getAcls(identity);
198         assertEquals(2, acls.length);
199 
200         // Attempt deletion and check delete successful
201         dao.delete(identity, "scott");
202         acls = dao.getAcls(identity);
203         assertEquals(1, acls.length);
204         assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient());
205     }
206 
207     public void testGettersSetters() throws Exception {
208         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
209 
210         assertNotNull(dao.getAclObjectIdentityDelete());
211         dao.setAclObjectIdentityDelete(null);
212         assertNull(dao.getAclObjectIdentityDelete());
213 
214         assertNotNull(dao.getAclObjectIdentityInsert());
215         dao.setAclObjectIdentityInsert(null);
216         assertNull(dao.getAclObjectIdentityInsert());
217 
218         assertNotNull(dao.getAclPermissionDelete());
219         dao.setAclPermissionDelete(null);
220         assertNull(dao.getAclPermissionDelete());
221 
222         assertNotNull(dao.getAclPermissionInsert());
223         dao.setAclPermissionInsert(null);
224         assertNull(dao.getAclPermissionInsert());
225 
226         assertNotNull(dao.getAclPermissionUpdate());
227         dao.setAclPermissionUpdate(null);
228         assertNull(dao.getAclPermissionUpdate());
229 
230         assertNotNull(dao.getAclsByObjectIdentity());
231         dao.setAclsByObjectIdentity(null);
232         assertNull(dao.getAclsByObjectIdentity());
233 
234         assertNotNull(dao.getLookupPermissionIdMapping());
235         dao.setLookupPermissionIdMapping(null);
236         assertNull(dao.getLookupPermissionIdMapping());
237 
238         assertNotNull(dao.getAclObjectIdentityDeleteStatement());
239         dao.setAclObjectIdentityDeleteStatement("SELECT ...");
240         assertEquals("SELECT ...", dao.getAclObjectIdentityDeleteStatement());
241 
242         assertNotNull(dao.getAclObjectIdentityInsertStatement());
243         dao.setAclObjectIdentityInsertStatement("SELECT ...");
244         assertEquals("SELECT ...", dao.getAclObjectIdentityInsertStatement());
245 
246         assertNotNull(dao.getAclPermissionDeleteStatement());
247         dao.setAclPermissionDeleteStatement("SELECT ...");
248         assertEquals("SELECT ...", dao.getAclPermissionDeleteStatement());
249 
250         assertNotNull(dao.getAclPermissionInsertStatement());
251         dao.setAclPermissionInsertStatement("SELECT ...");
252         assertEquals("SELECT ...", dao.getAclPermissionInsertStatement());
253 
254         assertNotNull(dao.getAclPermissionUpdateStatement());
255         dao.setAclPermissionUpdateStatement("SELECT ...");
256         assertEquals("SELECT ...", dao.getAclPermissionUpdateStatement());
257 
258         assertNotNull(dao.getAclsByObjectIdentityQuery());
259         dao.setAclsByObjectIdentityQuery("SELECT ...");
260         assertEquals("SELECT ...", dao.getAclsByObjectIdentityQuery());
261 
262         assertNotNull(dao.getLookupPermissionIdQuery());
263         dao.setLookupPermissionIdQuery("SELECT ...");
264         assertEquals("SELECT ...", dao.getLookupPermissionIdQuery());
265     }
266 
267     public void testNormalCreationAndDuplicateDetection()
268         throws Exception {
269         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
270         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
271                 "200");
272         AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
273                 "1");
274 
275         // Create a BasicAclEntry for this AclObjectIdentity
276         SimpleAclEntry simpleAcl1 = new SimpleAclEntry("marissa", identity,
277                 parentIdentity, SimpleAclEntry.CREATE);
278         dao.create(simpleAcl1);
279 
280         // Create another BasicAclEntry for this AclObjectIdentity
281         SimpleAclEntry simpleAcl2 = new SimpleAclEntry("scott", identity,
282                 parentIdentity, SimpleAclEntry.READ);
283         dao.create(simpleAcl2);
284 
285         // Check creation was successful
286         BasicAclEntry[] acls = dao.getAcls(identity);
287         assertEquals(2, acls.length);
288         assertEquals(simpleAcl1.getRecipient(), acls[0].getRecipient());
289         assertEquals(simpleAcl1.getMask(), acls[0].getMask());
290         assertEquals(simpleAcl2.getRecipient(), acls[1].getRecipient());
291         assertEquals(simpleAcl2.getMask(), acls[1].getMask());
292 
293         // Check it rejects an attempt to create another identical entry
294         try {
295             dao.create(simpleAcl1);
296             fail("Should have thrown DataIntegrityViolationException");
297         } catch (DataIntegrityViolationException expected) {
298             assertTrue(true);
299         }
300     }
301 
302     public void testRejectsInvalidParent() throws Exception {
303         JdbcExtendedDaoImpl dao = makePopulatedJdbcDao();
304         AclObjectIdentity identity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
305                 "201");
306         AclObjectIdentity parentIdentity = new NamedEntityObjectIdentity(OBJECT_IDENTITY,
307                 "987987987987986");
308         SimpleAclEntry simpleAcl = new SimpleAclEntry("marissa", identity,
309                 parentIdentity, SimpleAclEntry.CREATE);
310 
311         try {
312             dao.create(simpleAcl);
313             fail("Should have thrown DataRetrievalFailureException");
314         } catch (DataRetrievalFailureException expected) {
315             assertTrue(true);
316         }
317     }
318 
319     private JdbcExtendedDaoImpl makePopulatedJdbcDao()
320         throws Exception {
321         JdbcExtendedDaoImpl dao = new JdbcExtendedDaoImpl();
322         dao.setDataSource(PopulatedDatabase.getDataSource());
323         dao.afterPropertiesSet();
324 
325         return dao;
326     }
327 
328     //~ Inner Classes ==========================================================
329 
330     private class MockMappingSqlQuery extends MappingSqlQuery {
331         protected Object mapRow(ResultSet arg0, int arg1)
332             throws SQLException {
333             return null;
334         }
335     }
336 }