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