]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
a5cef46519aabf787d7557884016cc706ad96ad1
[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.importer;
25
26 import java.io.File;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import java.util.ArrayList;
30 import java.util.Hashtable;
31 import java.util.List;
32 import javax.xml.bind.JAXBContext;
33 import javax.xml.bind.Marshaller;
34 import org.collectionspace.services.authorization.perms.Permission;
35 import org.collectionspace.authentication.AuthN;
36 import org.collectionspace.services.authorization.PermissionRole;
37 import org.collectionspace.services.authorization.PermissionValue;
38 import org.collectionspace.services.authorization.perms.PermissionsList;
39 import org.collectionspace.services.authorization.PermissionsRolesList;
40 import org.collectionspace.services.client.TenantClient;
41 import org.collectionspace.services.authorization.Role;
42 import org.collectionspace.services.authorization.RoleValue;
43 import org.collectionspace.services.authorization.RolesList;
44 import org.collectionspace.services.authorization.SubjectType;
45 import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
46 import org.collectionspace.services.common.config.ServicesConfigReaderImpl;
47 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
48 import org.collectionspace.services.common.security.SecurityUtils;
49 import org.collectionspace.services.common.storage.jpa.JPATransactionContext;
50 import org.collectionspace.services.config.service.ServiceBindingType;
51 import org.collectionspace.services.config.tenant.TenantBindingType;
52
53 /**
54  * AuthorizationGen generates authorizations (permissions and roles)
55  * for tenant services
56  * @author 
57  */
58 public class AuthorizationGen {
59     final Logger logger = LoggerFactory.getLogger(AuthorizationGen.class);
60     //
61     // Should the base resource act as a proxy for its sub-resources for AuthZ purposes
62     //
63     final public static boolean AUTHZ_IS_ENTITY_PROXY = false;
64     
65     final public static String TENANT_MGMNT_ID = "0";
66     
67         private static final boolean USE_APP_GENERATED_BINDINGS = true;
68     
69     private List<Permission> readWritePermList = new ArrayList<Permission>();
70     private List<Permission> tenantMgmntPermList = new ArrayList<Permission>();
71     private List<PermissionRole> tenantMgmntPermRoleList = new ArrayList<PermissionRole>();
72     
73     private List<Permission> adminPermList = new ArrayList<Permission>();
74     private List<PermissionRole> adminPermRoleList = new ArrayList<PermissionRole>();
75     
76     private List<Permission> readerPermList = new ArrayList<Permission>();
77     private List<PermissionRole> readerPermRoleList = new ArrayList<PermissionRole>();
78     
79     private List<Role> adminRoles = new ArrayList<Role>();
80     private List<Role> readerRoles = new ArrayList<Role>();
81     
82     private Role cspaceTenantMgmntRole;
83     private Hashtable<String, TenantBindingType> tenantBindings = new Hashtable<String, TenantBindingType>();
84         //
85     // Store the list of default roles, perms, and roleperms
86     //
87     private List<PermissionRole> allPermRoleList = null;
88         private List<Permission> allPermList;
89         private List<Role> allRoleList;
90
91     public void initialize(String tenantRootDirPath) throws Exception {
92         ServicesConfigReaderImpl servicesConfigReader = new ServicesConfigReaderImpl(tenantRootDirPath);
93         servicesConfigReader.read(USE_APP_GENERATED_BINDINGS);        
94         Boolean useAppGeneratedBindings = servicesConfigReader.getConfiguration().isUseAppGeneratedTenantBindings();
95
96         TenantBindingConfigReaderImpl tenantBindingConfigReader =
97                 new TenantBindingConfigReaderImpl(tenantRootDirPath);
98         tenantBindingConfigReader.read(useAppGeneratedBindings);
99         // Note that we build permissions for all tenants, whether or not they are marked create disabled.
100         // This is a hack until we can correctly run an incremental import.
101         tenantBindings = tenantBindingConfigReader.getTenantBindings(
102                                                         TenantBindingConfigReaderImpl.INCLUDE_CREATE_DISABLED_TENANTS);
103         cspaceTenantMgmntRole = buildTenantMgmntRole();
104
105         if (logger.isDebugEnabled()) {
106             logger.debug("initialized with tenant bindings from " + tenantRootDirPath);
107         }
108     }
109
110     /**
111      * createDefaultPermissions creates default admin and reader permissions
112      * for each tenant found in the given tenant binding file
113      * @see initialize
114      * @return
115      */
116     public void createDefaultPermissions(JPATransactionContext jpaTransactionContext) {
117         for (String tenantId : tenantBindings.keySet()) {
118             List<Permission> adminPerms = createDefaultAdminPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY); // CRUDL perms
119             adminPermList.addAll(adminPerms);
120
121             List<Permission> readerPerms = createDefaultReaderPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY); // RL perms
122             readerPermList.addAll(readerPerms);
123             
124             List<Permission> readWritePerms = createDefaultReadWritePermissions(tenantId, AUTHZ_IS_ENTITY_PROXY); // CRUL perms
125             readWritePermList.addAll(readWritePerms);
126         }
127         
128         List<Permission> tenantMgmntPerms = createDefaultTenantMgmntPermissions();
129         tenantMgmntPermList.addAll(tenantMgmntPerms);
130     }
131
132     /**
133      * createDefaultAdminPermissions creates default admin permissions for all services
134      * used by the given tenant
135      * @param tenantId
136      * @return
137      */
138     public List<Permission> createDefaultAdminPermissions(String tenantId, boolean isEntityProxy) {
139         ArrayList<Permission> result = new ArrayList<Permission>();
140         TenantBindingType tbinding = tenantBindings.get(tenantId);
141         for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
142
143             //add permissions for the main path
144                 String resourceName = sbinding.getName().toLowerCase().trim();
145                 if (isEntityProxy == true) {
146                         resourceName = SecurityUtils.getResourceEntity(resourceName);
147                 }
148             Permission perm = buildAdminPermission(tbinding.getId(), resourceName);
149             result.add(perm);
150
151             //add permissions for alternate paths
152             if (isEntityProxy == false) {
153                     List<String> uriPaths = sbinding.getUriPath();
154                     for (String uriPath : uriPaths) {
155                         perm = buildAdminPermission(tbinding.getId(), uriPath.toLowerCase());
156                         result.add(perm);
157                     }
158             }
159         }
160         
161         return result;
162     }
163
164     /**
165      * createDefaultTenantMgmntPermissions creates default permissions for known 
166      * Tenant Mgmnt services. 
167      * @return
168      */
169     public List<Permission> createDefaultTenantMgmntPermissions() {
170         ArrayList<Permission> apcList = new ArrayList<Permission>();
171         // Later can think about ways to configure this if we want to
172         Permission perm = createTenantMgmntPermission(TenantClient.SERVICE_NAME);
173         apcList.add(perm);
174         
175         return apcList;
176     }
177
178     /**
179      * createTenantMgmntPermission creates special admin permissions for tenant management
180      * @return
181      */
182     private Permission  createTenantMgmntPermission(String resourceName) {
183         Permission perm = buildAdminPermission(TENANT_MGMNT_ID, resourceName);
184         return perm;
185     }
186
187     /**
188      * createDefaultReadWritePermissions creates read-write (CRUL) permissions for all services
189      * used by the given tenant
190      * @param tenantId
191      * @return
192      */
193     public List<Permission> createDefaultReadWritePermissions(String tenantId, boolean isEntityProxy) {
194         ArrayList<Permission> apcList = new ArrayList<Permission>();
195
196         TenantBindingType tbinding = tenantBindings.get(tenantId);
197         for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
198             //add permissions for the main path
199                 String resourceName = sbinding.getName().toLowerCase().trim();
200                 if (isEntityProxy == true) {
201                         resourceName = SecurityUtils.getResourceEntity(resourceName);
202                 }
203             Permission perm = buildReadWritePermission(tbinding.getId(), resourceName);
204             apcList.add(perm);
205
206             //add permissions for alternate paths
207             if (isEntityProxy == false) {
208                     List<String> uriPaths = sbinding.getUriPath();
209                     for (String uriPath : uriPaths) {
210                         perm = buildReadWritePermission(tbinding.getId(), uriPath.toLowerCase());
211                         apcList.add(perm);
212                     }
213             }
214         }
215
216         return apcList;
217     }
218     
219     /**
220      * createDefaultReaderPermissions creates read only permissions for all services
221      * used by the given tenant
222      * 
223      * @param tenantId
224      * @return
225      */
226     public List<Permission> createDefaultReaderPermissions(String tenantId, boolean isEntityProxy) {
227         ArrayList<Permission> apcList = new ArrayList<Permission>();
228         
229         TenantBindingType tbinding = tenantBindings.get(tenantId);
230         for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
231             //add permissions for the main path
232                 String resourceName = sbinding.getName().toLowerCase().trim();
233                 if (isEntityProxy == true) {
234                         resourceName = SecurityUtils.getResourceEntity(resourceName);
235                 }               
236             Permission perm = buildReaderPermission(tbinding.getId(), resourceName);
237             apcList.add(perm);
238
239             //add permissions for alternate paths
240             if (isEntityProxy == false) {
241                     List<String> uriPaths = sbinding.getUriPath();
242                     for (String uriPath : uriPaths) {
243                         perm = buildReaderPermission(tbinding.getId(), uriPath.toLowerCase());
244                         apcList.add(perm);
245                     }
246             }
247         }
248         
249         return apcList;
250     }
251
252     private Permission buildAdminPermission(String tenantId, String resourceName) {
253         String description = "Generated admin permission.";
254         return AuthorizationCommon.createPermission(tenantId, resourceName, description, AuthorizationCommon.ACTIONGROUP_CRUDL_NAME, true);
255     }
256     
257     private Permission buildReaderPermission(String tenantId, String resourceName) {
258         String description = "Generated read-only (RL) permission.";
259         return AuthorizationCommon.createPermission(tenantId, resourceName, description, AuthorizationCommon.ACTIONGROUP_RL_NAME, true);        
260     }
261     
262     private Permission buildReadWritePermission(String tenantId, String resourceName) {
263         String description = "Generated read-write (CRUL) permission.";
264         return AuthorizationCommon.createPermission(tenantId, resourceName, description, AuthorizationCommon.ACTIONGROUP_CRUL_NAME, true);      
265     }
266
267     public List<Permission> getDefaultPermissions() {
268         if (allPermList == null) {
269                 allPermList = new ArrayList<Permission>();
270                 allPermList.addAll(adminPermList);
271                 allPermList.addAll(readerPermList);
272                 allPermList.addAll(readWritePermList);          
273                 allPermList.addAll(tenantMgmntPermList);
274         }
275         return allPermList;
276     }
277
278     public List<Permission> getDefaultAdminPermissions() {
279         return adminPermList;
280     }
281
282     public List<Permission> getDefaultReaderPermissions() {
283         return readerPermList;
284     }
285
286     public List<Permission> getDefaultTenantMgmntPermissions() {
287         return tenantMgmntPermList;
288     }
289
290     /**
291      * createDefaultRoles creates default admin and reader roles
292      * for each tenant found in the given tenant binding file
293      */
294     public void createDefaultRoles(JPATransactionContext jpaTransactionContext) {
295         for (String tenantId : tenantBindings.keySet()) {
296
297             Role arole = buildTenantAdminRole(jpaTransactionContext, tenantId);
298             adminRoles.add(arole);
299
300             Role rrole = buildTenantReaderRole(jpaTransactionContext, tenantId);
301             readerRoles.add(rrole);
302         }
303     }
304
305     private Role buildTenantAdminRole(JPATransactionContext jpaTransactionContext, String tenantId) {
306         String type = "admin";
307         Role result = AuthorizationCommon.getRole(jpaTransactionContext, tenantId, AuthorizationCommon.ROLE_TENANT_ADMINISTRATOR);
308         
309         if (result == null) {
310                 // the role doesn't exist already, so we need to create it
311                 String description = "Generated tenant " + type + " role.";
312                 result = AuthorizationCommon.createRole(tenantId, AuthorizationCommon.ROLE_TENANT_ADMINISTRATOR, description, true /*immutable*/);
313         }
314         
315         return result;
316     }
317
318     private Role buildTenantReaderRole(JPATransactionContext jpaTransactionContext, String tenantId) {
319         String type = "read only";
320         Role result = AuthorizationCommon.getRole(jpaTransactionContext, tenantId, AuthorizationCommon.ROLE_TENANT_READER);
321         
322         if (result == null) {
323                 // the role doesn't exist already, so we need to create it
324                 String description = "Generated tenant " + type + " role.";
325                 result = AuthorizationCommon.createRole(tenantId, AuthorizationCommon.ROLE_TENANT_READER, description, true /*immutable*/);
326         }
327         
328         return result;
329     }
330     
331
332     public List<Role> getDefaultRoles() {
333         if (allRoleList == null) {
334                 allRoleList = new ArrayList<Role>();
335                 allRoleList.addAll(adminRoles);
336                 allRoleList.addAll(readerRoles);
337                 // Finally, add the tenant manager role to the list
338                 allRoleList.add(cspaceTenantMgmntRole);
339         }
340         return allRoleList;
341     }
342
343     public void associateDefaultPermissionsRoles() {
344         for (Permission p : adminPermList) {
345             PermissionRole permAdmRole = associatePermissionToRoles(p, adminRoles, true);
346             adminPermRoleList.add(permAdmRole);
347         }
348
349         for (Permission p : readerPermList) {
350             PermissionRole permRdrRole = associatePermissionToRoles(p, readerRoles, true);
351             readerPermRoleList.add(permRdrRole);
352         }
353         
354         //CSpace Tenant Manager has all access
355         // PLS - this looks wrong. This should be a tenantMgmnt role, and only have access to 
356         // tenantMgmnt perms. Will leave this for now...
357         List<Role> roles = new ArrayList<Role>();
358         roles.add(cspaceTenantMgmntRole);
359         /* for (Permission p : adminPermList) {
360             PermissionRole permCAdmRole = associatePermissionRoles(p, roles, false);
361             adminPermRoleList.add(permCAdmRole);
362         }  */
363         
364         // Now associate the tenant management perms to the role
365         for (Permission p : tenantMgmntPermList) {
366                 // Note we enforce tenant, as should all be tenant 0 (the special one)
367             PermissionRole permTMRole = associatePermissionToRoles(p, roles, true);
368             tenantMgmntPermRoleList.add(permTMRole);
369         }        
370     }
371
372     @Deprecated
373     public List<PermissionRole> associatePermissionsRoles(List<Permission> perms, List<Role> roles, boolean enforceTenancy) {
374         List<PermissionRole> result = null;
375         
376         List<PermissionRole> permRoles = new ArrayList<PermissionRole>();
377         for (Permission perm : perms) {
378             PermissionRole permRole = associatePermissionToRoles(perm, roles, enforceTenancy);
379             if (permRole != null) {
380                 permRoles.add(permRole);
381             }
382         }
383         
384         if (permRoles.isEmpty() == false) {
385                 result = permRoles;
386         }
387         
388         return result;
389     }
390
391     private PermissionRole associatePermissionToRoles(Permission perm,
392             List<Role> roles, boolean enforceTenancy) {
393         PermissionRole result = null;
394         
395         PermissionRole pr = new PermissionRole();
396         pr.setSubject(SubjectType.ROLE);
397         List<PermissionValue> permValueList = new ArrayList<PermissionValue>();
398         pr.setPermission(permValueList);
399         
400         PermissionValue permValue = new PermissionValue();
401         permValue.setPermissionId(perm.getCsid());
402         permValue.setResourceName(perm.getResourceName().toLowerCase());
403         permValue.setActionGroup(perm.getActionGroup());
404         permValue.setTenantId(perm.getTenantId());
405         permValueList.add(permValue);
406
407         List<RoleValue> roleValues = new ArrayList<RoleValue>();
408         for (Role role : roles) {
409                 boolean tenantIdsMatched = true;
410                 if (enforceTenancy == true) {
411                         tenantIdsMatched = role.getTenantId().equals(perm.getTenantId());
412                 }
413                 if (tenantIdsMatched == true) {
414                     RoleValue rv = new RoleValue();
415                     // This needs to use the qualified name, not the display name
416                     rv.setRoleName(role.getRoleName().toUpperCase());
417                     rv.setRoleId(role.getCsid());
418                     rv.setTenantId(role.getTenantId());
419                     roleValues.add(rv);
420                 } else {
421                         if (logger.isTraceEnabled() == true) {
422                                 logger.trace("Role and Permission tenant ID did not match."); //FIXME: REM - Remove this debug statement.
423                         }
424                 }
425         }
426         //
427         // If 'roleValues' is not empty, then associate it with the incoming 'perm' values
428         // otherwise, return null;
429         //
430         if (roleValues.isEmpty() == false) {
431                 pr.setRole(roleValues);
432                 result = pr;
433         }
434
435         return result;
436     }
437
438     public List<PermissionRole> getDefaultPermissionRoles() {
439         if (allPermRoleList  == null) {
440                 allPermRoleList = new ArrayList<PermissionRole>();
441                 allPermRoleList.addAll(adminPermRoleList);
442                 allPermRoleList.addAll(readerPermRoleList);
443                 allPermRoleList.addAll(tenantMgmntPermRoleList);
444         }
445         return allPermRoleList;
446     }
447
448     public List<PermissionRole> getDefaultAdminPermissionRoles() {
449         return adminPermRoleList;
450     }
451
452     public List<PermissionRole> getDefaultReaderPermissionRoles() {
453         return readerPermRoleList;
454     }
455
456     private Role buildTenantMgmntRole() {
457         Role role = new Role();
458         
459         role.setDescription("A generated super role that has permissions to manage tenants.");
460         role.setDisplayName(AuthN.ROLE_ALL_TENANTS_MANAGER);
461         role.setRoleName(AuthorizationCommon.getQualifiedRoleName(
462                         AuthN.ALL_TENANTS_MANAGER_TENANT_ID, role.getDisplayName()));
463         role.setCsid(AuthN.ROLE_ALL_TENANTS_MANAGER_ID);
464         role.setTenantId(AuthN.ALL_TENANTS_MANAGER_TENANT_ID);
465         
466         return role;
467     }
468     
469
470     public void exportDefaultRoles(String fileName) {
471         RolesList rList = new RolesList();
472         rList.setRole(this.getDefaultRoles());
473         //
474         // Since it is missing the @XMLRootElement annotation, create a JAXBElement wrapper for the RoleList instance
475         // so we can have it marshalled it correctly.
476         //
477         org.collectionspace.services.authorization.ObjectFactory objectFactory = new org.collectionspace.services.authorization.ObjectFactory();
478         toFile(objectFactory.createRolesList(rList), RolesList.class,
479                 fileName);
480         if (logger.isDebugEnabled()) {
481             logger.debug("exported roles to " + fileName);
482         }
483     }
484
485     public void exportDefaultPermissions(String fileName) {
486         PermissionsList pcList = new PermissionsList();
487         pcList.setPermission(this.getDefaultPermissions());
488         org.collectionspace.services.authorization.ObjectFactory objectFactory =
489                 new org.collectionspace.services.authorization.ObjectFactory();
490         toFile(pcList, PermissionsList.class,
491 //        toFile(objectFactory.createPermissionsList(pcList), PermissionsList.class,
492                 fileName);
493         if (logger.isDebugEnabled()) {
494             logger.debug("exported permissions to " + fileName);
495         }
496     }
497
498     public void exportDefaultPermissionRoles(String fileName) {
499         PermissionsRolesList psrsl = new PermissionsRolesList();
500         psrsl.setPermissionRole(this.getDefaultAdminPermissionRoles());
501         toFile(psrsl, PermissionsRolesList.class,
502                 fileName);
503         if (logger.isDebugEnabled()) {
504             logger.debug("exported permissions-roles to " + fileName);
505         }
506     }
507
508     private void toFile(Object o, Class jaxbClass, String fileName) {
509         File f = new File(fileName);
510         try {
511             JAXBContext jc = JAXBContext.newInstance(jaxbClass);
512             Marshaller m = jc.createMarshaller();
513             m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
514                     Boolean.TRUE);
515             m.marshal(o, f);
516         } catch (Exception e) {
517             e.printStackTrace();
518         }
519     }
520 }