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