View Javadoc

1   /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.springframework.security.acls;
16  
17  import org.springframework.security.acls.objectidentity.ObjectIdentity;
18  import org.springframework.security.acls.sid.Sid;
19  
20  import java.io.Serializable;
21  
22  
23  /**
24   * Represents an access control list (ACL) for a domain object.
25   *
26   * <p>
27   * An <tt>Acl</tt> represents all ACL entries for a given domain object. In
28   * order to avoid needing references to the domain object itself, this
29   * interface handles indirection between a domain object and an ACL object
30   * identity via the {@link
31   * org.springframework.security.acls.objectidentity.ObjectIdentity} interface.
32   * </p>
33   *
34   * <p>
35   * Implementing classes may elect to return instances that represent 
36   * {@link org.springframework.security.acls.Permission} information for either
37   * some OR all {@link org.springframework.security.acls.sid.Sid}
38   * instances. Therefore, an instance may NOT necessarily contain ALL <tt>Sid</tt>s
39   * for a given domain object.
40   * </p>
41   *
42   * @author Ben Alex
43   * @version $Id: Acl.java 2872 2008-04-05 20:43:10Z benalex $
44   */
45  public interface Acl extends Serializable {
46  
47      /**
48       * Returns all of the entries represented by the present <tt>Acl</tt>. Entries associated with
49       * the <tt>Acl</tt> parents are not returned.
50       * 
51       * <p>This method is typically used for administrative purposes.</p>
52       * 
53       * <p>The order that entries appear in the array is important for methods declared in the
54       * {@link MutableAcl} interface. Furthermore, some implementations MAY use ordering as
55       * part of advanced permission checking.</p>
56       * 
57       * <p>Do <em>NOT</em> use this method for making authorization decisions. Instead use {@link
58       * #isGranted(Permission[], Sid[], boolean)}.</p>
59       * 
60       * <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of
61       * <tt>Sid</tt>s. The caller is responsible for correctly handling the result if only a subset of
62       * <tt>Sid</tt>s is represented.</p>
63       *
64       * @return the list of entries represented by the <tt>Acl</tt>, or <tt>null</tt> if there are
65       * no entries presently associated with this <tt>Acl</tt>.
66       */
67      AccessControlEntry[] getEntries();
68  
69      /**
70       * Obtains the domain object this <tt>Acl</tt> provides entries for. This is immutable once an
71       * <tt>Acl</tt> is created.
72       *
73       * @return the object identity (never <tt>null</tt>)
74       */
75      ObjectIdentity getObjectIdentity();
76  
77      /**
78       * Determines the owner of the <tt>Acl</tt>. The meaning of ownership varies by implementation and is
79       * unspecified.
80       *
81       * @return the owner (may be <tt>null</tt> if the implementation does not use ownership concepts)
82       */
83      Sid getOwner();
84  
85      /**
86       * A domain object may have a parent for the purpose of ACL inheritance. If there is a parent, its ACL can
87       * be accessed via this method. In turn, the parent's parent (grandparent) can be accessed and so on.
88       * 
89       * <p>This method solely represents the presence of a navigation hierarchy between the parent <tt>Acl</tt> and this
90       * <tt>Acl</tt>. For actual inheritance to take place, the {@link #isEntriesInheriting()} must also be
91       * <tt>true</tt>.</p>
92       * 
93       * <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of
94       * <tt>Sid</tt>s. The caller is responsible for correctly handling the result if only a subset of
95       * <tt>Sid</tt>s is represented.</p>
96       *
97       * @return the parent <tt>Acl</tt> (may be <tt>null</tt> if this <tt>Acl</tt> does not have a parent)
98       */
99      Acl getParentAcl();
100 
101     /**
102      * Indicates whether the ACL entries from the {@link #getParentAcl()} should flow down into the current
103      * <tt>Acl</tt>.<p>The mere link between an <tt>Acl</tt> and a parent <tt>Acl</tt> on its own
104      * is insufficient to cause ACL entries to inherit down. This is because a domain object may wish to have entirely
105      * independent entries, but maintain the link with the parent for navigation purposes. Thus, this method denotes
106      * whether or not the navigation relationship also extends to the actual inheritance of entries.</p>
107      *
108      * @return <tt>true</tt> if parent ACL entries inherit into the current <tt>Acl</tt>
109      */
110     boolean isEntriesInheriting();
111 
112     /**
113      * This is the actual authorization logic method, and must be used whenever ACL authorization decisions are
114      * required.
115      * 
116      * <p>An array of <tt>Sid</tt>s are presented, representing security identifies of the current
117      * principal. In addition, an array of <tt>Permission</tt>s is presented which will have one or more bits set
118      * in order to indicate the permissions needed for an affirmative authorization decision. An array is presented
119      * because holding <em>any</em> of the <tt>Permission</tt>s inside the array will be sufficient for an
120      * affirmative authorization.</p>
121      * 
122      * <p>The actual approach used to make authorization decisions is left to the implementation and is not
123      * specified by this interface. For example, an implementation <em>MAY</em> search the current ACL in the order
124      * the ACL entries have been stored. If a single entry is found that has the same active bits as are shown in a
125      * passed <tt>Permission</tt>, that entry's grant or deny state may determine the authorization decision. If
126      * the case of a deny state, the deny decision will only be relevant if all other <tt>Permission</tt>s passed
127      * in the array have also been unsuccessfully searched. If no entry is found that match the bits in the current
128      * ACL, provided that {@link #isEntriesInheriting()} is <tt>true</tt>, the authorization decision may be
129      * passed to the parent ACL. If there is no matching entry, the implementation MAY throw an exception, or make a
130      * predefined authorization decision.</p>
131      * 
132      * <p>This method must operate correctly even if the <tt>Acl</tt> only represents a subset of <tt>Sid</tt>s,
133      * although the implementation is permitted to throw one of the signature-defined exceptions if the method 
134      * is called requesting an authorization decision for a {@link Sid} that was never loaded in this <tt>Acl</tt>.
135      * </p>
136      *
137      * @param permission the permission or permissions required (at least one entry required)
138      * @param sids the security identities held by the principal (at least one entry required)
139      * @param administrativeMode if <tt>true</tt> denotes the query is for administrative purposes and no logging
140      *        or auditing (if supported by the implementation) should be undertaken
141      *
142      * @return <tt>true</tt> if authorization is granted
143      *
144      * @throws NotFoundException MUST be thrown if an implementation cannot make an authoritative authorization
145      *         decision, usually because there is no ACL information for this particular permission and/or SID
146      * @throws UnloadedSidException thrown if the <tt>Acl</tt> does not have details for one or more of the
147      *         <tt>Sid</tt>s passed as arguments
148      */
149     boolean isGranted(Permission[] permission, Sid[] sids, boolean administrativeMode)
150         throws NotFoundException, UnloadedSidException;
151 
152     /**
153      * For efficiency reasons an <tt>Acl</tt> may be loaded and <em>not</em> contain entries for every
154      * <tt>Sid</tt> in the system. If an <tt>Acl</tt> has been loaded and does not represent every
155      * <tt>Sid</tt>, all methods of the <tt>Acl</tt> can only be used within the limited scope of the
156      * <tt>Sid</tt> instances it actually represents.
157      * <p>
158      * It is normal to load an <tt>Acl</tt> for only particular <tt>Sid</tt>s if read-only authorization
159      * decisions are being made. However, if user interface reporting or modification of <tt>Acl</tt>s are
160      * desired, an <tt>Acl</tt> should be loaded with all <tt>Sid</tt>s. This method denotes whether or
161      * not the specified <tt>Sid</tt>s have been loaded or not.
162      * </p>
163      *
164      * @param sids one or more security identities the caller is interest in knowing whether this <tt>Sid</tt>
165      *        supports
166      *
167      * @return <tt>true</tt> if every passed <tt>Sid</tt> is represented by this <tt>Acl</tt> instance
168      */
169     boolean isSidLoaded(Sid[] sids);
170 }