]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
aa1462a828273afca6547d1d6f4538db5ab05a48
[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.mapAction(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.mapAction(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.mapAction(action);
182         TransactionStatus status = provider.beginTransaction("deletePermssions");
183         try {
184             deletePermissions(oid, p, null);
185             provider.commitTransaction(status);
186             if (log.isDebugEnabled()) {
187                 log.debug("deletepermissions(res,action) success, "
188                         + " res=" + res.toString()
189                         + " action=" + action.toString()
190                         + " oid=" + oid.toString()
191                         + " perm=" + p.toString());
192             }
193         } catch (AclDataAccessException aex) {
194             provider.rollbackTransaction(status);
195             log.debug("deletepermissions(res,action) failed,"
196                     + " oid=" + oid.toString()
197                     + " res=" + res.toString()
198                     + " action=" + action.toString()
199                     + " oid=" + oid.toString()
200                     + " perm=" + p.toString(), aex);
201             throw new PermissionException(aex);
202         } catch (Exception ex) {
203             provider.rollbackTransaction(status);
204             String msg = "deletepermissions(res,action,prin[]) failed,"
205                     + " oid=" + oid.toString()
206                     + " res=" + res.toString()
207                     + " action=" + action.toString()
208                     + " oid=" + oid.toString()
209                     + " perm=" + p.toString();
210             if (log.isDebugEnabled()) {
211                 log.debug(msg, ex);
212             }
213             if (ex instanceof PermissionException) {
214                 throw (PermissionException) ex;
215             }
216             throw new PermissionException(msg, ex);
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("deletePermssion");
226         try {
227             provider.getProviderAclService().deleteAcl(oid, true);
228             provider.commitTransaction(status);
229             if (log.isDebugEnabled()) {
230                 log.debug("deletepermissions(res) success, "
231                         + " res=" + res.toString()
232                         + " oid=" + oid.toString());
233             }
234         } catch (AclDataAccessException aex) {
235             provider.rollbackTransaction(status);
236             log.debug("deletepermissions(res) failed,"
237                     + " oid=" + oid.toString()
238                     + " res=" + res.toString()
239                     + " oid=" + oid.toString(), aex);
240             throw new PermissionException(aex);
241         } catch (Exception ex) {
242             provider.rollbackTransaction(status);
243             String msg = "deletepermissions(res) failed,"
244                     + " oid=" + oid.toString()
245                     + " res=" + res.toString()
246                     + " oid=" + oid.toString();
247             if (log.isDebugEnabled()) {
248                 log.debug(msg, ex);
249             }
250             if (ex instanceof PermissionException) {
251                 throw (PermissionException) ex;
252             }
253             throw new PermissionException(msg, ex);
254         }
255     }
256
257     private void addPermission(ObjectIdentity oid, Permission permission,
258             Sid sid) throws PermissionException {
259         MutableAcl acl;
260
261         try {
262             acl = getAcl(oid);
263         } catch (NotFoundException nfe) {
264             if (log.isDebugEnabled()) {
265                 log.debug("addPermission: acl not found for oid=" + oid.toString()
266                         + " perm=" + permission.toString()
267                         + " sid=" + sid.toString()
268                         + " adding...");
269             }
270             acl = provider.getProviderAclService().createAcl(oid);
271         }
272         acl.insertAce(acl.getEntries().size(), permission, sid, true);
273         provider.getProviderAclService().updateAcl(acl);
274
275         if (log.isDebugEnabled()) {
276             log.debug("addPermission: added acl for oid=" + oid.toString()
277                     + " perm=" + permission.toString()
278                     + " sid=" + sid.toString());
279         }
280     }
281
282     private void deletePermissions(ObjectIdentity oid, Permission permission, Sid sid) /** throws AclDataAccessException */
283     {
284         int i = 0;
285         MutableAcl acl = getAcl(oid);
286         List<AccessControlEntry> acel = acl.getEntries();
287         int aces = acel.size();
288         if (log.isDebugEnabled()) {
289             log.debug("deletePermissions: for acl oid=" + oid.toString()
290                     + " found " + aces + " aces");
291         }
292         ArrayList<Integer> foundAces = new ArrayList<Integer>();
293         Iterator iter = acel.listIterator();
294         //not possible to delete while iterating
295         while (iter.hasNext()) {
296             AccessControlEntry ace = (AccessControlEntry) iter.next();
297             if (sid != null) {
298                 if (ace.getSid().equals(sid)
299                         && ace.getPermission().equals(permission)) {
300                     foundAces.add(i);
301                     i++;
302                 }
303             } else {
304                 if (ace.getPermission().equals(permission)) {
305                     foundAces.add(i);
306                     i++;
307                 }
308             }
309         }
310         for (int j = foundAces.size() - 1; j >= 0; j--) {
311             //the following operation does not work while iterating in the while loop
312             acl.deleteAce(foundAces.get(j)); //autobox
313         }
314         provider.getProviderAclService().updateAcl(acl);
315
316         if (log.isDebugEnabled()) {
317             log.debug("deletePermissions: for acl oid=" + oid.toString()
318                     + " deleted " + i + " aces");
319         }
320     }
321
322     private MutableAcl getAcl(ObjectIdentity oid) throws NotFoundException {
323         MutableAcl acl = null;
324         acl = (MutableAcl) provider.getProviderAclService().readAclById(oid);
325         if (log.isDebugEnabled()) {
326             log.debug("found acl for oid=" + oid.toString());
327         }
328         return acl;
329     }
330 }