]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
5002a6e4fd4279bff953e06f0166c1cdc51bf81d
[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 import org.collectionspace.services.authorization.AuthZ;
31 import org.collectionspace.services.authorization.perms.Permission;
32 import org.collectionspace.services.authorization.PermissionRole;
33 import org.collectionspace.services.authorization.PermissionRoleRel;
34 import org.collectionspace.services.authorization.Role;
35 import org.collectionspace.services.authorization.SubjectType;
36 import org.collectionspace.services.authorization.importer.AuthorizationGen;
37 import org.collectionspace.services.authorization.importer.AuthorizationSeed;
38 import org.collectionspace.services.authorization.importer.AuthorizationStore;
39 import org.collectionspace.services.authorization.storage.PermissionRoleUtil;
40 import org.hibernate.exception.ConstraintViolationException;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.context.support.ClassPathXmlApplicationContext;
44 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
45 import org.springframework.security.core.Authentication;
46 import org.springframework.security.core.GrantedAuthority;
47 import org.springframework.security.core.authority.GrantedAuthorityImpl;
48 import org.springframework.security.core.context.SecurityContextHolder;
49 import org.springframework.transaction.TransactionDefinition;
50 import org.springframework.transaction.TransactionStatus;
51 import org.springframework.transaction.support.DefaultTransactionDefinition;
52
53 /**
54  * A driver for seeding authorization
55  * @author 
56  */
57 public class AuthorizationSeedDriver {
58
59     final Logger logger = LoggerFactory.getLogger(AuthorizationSeedDriver.class);
60     final static private String SPRING_SECURITY_METADATA = "applicationContext-authorization-test.xml";
61     final static private String ROLE_FILE = "import-roles.xml";
62     final static private String PERMISSION_FILE = "import-permissions.xml";
63     final static private String PERMISSION_ROLE_FILE = "import-permissions-roles.xml";
64     private String user;
65     private String password;
66     private String tenantBindingFile;
67     private String exportDir;
68     private AuthorizationGen authzGen;
69     private org.springframework.jdbc.datasource.DataSourceTransactionManager txManager;
70
71     /**
72      * AuthorizationSeedDriver
73      * @param user to use to establish security context. should be in ROLE_ADMINISTRATOR
74      * @param password
75      * @param tenantBindingFile
76      * @param importDir dir to import permisison/permission role file from. same as
77      * export dir by default
78      * @param exportDir dir to export permission/permission role file to
79      */
80     public AuthorizationSeedDriver(String user, String password,
81             String tenantBindingFile,
82             String exportDir) {
83         if (user == null || user.isEmpty()) {
84             throw new IllegalArgumentException("username required.");
85         }
86         this.user = user;
87
88         if (password == null || password.isEmpty()) {
89             throw new IllegalArgumentException("password required.");
90         }
91         this.password = password;
92         
93         if (tenantBindingFile == null || tenantBindingFile.isEmpty()) {
94             throw new IllegalArgumentException("tenantbinding file are required.");
95         }
96         this.tenantBindingFile = tenantBindingFile;
97         if (exportDir == null || exportDir.isEmpty()) {
98             throw new IllegalArgumentException("exportdir required.");
99         }
100         this.exportDir = exportDir;
101
102     }
103
104     public void generate() {
105         try {
106             authzGen = new AuthorizationGen();
107             authzGen.initialize(tenantBindingFile);
108             authzGen.createDefaultRoles();
109             authzGen.createDefaultPermissions();
110             authzGen.associateDefaultPermissionsRoles();
111             authzGen.exportDefaultRoles(exportDir + File.separator + ROLE_FILE);
112             authzGen.exportDefaultPermissions(exportDir + File.separator + PERMISSION_FILE);
113             authzGen.exportDefaultPermissionRoles(exportDir + File.separator + PERMISSION_ROLE_FILE);
114             if (logger.isDebugEnabled()) {
115                 logger.debug("Authorization generation completed but not yet persisted.");
116             }
117         } catch (Exception ex) {
118             logger.error("AuthorizationSeedDriver caught an exception: ", ex);
119             throw new RuntimeException(ex);
120         }
121     }
122
123     public void seed() {
124         TransactionStatus status = null;
125         try {
126                 // Push all the authz info into the cspace DB tables -this include default roles, permissions, and permroles
127             store();
128
129             setupSpring();
130             status = beginTransaction("seedData");
131             AuthorizationSeed authzSeed = new AuthorizationSeed();
132             authzSeed.seedPermissions(authzGen.getDefaultPermissions(), authzGen.getDefaultPermissionRoles());
133 //            authzSeed.seedPermissions(exportDir + File.separator + PERMISSION_FILE,
134 //                    exportDir + File.separator + PERMISSION_ROLE_FILE);
135             if (logger.isDebugEnabled()) {
136                 logger.debug("authorization seeding completed ");
137             }
138         } catch (Exception ex) {
139             if (status != null) {
140                 rollbackTransaction(status);
141             }
142             if (logger.isDebugEnabled()) {
143                 ex.printStackTrace();
144             }
145             throw new RuntimeException(ex);
146         } finally {
147             if (status != null) {
148                 commitTransaction(status);
149             }
150             logout();
151         }
152     }
153
154     private void setupSpring() {
155
156         ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
157                 new String[]{SPRING_SECURITY_METADATA});
158         login();
159         System.setProperty("spring-beans-config", SPRING_SECURITY_METADATA);
160         // authZ local not used but call to AuthZ.get() has side-effect of initializing our Spring Security context
161         AuthZ authZ = AuthZ.get();
162         txManager = (org.springframework.jdbc.datasource.DataSourceTransactionManager) appContext.getBean("transactionManager");
163         if (logger.isDebugEnabled()) {
164             logger.debug("Spring Security setup complete.");
165         }
166     }
167
168     private void login() {
169         //GrantedAuthority cspace_admin = new GrantedAuthorityImpl("ROLE_ADMINISTRATOR");
170         GrantedAuthority spring_security_admin = new GrantedAuthorityImpl("ROLE_SPRING_ADMIN"); //NOTE: Must match with value in applicationContext-authorization-test.xml (aka SPRING_SECURITY_METADATA)
171         HashSet<GrantedAuthority> gauths = new HashSet<GrantedAuthority>();
172         //gauths.add(cspace_admin);
173         gauths.add(spring_security_admin);
174         Authentication authRequest = new UsernamePasswordAuthenticationToken(user, password, gauths);
175         SecurityContextHolder.getContext().setAuthentication(authRequest);
176         if (logger.isDebugEnabled()) {
177             logger.debug("Spring Security login successful for user=" + user);
178         }
179     }
180
181     private void logout() {
182         SecurityContextHolder.getContext().setAuthentication(null);
183         if (logger.isDebugEnabled()) {
184             logger.debug("Spring Security logged out user=" + user);
185         }
186     }
187
188     private void store() throws Exception {
189         AuthorizationStore authzStore = new AuthorizationStore();
190         for (Role role : authzGen.getDefaultRoles()) {
191                 try {
192                         authzStore.store(role);
193                 } catch (Exception e) {
194                         //
195                         // If the role already exists, read it in and replace the instance
196                         // we're trying to import with the exist one.  This will ensure that the rest
197                         // of import uses the correct CSID.
198                         if (e.getCause() instanceof ConstraintViolationException) {
199                                 Role existingRole = authzStore.getRoleByName(role.getRoleName(), role.getTenantId());
200                                 //
201                                 role = existingRole;
202                         }
203                 }
204         }
205
206         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
207             authzStore.store(perm);
208         }
209
210         List<PermissionRoleRel> permRoleRels = new ArrayList<PermissionRoleRel>();
211         for (PermissionRole pr : authzGen.getDefaultPermissionRoles()) {
212             PermissionRoleUtil.buildPermissionRoleRel(pr, SubjectType.ROLE, permRoleRels, false /*not for delete*/);
213         }
214         for (PermissionRoleRel permRoleRel : permRoleRels) {
215             authzStore.store(permRoleRel);
216         }
217
218         if (logger.isInfoEnabled()) {
219             logger.info("Authroization metata persisted.");
220         }
221     }
222
223     private TransactionStatus beginTransaction(String name) {
224         DefaultTransactionDefinition def = new DefaultTransactionDefinition();
225         // explicitly setting the transaction name is something that can only be done programmatically
226         def.setName(name);
227         def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
228         return txManager.getTransaction(def);
229     }
230
231     private void rollbackTransaction(TransactionStatus status) {
232         txManager.rollback(status);
233     }
234
235     private void commitTransaction(TransactionStatus status) {
236         txManager.commit(status);
237     }
238 }