Clover coverage report - Acegi Security System for Spring - 1.0.0-RC1
Coverage timestamp: Mon Dec 5 2005 09:05:15 EST
file stats: LOC: 250   Methods: 12
NCLOC: 136   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AuthorizeTag.java 93.3% 98.4% 100% 97.1%
coverage coverage
 1    /* Copyright 2004, 2005 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   
 16    package org.acegisecurity.taglibs.authz;
 17   
 18    import org.acegisecurity.Authentication;
 19    import org.acegisecurity.GrantedAuthority;
 20    import org.acegisecurity.GrantedAuthorityImpl;
 21    import org.acegisecurity.context.SecurityContextHolder;
 22   
 23    import org.springframework.util.StringUtils;
 24   
 25    import org.springframework.web.util.ExpressionEvaluationUtils;
 26   
 27    import java.util.Arrays;
 28    import java.util.Collection;
 29    import java.util.Collections;
 30    import java.util.HashSet;
 31    import java.util.Iterator;
 32    import java.util.Set;
 33   
 34    import javax.servlet.jsp.JspException;
 35    import javax.servlet.jsp.tagext.Tag;
 36    import javax.servlet.jsp.tagext.TagSupport;
 37   
 38   
 39    /**
 40    * An implementation of {@link javax.servlet.jsp.tagext.Tag} that allows it's
 41    * body through if some authorizations are granted to the request's principal.
 42    *
 43    * @author Francois Beausoleil
 44    * @version $Id: AuthorizeTag.java,v 1.13 2005/11/17 00:56:29 benalex Exp $
 45    */
 46    public class AuthorizeTag extends TagSupport {
 47    //~ Instance fields ========================================================
 48   
 49    private String ifAllGranted = "";
 50    private String ifAnyGranted = "";
 51    private String ifNotGranted = "";
 52   
 53    //~ Methods ================================================================
 54   
 55  7 public void setIfAllGranted(String ifAllGranted) throws JspException {
 56  7 this.ifAllGranted = ifAllGranted;
 57    }
 58   
 59  1 public String getIfAllGranted() {
 60  1 return ifAllGranted;
 61    }
 62   
 63  10 public void setIfAnyGranted(String ifAnyGranted) throws JspException {
 64  10 this.ifAnyGranted = ifAnyGranted;
 65    }
 66   
 67  1 public String getIfAnyGranted() {
 68  1 return ifAnyGranted;
 69    }
 70   
 71  5 public void setIfNotGranted(String ifNotGranted) throws JspException {
 72  5 this.ifNotGranted = ifNotGranted;
 73    }
 74   
 75  1 public String getIfNotGranted() {
 76  1 return ifNotGranted;
 77    }
 78   
 79  20 public int doStartTag() throws JspException {
 80  20 if (((null == ifAllGranted) || "".equals(ifAllGranted))
 81    && ((null == ifAnyGranted) || "".equals(ifAnyGranted))
 82    && ((null == ifNotGranted) || "".equals(ifNotGranted))) {
 83  1 return Tag.SKIP_BODY;
 84    }
 85   
 86  19 final Collection granted = getPrincipalAuthorities();
 87   
 88  19 final String evaledIfNotGranted = ExpressionEvaluationUtils
 89    .evaluateString("ifNotGranted", ifNotGranted, pageContext);
 90   
 91  19 if ((null != evaledIfNotGranted) && !"".equals(evaledIfNotGranted)) {
 92  5 Set grantedCopy = retainAll(granted,
 93    parseAuthoritiesString(evaledIfNotGranted));
 94   
 95  5 if (!grantedCopy.isEmpty()) {
 96  3 return Tag.SKIP_BODY;
 97    }
 98    }
 99   
 100  16 final String evaledIfAllGranted = ExpressionEvaluationUtils
 101    .evaluateString("ifAllGranted", ifAllGranted, pageContext);
 102   
 103  16 if ((null != evaledIfAllGranted) && !"".equals(evaledIfAllGranted)) {
 104  6 if (!granted.containsAll(parseAuthoritiesString(evaledIfAllGranted))) {
 105  3 return Tag.SKIP_BODY;
 106    }
 107    }
 108   
 109  13 final String evaledIfAnyGranted = ExpressionEvaluationUtils
 110    .evaluateString("ifAnyGranted", ifAnyGranted, pageContext);
 111   
 112  13 if ((null != evaledIfAnyGranted) && !"".equals(evaledIfAnyGranted)) {
 113  8 Set grantedCopy = retainAll(granted,
 114    parseAuthoritiesString(evaledIfAnyGranted));
 115   
 116  7 if (grantedCopy.isEmpty()) {
 117  3 return Tag.SKIP_BODY;
 118    }
 119    }
 120   
 121  9 return Tag.EVAL_BODY_INCLUDE;
 122    }
 123   
 124  19 private Collection getPrincipalAuthorities() {
 125  19 Authentication currentUser = SecurityContextHolder.getContext()
 126    .getAuthentication();
 127   
 128  19 if (null == currentUser) {
 129  2 return Collections.EMPTY_LIST;
 130    }
 131   
 132  17 if ((null == currentUser.getAuthorities())
 133    || (currentUser.getAuthorities().length < 1)) {
 134  0 return Collections.EMPTY_LIST;
 135    }
 136   
 137  17 Collection granted = Arrays.asList(currentUser.getAuthorities());
 138   
 139  17 return granted;
 140    }
 141   
 142  25 private Set authoritiesToRoles(Collection c) {
 143  25 Set target = new HashSet();
 144   
 145  25 for (Iterator iterator = c.iterator(); iterator.hasNext();) {
 146  33 GrantedAuthority authority = (GrantedAuthority) iterator.next();
 147   
 148  33 if (null == authority.getAuthority()) {
 149  1 throw new IllegalArgumentException(
 150    "Cannot process GrantedAuthority objects which return null from getAuthority() - attempting to process "
 151    + authority.toString());
 152    }
 153   
 154  32 target.add(authority.getAuthority());
 155    }
 156   
 157  24 return target;
 158    }
 159   
 160  19 private Set parseAuthoritiesString(String authorizationsString) {
 161  19 final Set requiredAuthorities = new HashSet();
 162  19 final String[] authorities = StringUtils
 163    .commaDelimitedListToStringArray(authorizationsString);
 164   
 165  19 for (int i = 0; i < authorities.length; i++) {
 166  25 String authority = authorities[i];
 167   
 168    // Remove the role's whitespace characters without depending on JDK 1.4+
 169    // Includes space, tab, new line, carriage return and form feed.
 170  25 String role = StringUtils.replace(authority, " ", "");
 171  25 role = StringUtils.replace(role, "\t", "");
 172  25 role = StringUtils.replace(role, "\r", "");
 173  25 role = StringUtils.replace(role, "\n", "");
 174  25 role = StringUtils.replace(role, "\f", "");
 175   
 176  25 requiredAuthorities.add(new GrantedAuthorityImpl(role));
 177    }
 178   
 179  19 return requiredAuthorities;
 180    }
 181   
 182    /**
 183    * Find the common authorities between the current authentication's {@link
 184    * GrantedAuthority} and the ones that have been specified in the tag's
 185    * ifAny, ifNot or ifAllGranted attributes.
 186    *
 187    * <p>
 188    * We need to manually iterate over both collections, because the granted
 189    * authorities might not implement {@link Object#equals(Object)} and
 190    * {@link Object#hashCode()} in the same way as {@link
 191    * GrantedAuthorityImpl}, thereby invalidating {@link
 192    * Collection#retainAll(java.util.Collection)} results.
 193    * </p>
 194    *
 195    * <p>
 196    * <strong>CAVEAT</strong>: This method <strong>will not</strong> work if
 197    * the granted authorities returns a <code>null</code> string as the
 198    * return value of {@link
 199    * org.acegisecurity.GrantedAuthority#getAuthority()}.
 200    * </p>
 201    *
 202    * <p>
 203    * Reported by rawdave, on Fri Feb 04, 2005 2:11 pm in the Acegi Security
 204    * System for Spring forums.
 205    * </p>
 206    *
 207    * @param granted The authorities granted by the authentication. May be any
 208    * implementation of {@link GrantedAuthority} that does
 209    * <strong>not</strong> return <code>null</code> from {@link
 210    * org.acegisecurity.GrantedAuthority#getAuthority()}.
 211    * @param required A {@link Set} of {@link GrantedAuthorityImpl}s that have
 212    * been built using ifAny, ifAll or ifNotGranted.
 213    *
 214    * @return A set containing only the common authorities between
 215    * <var>granted</var> and <var>required</var>.
 216    *
 217    * @see <a
 218    * href="http://forum.springframework.org/viewtopic.php?t=3367">authz:authorize
 219    * ifNotGranted not behaving as expected</a>
 220    */
 221  13 private Set retainAll(final Collection granted, final Set required) {
 222  13 Set grantedRoles = authoritiesToRoles(granted);
 223  12 Set requiredRoles = authoritiesToRoles(required);
 224  12 grantedRoles.retainAll(requiredRoles);
 225   
 226  12 return rolesToAuthorities(grantedRoles, granted);
 227    }
 228   
 229  12 private Set rolesToAuthorities(Set grantedRoles, Collection granted) {
 230  12 Set target = new HashSet();
 231   
 232  12 for (Iterator iterator = grantedRoles.iterator(); iterator.hasNext();) {
 233  7 String role = (String) iterator.next();
 234   
 235  7 for (Iterator grantedIterator = granted.iterator();
 236  10 grantedIterator.hasNext();) {
 237  10 GrantedAuthority authority = (GrantedAuthority) grantedIterator
 238    .next();
 239   
 240  10 if (authority.getAuthority().equals(role)) {
 241  7 target.add(authority);
 242   
 243  7 break;
 244    }
 245    }
 246    }
 247   
 248  12 return target;
 249    }
 250    }