Coverage Report - org.acegisecurity.taglibs.authz.AccessControlListTag
 
Classes in this File Line Coverage Branch Coverage Complexity
AccessControlListTag
0% 
0% 
4.125
 
 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.taglibs.authz;
 16  
 
 17  
 import org.acegisecurity.acls.Acl;
 18  
 import org.acegisecurity.acls.AclService;
 19  
 import org.acegisecurity.acls.NotFoundException;
 20  
 import org.acegisecurity.acls.Permission;
 21  
 import org.acegisecurity.acls.domain.BasePermission;
 22  
 import org.acegisecurity.acls.objectidentity.ObjectIdentity;
 23  
 import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategy;
 24  
 import org.acegisecurity.acls.objectidentity.ObjectIdentityRetrievalStrategyImpl;
 25  
 import org.acegisecurity.acls.sid.Sid;
 26  
 import org.acegisecurity.acls.sid.SidRetrievalStrategy;
 27  
 import org.acegisecurity.acls.sid.SidRetrievalStrategyImpl;
 28  
 
 29  
 import org.acegisecurity.context.SecurityContextHolder;
 30  
 
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 
 34  
 import org.springframework.context.ApplicationContext;
 35  
 
 36  
 import org.springframework.web.context.support.WebApplicationContextUtils;
 37  
 import org.springframework.web.util.ExpressionEvaluationUtils;
 38  
 
 39  
 import java.util.HashSet;
 40  
 import java.util.Map;
 41  
 import java.util.Set;
 42  
 import java.util.StringTokenizer;
 43  
 
 44  
 import javax.servlet.ServletContext;
 45  
 import javax.servlet.jsp.JspException;
 46  
 import javax.servlet.jsp.PageContext;
 47  
 import javax.servlet.jsp.tagext.Tag;
 48  
 import javax.servlet.jsp.tagext.TagSupport;
 49  
 
 50  
 
 51  
 /**
 52  
  * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows its body through if some authorizations
 53  
  * are granted to the request's principal.<p>One or more comma separate numeric are specified via the
 54  
  * <code>hasPermission</code> attribute. Those permissions are then converted into {@link Permission} instances. These
 55  
  * instances are then presented as an array to the {@link Acl#isGranted(Permission[],
 56  
  * org.acegisecurity.acls.sid.Sid[], boolean)} method. The {@link Sid} presented is determined by the {@link
 57  
  * SidRetrievalStrategy}.</p>
 58  
  *  <p>For this class to operate it must be able to access the application context via the
 59  
  * <code>WebApplicationContextUtils</code> and locate an {@link AclService} and {@link SidRetrievalStrategy}.
 60  
  * Application contexts must provide one and only one of these Java types.</p>
 61  
  *
 62  
  * @author Ben Alex
 63  
  * @version $Id: AccessControlListTag.java 1784 2007-02-24 21:00:24Z luke_t $
 64  
  */
 65  0
 public class AccessControlListTag extends TagSupport {
 66  
     //~ Static fields/initializers =====================================================================================
 67  
 
 68  0
     protected static final Log logger = LogFactory.getLog(AccessControlListTag.class);
 69  
 
 70  
     //~ Instance fields ================================================================================================
 71  
 
 72  
     private AclService aclService;
 73  
     private ApplicationContext applicationContext;
 74  
     private Object domainObject;
 75  
     private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy;
 76  
     private SidRetrievalStrategy sidRetrievalStrategy;
 77  0
     private String hasPermission = "";
 78  
 
 79  
     //~ Methods ========================================================================================================
 80  
 
 81  
     public int doStartTag() throws JspException {
 82  0
         initializeIfRequired();
 83  
 
 84  0
         if ((null == hasPermission) || "".equals(hasPermission)) {
 85  0
             return Tag.SKIP_BODY;
 86  
         }
 87  
 
 88  0
         final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission,
 89  
                 pageContext);
 90  
 
 91  0
         Permission[] requiredPermissions = null;
 92  
 
 93  
         try {
 94  0
             requiredPermissions = parsePermissionsString(evaledPermissionsString);
 95  0
         } catch (NumberFormatException nfe) {
 96  0
             throw new JspException(nfe);
 97  0
         }
 98  
 
 99  0
         Object resolvedDomainObject = null;
 100  
 
 101  0
         if (domainObject instanceof String) {
 102  0
             resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", (String) domainObject,
 103  
                     Object.class, pageContext);
 104  
         } else {
 105  0
             resolvedDomainObject = domainObject;
 106  
         }
 107  
 
 108  0
         if (resolvedDomainObject == null) {
 109  0
             if (logger.isDebugEnabled()) {
 110  0
                 logger.debug("domainObject resolved to null, so including tag body");
 111  
             }
 112  
 
 113  
             // Of course they have access to a null object!
 114  0
             return Tag.EVAL_BODY_INCLUDE;
 115  
         }
 116  
 
 117  0
         if (SecurityContextHolder.getContext().getAuthentication() == null) {
 118  0
             if (logger.isDebugEnabled()) {
 119  0
                 logger.debug(
 120  
                     "SecurityContextHolder did not return a non-null Authentication object, so skipping tag body");
 121  
             }
 122  
 
 123  0
             return Tag.SKIP_BODY;
 124  
         }
 125  
 
 126  0
         Sid[] sids = sidRetrievalStrategy.getSids(SecurityContextHolder.getContext().getAuthentication());
 127  0
         ObjectIdentity oid = objectIdentityRetrievalStrategy.getObjectIdentity(resolvedDomainObject);
 128  
 
 129  
         // Obtain aclEntrys applying to the current Authentication object
 130  
         try {
 131  0
             Acl acl = aclService.readAclById(oid, sids);
 132  
 
 133  0
             if (acl.isGranted(requiredPermissions, sids, false)) {
 134  0
                 return Tag.EVAL_BODY_INCLUDE;
 135  
             } else {
 136  0
                 return Tag.SKIP_BODY;
 137  
             }
 138  0
         } catch (NotFoundException nfe) {
 139  0
             return Tag.SKIP_BODY;
 140  
         }
 141  
     }
 142  
 
 143  
     /**
 144  
      * Allows test cases to override where application context obtained from.
 145  
      *
 146  
      * @param pageContext so the <code>ServletContext</code> can be accessed as required by Spring's
 147  
      *        <code>WebApplicationContextUtils</code>
 148  
      *
 149  
      * @return the Spring application context (never <code>null</code>)
 150  
      */
 151  
     protected ApplicationContext getContext(PageContext pageContext) {
 152  0
         ServletContext servletContext = pageContext.getServletContext();
 153  
 
 154  0
         return WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
 155  
     }
 156  
 
 157  
     public Object getDomainObject() {
 158  0
         return domainObject;
 159  
     }
 160  
 
 161  
     public String getHasPermission() {
 162  0
         return hasPermission;
 163  
     }
 164  
 
 165  
     private void initializeIfRequired() throws JspException {
 166  0
         if (applicationContext == null) {
 167  0
             this.applicationContext = getContext(pageContext);
 168  
 
 169  0
             Map map = applicationContext.getBeansOfType(AclService.class);
 170  
 
 171  0
             if (map.size() != 1) {
 172  0
                 throw new JspException(
 173  
                     "Found incorrect number of AclService instances in application context - you must have only have one!");
 174  
             }
 175  
 
 176  0
             aclService = (AclService) map.values().iterator().next();
 177  
 
 178  0
             map = applicationContext.getBeansOfType(SidRetrievalStrategy.class);
 179  
 
 180  0
             if (map.size() == 0) {
 181  0
                 sidRetrievalStrategy = new SidRetrievalStrategyImpl();
 182  0
             } else if (map.size() == 1) {
 183  0
                 sidRetrievalStrategy = (SidRetrievalStrategy) map.values().iterator().next();
 184  
             } else {
 185  0
                 throw new JspException("Found incorrect number of SidRetrievalStrategy instances in application "
 186  
                         + "context - you must have only have one!");
 187  
             }
 188  
 
 189  0
             map = applicationContext.getBeansOfType(ObjectIdentityRetrievalStrategy.class);
 190  
 
 191  0
             if (map.size() == 0) {
 192  0
                 objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
 193  0
             } else if (map.size() == 1) {
 194  0
                 objectIdentityRetrievalStrategy = (ObjectIdentityRetrievalStrategy) map.values().iterator().next();
 195  
             } else {
 196  0
                 throw new JspException("Found incorrect number of ObjectIdentityRetrievalStrategy instances in "
 197  
                         + "application context - you must have only have one!");
 198  
             }
 199  
         }
 200  0
     }
 201  
 
 202  
     private Permission[] parsePermissionsString(String integersString)
 203  
         throws NumberFormatException {
 204  0
         final Set permissions = new HashSet();
 205  
         final StringTokenizer tokenizer;
 206  0
         tokenizer = new StringTokenizer(integersString, ",", false);
 207  
 
 208  0
         while (tokenizer.hasMoreTokens()) {
 209  0
             String integer = tokenizer.nextToken();
 210  0
             permissions.add(BasePermission.buildFromMask(new Integer(integer).intValue()));
 211  0
         }
 212  
 
 213  0
         return (Permission[]) permissions.toArray(new Permission[] {});
 214  
     }
 215  
 
 216  
     public void setDomainObject(Object domainObject) {
 217  0
         this.domainObject = domainObject;
 218  0
     }
 219  
 
 220  
     public void setHasPermission(String hasPermission) {
 221  0
         this.hasPermission = hasPermission;
 222  0
     }
 223  
 }