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