]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
37c9112f9a3ea04d36ab9aecc16b0b1a87cd8149
[tmp/jakarta-migration.git] /
1 /**
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:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
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.
23  */
24 package org.collectionspace.services.authorization.driver;
25
26 import java.io.File;
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30
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;
41
42 import org.hibernate.exception.ConstraintViolationException;
43
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
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;
56
57 /**
58  * A driver for seeding authorization
59  * @author 
60  */
61 public class AuthorizationSeedDriver {
62
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";
68     private String user;
69     private String password;
70     private String tenantBindingFile;
71     private String exportDir;
72     private AuthorizationGen authzGen;
73     private org.springframework.jdbc.datasource.DataSourceTransactionManager txManager;
74
75     /**
76      * AuthorizationSeedDriver
77      * @param user to use to establish security context. should be in ROLE_ADMINISTRATOR
78      * @param password
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
83      */
84     public AuthorizationSeedDriver(String user, String password,
85             String tenantBindingFile,
86             String exportDir) {
87         if (user == null || user.isEmpty()) {
88             throw new IllegalArgumentException("username required.");
89         }
90         this.user = user;
91
92         if (password == null || password.isEmpty()) {
93             throw new IllegalArgumentException("password required.");
94         }
95         this.password = password;
96         
97         if (tenantBindingFile == null || tenantBindingFile.isEmpty()) {
98             throw new IllegalArgumentException("tenantbinding file are required.");
99         }
100         this.tenantBindingFile = tenantBindingFile;
101         if (exportDir == null || exportDir.isEmpty()) {
102             throw new IllegalArgumentException("exportdir required.");
103         }
104         this.exportDir = exportDir;
105
106     }
107
108     public void generate() {
109         try {
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.");
120             }
121         } catch (Exception ex) {
122             logger.error("AuthorizationSeedDriver caught an exception: ", ex);
123             throw new RuntimeException(ex);
124         }
125     }
126
127     public void seed() {
128         TransactionStatus status = null;
129         try {
130                 // Push all the authz info into the cspace DB tables -this include default roles, permissions, and permroles
131             store();
132
133             setupSpring();
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 ");
141             }
142         } catch (Exception ex) {
143             if (status != null) {
144                 rollbackTransaction(status);
145             }
146             if (logger.isDebugEnabled()) {
147                 ex.printStackTrace();
148             }
149             throw new RuntimeException(ex);
150         } finally {
151             if (status != null) {
152                 commitTransaction(status);
153             }
154             logout();
155         }
156     }
157
158     private void setupSpring() {
159
160         ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
161                 new String[]{SPRING_SECURITY_METADATA});
162         login();
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.");
169         }
170     }
171
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);
182         }
183     }
184
185     private void logout() {
186         SecurityContextHolder.getContext().setAuthentication(null);
187         if (logger.isDebugEnabled()) {
188             logger.debug("Spring Security logged out user=" + user);
189         }
190     }
191
192     private void store() throws Exception {
193         AuthorizationStore authzStore = new AuthorizationStore();
194         for (Role role : authzGen.getDefaultRoles()) {
195                 try {
196                         authzStore.store(role);
197                 } catch (Exception e) {
198                         //
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());
204                                 //
205                                 role = existingRole;
206                         }
207                 }
208         }
209
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);
212         }
213
214         List<PermissionRoleRel> permRoleRels = new ArrayList<PermissionRoleRel>();
215         for (PermissionRole pr : authzGen.getDefaultPermissionRoles()) {
216             PermissionRoleUtil.buildPermissionRoleRel(pr, SubjectType.ROLE, permRoleRels, false /*not for delete*/);
217         }
218         for (PermissionRoleRel permRoleRel : permRoleRels) {
219             authzStore.store(permRoleRel);
220         }
221
222         if (logger.isInfoEnabled()) {
223             logger.info("Authroization metata persisted.");
224         }
225     }
226
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
230         def.setName(name);
231         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
232         return txManager.getTransaction(def);
233     }
234
235     private void rollbackTransaction(TransactionStatus status) {
236         txManager.rollback(status);
237     }
238
239     private void commitTransaction(TransactionStatus status) {
240         txManager.commit(status);
241     }
242 }