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.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;
55 * AuthorizationGen generates authorizations (permissions and roles)
59 public class AuthorizationGen {
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";
68 // ActionGroup labels/constants
70 final public static String ACTIONGROUP_CRUDL = "CRUDL";
71 final public static String ACTIONGROUP_RL = "RL";
73 // Should the base resource act as a proxy for its sub-resources for AuthZ purposes
75 final public static boolean AUTHZ_IS_ENTITY_PROXY = false;
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>();
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();
95 if (logger.isDebugEnabled()) {
96 logger.debug("initialized with tenant bindings from " + tenantRootDirPath);
101 * createDefaultPermissions creates default admin and reader permissions
102 * for each tenant found in the given tenant binding file
106 public void createDefaultPermissions() {
107 for (String tenantId : tenantBindings.keySet()) {
108 List<Permission> adminPerms = createDefaultAdminPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
109 adminPermList.addAll(adminPerms);
111 List<Permission> readerPerms = createDefaultReaderPermissions(tenantId, AUTHZ_IS_ENTITY_PROXY);
112 readerPermList.addAll(readerPerms);
117 * createDefaultAdminPermissions creates default admin permissions for all services
118 * used by the given tenant
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()) {
127 //add permissions for the main path
128 String resourceName = sbinding.getName().toLowerCase().trim();
129 if (isEntityProxy == true) {
130 resourceName = SecurityUtils.getResourceEntity(resourceName);
132 Permission perm = buildAdminPermission(tbinding.getId(),
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());
150 private Permission buildAdminPermission(String tenantId, String resourceName) {
151 String id = UUID.randomUUID().toString();
152 Permission perm = new Permission();
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);
160 perm.setActionGroup(ACTIONGROUP_CRUDL);
161 ArrayList<PermissionAction> pas = new ArrayList<PermissionAction>();
162 perm.setActions(pas);
164 PermissionAction permAction = PermissionActionUtil.create(perm, ActionType.CREATE);
167 permAction = PermissionActionUtil.create(perm, ActionType.READ);
170 permAction = PermissionActionUtil.create(perm, ActionType.UPDATE);
173 permAction = PermissionActionUtil.create(perm, ActionType.DELETE);
176 permAction = PermissionActionUtil.create(perm, ActionType.SEARCH);
183 * createDefaultReaderPermissions creates read only permissions for all services
184 * used by the given tenant
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);
197 Permission perm = buildReaderPermission(tbinding.getId(),
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());
215 private Permission buildReaderPermission(String tenantId, String resourceName) {
216 String id = UUID.randomUUID().toString();
217 Permission perm = new Permission();
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);
225 perm.setActionGroup(ACTIONGROUP_RL);
226 ArrayList<PermissionAction> pas = new ArrayList<PermissionAction>();
227 perm.setActions(pas);
229 PermissionAction permAction = PermissionActionUtil.create(perm, ActionType.READ);
232 permAction = PermissionActionUtil.create(perm, ActionType.SEARCH);
238 public List<Permission> getDefaultPermissions() {
239 List<Permission> allPermList = new ArrayList<Permission>();
240 allPermList.addAll(adminPermList);
241 allPermList.addAll(readerPermList);
245 public List<Permission> getDefaultAdminPermissions() {
246 return adminPermList;
249 public List<Permission> getDefaultReaderPermissions() {
250 return readerPermList;
254 * createDefaultRoles creates default admin and reader roles
255 * for each tenant found in the given tenant binding file
257 public void createDefaultRoles() {
258 for (String tenantId : tenantBindings.keySet()) {
260 Role arole = buildTenantAdminRole(tenantId);
261 adminRoles.add(arole);
263 Role rrole = buildTenantReaderRole(tenantId);
264 readerRoles.add(rrole);
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 +
274 role.getDisplayName());
276 String id = UUID.randomUUID().toString();
278 role.setDescription("generated tenant admin role");
279 role.setTenantId(tenantId);
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 +
289 role.getDisplayName());
290 String id = UUID.randomUUID().toString();
292 role.setDescription("generated tenant read only role");
293 role.setTenantId(tenantId);
297 public List<Role> getDefaultRoles() {
298 List<Role> allRoleList = new ArrayList<Role>();
299 allRoleList.addAll(adminRoles);
300 allRoleList.addAll(readerRoles);
304 public void associateDefaultPermissionsRoles() {
305 for (Permission p : adminPermList) {
306 PermissionRole permAdmRole = associatePermissionRoles(p, adminRoles, true);
307 adminPermRoleList.add(permAdmRole);
310 for (Permission p : readerPermList) {
311 PermissionRole permRdrRole = associatePermissionRoles(p, readerRoles, true);
312 readerPermRoleList.add(permRdrRole);
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);
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.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);
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.setRoles(roleValues);
386 public List<PermissionRole> getDefaultPermissionRoles() {
387 List<PermissionRole> allPermRoleList = new ArrayList<PermissionRole>();
388 allPermRoleList.addAll(adminPermRoleList);
389 allPermRoleList.addAll(readerPermRoleList);
390 return allPermRoleList;
393 public List<PermissionRole> getDefaultAdminPermissionRoles() {
394 return adminPermRoleList;
397 public List<PermissionRole> getDefaultReaderPermissionRoles() {
398 return readerPermRoleList;
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);
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,
418 if (logger.isDebugEnabled()) {
419 logger.debug("exported roles to " + fileName);
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,
431 if (logger.isDebugEnabled()) {
432 logger.debug("exported permissions to " + fileName);
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,
444 if (logger.isDebugEnabled()) {
445 logger.debug("exported permissions-roles to " + fileName);
449 private void toFile(Object o, Class jaxbClass, String fileName) {
450 File f = new File(fileName);
452 JAXBContext jc = JAXBContext.newInstance(jaxbClass);
453 Marshaller m = jc.createMarshaller();
454 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
457 } catch (Exception e) {