001: /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015: package sample.contact;
016:
017: import org.acegisecurity.Authentication;
018: import org.acegisecurity.GrantedAuthority;
019: import org.acegisecurity.GrantedAuthorityImpl;
020:
021: import org.acegisecurity.acls.MutableAcl;
022: import org.acegisecurity.acls.MutableAclService;
023: import org.acegisecurity.acls.Permission;
024: import org.acegisecurity.acls.domain.AclImpl;
025: import org.acegisecurity.acls.domain.BasePermission;
026: import org.acegisecurity.acls.objectidentity.ObjectIdentity;
027: import org.acegisecurity.acls.objectidentity.ObjectIdentityImpl;
028: import org.acegisecurity.acls.sid.PrincipalSid;
029:
030: import org.acegisecurity.context.SecurityContextHolder;
031:
032: import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
033:
034: import org.springframework.beans.factory.InitializingBean;
035:
036: import org.springframework.jdbc.core.JdbcTemplate;
037:
038: import org.springframework.transaction.PlatformTransactionManager;
039: import org.springframework.transaction.TransactionStatus;
040: import org.springframework.transaction.support.TransactionCallback;
041: import org.springframework.transaction.support.TransactionTemplate;
042:
043: import org.springframework.util.Assert;
044:
045: import java.util.Random;
046:
047: import javax.sql.DataSource;
048:
049: /**
050: * Populates the Contacts in-memory database with contact and ACL information.
051: *
052: * @author Ben Alex
053: * @version $Id: DataSourcePopulator.java 1754 2006-11-17 02:01:21Z benalex $
054: */
055: public class DataSourcePopulator implements InitializingBean {
056: //~ Instance fields ================================================================================================
057:
058: JdbcTemplate template;
059: private MutableAclService mutableAclService;
060: Random rnd = new Random();
061: TransactionTemplate tt;
062: String[] firstNames = { "Bob", "Mary", "James", "Jane", "Kristy",
063: "Kirsty", "Kate", "Jeni", "Angela", "Melanie", "Kent",
064: "William", "Geoff", "Jeff", "Adrian", "Amanda", "Lisa",
065: "Elizabeth", "Prue", "Richard", "Darin", "Phillip",
066: "Michael", "Belinda", "Samantha", "Brian", "Greg",
067: "Matthew" };
068: String[] lastNames = { "Smith", "Williams", "Jackson", "Rictor",
069: "Nelson", "Fitzgerald", "McAlpine", "Sutherland", "Abbott",
070: "Hall", "Edwards", "Gates", "Black", "Brown", "Gray",
071: "Marwell", "Booch", "Johnson", "McTaggart", "Parklin",
072: "Findlay", "Robinson", "Giugni", "Lang", "Chi",
073: "Carmichael" };
074: private int createEntities = 50;
075:
076: //~ Methods ========================================================================================================
077:
078: public void afterPropertiesSet() throws Exception {
079: Assert.notNull(mutableAclService, "mutableAclService required");
080: Assert.notNull(template, "dataSource required");
081: Assert.notNull(tt, "platformTransactionManager required");
082:
083: // Set a user account that will initially own all the created data
084: Authentication authRequest = new UsernamePasswordAuthenticationToken(
085: "marissa", "koala",
086: new GrantedAuthority[] { new GrantedAuthorityImpl(
087: "ROLE_IGNORED") });
088: SecurityContextHolder.getContext().setAuthentication(
089: authRequest);
090:
091: template
092: .execute("CREATE TABLE ACL_SID(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,PRINCIPAL BOOLEAN NOT NULL,SID VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_1 UNIQUE(SID,PRINCIPAL));");
093: template
094: .execute("CREATE TABLE ACL_CLASS(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,CLASS VARCHAR_IGNORECASE(100) NOT NULL,CONSTRAINT UNIQUE_UK_2 UNIQUE(CLASS));");
095: template
096: .execute("CREATE TABLE ACL_OBJECT_IDENTITY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,OBJECT_ID_CLASS BIGINT NOT NULL,OBJECT_ID_IDENTITY BIGINT NOT NULL,PARENT_OBJECT BIGINT,OWNER_SID BIGINT,ENTRIES_INHERITING BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_3 UNIQUE(OBJECT_ID_CLASS,OBJECT_ID_IDENTITY),CONSTRAINT FOREIGN_FK_1 FOREIGN KEY(PARENT_OBJECT)REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_2 FOREIGN KEY(OBJECT_ID_CLASS)REFERENCES ACL_CLASS(ID),CONSTRAINT FOREIGN_FK_3 FOREIGN KEY(OWNER_SID)REFERENCES ACL_SID(ID));");
097: template
098: .execute("CREATE TABLE ACL_ENTRY(ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 100) NOT NULL PRIMARY KEY,ACL_OBJECT_IDENTITY BIGINT NOT NULL,ACE_ORDER INT NOT NULL,SID BIGINT NOT NULL,MASK INTEGER NOT NULL,GRANTING BOOLEAN NOT NULL,AUDIT_SUCCESS BOOLEAN NOT NULL,AUDIT_FAILURE BOOLEAN NOT NULL,CONSTRAINT UNIQUE_UK_4 UNIQUE(ACL_OBJECT_IDENTITY,ACE_ORDER),CONSTRAINT FOREIGN_FK_4 FOREIGN KEY(ACL_OBJECT_IDENTITY) REFERENCES ACL_OBJECT_IDENTITY(ID),CONSTRAINT FOREIGN_FK_5 FOREIGN KEY(SID) REFERENCES ACL_SID(ID));");
099:
100: template
101: .execute("CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(50) NOT NULL,ENABLED BOOLEAN NOT NULL);");
102: template
103: .execute("CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
104: template
105: .execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);");
106:
107: template
108: .execute("CREATE TABLE CONTACTS(ID BIGINT NOT NULL PRIMARY KEY, CONTACT_NAME VARCHAR_IGNORECASE(50) NOT NULL, EMAIL VARCHAR_IGNORECASE(50) NOT NULL)");
109:
110: /*
111: Passwords encoded using MD5, NOT in Base64 format, with null as salt
112: Encoded password for marissa is "koala"
113: Encoded password for dianne is "emu"
114: Encoded password for scott is "wombat"
115: Encoded password for peter is "opal" (but user is disabled)
116: Encoded password for bill is "wombat"
117: Encoded password for bob is "wombat"
118: Encoded password for jane is "wombat"
119:
120: */
121: template
122: .execute("INSERT INTO USERS VALUES('marissa','a564de63c2d0da68cf47586ee05984d7',TRUE);");
123: template
124: .execute("INSERT INTO USERS VALUES('dianne','65d15fe9156f9c4bbffd98085992a44e',TRUE);");
125: template
126: .execute("INSERT INTO USERS VALUES('scott','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
127: template
128: .execute("INSERT INTO USERS VALUES('peter','22b5c9accc6e1ba628cedc63a72d57f8',FALSE);");
129: template
130: .execute("INSERT INTO USERS VALUES('bill','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
131: template
132: .execute("INSERT INTO USERS VALUES('bob','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
133: template
134: .execute("INSERT INTO USERS VALUES('jane','2b58af6dddbd072ed27ffc86725d7d3a',TRUE);");
135: template
136: .execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_USER');");
137: template
138: .execute("INSERT INTO AUTHORITIES VALUES('marissa','ROLE_SUPERVISOR');");
139: template
140: .execute("INSERT INTO AUTHORITIES VALUES('dianne','ROLE_USER');");
141: template
142: .execute("INSERT INTO AUTHORITIES VALUES('scott','ROLE_USER');");
143: template
144: .execute("INSERT INTO AUTHORITIES VALUES('peter','ROLE_USER');");
145: template
146: .execute("INSERT INTO AUTHORITIES VALUES('bill','ROLE_USER');");
147: template
148: .execute("INSERT INTO AUTHORITIES VALUES('bob','ROLE_USER');");
149: template
150: .execute("INSERT INTO AUTHORITIES VALUES('jane','ROLE_USER');");
151:
152: template
153: .execute("INSERT INTO contacts VALUES (1, 'John Smith', 'john@somewhere.com');");
154: template
155: .execute("INSERT INTO contacts VALUES (2, 'Michael Citizen', 'michael@xyz.com');");
156: template
157: .execute("INSERT INTO contacts VALUES (3, 'Joe Bloggs', 'joe@demo.com');");
158: template
159: .execute("INSERT INTO contacts VALUES (4, 'Karen Sutherland', 'karen@sutherland.com');");
160: template
161: .execute("INSERT INTO contacts VALUES (5, 'Mitchell Howard', 'mitchell@abcdef.com');");
162: template
163: .execute("INSERT INTO contacts VALUES (6, 'Rose Costas', 'rose@xyz.com');");
164: template
165: .execute("INSERT INTO contacts VALUES (7, 'Amanda Smith', 'amanda@abcdef.com');");
166: template
167: .execute("INSERT INTO contacts VALUES (8, 'Cindy Smith', 'cindy@smith.com');");
168: template
169: .execute("INSERT INTO contacts VALUES (9, 'Jonathan Citizen', 'jonathan@xyz.com');");
170:
171: for (int i = 10; i < createEntities; i++) {
172: String[] person = selectPerson();
173: template.execute("INSERT INTO contacts VALUES (" + i
174: + ", '" + person[2] + "', '"
175: + person[0].toLowerCase() + "@"
176: + person[1].toLowerCase() + ".com');");
177: }
178:
179: // Create acl_object_identity rows (and also acl_class rows as needed
180: for (int i = 1; i < createEntities; i++) {
181: final ObjectIdentity objectIdentity = new ObjectIdentityImpl(
182: Contact.class, new Long(i));
183: tt.execute(new TransactionCallback() {
184: public Object doInTransaction(TransactionStatus arg0) {
185: MutableAcl acl = mutableAclService
186: .createAcl(objectIdentity);
187:
188: return null;
189: }
190: });
191: }
192:
193: // Now grant some permissions
194: grantPermissions(1, "marissa", BasePermission.ADMINISTRATION);
195: grantPermissions(2, "marissa", BasePermission.READ);
196: grantPermissions(3, "marissa", BasePermission.READ);
197: grantPermissions(3, "marissa", BasePermission.WRITE);
198: grantPermissions(3, "marissa", BasePermission.DELETE);
199: grantPermissions(4, "marissa", BasePermission.ADMINISTRATION);
200: grantPermissions(4, "dianne", BasePermission.ADMINISTRATION);
201: grantPermissions(4, "scott", BasePermission.READ);
202: grantPermissions(5, "dianne", BasePermission.ADMINISTRATION);
203: grantPermissions(5, "dianne", BasePermission.READ);
204: grantPermissions(6, "dianne", BasePermission.READ);
205: grantPermissions(6, "dianne", BasePermission.WRITE);
206: grantPermissions(6, "dianne", BasePermission.DELETE);
207: grantPermissions(6, "scott", BasePermission.READ);
208: grantPermissions(7, "scott", BasePermission.ADMINISTRATION);
209: grantPermissions(8, "dianne", BasePermission.ADMINISTRATION);
210: grantPermissions(8, "dianne", BasePermission.READ);
211: grantPermissions(8, "scott", BasePermission.READ);
212: grantPermissions(9, "scott", BasePermission.ADMINISTRATION);
213: grantPermissions(9, "scott", BasePermission.READ);
214: grantPermissions(9, "scott", BasePermission.WRITE);
215: grantPermissions(9, "scott", BasePermission.DELETE);
216:
217: // Now expressly change the owner of the first ten contacts
218: // We have to do this last, because "marissa" owns all of them (doing it sooner would prevent ACL updates)
219: // Note that ownership has no impact on permissions - they're separate (ownership only allows ACl editing)
220: changeOwner(5, "dianne");
221: changeOwner(6, "dianne");
222: changeOwner(7, "scott");
223: changeOwner(8, "dianne");
224: changeOwner(9, "scott");
225:
226: String[] users = { "bill", "bob", "jane" }; // don't want to mess around with consistent sample data
227: Permission[] permissions = { BasePermission.ADMINISTRATION,
228: BasePermission.READ, BasePermission.DELETE };
229:
230: for (int i = 10; i < createEntities; i++) {
231: String user = users[rnd.nextInt(users.length)];
232: Permission permission = permissions[rnd
233: .nextInt(permissions.length)];
234: grantPermissions(i, user, permission);
235:
236: String user2 = users[rnd.nextInt(users.length)];
237: Permission permission2 = permissions[rnd
238: .nextInt(permissions.length)];
239: grantPermissions(i, user2, permission2);
240: }
241:
242: SecurityContextHolder.clearContext();
243: }
244:
245: private void changeOwner(int contactNumber, String newOwnerUsername) {
246: AclImpl acl = (AclImpl) mutableAclService
247: .readAclById(new ObjectIdentityImpl(Contact.class,
248: new Long(contactNumber)));
249: acl.setOwner(new PrincipalSid(newOwnerUsername));
250: updateAclInTransaction(acl);
251: }
252:
253: public int getCreateEntities() {
254: return createEntities;
255: }
256:
257: private void grantPermissions(int contactNumber,
258: String recipientUsername, Permission permission) {
259: AclImpl acl = (AclImpl) mutableAclService
260: .readAclById(new ObjectIdentityImpl(Contact.class,
261: new Long(contactNumber)));
262: acl.insertAce(null, permission, new PrincipalSid(
263: recipientUsername), true);
264: updateAclInTransaction(acl);
265: }
266:
267: private String[] selectPerson() {
268: String firstName = firstNames[rnd.nextInt(firstNames.length)];
269: String lastName = lastNames[rnd.nextInt(lastNames.length)];
270:
271: return new String[] { firstName, lastName,
272: firstName + " " + lastName };
273: }
274:
275: public void setCreateEntities(int createEntities) {
276: this .createEntities = createEntities;
277: }
278:
279: public void setDataSource(DataSource dataSource) {
280: this .template = new JdbcTemplate(dataSource);
281: }
282:
283: public void setMutableAclService(MutableAclService mutableAclService) {
284: this .mutableAclService = mutableAclService;
285: }
286:
287: public void setPlatformTransactionManager(
288: PlatformTransactionManager platformTransactionManager) {
289: this .tt = new TransactionTemplate(platformTransactionManager);
290: }
291:
292: private void updateAclInTransaction(final MutableAcl acl) {
293: tt.execute(new TransactionCallback() {
294: public Object doInTransaction(TransactionStatus arg0) {
295: mutableAclService.updateAcl(acl);
296:
297: return null;
298: }
299: });
300: }
301: }
|