Coverage Report - org.acegisecurity.afterinvocation.AclEntryAfterInvocationCollectionFilteringProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
AclEntryAfterInvocationCollectionFilteringProvider
0% 
0% 
8
 
 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.acegisecurity.afterinvocation;
 16  
 
 17  
 import org.acegisecurity.AccessDeniedException;
 18  
 import org.acegisecurity.Authentication;
 19  
 import org.acegisecurity.AuthorizationServiceException;
 20  
 import org.acegisecurity.ConfigAttribute;
 21  
 import org.acegisecurity.ConfigAttributeDefinition;
 22  
 
 23  
 import org.acegisecurity.acls.AclService;
 24  
 import org.acegisecurity.acls.Permission;
 25  
 
 26  
 import org.apache.commons.logging.Log;
 27  
 import org.apache.commons.logging.LogFactory;
 28  
 
 29  
 import java.util.Collection;
 30  
 import java.util.Iterator;
 31  
 
 32  
 
 33  
 /**
 34  
  * <p>Given a <code>Collection</code> of domain object instances returned from a secure object invocation, remove
 35  
  * any <code>Collection</code> elements the principal does not have appropriate permission to access as defined by the
 36  
  * {@link AclService}.</p>
 37  
  *  <p>The <code>AclService</code> is used to retrieve the access control list (ACL) permissions associated with
 38  
  * each <code>Collection</code> domain object instance element for the current <code>Authentication</code> object.</p>
 39  
  *  <p>This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link
 40  
  * #processConfigAttribute}. The provider will then lookup the ACLs from the <code>AclService</code> and ensure the
 41  
  * principal is
 42  
  * {@link org.acegisecurity.acls.Acl#isGranted(org.acegisecurity.acls.Permission[],
 43  
  * org.acegisecurity.acls.sid.Sid[], boolean) Acl.isGranted(Permission[], Sid[], boolean)}
 44  
  * when presenting the {@link #requirePermission} array to that method.</p>
 45  
  *  <p>If the principal does not have permission, that element will not be included in the returned
 46  
  * <code>Collection</code>.</p>
 47  
  *  <p>Often users will setup a <code>BasicAclEntryAfterInvocationProvider</code> with a {@link
 48  
  * #processConfigAttribute} of <code>AFTER_ACL_COLLECTION_READ</code> and a {@link #requirePermission} of
 49  
  * <code>BasePermission.READ</code>. These are also the defaults.</p>
 50  
  *  <p>If the provided <code>returnObject</code> is <code>null</code>, a <code>null</code><code>Collection</code>
 51  
  * will be returned. If the provided <code>returnObject</code> is not a <code>Collection</code>, an {@link
 52  
  * AuthorizationServiceException} will be thrown.</p>
 53  
  *  <p>All comparisons and prefixes are case sensitive.</p>
 54  
  *
 55  
  * @author Ben Alex
 56  
  * @author Paulo Neves
 57  
  * @version $Id: AclEntryAfterInvocationCollectionFilteringProvider.java 1784 2007-02-24 21:00:24Z luke_t $
 58  
  */
 59  
 public class AclEntryAfterInvocationCollectionFilteringProvider extends AbstractAclProvider {
 60  
     //~ Static fields/initializers =====================================================================================
 61  
 
 62  0
     protected static final Log logger = LogFactory.getLog(AclEntryAfterInvocationCollectionFilteringProvider.class);
 63  
 
 64  
     //~ Constructors ===================================================================================================
 65  
 
 66  
     public AclEntryAfterInvocationCollectionFilteringProvider(AclService aclService, Permission[] requirePermission) {
 67  0
         super(aclService, "AFTER_ACL_COLLECTION_READ", requirePermission);
 68  0
     }
 69  
 
 70  
     //~ Methods ========================================================================================================
 71  
 
 72  
     public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,
 73  
         Object returnedObject) throws AccessDeniedException {
 74  0
         Iterator iter = config.getConfigAttributes();
 75  
 
 76  0
         while (iter.hasNext()) {
 77  0
             ConfigAttribute attr = (ConfigAttribute) iter.next();
 78  
 
 79  0
             if (this.supports(attr)) {
 80  
                 // Need to process the Collection for this invocation
 81  0
                 if (returnedObject == null) {
 82  0
                     if (logger.isDebugEnabled()) {
 83  0
                         logger.debug("Return object is null, skipping");
 84  
                     }
 85  
 
 86  0
                     return null;
 87  
                 }
 88  
 
 89  0
                 Filterer filterer = null;
 90  
 
 91  0
                 if (returnedObject instanceof Collection) {
 92  0
                     Collection collection = (Collection) returnedObject;
 93  0
                     filterer = new CollectionFilterer(collection);
 94  0
                 } else if (returnedObject.getClass().isArray()) {
 95  0
                     Object[] array = (Object[]) returnedObject;
 96  0
                     filterer = new ArrayFilterer(array);
 97  0
                 } else {
 98  0
                     throw new AuthorizationServiceException("A Collection or an array (or null) was required as the "
 99  
                             + "returnedObject, but the returnedObject was: " + returnedObject);
 100  
                 }
 101  
 
 102  
                 // Locate unauthorised Collection elements
 103  0
                 Iterator collectionIter = filterer.iterator();
 104  
 
 105  0
                 while (collectionIter.hasNext()) {
 106  0
                     Object domainObject = collectionIter.next();
 107  
 
 108  0
                     boolean hasPermission = false;
 109  
 
 110  0
                     if (domainObject == null) {
 111  0
                         hasPermission = true;
 112  0
                     } else if (!getProcessDomainObjectClass().isAssignableFrom(domainObject.getClass())) {
 113  0
                         hasPermission = true;
 114  
                     } else {
 115  0
                         hasPermission = hasPermission(authentication, domainObject);
 116  
 
 117  0
                         if (!hasPermission) {
 118  0
                             filterer.remove(domainObject);
 119  
 
 120  0
                             if (logger.isDebugEnabled()) {
 121  0
                                 logger.debug("Principal is NOT authorised for element: " + domainObject);
 122  
                             }
 123  
                         }
 124  
                     }
 125  0
                 }
 126  
 
 127  0
                 return filterer.getFilteredObject();
 128  
             }
 129  0
         }
 130  
 
 131  0
         return returnedObject;
 132  
     }
 133  
 }