]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
ffaa8f7d5e63a9ad48149bd991c4889abf7d8e36
[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.Date;
31 import java.util.Hashtable;
32 import java.util.List;
33 import java.util.UUID;
34 import javax.xml.bind.JAXBContext;
35 import javax.xml.bind.Marshaller;
36 import org.collectionspace.services.authorization.perms.ActionType;
37 import org.collectionspace.services.authorization.perms.Permission;
38 import org.collectionspace.services.authorization.perms.EffectType;
39 import org.collectionspace.services.authorization.perms.PermissionAction;
40 import org.collectionspace.services.authorization.PermissionActionUtil;
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 import org.collectionspace.services.client.RoleClient;
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 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
51 import org.collectionspace.services.common.service.ServiceBindingType;
52 import org.collectionspace.services.common.tenant.TenantBindingType;
53 import org.collectionspace.services.common.security.SecurityUtils;
54
55 /**
56  * AuthorizationGen generates authorizations (permissions and roles)
57  * for tenant services
58  * @author 
59  */
60 public class AuthorizationGen {
61
62         final public static String ROLE_PREFIX = "ROLE_";
63     final public static String ROLE_ADMINISTRATOR = "ADMINISTRATOR";
64     final public static String ROLE_TENANT_ADMINISTRATOR = "TENANT_ADMINISTRATOR";
65     final public static String ROLE_TENANT_READER = "TENANT_READER";
66     final public static String ROLE_ADMINISTRATOR_ID = "0";
67     final public static String ADMINISTRATOR_TENANT_ID = "0";
68     //
69     // ActionGroup labels/constants
70     //
71     final public static String ACTIONGROUP_CRUDL = "CRUDL";
72     final public static String ACTIONGROUP_RL = "RL";
73     //
74     // Should the base resource act as a proxy for its sub-resources for AuthZ purposes
75     //
76     final public static boolean AUTHZ_IS_ENTITY_PROXY = false;
77     
78     final Logger logger = LoggerFactory.getLogger(AuthorizationGen.class);
79     private List<Permission> adminPermList = new ArrayList<Permission>();
80     private List<PermissionRole> adminPermRoleList = new ArrayList<PermissionRole>();
81     private List<Permission> readerPermList = new ArrayList<Permission>();
82     private List<PermissionRole> readerPermRoleList = new ArrayList<PermissionRole>();
83     private List<Role> adminRoles = new ArrayList<Role>();
84     private List<Role> readerRoles = new ArrayList<Role>();
85     private Role cspaceAdminRole;
86     private Hashtable<String, TenantBindingType> tenantBindings =
87             new Hashtable<String, TenantBindingType>();
88
89     public void initialize(String tenantRootDirPath) throws Exception {
90         TenantBindingConfigReaderImpl tenantBindingConfigReader =
91                 new TenantBindingConfigReaderImpl(tenantRootDirPath);
92         tenantBindingConfigReader.read();
93         tenantBindings = tenantBindingConfigReader.getTenantBindings();
94         cspaceAdminRole = buildCSpaceAdminRole();
95
96         if (logger.isDebugEnabled()) {
97             logger.debug("initialized with tenant bindings from " + tenantRootDirPath);
98         }
99     }
100
101     /**
102      * createDefaultPermissions creates default admin and reader permissions
103      * for each tenant found in the given tenant binding file
104      * @see initialize
105      * @return
106      */
107     public void createDefaultPermissions() {
108         for (String tenantId : tenantBindings.keySet()) {
109             List<Permission> adminPerms = createDefaultAdminPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
110             adminPermList.addAll(adminPerms);
111
112             List<Permission> readerPerms = createDefaultReaderPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
113             readerPermList.addAll(readerPerms);
114         }
115     }
116
117     /**
118      * createDefaultAdminPermissions creates default admin permissions for all services
119      * used by the given tenant
120      * @param tenantId
121      * @return
122      */
123     public List<Permission> createDefaultAdminPermissions(String tenantId, boolean isEntityProxy) {
124         ArrayList<Permission> apcList = new ArrayList<Permission>();
125         TenantBindingType tbinding = tenantBindings.get(tenantId);
126         for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
127
128             //add permissions for the main path
129                 String resourceName = sbinding.getName().toLowerCase().trim();
130                 if (isEntityProxy == true) {
131                         resourceName = SecurityUtils.getResourceEntity(resourceName);
132                 }
133             Permission perm = buildAdminPermission(tbinding.getId(),
134                     resourceName);
135             apcList.add(perm);
136
137             //add permissions for alternate paths
138             if (isEntityProxy == false) {
139                     List<String> uriPaths = sbinding.getUriPath();
140                     for (String uriPath : uriPaths) {
141                         perm = buildAdminPermission(tbinding.getId(),
142                                 uriPath.toLowerCase());
143                         apcList.add(perm);
144                     }
145             }
146         }
147         
148         return apcList;
149     }
150
151     private Permission buildAdminPermission(String tenantId, String resourceName) {
152         String id = UUID.randomUUID().toString();
153         Permission perm = new Permission();
154         perm.setCsid(id);
155         perm.setDescription("generated admin permission");
156         perm.setCreatedAtItem(new Date());
157         perm.setResourceName(resourceName.toLowerCase().trim());
158         perm.setEffect(EffectType.PERMIT);
159         perm.setTenantId(tenantId);
160         
161         perm.setActionGroup(ACTIONGROUP_CRUDL);
162         ArrayList<PermissionAction> pas = new ArrayList<PermissionAction>();
163         perm.setAction(pas);
164
165         PermissionAction permAction = PermissionActionUtil.create(perm, ActionType.CREATE);
166         pas.add(permAction);
167         
168         permAction = PermissionActionUtil.create(perm, ActionType.READ);
169         pas.add(permAction);
170         
171         permAction = PermissionActionUtil.create(perm, ActionType.UPDATE);
172         pas.add(permAction);
173         
174         permAction = PermissionActionUtil.create(perm, ActionType.DELETE);
175         pas.add(permAction);
176         
177         permAction = PermissionActionUtil.create(perm, ActionType.SEARCH);
178         pas.add(permAction);
179         
180         return perm;
181     }
182
183     /**
184      * createDefaultReaderPermissions creates read only permissions for all services
185      * used by the given tenant
186      * @param tenantId
187      * @return
188      */
189     public List<Permission> createDefaultReaderPermissions(String tenantId, boolean isEntityProxy) {
190         ArrayList<Permission> apcList = new ArrayList<Permission>();
191         TenantBindingType tbinding = tenantBindings.get(tenantId);
192         for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
193             //add permissions for the main path
194                 String resourceName = sbinding.getName().toLowerCase().trim();
195                 if (isEntityProxy == true) {
196                         resourceName = SecurityUtils.getResourceEntity(resourceName);
197                 }               
198             Permission perm = buildReaderPermission(tbinding.getId(),
199                     resourceName);
200             apcList.add(perm);
201
202             //add permissions for alternate paths
203             if (isEntityProxy == false) {
204                     List<String> uriPaths = sbinding.getUriPath();
205                     for (String uriPath : uriPaths) {
206                         perm = buildReaderPermission(tbinding.getId(),
207                                 uriPath.toLowerCase());
208                         apcList.add(perm);
209                     }
210             }
211         }
212         return apcList;
213
214     }
215
216     private Permission buildReaderPermission(String tenantId, String resourceName) {
217         String id = UUID.randomUUID().toString();
218         Permission perm = new Permission();
219         perm.setCsid(id);
220         perm.setCreatedAtItem(new Date());
221         perm.setDescription("generated readonly permission");
222         perm.setResourceName(resourceName.toLowerCase().trim());
223         perm.setEffect(EffectType.PERMIT);
224         perm.setTenantId(tenantId);
225         
226         perm.setActionGroup(ACTIONGROUP_RL);
227         ArrayList<PermissionAction> pas = new ArrayList<PermissionAction>();
228         perm.setAction(pas);
229
230         PermissionAction permAction = PermissionActionUtil.create(perm, ActionType.READ);
231         pas.add(permAction);
232
233         permAction = PermissionActionUtil.create(perm, ActionType.SEARCH);
234         pas.add(permAction);
235
236         return perm;
237     }
238
239     public List<Permission> getDefaultPermissions() {
240         List<Permission> allPermList = new ArrayList<Permission>();
241         allPermList.addAll(adminPermList);
242         allPermList.addAll(readerPermList);
243         return allPermList;
244     }
245
246     public List<Permission> getDefaultAdminPermissions() {
247         return adminPermList;
248     }
249
250     public List<Permission> getDefaultReaderPermissions() {
251         return readerPermList;
252     }
253
254     /**
255      * createDefaultRoles creates default admin and reader roles
256      * for each tenant found in the given tenant binding file
257      */
258     public void createDefaultRoles() {
259         for (String tenantId : tenantBindings.keySet()) {
260
261             Role arole = buildTenantAdminRole(tenantId);
262             adminRoles.add(arole);
263
264             Role rrole = buildTenantReaderRole(tenantId);
265             readerRoles.add(rrole);
266         }
267     }
268
269     private Role buildTenantAdminRole(String tenantId) {
270         return buildTenantRole(tenantId, ROLE_TENANT_ADMINISTRATOR, "admin");
271     }
272
273     private Role buildTenantReaderRole(String tenantId) {
274         return buildTenantRole(tenantId, ROLE_TENANT_READER, "read only");
275     }
276
277     private Role buildTenantRole(String tenantId, String name, String type) {
278         Role role = new Role();
279         role.setCreatedAtItem(new Date());
280         role.setDisplayName(name);
281         role.setRoleName(ROLE_PREFIX +
282                         tenantId + "_" +
283                         role.getDisplayName());
284         String id = UUID.randomUUID().toString();
285         role.setCsid(id);
286         role.setDescription("generated tenant "+type+" role");
287         role.setTenantId(tenantId);
288         role.setMetadataProtection(RoleClient.IMMUTABLE);
289         role.setPermsProtection(RoleClient.IMMUTABLE);
290         return role;
291     }
292
293     public List<Role> getDefaultRoles() {
294         List<Role> allRoleList = new ArrayList<Role>();
295         allRoleList.addAll(adminRoles);
296         allRoleList.addAll(readerRoles);
297         return allRoleList;
298     }
299
300     public void associateDefaultPermissionsRoles() {
301         for (Permission p : adminPermList) {
302             PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles, true);
303             adminPermRoleList.add(permAdmRole);
304         }
305
306         for (Permission p : readerPermList) {
307             PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles, true);
308             readerPermRoleList.add(permRdrRole);
309         }
310         
311         //CSpace Administrator has all access
312         List<Role> roles = new ArrayList<Role>();
313         roles.add(cspaceAdminRole);
314         for (Permission p : adminPermList) {
315             PermissionRole permCAdmRole = associatePermissionRoles(p, roles, false);
316             adminPermRoleList.add(permCAdmRole);
317         }        
318     }
319
320     public List<PermissionRole> associatePermissionsRoles(List<Permission> perms, List<Role> roles, boolean enforceTenancy) {
321         List<PermissionRole> result = null;
322         
323         List<PermissionRole> permRoles = new ArrayList<PermissionRole>();
324         for (Permission perm : perms) {
325             PermissionRole permRole = associatePermissionRoles(perm, roles, enforceTenancy);
326             if (permRole != null) {
327                 permRoles.add(permRole);
328             }
329         }
330         
331         if (permRoles.isEmpty() == false) {
332                 result = permRoles;
333         }
334         
335         return result;
336     }
337
338     private PermissionRole associatePermissionRoles(Permission perm,
339             List<Role> roles, boolean enforceTenancy) {
340         PermissionRole result = null;
341         
342         PermissionRole pr = new PermissionRole();
343         pr.setSubject(SubjectType.ROLE);
344         List<PermissionValue> permValues = new ArrayList<PermissionValue>();
345         pr.setPermission(permValues);
346         PermissionValue permValue = new PermissionValue();
347         permValue.setPermissionId(perm.getCsid());
348         permValue.setResourceName(perm.getResourceName().toLowerCase());
349         permValue.setActionGroup(perm.getActionGroup());
350         permValues.add(permValue);
351
352         List<RoleValue> roleValues = new ArrayList<RoleValue>();
353         for (Role role : roles) {
354                 boolean tenantIdsMatched = true;
355                 if (enforceTenancy == true) {
356                         tenantIdsMatched = role.getTenantId().equals(perm.getTenantId());
357                 }
358                 if (tenantIdsMatched == true) {
359                     RoleValue rv = new RoleValue();
360                     // This needs to use the qualified name, not the display name
361                     rv.setRoleName(role.getRoleName().toUpperCase());
362                     rv.setRoleId(role.getCsid());
363                     roleValues.add(rv);
364                 } else {
365                         if (logger.isTraceEnabled() == true) {
366                                 logger.trace("Role and Permission tenant ID did not match."); //FIXME: REM - Remove this debug statement.
367                         }
368                 }
369         }
370         //
371         // If 'roleValues' is not empty, then associate it with the incoming 'perm' values
372         // otherwise, return null;
373         //
374         if (roleValues.isEmpty() == false) {
375                 pr.setRole(roleValues);
376                 result = pr;
377         }
378
379         return result;
380     }
381
382     public List<PermissionRole> getDefaultPermissionRoles() {
383         List<PermissionRole> allPermRoleList = new ArrayList<PermissionRole>();
384         allPermRoleList.addAll(adminPermRoleList);
385         allPermRoleList.addAll(readerPermRoleList);
386         return allPermRoleList;
387     }
388
389     public List<PermissionRole> getDefaultAdminPermissionRoles() {
390         return adminPermRoleList;
391     }
392
393     public List<PermissionRole> getDefaultReaderPermissionRoles() {
394         return readerPermRoleList;
395     }
396
397     private Role buildCSpaceAdminRole() {
398         Role role = new Role();
399         role.setDisplayName(ROLE_ADMINISTRATOR);
400         role.setRoleName(ROLE_PREFIX + role.getDisplayName());
401         role.setCsid(ROLE_ADMINISTRATOR_ID);
402         role.setTenantId(ADMINISTRATOR_TENANT_ID);
403         return role;
404     }
405
406     public void exportDefaultRoles(String fileName) {
407         RolesList rList = new RolesList();
408         List<Role> allRoleList = new ArrayList<Role>();
409         allRoleList.addAll(adminRoles);
410         allRoleList.addAll(readerRoles);
411         rList.setRole(allRoleList);
412         //
413         // Since it is missing the @XMLRootElement annotation, create a JAXBElement wrapper for the RoleList instance
414         // so we can have it marshalled it correctly.
415         //
416         org.collectionspace.services.authorization.ObjectFactory objectFactory = new org.collectionspace.services.authorization.ObjectFactory();
417         toFile(objectFactory.createRolesList(rList), RolesList.class,
418                 fileName);
419         if (logger.isDebugEnabled()) {
420             logger.debug("exported roles to " + fileName);
421         }
422     }
423
424     public void exportDefaultPermissions(String fileName) {
425         PermissionsList pcList = new PermissionsList();
426         List<Permission> allPermList = new ArrayList<Permission>();
427         allPermList.addAll(adminPermList);
428         allPermList.addAll(readerPermList);
429         pcList.setPermission(allPermList);
430         org.collectionspace.services.authorization.ObjectFactory objectFactory =
431                 new org.collectionspace.services.authorization.ObjectFactory();
432         toFile(pcList, PermissionsList.class,
433 //        toFile(objectFactory.createPermissionsList(pcList), PermissionsList.class,
434                 fileName);
435         if (logger.isDebugEnabled()) {
436             logger.debug("exported permissions to " + fileName);
437         }
438     }
439
440     public void exportDefaultPermissionRoles(String fileName) {
441         PermissionsRolesList psrsl = new PermissionsRolesList();
442         List<PermissionRole> allPermRoleList = new ArrayList<PermissionRole>();
443         allPermRoleList.addAll(adminPermRoleList);
444         allPermRoleList.addAll(readerPermRoleList);
445         psrsl.setPermissionRole(allPermRoleList);
446         toFile(psrsl, PermissionsRolesList.class,
447                 fileName);
448         if (logger.isDebugEnabled()) {
449             logger.debug("exported permissions-roles to " + fileName);
450         }
451     }
452
453     private void toFile(Object o, Class jaxbClass, String fileName) {
454         File f = new File(fileName);
455         try {
456             JAXBContext jc = JAXBContext.newInstance(jaxbClass);
457             Marshaller m = jc.createMarshaller();
458             m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
459                     Boolean.TRUE);
460             m.marshal(o, f);
461         } catch (Exception e) {
462             e.printStackTrace();
463         }
464     }
465 }