2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.authorization.driver;
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
31 import org.collectionspace.services.authorization.AuthZ;
32 import org.collectionspace.services.authorization.perms.Permission;
33 import org.collectionspace.services.authorization.PermissionRole;
34 import org.collectionspace.services.authorization.PermissionRoleRel;
35 import org.collectionspace.services.authorization.Role;
36 import org.collectionspace.services.authorization.SubjectType;
37 import org.collectionspace.services.authorization.importer.AuthorizationGen;
38 import org.collectionspace.services.authorization.importer.AuthorizationSeed;
39 import org.collectionspace.services.common.authorization_mgt.AuthorizationStore;
40 import org.collectionspace.services.authorization.storage.PermissionRoleUtil;
42 import org.hibernate.exception.ConstraintViolationException;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
47 import org.springframework.context.support.ClassPathXmlApplicationContext;
48 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
49 import org.springframework.security.core.Authentication;
50 import org.springframework.security.core.GrantedAuthority;
51 import org.springframework.security.core.authority.GrantedAuthorityImpl;
52 import org.springframework.security.core.context.SecurityContextHolder;
53 import org.springframework.transaction.TransactionDefinition;
54 import org.springframework.transaction.TransactionStatus;
55 import org.springframework.transaction.support.DefaultTransactionDefinition;
58 * A driver for seeding authorization
61 public class AuthorizationSeedDriver {
63 final Logger logger = LoggerFactory.getLogger(AuthorizationSeedDriver.class);
64 final static private String SPRING_SECURITY_METADATA = "applicationContext-authorization-test.xml";
65 final static private String ROLE_FILE = "import-roles.xml";
66 final static private String PERMISSION_FILE = "import-permissions.xml";
67 final static private String PERMISSION_ROLE_FILE = "import-permissions-roles.xml";
69 private String password;
70 private String tenantBindingFile;
71 private String exportDir;
72 private AuthorizationGen authzGen;
73 private org.springframework.jdbc.datasource.DataSourceTransactionManager txManager;
76 * AuthorizationSeedDriver
77 * @param user to use to establish security context. should be in ROLE_ADMINISTRATOR
79 * @param tenantBindingFile
80 * @param importDir dir to import permisison/permission role file from. same as
81 * export dir by default
82 * @param exportDir dir to export permission/permission role file to
84 public AuthorizationSeedDriver(String user, String password,
85 String tenantBindingFile,
87 if (user == null || user.isEmpty()) {
88 throw new IllegalArgumentException("username required.");
92 if (password == null || password.isEmpty()) {
93 throw new IllegalArgumentException("password required.");
95 this.password = password;
97 if (tenantBindingFile == null || tenantBindingFile.isEmpty()) {
98 throw new IllegalArgumentException("tenantbinding file are required.");
100 this.tenantBindingFile = tenantBindingFile;
101 if (exportDir == null || exportDir.isEmpty()) {
102 throw new IllegalArgumentException("exportdir required.");
104 this.exportDir = exportDir;
108 public void generate() {
110 authzGen = new AuthorizationGen();
111 authzGen.initialize(tenantBindingFile);
112 authzGen.createDefaultRoles();
113 authzGen.createDefaultPermissions();
114 authzGen.associateDefaultPermissionsRoles();
115 authzGen.exportDefaultRoles(exportDir + File.separator + ROLE_FILE);
116 authzGen.exportDefaultPermissions(exportDir + File.separator + PERMISSION_FILE);
117 authzGen.exportDefaultPermissionRoles(exportDir + File.separator + PERMISSION_ROLE_FILE);
118 if (logger.isDebugEnabled()) {
119 logger.debug("Authorization generation completed but not yet persisted.");
121 } catch (Exception ex) {
122 logger.error("AuthorizationSeedDriver caught an exception: ", ex);
123 throw new RuntimeException(ex);
128 TransactionStatus status = null;
130 // Push all the authz info into the cspace DB tables -this include default roles, permissions, and permroles
134 status = beginTransaction("seedData");
135 AuthorizationSeed authzSeed = new AuthorizationSeed();
136 authzSeed.seedPermissions(authzGen.getDefaultPermissions(), authzGen.getDefaultPermissionRoles());
137 // authzSeed.seedPermissions(exportDir + File.separator + PERMISSION_FILE,
138 // exportDir + File.separator + PERMISSION_ROLE_FILE);
139 if (logger.isDebugEnabled()) {
140 logger.debug("authorization seeding completed ");
142 } catch (Exception ex) {
143 if (status != null) {
144 rollbackTransaction(status);
146 if (logger.isDebugEnabled()) {
147 ex.printStackTrace();
149 throw new RuntimeException(ex);
151 if (status != null) {
152 commitTransaction(status);
158 private void setupSpring() {
160 ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
161 new String[]{SPRING_SECURITY_METADATA});
163 System.setProperty("spring-beans-config", SPRING_SECURITY_METADATA);
164 // authZ local not used but call to AuthZ.get() has side-effect of initializing our Spring Security context
165 AuthZ authZ = AuthZ.get();
166 txManager = (org.springframework.jdbc.datasource.DataSourceTransactionManager) appContext.getBean("transactionManager");
167 if (logger.isDebugEnabled()) {
168 logger.debug("Spring Security setup complete.");
172 private void login() {
173 //GrantedAuthority cspace_admin = new GrantedAuthorityImpl("ROLE_ADMINISTRATOR");
174 GrantedAuthority spring_security_admin = new GrantedAuthorityImpl("ROLE_SPRING_ADMIN"); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
175 HashSet<GrantedAuthority> gauths = new HashSet<GrantedAuthority>();
176 //gauths.add(cspace_admin);
177 gauths.add(spring_security_admin);
178 Authentication authRequest = new UsernamePasswordAuthenticationToken(user, password, gauths);
179 SecurityContextHolder.getContext().setAuthentication(authRequest);
180 if (logger.isDebugEnabled()) {
181 logger.debug("Spring Security login successful for user=" + user);
185 private void logout() {
186 SecurityContextHolder.getContext().setAuthentication(null);
187 if (logger.isDebugEnabled()) {
188 logger.debug("Spring Security logged out user=" + user);
192 private void store() throws Exception {
193 AuthorizationStore authzStore = new AuthorizationStore();
194 for (Role role : authzGen.getDefaultRoles()) {
196 authzStore.store(role);
197 } catch (Exception e) {
199 // If the role already exists, read it in and replace the instance
200 // we're trying to import with the exist one. This will ensure that the rest
201 // of import uses the correct CSID.
202 if (e.getCause() instanceof ConstraintViolationException) {
203 Role existingRole = authzStore.getRoleByName(role.getRoleName(), role.getTenantId());
210 for (Permission perm : authzGen.getDefaultPermissions()) { //FIXME: REM - 3/27/2012 - If we change the CSID of permissions to something like a refname, then we need to check for existing perms just like we did above for roles
211 authzStore.store(perm);
214 List<PermissionRoleRel> permRoleRels = new ArrayList<PermissionRoleRel>();
215 for (PermissionRole pr : authzGen.getDefaultPermissionRoles()) {
216 PermissionRoleUtil.buildPermissionRoleRel(pr, SubjectType.ROLE, permRoleRels, false /*not for delete*/);
218 for (PermissionRoleRel permRoleRel : permRoleRels) {
219 authzStore.store(permRoleRel);
222 if (logger.isInfoEnabled()) {
223 logger.info("Authroization metata persisted.");
227 private TransactionStatus beginTransaction(String name) {
228 DefaultTransactionDefinition def = new DefaultTransactionDefinition();
229 // explicitly setting the transaction name is something that can only be done programmatically
231 def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
232 return txManager.getTransaction(def);
235 private void rollbackTransaction(TransactionStatus status) {
236 txManager.rollback(status);
239 private void commitTransaction(TransactionStatus status) {
240 txManager.commit(status);