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