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 org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.collectionspace.services.authorization.CSpaceAction;
30 import org.collectionspace.services.authorization.spi.CSpacePermissionManager;
31 import org.collectionspace.services.authorization.CSpaceResource;
32 import org.collectionspace.services.authorization.PermissionException;
33 import org.collectionspace.services.authorization.PermissionNotFoundException;
34 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
35 import org.springframework.security.acls.model.AccessControlEntry;
36 import org.springframework.security.acls.model.MutableAcl;
37 import org.springframework.security.acls.model.NotFoundException;
38 import org.springframework.security.acls.model.ObjectIdentity;
39 import org.springframework.security.acls.model.Permission;
40 import org.springframework.security.acls.model.Sid;
41 import org.springframework.transaction.TransactionDefinition;
42 import org.springframework.transaction.TransactionStatus;
43 import org.springframework.transaction.support.DefaultTransactionDefinition;
46 * Manages permissions in Spring Security
49 public class SpringPermissionManager implements CSpacePermissionManager {
51 final Log log = LogFactory.getLog(SpringPermissionEvaluator.class);
52 private SpringAuthorizationProvider provider;
54 SpringPermissionManager(SpringAuthorizationProvider provider) {
55 this.provider = provider;
59 public void addPermissions(CSpaceResource res, CSpaceAction action, String[] principals)
60 throws PermissionException {
61 ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
62 Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals);
63 Permission p = SpringAuthorizationProvider.mapPermssion(action);
64 TransactionStatus status = provider.beginTransaction("addPermssions");
66 for (Sid sid : sids) {
67 addPermission(oid, p, sid);
68 if (log.isDebugEnabled()) {
69 log.debug("added permission "
70 + " res=" + res.toString()
71 + " action=" + action.toString()
72 + " oid=" + oid.toString()
73 + " perm=" + p.toString()
74 + " sid=" + sids.toString());
77 } catch (Exception ex) {
78 provider.rollbackTransaction(status);
79 if (log.isDebugEnabled()) {
82 throw new PermissionException(ex);
84 provider.commitTransaction(status);
89 public void deletePermissions(CSpaceResource res, CSpaceAction action, String[] principals)
90 throws PermissionNotFoundException, PermissionException {
91 ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
92 Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals);
93 Permission p = SpringAuthorizationProvider.mapPermssion(action);
94 TransactionStatus status = provider.beginTransaction("deletePermssions");
96 for (Sid sid : sids) {
97 deletePermissions(oid, p, sid);
98 if (log.isDebugEnabled()) {
99 log.debug("deleted permission "
100 + " res=" + res.toString()
101 + " action=" + action.toString()
102 + " oid=" + oid.toString()
103 + " perm=" + p.toString()
104 + " sid=" + sids.toString());
107 } catch (Exception ex) {
108 provider.rollbackTransaction(status);
109 if (log.isDebugEnabled()) {
110 ex.printStackTrace();
112 throw new PermissionException(ex);
114 provider.commitTransaction(status);
119 public void deletePermissions(CSpaceResource res, CSpaceAction action)
120 throws PermissionNotFoundException, PermissionException {
121 ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
122 Permission p = SpringAuthorizationProvider.mapPermssion(action);
123 TransactionStatus status = provider.beginTransaction("deletePermssions");
125 deletePermissions(oid, p, null);
126 if (log.isDebugEnabled()) {
127 log.debug("deleted permissions "
128 + " res=" + res.toString()
129 + " action=" + action.toString()
130 + " oid=" + oid.toString()
131 + " perm=" + p.toString());
133 } catch (Exception ex) {
134 provider.rollbackTransaction(status);
135 if (log.isDebugEnabled()) {
136 ex.printStackTrace();
138 throw new PermissionException(ex);
140 provider.commitTransaction(status);
146 public void deletePermissions(CSpaceResource res)
147 throws PermissionNotFoundException, PermissionException {
148 ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
149 TransactionStatus status = provider.beginTransaction("addPermssion");
151 provider.getProviderAclService().deleteAcl(oid, true);
152 } catch (Exception ex) {
153 provider.rollbackTransaction(status);
154 if (log.isDebugEnabled()) {
155 ex.printStackTrace();
157 throw new PermissionException(ex);
159 provider.commitTransaction(status);
161 if (log.isDebugEnabled()) {
162 log.debug("deleted permissions "
163 + " res=" + res.toString()
164 + " oid=" + oid.toString());
168 private void addPermission(ObjectIdentity oid, Permission permission,
169 Sid recipient) throws PermissionException {
174 } catch (PermissionException pnfe) {
175 acl = provider.getProviderAclService().createAcl(oid);
177 acl.insertAce(acl.getEntries().size(), permission, recipient, true);
178 provider.getProviderAclService().updateAcl(acl);
180 if (log.isDebugEnabled()) {
181 log.debug("addPermission: added acl for oid=" + oid.toString()
182 + " perm=" + permission.toString()
183 + " sid=" + recipient.toString());
187 private void deletePermissions(ObjectIdentity oid, Permission permission, Sid recipient)
188 throws PermissionException {
191 MutableAcl acl = getAcl(oid);
192 List<AccessControlEntry> entries = acl.getEntries();
193 if (log.isDebugEnabled()) {
194 log.debug("deletePermissions: for acl oid=" + oid.toString()
195 + " found " + entries.size() + " aces");
198 for (int i = 0; i < entries.size(); i++) {
199 AccessControlEntry ace = entries.get(i);
200 if (recipient != null) {
201 if (ace.getSid().equals(recipient)
202 && ace.getPermission().equals(permission)) {
207 if (ace.getPermission().equals(permission)) {
213 provider.getProviderAclService().updateAcl(acl);
215 if (log.isDebugEnabled()) {
216 log.debug("deletePermissions: for acl oid=" + oid.toString()
217 + " deleted " + j + " aces");
221 private MutableAcl getAcl(ObjectIdentity oid) throws PermissionNotFoundException {
222 MutableAcl acl = null;
224 acl = (MutableAcl) provider.getProviderAclService().readAclById(oid);
225 if (log.isDebugEnabled()) {
226 log.debug("found acl for oid=" + oid.toString());
228 } catch (NotFoundException nfe) {
229 String msg = "Cound not find acl for oid=" + oid.toString();
231 throw new PermissionNotFoundException(msg);