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