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