]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
8b942352b091d648c9f7835f80a310d6b558c5d7
[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.spring;
25
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
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.CSpacePermissionManager;
33 import org.collectionspace.services.authorization.CSpaceResource;
34 import org.collectionspace.services.authorization.PermissionException;
35 import org.collectionspace.services.authorization.PermissionNotFoundException;
36 import org.springframework.security.acls.model.AccessControlEntry;
37 import org.springframework.security.acls.model.AclDataAccessException;
38 import org.springframework.security.acls.model.AlreadyExistsException;
39 import org.springframework.security.acls.model.MutableAcl;
40 import org.springframework.security.acls.model.NotFoundException;
41 import org.springframework.security.acls.model.ObjectIdentity;
42 import org.springframework.security.acls.model.Permission;
43 import org.springframework.security.acls.model.Sid;
44 import org.springframework.transaction.TransactionStatus;
45
46 /**
47  * Manages permissions in Spring Security
48  * @author 
49  */
50 public class SpringPermissionManager implements CSpacePermissionManager {
51
52     final Log log = LogFactory.getLog(SpringPermissionEvaluator.class);
53     private SpringAuthorizationProvider provider;
54
55     SpringPermissionManager(SpringAuthorizationProvider provider) {
56         this.provider = provider;
57     }
58
59     @Override
60     public void addPermissions(CSpaceResource res, CSpaceAction action, String[] principals)
61             throws PermissionException {
62         ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
63         Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals);
64         Permission p = SpringAuthorizationProvider.mapPermission(action);
65         TransactionStatus status = provider.beginTransaction("addPermssions");
66
67         //add permission for each sid
68         for (Sid sid : sids) {
69             try {
70                 addPermission(oid, p, sid);
71                 if (log.isDebugEnabled()) {
72                     log.debug("addpermissions(res,action,prin[]), success for "
73                             + " res=" + res.toString()
74                             + " action=" + action.toString()
75                             + " oid=" + oid.toString()
76                             + " perm=" + p.toString()
77                             + " sid=" + sid.toString());
78                 }
79
80             } catch (AlreadyExistsException aex) {
81                 if (log.isWarnEnabled()) {
82                     log.warn("addpermissions(res,action,prin[]) failed,"
83                             + " oid=" + oid.toString()
84                             + " res=" + res.toString()
85                             + " action=" + action.toString()
86                             + " oid=" + oid.toString()
87                             + " perm=" + p.toString(), aex);
88                 }
89                 //keep going
90             } catch (Exception ex) {
91                 String msg = "addpermissions(res,action,prin[]) failed,"
92                         + " oid=" + oid.toString()
93                         + " res=" + res.toString()
94                         + " action=" + action.toString()
95                         + " oid=" + oid.toString()
96                         + " perm=" + p.toString();
97                 if (log.isDebugEnabled()) {
98                     log.debug(msg, ex);
99                 }
100                 //don't know what might be wrong...stop
101                 provider.rollbackTransaction(status);
102                 if (ex instanceof PermissionException) {
103                     throw (PermissionException) ex;
104                 }
105                 throw new PermissionException(msg, ex);
106             }
107         }//rof
108         provider.commitTransaction(status);
109         if (log.isDebugEnabled()) {
110             log.debug("addpermissions(res,action,prin[]), success for "
111                     + " res=" + res.toString()
112                     + " action=" + action.toString()
113                     + " oid=" + oid.toString()
114                     + " perm=" + p.toString()
115                     + " sids=" + sids.toString());
116         }
117     }
118
119     @Override
120     public void deletePermissions(CSpaceResource res, CSpaceAction action, String[] principals)
121             throws PermissionNotFoundException, PermissionException {
122         ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
123         Sid[] sids = SpringAuthorizationProvider.mapPrincipal(principals);
124         Permission p = SpringAuthorizationProvider.mapPermission(action);
125         TransactionStatus status = provider.beginTransaction("deletePermssions");
126         //delete permission for each sid
127         for (Sid sid : sids) {
128             try {
129                 deletePermissions(oid, p, sid);
130                 if (log.isDebugEnabled()) {
131                     log.debug("deletedpermissions(res,action,prin[]), success for "
132                             + " res=" + res.toString()
133                             + " action=" + action.toString()
134                             + " oid=" + oid.toString()
135                             + " perm=" + p.toString()
136                             + " sid=" + sid.toString());
137                 }
138             } catch (AclDataAccessException aex) {
139                 if (log.isWarnEnabled()) {
140                     log.debug("deletepermissions(res,action,prin[]) failed, "
141                             + " oid=" + oid.toString()
142                             + " res=" + res.toString()
143                             + " action=" + action.toString()
144                             + " oid=" + oid.toString()
145                             + " perm=" + p.toString(), aex);
146                 }
147                 //keep going
148             } catch (Exception ex) {
149                 String msg = "deletepermissions(res,action,prin[]) failed,"
150                         + " oid=" + oid.toString()
151                         + " res=" + res.toString()
152                         + " action=" + action.toString()
153                         + " oid=" + oid.toString()
154                         + " perm=" + p.toString();
155                 if (log.isDebugEnabled()) {
156                     log.debug(msg, ex);
157                 }
158                 //don't know what might be wrong...stop
159                 provider.rollbackTransaction(status);
160                 if (ex instanceof PermissionException) {
161                     throw (PermissionException) ex;
162                 }
163                 throw new PermissionException(msg, ex);
164             }
165         }
166         provider.commitTransaction(status);
167         if (log.isDebugEnabled()) {
168             log.debug("deletedpermissions(res,action,prin[]), success for "
169                     + " res=" + res.toString()
170                     + " action=" + action.toString()
171                     + " oid=" + oid.toString()
172                     + " perm=" + p.toString()
173                     + " sids=" + sids.toString());
174         }
175     }
176
177     @Override
178     public void deletePermissions(CSpaceResource res, CSpaceAction action)
179             throws PermissionNotFoundException, PermissionException {
180         ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
181         Permission p = SpringAuthorizationProvider.mapPermission(action);
182         TransactionStatus status = provider.beginTransaction("deletePermssions");
183         try {
184             deletePermissions(oid, p, null);
185         } catch (AclDataAccessException aex) {
186             provider.rollbackTransaction(status);
187             log.debug("deletepermissions(res,action) failed,"
188                     + " oid=" + oid.toString()
189                     + " res=" + res.toString()
190                     + " action=" + action.toString()
191                     + " oid=" + oid.toString()
192                     + " perm=" + p.toString(), aex);
193             throw new PermissionException(aex);
194         } catch (Exception ex) {
195             provider.rollbackTransaction(status);
196             String msg = "deletepermissions(res,action,prin[]) failed,"
197                     + " oid=" + oid.toString()
198                     + " res=" + res.toString()
199                     + " action=" + action.toString()
200                     + " oid=" + oid.toString()
201                     + " perm=" + p.toString();
202             if (log.isDebugEnabled()) {
203                 log.debug(msg, ex);
204             }
205             if (ex instanceof PermissionException) {
206                 throw (PermissionException) ex;
207             }
208             throw new PermissionException(msg, ex);
209         }
210         provider.commitTransaction(status);
211         if (log.isDebugEnabled()) {
212             log.debug("deletepermissions(res,action) success, "
213                     + " res=" + res.toString()
214                     + " action=" + action.toString()
215                     + " oid=" + oid.toString()
216                     + " perm=" + p.toString());
217         }
218
219     }
220
221     @Override
222     public void deletePermissions(CSpaceResource res)
223             throws PermissionNotFoundException, PermissionException {
224         ObjectIdentity oid = SpringAuthorizationProvider.mapResource(res);
225         TransactionStatus status = provider.beginTransaction("addPermssion");
226         try {
227             provider.getProviderAclService().deleteAcl(oid, true);
228         } catch (AclDataAccessException aex) {
229             provider.rollbackTransaction(status);
230             log.debug("deletepermissions(res) failed,"
231                     + " oid=" + oid.toString()
232                     + " res=" + res.toString()
233                     + " oid=" + oid.toString(), aex);
234             throw new PermissionException(aex);
235         } catch (Exception ex) {
236             provider.rollbackTransaction(status);
237             String msg = "deletepermissions(res) failed,"
238                     + " oid=" + oid.toString()
239                     + " res=" + res.toString()
240                     + " oid=" + oid.toString();
241             if (log.isDebugEnabled()) {
242                 log.debug(msg, ex);
243             }
244             if (ex instanceof PermissionException) {
245                 throw (PermissionException) ex;
246             }
247             throw new PermissionException(msg, ex);
248         }
249         provider.commitTransaction(status);
250
251         if (log.isDebugEnabled()) {
252             log.debug("deletepermissions(res) success, "
253                     + " res=" + res.toString()
254                     + " oid=" + oid.toString());
255         }
256     }
257
258     private void addPermission(ObjectIdentity oid, Permission permission,
259             Sid sid) throws PermissionException {
260         MutableAcl acl;
261
262         try {
263             acl = getAcl(oid);
264         } catch (NotFoundException nfe) {
265             if (log.isDebugEnabled()) {
266                 log.debug("addPermission: acl not found for oid=" + oid.toString()
267                         + " perm=" + permission.toString()
268                         + " sid=" + sid.toString()
269                         + " adding...");
270             }
271             acl = provider.getProviderAclService().createAcl(oid);
272         }
273         acl.insertAce(acl.getEntries().size(), permission, sid, true);
274         provider.getProviderAclService().updateAcl(acl);
275
276         if (log.isDebugEnabled()) {
277             log.debug("addPermission: added acl for oid=" + oid.toString()
278                     + " perm=" + permission.toString()
279                     + " sid=" + sid.toString());
280         }
281     }
282
283     private void deletePermissions(ObjectIdentity oid, Permission permission, Sid sid) /** throws AclDataAccessException */
284     {
285         int i = 0;
286         MutableAcl acl = getAcl(oid);
287         List<AccessControlEntry> acel = acl.getEntries();
288         int aces = acel.size();
289         if (log.isDebugEnabled()) {
290             log.debug("deletePermissions: for acl oid=" + oid.toString()
291                     + " found " + aces + " aces");
292         }
293         ArrayList<Integer> foundAces = new ArrayList<Integer>();
294         Iterator iter = acel.listIterator();
295         //not possible to delete while iterating
296         while(iter.hasNext()) {
297             AccessControlEntry ace = (AccessControlEntry)iter.next();
298             if (sid != null) {
299                 if (ace.getSid().equals(sid)
300                         && ace.getPermission().equals(permission)) {
301                     foundAces.add(i);
302                     i++;
303                 }
304             } else {
305                 if (ace.getPermission().equals(permission)) {
306                     foundAces.add(i);
307                     i++;
308                 }
309             }
310         }
311         for (int j = foundAces.size() - 1; j >= 0; j--) {
312             //the following operation does not work while iterating in the while loop
313             acl.deleteAce(foundAces.get(j)); //autobox
314         }
315         provider.getProviderAclService().updateAcl(acl);
316
317         if (log.isDebugEnabled()) {
318             log.debug("deletePermissions: for acl oid=" + oid.toString()
319                     + " deleted " + i + " aces");
320         }
321     }
322
323     private MutableAcl getAcl(ObjectIdentity oid) throws NotFoundException {
324         MutableAcl acl = null;
325         acl = (MutableAcl) provider.getProviderAclService().readAclById(oid);
326         if (log.isDebugEnabled()) {
327             log.debug("found acl for oid=" + oid.toString());
328         }
329         return acl;
330     }
331 }