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 }