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:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
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.
24 package org.collectionspace.services.authorization.importer;
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.client.TenantClient;
47 import org.collectionspace.services.authorization.Role;
48 import org.collectionspace.services.authorization.RoleValue;
49 import org.collectionspace.services.authorization.RolesList;
50 import org.collectionspace.services.authorization.SubjectType;
51 import org.collectionspace.services.common.authorization_mgt.AuthorizationCommon;
52 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
53 import org.collectionspace.services.common.security.SecurityUtils;
54 import org.collectionspace.services.config.service.ServiceBindingType;
55 import org.collectionspace.services.config.tenant.TenantBindingType;
58 * AuthorizationGen generates authorizations (permissions and roles)
62 public class AuthorizationGen {
65 // Should the base resource act as a proxy for its sub-resources for AuthZ purposes
67 final public static boolean AUTHZ_IS_ENTITY_PROXY = false;
69 final public static String TENANT_MGMNT_ID = "0";
71 final Logger logger = LoggerFactory.getLogger(AuthorizationGen.class);
72 private List<Permission> tenantMgmntPermList = new ArrayList<Permission>();
73 private List<PermissionRole> tenantMgmntPermRoleList = new ArrayList<PermissionRole>();
74 private List<Permission> adminPermList = new ArrayList<Permission>();
75 private List<PermissionRole> adminPermRoleList = new ArrayList<PermissionRole>();
76 private List<Permission> readerPermList = new ArrayList<Permission>();
77 private List<PermissionRole> readerPermRoleList = new ArrayList<PermissionRole>();
78 private List<Role> adminRoles = new ArrayList<Role>();
79 private List<Role> readerRoles = new ArrayList<Role>();
80 private Role cspaceTenantMgmntRole;
81 private Hashtable<String, TenantBindingType> tenantBindings =
82 new Hashtable<String, TenantBindingType>();
84 // Store the list of default roles, perms, and roleperms
86 private List<PermissionRole> allPermRoleList = null;
87 private List<Permission> allPermList;
88 private List<Role> allRoleList;
90 public void initialize(String tenantRootDirPath) throws Exception {
91 TenantBindingConfigReaderImpl tenantBindingConfigReader =
92 new TenantBindingConfigReaderImpl(tenantRootDirPath);
93 tenantBindingConfigReader.read();
94 tenantBindings = tenantBindingConfigReader.getTenantBindings();
95 cspaceTenantMgmntRole = buildTenantMgmntRole();
97 if (logger.isDebugEnabled()) {
98 logger.debug("initialized with tenant bindings from " + tenantRootDirPath);
103 * createDefaultPermissions creates default admin and reader permissions
104 * for each tenant found in the given tenant binding file
108 public void createDefaultPermissions() {
109 for (String tenantId : tenantBindings.keySet()) {
110 List<Permission> adminPerms = createDefaultAdminPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
111 adminPermList.addAll(adminPerms);
113 List<Permission> readerPerms = createDefaultReaderPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
114 readerPermList.addAll(readerPerms);
117 List<Permission> tenantMgmntPerms = createDefaultTenantMgmntPermissions();
118 tenantMgmntPermList.addAll(tenantMgmntPerms);
122 * createDefaultAdminPermissions creates default admin permissions for all services
123 * used by the given tenant
127 public List<Permission> createDefaultAdminPermissions(String tenantId, boolean isEntityProxy) {
128 ArrayList<Permission> apcList = new ArrayList<Permission>();
129 TenantBindingType tbinding = tenantBindings.get(tenantId);
130 for (ServiceBindingType sbinding : tbinding.getServiceBindings()) {
132 //add permissions for the main path
133 String resourceName = sbinding.getName().toLowerCase().trim();
134 if (isEntityProxy == true) {
135 resourceName = SecurityUtils.getResourceEntity(resourceName);
137 Permission perm = buildAdminPermission(tbinding.getId(),
141 //add permissions for alternate paths
142 if (isEntityProxy == false) {
143 List<String> uriPaths = sbinding.getUriPath();
144 for (String uriPath : uriPaths) {
145 perm = buildAdminPermission(tbinding.getId(),
146 uriPath.toLowerCase());
156 * createDefaultTenantMgmntPermissions creates default permissions for known
157 * Tenant Mgmnt services.
160 public List<Permission> createDefaultTenantMgmntPermissions() {
161 ArrayList<Permission> apcList = new ArrayList<Permission>();
162 // Later can think about ways to configure this if we want to
163 Permission perm = createTenantMgmntPermission(TenantClient.SERVICE_NAME);
170 * createTenantMgmntPermission creates special admin permissions for tenant management
173 private Permission createTenantMgmntPermission(String resourceName) {
174 Permission perm = buildAdminPermission(TENANT_MGMNT_ID, resourceName);
178 private Permission buildAdminPermission(String tenantId, String resourceName) {
179 String description = "Generated admin permission.";
180 return AuthorizationCommon.createPermission(tenantId, resourceName, description, AuthorizationCommon.ACTIONGROUP_CRUDL_NAME);
184 * createDefaultReaderPermissions creates read only permissions for all services
185 * used by the given tenant
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);
198 Permission perm = buildReaderPermission(tbinding.getId(),
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());
216 private Permission buildReaderPermission(String tenantId, String resourceName) {
217 String description = "Generated read-only permission.";
218 return AuthorizationCommon.createPermission(tenantId, resourceName, description, AuthorizationCommon.ACTIONGROUP_RL_NAME);
221 public List<Permission> getDefaultPermissions() {
222 if (allPermList == null) {
223 allPermList = new ArrayList<Permission>();
224 allPermList.addAll(adminPermList);
225 allPermList.addAll(readerPermList);
226 allPermList.addAll(tenantMgmntPermList);
231 public List<Permission> getDefaultAdminPermissions() {
232 return adminPermList;
235 public List<Permission> getDefaultReaderPermissions() {
236 return readerPermList;
239 public List<Permission> getDefaultTenantMgmntPermissions() {
240 return tenantMgmntPermList;
244 * createDefaultRoles creates default admin and reader roles
245 * for each tenant found in the given tenant binding file
247 public void createDefaultRoles() {
248 for (String tenantId : tenantBindings.keySet()) {
250 Role arole = buildTenantAdminRole(tenantId);
251 adminRoles.add(arole);
253 Role rrole = buildTenantReaderRole(tenantId);
254 readerRoles.add(rrole);
258 private Role buildTenantAdminRole(String tenantId) {
259 String type = "admin";
260 Role result = AuthorizationCommon.getRole(tenantId, AuthorizationCommon.ROLE_TENANT_ADMINISTRATOR);
262 if (result == null) {
263 // the role doesn't exist already, so we need to create it
264 String description = "Generated tenant " + type + " role.";
265 result = AuthorizationCommon.createRole(tenantId, AuthorizationCommon.ROLE_TENANT_ADMINISTRATOR, description, true /*immutable*/);
271 private Role buildTenantReaderRole(String tenantId) {
272 String type = "read only";
273 Role result = AuthorizationCommon.getRole(tenantId, AuthorizationCommon.ROLE_TENANT_READER);
275 if (result == null) {
276 // the role doesn't exist already, so we need to create it
277 String description = "Generated tenant " + type + " role.";
278 result = AuthorizationCommon.createRole(tenantId, AuthorizationCommon.ROLE_TENANT_READER, description, true /*immutable*/);
285 public List<Role> getDefaultRoles() {
286 if (allRoleList == null) {
287 allRoleList = new ArrayList<Role>();
288 allRoleList.addAll(adminRoles);
289 allRoleList.addAll(readerRoles);
290 // Finally, add the tenant manager role to the list
291 allRoleList.add(cspaceTenantMgmntRole);
296 public void associateDefaultPermissionsRoles() {
297 for (Permission p : adminPermList) {
298 PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles, true);
299 adminPermRoleList.add(permAdmRole);
302 for (Permission p : readerPermList) {
303 PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles, true);
304 readerPermRoleList.add(permRdrRole);
307 //CSpace Tenant Manager has all access
308 // PLS - this looks wrong. This should be a tenantMgmnt role, and only have access to
309 // tenantMgmnt perms. Will leave this for now...
310 List<Role> roles = new ArrayList<Role>();
311 roles.add(cspaceTenantMgmntRole);
312 /* for (Permission p : adminPermList) {
313 PermissionRole permCAdmRole = associatePermissionRoles(p, roles, false);
314 adminPermRoleList.add(permCAdmRole);
316 // Now associate the tenant management perms to the role
317 for (Permission p : tenantMgmntPermList) {
318 // Note we enforce tenant, as should all be tenant 0 (the special one)
319 PermissionRole permTMRole = associatePermissionRoles(p, roles, true);
320 tenantMgmntPermRoleList.add(permTMRole);
324 public List<PermissionRole> associatePermissionsRoles(List<Permission> perms, List<Role> roles, boolean enforceTenancy) {
325 List<PermissionRole> result = null;
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);
335 if (permRoles.isEmpty() == false) {
342 private PermissionRole associatePermissionRoles(Permission perm,
343 List<Role> roles, boolean enforceTenancy) {
344 PermissionRole result = null;
346 PermissionRole pr = new PermissionRole();
347 pr.setSubject(SubjectType.ROLE);
348 List<PermissionValue> permValues = new ArrayList<PermissionValue>();
349 pr.setPermission(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);
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());
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());
369 if (logger.isTraceEnabled() == true) {
370 logger.trace("Role and Permission tenant ID did not match."); //FIXME: REM - Remove this debug statement.
375 // If 'roleValues' is not empty, then associate it with the incoming 'perm' values
376 // otherwise, return null;
378 if (roleValues.isEmpty() == false) {
379 pr.setRole(roleValues);
386 public List<PermissionRole> getDefaultPermissionRoles() {
387 if (allPermRoleList == null) {
388 allPermRoleList = new ArrayList<PermissionRole>();
389 allPermRoleList.addAll(adminPermRoleList);
390 allPermRoleList.addAll(readerPermRoleList);
391 allPermRoleList.addAll(tenantMgmntPermRoleList);
393 return allPermRoleList;
396 public List<PermissionRole> getDefaultAdminPermissionRoles() {
397 return adminPermRoleList;
400 public List<PermissionRole> getDefaultReaderPermissionRoles() {
401 return readerPermRoleList;
404 private Role buildTenantMgmntRole() {
405 Role role = new Role();
407 role.setDescription("A generated super role that has permissions to manage tenants.");
408 role.setDisplayName(AuthorizationCommon.ROLE_ALL_TENANTS_MANAGER);
409 role.setRoleName(AuthorizationCommon.getQualifiedRoleName(
410 AuthorizationCommon.ALL_TENANTS_MANAGER_TENANT_ID, role.getDisplayName()));
411 role.setCsid(AuthorizationCommon.ROLE_ALL_TENANTS_MANAGER_ID);
412 role.setTenantId(AuthorizationCommon.ALL_TENANTS_MANAGER_TENANT_ID);
418 public void exportDefaultRoles(String fileName) {
419 RolesList rList = new RolesList();
420 rList.setRole(this.getDefaultRoles());
422 // Since it is missing the @XMLRootElement annotation, create a JAXBElement wrapper for the RoleList instance
423 // so we can have it marshalled it correctly.
425 org.collectionspace.services.authorization.ObjectFactory objectFactory = new org.collectionspace.services.authorization.ObjectFactory();
426 toFile(objectFactory.createRolesList(rList), RolesList.class,
428 if (logger.isDebugEnabled()) {
429 logger.debug("exported roles to " + fileName);
433 public void exportDefaultPermissions(String fileName) {
434 PermissionsList pcList = new PermissionsList();
435 pcList.setPermission(this.getDefaultPermissions());
436 org.collectionspace.services.authorization.ObjectFactory objectFactory =
437 new org.collectionspace.services.authorization.ObjectFactory();
438 toFile(pcList, PermissionsList.class,
439 // toFile(objectFactory.createPermissionsList(pcList), PermissionsList.class,
441 if (logger.isDebugEnabled()) {
442 logger.debug("exported permissions to " + fileName);
446 public void exportDefaultPermissionRoles(String fileName) {
447 PermissionsRolesList psrsl = new PermissionsRolesList();
448 psrsl.setPermissionRole(this.getDefaultAdminPermissionRoles());
449 toFile(psrsl, PermissionsRolesList.class,
451 if (logger.isDebugEnabled()) {
452 logger.debug("exported permissions-roles to " + fileName);
456 private void toFile(Object o, Class jaxbClass, String fileName) {
457 File f = new File(fileName);
459 JAXBContext jc = JAXBContext.newInstance(jaxbClass);
460 Marshaller m = jc.createMarshaller();
461 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
464 } catch (Exception e) {