KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > slide > security > SecurityImpl


1 /*
2  * $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/security/SecurityImpl.java,v 1.53.2.5 2004/11/24 11:40:00 ozeigermann Exp $
3  * $Revision: 1.53.2.5 $
4  * $Date: 2004/11/24 11:40:00 $
5  *
6  * ====================================================================
7  *
8  * Copyright 1999-2002 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */

23
24 package org.apache.slide.security;
25
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Enumeration;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Hashtable;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.Vector;
39 import org.apache.slide.common.Namespace;
40 import org.apache.slide.common.NamespaceConfig;
41 import org.apache.slide.common.ServiceAccessException;
42 import org.apache.slide.common.SlideException;
43 import org.apache.slide.common.SlideToken;
44 import org.apache.slide.common.Uri;
45 import org.apache.slide.content.NodeProperty;
46 import org.apache.slide.content.NodeRevisionDescriptor;
47 import org.apache.slide.content.NodeRevisionDescriptors;
48 import org.apache.slide.content.NodeRevisionNumber;
49 import org.apache.slide.content.RevisionDescriptorNotFoundException;
50 import org.apache.slide.store.Store;
51 import org.apache.slide.structure.ActionNode;
52 import org.apache.slide.structure.LinkNode;
53 import org.apache.slide.structure.ObjectAlreadyExistsException;
54 import org.apache.slide.structure.ObjectNode;
55 import org.apache.slide.structure.ObjectNotFoundException;
56 import org.apache.slide.structure.SubjectNode;
57 import org.apache.slide.util.Configuration;
58 import org.apache.slide.util.XMLValue;
59 import org.apache.slide.util.logger.Logger;
60 import org.apache.slide.event.VetoException;
61 import org.apache.slide.event.EventDispatcher;
62 import org.apache.slide.event.SecurityEvent;
63 import org.jdom.JDOMException;
64
65 /**
66  * Security helper.
67  *
68  * @version $Revision: 1.53.2.5 $
69  */

70 public class SecurityImpl implements Security {
71     
72     private static final String LOG_CHANNEL = SecurityImpl.class.getName();
73     private static final String PRIVILEGE_MEMBER_SET = "privilege-member-set";
74     private static final String PRIVILEGE_NAMESPACE = "privilege-namespace";
75     protected Logger logger;
76     
77     
78     /**
79      * Constructor.
80      */

81     public SecurityImpl() {}
82     
83     /**
84      * Constructor.
85      *
86      * @param namespace Namespace
87      * @param namespaceConfig Namespace configuration
88      */

89     public SecurityImpl(Namespace namespace, NamespaceConfig namespaceConfig) {
90         init(namespace, namespaceConfig);
91     }
92     
93     public void init(Namespace namespace, NamespaceConfig namespaceConfig) {
94         this.namespace = namespace;
95         this.namespaceConfig = namespaceConfig;
96         this.rolesCache = new Hashtable();
97         aclInheritanceType = namespaceConfig.getAclInheritanceType();
98         logger = namespace.getLogger();
99     }
100     
101     // ----------------------------------------------------- Instance Variables
102

103     
104     /**
105      * Namespace.
106      */

107     protected Namespace namespace;
108     
109     
110     /**
111      * Namespace configuration.
112      */

113     protected NamespaceConfig namespaceConfig;
114     
115     
116     /**
117      * Roles cache.
118      * Role name -> Role interface.
119      */

120     protected Hashtable rolesCache;
121     
122     protected int aclInheritanceType;
123     
124     /**
125      * The actions that can modify objects in the repository. These are used
126      * to determine actions cache invalidation.
127      */

128     private Set modificationActions;
129     
130     // ------------------------------------------------------- Security Methods
131

132     
133     /**
134      * Set a new set of permissions on an object.
135      *
136      * @param token Credentials token
137      * @param object Object on which permission is granted
138      * @exception ServiceAccessException DataSource access error
139      * @exception ObjectNotFoundException Specified object was not found
140      * in the DataSource
141      * @exception AccessDeniedException Insufficent credentials
142      */

143     public void setPermissions(SlideToken token, String object,
144                                Enumeration permissions)
145         throws ServiceAccessException, ObjectNotFoundException,
146         AccessDeniedException {
147         
148         Uri objectUri = namespace.getUri(token, object);
149         ObjectNode objectNode = objectUri.getStore().retrieveObject(objectUri);
150         
151         checkCredentials(token, objectNode,
152                          namespaceConfig.getGrantPermissionAction());
153         checkCredentials(token, objectNode,
154                          namespaceConfig.getRevokePermissionAction());
155         
156         objectUri.getStore().revokePermissions(objectUri);
157         
158         while (permissions.hasMoreElements()) {
159             NodePermission permission =
160                 (NodePermission) permissions.nextElement();
161             objectUri.getStore().grantPermission(objectUri, permission);
162         }
163         
164     }
165     
166     
167     /**
168      * Grants a new permission.
169      *
170      * @param token Credentials token
171      * @param object Object on which permission is granted
172      * @param subject The subject to whom the permission is granted.
173      * @param action The action which the subject can perform
174      * @exception ServiceAccessException DataSource access error
175      * @exception ObjectNotFoundException Specified object was not found
176      * in the DataSource
177      * @exception AccessDeniedException Insufficent credentials
178      */

179     public void grantPermission(SlideToken token, ObjectNode object,
180                                 SubjectNode subject, ActionNode action)
181         throws ServiceAccessException, ObjectNotFoundException,
182         AccessDeniedException, VetoException {
183         grantPermission(token, object, subject, action, true);
184     }
185     
186     
187     /**
188      * Grants a new permission.
189      *
190      * @param token Credentials token
191      * @param object Object on which permission is granted
192      * @param subject Subject who can perform the action
193      * @param action Action which can be performed
194      * @param inheritable Create an inheritable permission
195      * @exception ServiceAccessException DataSource access error
196      * @exception ObjectNotFoundException Specified object was not found
197      * in the DataSource
198      * @exception AccessDeniedException Insufficent credentials
199      */

200     public void grantPermission(SlideToken token, ObjectNode object,
201                                 SubjectNode subject, ActionNode action,
202                                 boolean inheritable)
203         throws ServiceAccessException, ObjectNotFoundException,
204         AccessDeniedException, VetoException {
205         NodePermission permission = new NodePermission(object, subject, action,
206                                                        inheritable);
207         grantPermission(token, permission);
208     }
209     
210     
211     /**
212      * Grants a new permission.
213      *
214      * @param token Credentials token
215      * @param permission New permission
216      * @exception ServiceAccessException DataSource access error
217      * @exception ObjectNotFoundException Specified object was not found
218      * in the DataSource
219      * @exception AccessDeniedException Insufficent credentials
220      */

221     public void grantPermission(SlideToken token,
222                                 NodePermission permission)
223         throws ServiceAccessException, ObjectNotFoundException,
224         AccessDeniedException, VetoException {
225         Uri objectUri = namespace.getUri(token, permission.getObjectUri());
226         ObjectNode object = objectUri.getStore()
227             .retrieveObject(objectUri);
228         
229         // Checking if the permission is already present
230
Enumeration permissions = enumeratePermissions(token, object);
231         boolean alreadyPresent = false;
232         while (permissions.hasMoreElements() && !alreadyPresent) {
233             if (permission.equals(permissions.nextElement())) {
234                 alreadyPresent = true;
235             }
236         }
237         
238         if (!alreadyPresent) {
239             checkCredentials(token, object,
240                              namespaceConfig.getGrantPermissionAction());
241             objectUri.getStore().grantPermission(objectUri, permission);
242         }
243
244         // Fire event
245
if ( permission.isNegative() ) {
246             if ( SecurityEvent.DENY_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.DENY_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission));
247         } else {
248             if ( SecurityEvent.GRANT_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.GRANT_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission));
249         }
250     }
251     
252     
253     /**
254      * Deny a new permission.
255      *
256      * @param token Credentials token
257      * @param object Object on which permission is denied
258      * @param subject The subject to whom a action is denied
259      * @param action The action which is denied
260      * @exception ServiceAccessException DataSource access error
261      * @exception ObjectNotFoundException Specified object was not found
262      * in the DataSource
263      * @exception AccessDeniedException Insufficent credentials
264      */

265     public void denyPermission(SlideToken token, ObjectNode object,
266                                SubjectNode subject, ActionNode action)
267         throws ServiceAccessException, ObjectNotFoundException,
268         AccessDeniedException, VetoException {
269         denyPermission(token, object, subject, action, true);
270     }
271     
272     
273     /**
274      * Deny a new permission.
275      *
276      * @param token Credentials token
277      * @param object Object on which permission is granted
278      * @param subject Subject who can perform the action
279      * @param action Action which can be performed
280      * @param inheritable Create an inheritable permission
281      * @exception ServiceAccessException DataSource access error
282      * @exception ObjectNotFoundException Specified object was not found
283      * in the DataSource
284      * @exception AccessDeniedException Insufficent credentials
285      */

286     public void denyPermission(SlideToken token, ObjectNode object,
287                                SubjectNode subject, ActionNode action,
288                                boolean inheritable)
289         throws ServiceAccessException, ObjectNotFoundException,
290         AccessDeniedException, VetoException {
291         NodePermission permission = new NodePermission(object, subject, action,
292                                                        inheritable, true);
293         denyPermission(token, permission);
294     }
295     
296     
297     /**
298      * Deny a new permission.
299      *
300      * @param token Credentials token
301      * @param permission New permission
302      * @exception ServiceAccessException DataSource access error
303      * @exception ObjectNotFoundException Specified object was not found
304      * in the DataSource
305      * @exception AccessDeniedException Insufficent credentials
306      */

307     public void denyPermission(SlideToken token,
308                                NodePermission permission)
309         throws ServiceAccessException, ObjectNotFoundException,
310         AccessDeniedException, VetoException {
311         // Make sure the permission we're about to set is indeed a negative
312
// permission
313
if (!permission.isNegative())
314             permission.setNegative(true);
315         grantPermission(token, permission);
316     }
317     
318     
319     /**
320      * Revokes a permission.
321      *
322      * @param token Credentials token
323      * @param object Object on which permission is revoked
324      * @param subject Subject who can perform the action
325      * @param action Action which can be performed
326      * @exception ServiceAccessException DataSource access error
327      * @exception ObjectNotFoundException Specified object was not found
328      * in the DataSource
329      * @exception AccessDeniedException Insufficent credentials
330      */

331     public void revokePermission(SlideToken token, ObjectNode object,
332                                  SubjectNode subject, ActionNode action)
333         throws ServiceAccessException, ObjectNotFoundException,
334         AccessDeniedException, VetoException {
335         //Domain.info("Revoke permission on " + object.getUri());
336
checkCredentials(token, object, namespaceConfig
337                              .getRevokePermissionAction());
338         NodePermission permission = new NodePermission(object, subject,
339                                                        action);
340         Uri objectUri = namespace.getUri(token, object.getUri());
341         objectUri.getStore()
342             .revokePermission(objectUri, permission);
343
344         // Fire event
345
if ( SecurityEvent.REVOKE_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.REVOKE_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission));
346     }
347     
348     
349     
350     /**
351      * Revokes a permission.
352      *
353      * @param token Credentials token
354      * @param permission Permission to be removed
355      * @exception ServiceAccessException DataSource access error
356      * @exception ObjectNotFoundException Specified object was not found
357      * in the DataSource
358      * @exception AccessDeniedException Insufficent credentials
359      */

360     public void revokePermission(SlideToken token, NodePermission permission)
361         throws ServiceAccessException, ObjectNotFoundException,
362         AccessDeniedException, VetoException {
363         
364         Uri objectUri = namespace.getUri(token, permission.getObjectUri());
365         ObjectNode object = objectUri.getStore().retrieveObject(objectUri);
366         
367         checkCredentials(token, object,
368                          namespaceConfig.getRevokePermissionAction());
369         objectUri.getStore().revokePermission(objectUri, permission);
370
371         // Fire event
372
if ( SecurityEvent.REVOKE_PERMISSION.isEnabled() ) EventDispatcher.getInstance().fireVetoableEvent(SecurityEvent.REVOKE_PERMISSION, new SecurityEvent(this, token, namespace, objectUri, permission));
373     }
374     
375     
376     /**
377      * Check if the credentials given grants permission to perform
378      * the specified action on the specified subject.
379      *
380      * @param token Credentials token
381      * @param object Object on which the action is performed
382      * @param action Action performed
383      * @exception ServiceAccessException DataSource access error
384      * @exception AccessDeniedException The credentials does not grant
385      * the permission to perform the specified action
386      */

387     public void checkCredentials(SlideToken token, ObjectNode object,
388                                  ActionNode action)
389         throws ServiceAccessException, AccessDeniedException {
390         
391         if (!token.isForceSecurity()) {
392             return;
393         }
394         
395         try {
396             if (Configuration.useIntegratedSecurity()) {
397                 // check if permission has already been checked
398
Boolean permission = token.checkPermissionCache(object, action);
399                 if (permission == null) {
400                     // if not checked before, check now
401
try {
402                         Uri objectUri = namespace.getUri(token, object.getUri());
403                         ObjectNode realObject = objectUri.getStore()
404                             .retrieveObject(objectUri);
405                         checkPermission(token, realObject, action);
406                         token.cachePermission(object, action, true);
407                     } catch (AccessDeniedException ade) {
408                         token.cachePermission(object, action, false);
409                         ade.fillInStackTrace();
410                         throw ade;
411                     }
412                 }
413                 else {
414                     if (!(permission.booleanValue())) {
415                         throw new AccessDeniedException
416                             (object.getUri(),
417                              getPrincipal(token).getPath().toString(),
418                              action.getUri());
419                     }
420                 }
421             }
422         } catch (ObjectNotFoundException e) {
423             String subjectUri = "*** Could not determine principal ***";
424             try {
425                 subjectUri = getPrincipal(token).getPath().toString();
426             } catch (Exception x) {}
427             throw new AccessDeniedException
428                 (object.getUri(),
429                  subjectUri,
430                  action.getUri());
431         }
432     }
433     
434     
435     /**
436      * Check whether or not an actor can perform the specified activity
437      * on a collection.
438      *
439      * @param object Object on which access is tested
440      * @param subject Subject who seeks to perform the action
441      * @param action Action which is to be performed
442      * @exception ServiceAccessException DataSource access error
443      * @exception ObjectNotFoundException Specified object was not found
444      * in the DataSource
445      * @exception AccessDeniedException Insufficent credentials
446      */

447     public void checkPermission(ObjectNode object, SubjectNode subject,
448                                 ActionNode action)
449         throws ServiceAccessException, AccessDeniedException,
450         ObjectNotFoundException {
451         if (!hasPermission(object, subject, action)) {
452             throw new AccessDeniedException(object.getUri(), subject.getUri(),
453                                             action.getUri());
454         }
455
456         determineActionsCacheInvalidation(object, action);
457     }
458     
459     /**
460      * Check whether or not an actor (principal) can perform the specified activity
461      * on the specified resource.
462      *
463      * @param token a SlideToken
464      * @param object Object on which access is tested
465      * @param action Action which is to be performed
466      *
467      * @throws ServiceAccessException
468      * @throws AccessDeniedException
469      * @throws ObjectNotFoundException
470      */

471     public void checkPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, AccessDeniedException, ObjectNotFoundException {
472         if (!hasPermission(token, object, action)) {
473             throw new AccessDeniedException(object.getUri(), getPrincipal(token).getUri(),
474                                             action.getUri());
475         }
476
477         determineActionsCacheInvalidation(object, action);
478     }
479     
480     
481     /**
482      * Check whether or not an actor can perform the specified activity
483      * on a collection.
484      *
485      * @param object Object on which access is tested
486      * @param subject Subject who seeks to perform the action
487      * @param action Action which is to be performed
488      * @return true if the action can be performed
489      * @exception ServiceAccessException DataSource access error
490      * @exception ObjectNotFoundException Specified object was not found
491      * in the DataSource
492      */

493     public boolean hasPermission(ObjectNode object, SubjectNode subject,
494                                  ActionNode action)
495         throws ServiceAccessException, ObjectNotFoundException {
496         
497         // no check for default action (server intitialization)
498
if (action.equals(ActionNode.DEFAULT)) {
499             return true;
500         }
501         
502         boolean granted = false;
503         boolean denied = false;
504         boolean rootObjectReached = false;
505         
506         ObjectNode courObject = object;
507         
508         Uri subjectUri = namespace.getUri(subject.getUri());
509         Uri actionUri = namespace.getUri(action.getUri());
510         
511         // check if allready granded
512

513         while (!granted && !denied && !rootObjectReached) {
514             
515             Uri courUri = namespace.getUri(courObject.getUri());
516             Enumeration permissions = courUri.getStore()
517                 .enumeratePermissions(courUri);
518             
519             while (permissions.hasMoreElements()) {
520                 
521                 boolean oldGranted = granted;
522                 boolean oldDenied = denied;
523                 
524                 NodePermission permission =
525                     (NodePermission) permissions.nextElement();
526                 String permissionSubject = permission.getSubjectUri();
527                 
528                 if (permissionSubject.equals(SubjectNode.SELF_URI)) {
529                     
530                     boolean check;
531                     check = object.getUri().equals(subjectUri.toString());
532                     if (permission.isInheritable()) {
533                         String subjectUriString = subjectUri.toString();
534                         if(!subjectUriString.endsWith("/"))
535                             subjectUriString = subjectUriString + "/";
536                         
537                         check |= object.getUri().startsWith(subjectUriString);
538                     }
539                     
540                     // Self permission
541
granted = (!permission.isNegative())
542                         && (check)
543                         && (actionUri.toString()
544                                 .startsWith(permission.getActionUri()));
545                     denied = (permission.isNegative())
546                         && (check)
547                         && (actionUri.toString()
548                                 .startsWith(permission.getActionUri()));
549                     
550                 } else if (permission.isInheritable()
551                            || permission.getObjectUri().equals(object.getUri())) {
552                     
553                     if (permissionSubject.startsWith("/")) {
554                         
555                         // Node permission
556

557                         String permSubj = permission.getSubjectUri();
558                         if(!permSubj.endsWith("/"))
559                             permSubj = permSubj + "/";
560                         boolean match = subjectUri.toString().
561                             equals(permission.getSubjectUri()) ||
562                             subjectUri.toString().startsWith(permSubj);
563                         match &= actionUri.toString().
564                             startsWith(permission.getActionUri());
565                         
566                         granted = (!permission.isNegative()) && match;
567                         denied = permission.isNegative() && match;
568                         
569                     } else if (permissionSubject.startsWith("+")) {
570                         
571                         // Permission group which needs to be expanded
572
Uri permissionSubjectUri =
573                             namespace.getUri(permissionSubject.substring(1));
574                         ObjectNode group =
575                             permissionSubjectUri.getStore().retrieveObject
576                             (permissionSubjectUri);
577                         // if the node is a GroupNode, expand it out to
578
// normal permissions
579
if (group instanceof
580                             org.apache.slide.structure.GroupNode ) {
581                             if (group.hasChildren()) {
582                                 Enumeration groupMembers =
583                                     group.enumerateChildren();
584                                 // parse thru the children of the group and
585
// check permissions on each
586
while (groupMembers.hasMoreElements()) {
587                                     
588                                     oldGranted = granted;
589                                     oldDenied = denied;
590                                     
591                                     Uri childUri =
592                                         namespace.getUri
593                                         ((String) groupMembers.nextElement());
594                                     ObjectNode childNode =
595                                         childUri.getStore().retrieveObject
596                                         (childUri);
597                                     String childSubjectUri = childNode
598                                         instanceof LinkNode ?
599                                         ((LinkNode) childNode)
600                                         .getLinkedUri() :
601                                         childNode.getUri() ;
602                                     
603                                     String testUri;
604                                     if(!childSubjectUri.endsWith("/"))
605                                         testUri = childSubjectUri+"/";
606                                     else
607                                         testUri = childSubjectUri;
608                                     
609                                     boolean match = subjectUri.toString().
610                                         equals(childSubjectUri) ||
611                                         subjectUri.toString().
612                                         startsWith(testUri);
613                                     match &= actionUri.toString().
614                                         startsWith(permission.getActionUri());
615                                     
616                                     granted = (!permission.isNegative()) &&
617                                         match;
618                                     denied = permission.isNegative() && match;
619                                     
620                                     granted = granted | oldGranted;
621                                     denied = denied | oldDenied;
622                                     
623                                 }
624                             }
625                         }
626                         
627                     } else {
628                         
629                         // Role permission
630
granted = (!permission.isNegative())
631                             && (hasRole(subject, permissionSubject))
632                             && (actionUri.toString()
633                                     .startsWith(permission.getActionUri()));
634                         denied = (permission.isNegative())
635                             && (hasRole(subject, permissionSubject))
636                             && (actionUri.toString()
637                                     .startsWith(permission.getActionUri()));
638                         
639                     }
640                     
641                 }
642                 
643                 granted = granted | oldGranted;
644                 denied = denied | oldDenied;
645                 
646             }
647             
648             Uri parentUri = courUri.getParentUri();
649             
650             if (parentUri != null) {
651                 courObject = parentUri.getStore()
652                     .retrieveObject(parentUri);
653             } else {
654                 rootObjectReached = true;
655             }
656         }
657         
658         // Negative permissions have priority (if they're defined on the same
659
// node)
660
if (denied) {
661             return false;
662         }
663         
664         if (!granted) {
665             return false;
666         }
667         
668         return true;
669         
670     }
671     
672     /**
673      * Check whether or not an actor (principal) can perform the specified activity
674      * on the specified resource.
675      *
676      * @param token a SlideToken
677      * @param object Object on which access is tested
678      * @param action Action which is to be performed
679      *
680      * @return true if the action can be performed
681      *
682      * @throws ServiceAccessException
683      * @throws ObjectNotFoundException
684      */

685     public boolean hasPermission(SlideToken token, ObjectNode object, ActionNode action) throws ServiceAccessException, ObjectNotFoundException {
686         Boolean cachedPermission = token.checkPermissionCache(object, action);
687         if (cachedPermission != null) {
688             return cachedPermission.booleanValue();
689         }
690         else {
691             return hasPermission(object, (SubjectNode)getPrincipal(token), action);
692         }
693     }
694     
695     
696     /**
697      * Enumerates permissions on an object.
698      *
699      * @param token Credentials token
700      * @param object Object on which permission is granted
701      * @exception ServiceAccessException DataSource access error
702      * @exception ObjectNotFoundException Specified object was not found
703      * in the DataSource
704      * @exception AccessDeniedException Insufficent credentials
705      */

706     public Enumeration enumeratePermissions(SlideToken token,
707                                             ObjectNode object)
708         throws ServiceAccessException, ObjectNotFoundException,
709         AccessDeniedException {
710         
711         return enumeratePermissions(token, object, false);
712     }
713     
714     
715     /**
716      * Enumerates permissions on an object.
717      *
718      * @param token Credentials token
719      * @param object Object on which permission is granted
720      * @exception ServiceAccessException DataSource access error
721      * @exception ObjectNotFoundException Specified object was not found
722      * in the DataSource
723      * @exception AccessDeniedException Insufficent credentials
724      */

725     public Enumeration enumeratePermissions(SlideToken token,
726                                             ObjectNode object,
727                                             boolean includeInherited)
728         throws ServiceAccessException, ObjectNotFoundException {
729         return enumeratePermissions(token, object.getUri(), includeInherited);
730     }
731     
732     
733     /**
734      * Enumerates permissions on an object.
735      *
736      * @param token Credentials token
737      * @param object Object on which permission is granted
738      * @exception ServiceAccessException DataSource access error
739      * @exception ObjectNotFoundException Specified object was not found
740      * in the DataSource
741      * @exception AccessDeniedException Insufficent credentials
742      */

743     public Enumeration enumeratePermissions(SlideToken token,
744                                             String object)
745         throws ServiceAccessException, ObjectNotFoundException,
746         AccessDeniedE