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