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.spring;
26 import java.util.List;
27 import java.io.Serializable;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.collectionspace.services.authorization.CSpaceAction;
32 import org.collectionspace.services.authorization.spi.CSpacePermissionEvaluator;
33 import org.collectionspace.services.authorization.CSpaceResource;
34 import org.springframework.security.access.PermissionEvaluator;
35 import org.springframework.security.acls.model.Permission;
36 import org.springframework.security.core.Authentication;
37 import org.springframework.security.core.GrantedAuthority;
38 import org.springframework.security.core.context.SecurityContextHolder;
41 * SpringPermissionEvaluator evaluates permissions in Spring Security
44 public class SpringPermissionEvaluator implements CSpacePermissionEvaluator {
46 final Log log = LogFactory.getLog(SpringPermissionEvaluator.class); //FIXEME: REM - Use SLF4J interfaces instead of directly using Apache Commons Logging.
47 private SpringAuthorizationProvider provider;
49 SpringPermissionEvaluator(SpringAuthorizationProvider provider) {
50 this.provider = provider;
54 public boolean hasPermission(CSpaceResource res, CSpaceAction action) {
55 boolean result = false;
58 Permission perm = SpringAuthorizationProvider.getPermission(action);
59 Authentication authToken = SecurityContextHolder.getContext().getAuthentication();
60 Serializable objectIdId = SpringAuthorizationProvider.getObjectIdentityIdentifier(res);
61 String objectIdType = SpringAuthorizationProvider.getObjectIdentityType(res);
62 PermissionEvaluator eval = provider.getProviderPermissionEvaluator();
64 debug(res, authToken, objectIdId, objectIdType, perm);
65 result = eval.hasPermission(authToken,
66 objectIdId, objectIdType, perm);
67 } catch (Throwable e) {
68 if (exceptionChainContainsNetworkError(e) == true) {
70 // If this exception is caused by a network timeout, we want to re-attempt
74 log.error("Unexpected exception encountered while evaluating permissions.", e);
80 private void debug(CSpaceResource res,
81 Authentication authToken,
82 Serializable objectIdId,
85 if (log.isTraceEnabled() == true) {
86 log.debug(this.getClass().getCanonicalName() + ":" + this);
87 String resourceTarget = "[" + res.getId() + "]" + " | " +
88 "[" + "objectIdId: " + objectIdType + "(" + objectIdId + ")]";
89 System.out.println("PERMISSION CHECK FOR: " + resourceTarget);
90 System.out.println("\tPrincipal: " + authToken.getName() +
91 "\tTenant ID: " + res.getTenantId());
92 System.out.println("\tRoles: " + authToken.getAuthorities());
93 System.out.println("\tPermission Mask: " + perm.getMask() +
94 " - Permission Pattern: " + perm.getPattern());
95 System.out.println("");
99 public static boolean exceptionChainContainsNetworkError(Throwable exceptionChain) {
100 boolean result = false;
101 Throwable cause = exceptionChain;
103 while (cause != null) {
104 if (isCauseNetworkRelated(cause) == true) {
109 cause = cause.getCause();
115 private static boolean isCauseNetworkRelated(Throwable cause) {
116 boolean result = false;
118 String className = cause.getClass().getCanonicalName();
119 if (className.contains("java.net") || className.contains("java.io")) {