All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.enterprise.security.web.integration.WebPermissionUtil Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.enterprise.security.web.integration;

import com.sun.enterprise.security.web.*;
import com.sun.enterprise.security.*;
import java.util.*;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.WebResourcePermission;
import javax.security.jacc.WebRoleRefPermission;
import javax.security.jacc.WebUserDataPermission;

import java.util.logging.*; 
import com.sun.logging.LogDomains;
import java.security.Permission;
import java.security.Permissions;

import com.sun.enterprise.deployment.*;
import com.sun.enterprise.deployment.web.*;
import com.sun.enterprise.security.acl.*;
/**
 * This class is used for generating Web permissions based on the 
 * deployment descriptor.
 * @author Harpreet Singh
 * @author Jean-Francois Arcand
 * @author Ron Monzillo
 */
public class WebPermissionUtil {

    static Logger logger = Logger.getLogger(LogDomains.SECURITY_LOGGER);
    
    public WebPermissionUtil() {
    }
    
    /* changed to order default pattern / below extension */
    private static final int PT_DEFAULT      = 0;
    private static final int PT_EXTENSION    = 1;
    private static final int PT_PREFIX	     = 2;
    private static final int PT_EXACT 	     = 3;
      
    static int patternType(Object urlPattern) {
	String pattern = urlPattern.toString();
	if (pattern.startsWith("*.")) return PT_EXTENSION;
	else if (pattern.startsWith("/") && pattern.endsWith("/*")) 
	    return PT_PREFIX;
	else if (pattern.equals("/")) return PT_DEFAULT;
	else return PT_EXACT;
    }

    static boolean implies(String pattern, String path) {

        // Check for exact match
        if (pattern.equals(path))
            return (true);

        // Check for path prefix matching
        if (pattern.startsWith("/") && pattern.endsWith("/*")) {
            pattern = pattern.substring(0, pattern.length() - 2);

	    int length = pattern.length();

            if (length == 0) return (true);  // "/*" is the same as "/"

	    return (path.startsWith(pattern) && 
		    (path.length() == length || 
		     path.substring(length).startsWith("/")));
        }

        // Check for suffix matching
        if (pattern.startsWith("*.")) {
            int slash = path.lastIndexOf('/');
            int period = path.lastIndexOf('.');
            if ((slash >= 0) && (period > slash) &&
                path.endsWith(pattern.substring(1))) {
                return (true);
            }
            return (false);
        }

        // Check for universal mapping
        if (pattern.equals("/"))
            return (true);

        return (false);
    }

    public static HashMap parseConstraints(WebBundleDescriptor wbd)
    {
	
      if (logger.isLoggable(Level.FINE)){
	  logger.entering("WebPermissionUtil", "parseConstraints");
      }

      Set roleSet = wbd.getRoles();

      HashMap qpMap = new HashMap();

      // bootstrap the map with the default pattern;
      qpMap.put("/", new MapValue("/"));

      //Enumerate over security constraints
      Enumeration esc = wbd.getSecurityConstraints(); 
      while (esc.hasMoreElements()) {
	  
	  if (logger.isLoggable(Level.FINE)){
	      logger.log(Level.FINE,"JACC: constraint translation: begin parsing security constraint");
	  }

	  SecurityConstraint sc = (SecurityConstraint) esc.nextElement();
	  AuthorizationConstraint ac = sc.getAuthorizationConstraint();
	  UserDataConstraint udc = sc.getUserDataConstraint();

	  // Enumerate over collections of URLPatterns within constraint
	  for (WebResourceCollection wrc: sc.getWebResourceCollections()) {

	      if (logger.isLoggable(Level.FINE)){
		  logger.log(Level.FINE,"JACC: constraint translation: begin parsing web resource collection");
	      }

	      // Enumerate over URLPatterns within collection
	      for (String url: wrc.getUrlPatterns()) {
                  if (url != null) {
 		      // FIX TO BE CONFIRMED: encode all colons
 		      url = url.replaceAll(":","%3A");
 		  }

		  if (logger.isLoggable(Level.FINE)){
		      logger.log(Level.FINE,"JACC: constraint translation: process url: "+url);
		  }

		  // determine if pattern is already in map
		  MapValue mValue = (MapValue) qpMap.get(url);

		  // apply new patterns to map
		  if (mValue == null) {
		      mValue = new MapValue(url);

		      //Iterate over patterns in map
		      Iterator it = qpMap.keySet().iterator(); 
		      while (it.hasNext()) {

			  String otherUrl = (String) it.next();

			  int otherUrlType = patternType(otherUrl);
			  switch(patternType(url)) {

			      // if the new url/pattern is a path-prefix 
			      // pattern, it must be qualified by every 
			      // different (from it) path-prefix pattern 
			      // (in the map) that is implied by the new 
			      // pattern, and every exact pattern (in the map)
			      // that is implied by the new url.
			      // Also, the new pattern  must be added as a 
			      // qualifier of the default pattern, and every 
			      // extension pattern (existing in the map), and 
			      // of every different path-prefix pattern that 
			      // implies the new pattern.
			      // Note that we know that the new pattern does
			      // not exist in the map, thus we know that the
			      // new pattern is different from any existing
			      // path prefix pattern.
	     
			      case PT_PREFIX:
				  if ((otherUrlType == PT_PREFIX || 
				      otherUrlType == PT_EXACT) &&
				      implies(url,otherUrl))
				      mValue.addQualifier(otherUrl);
			  
				  else if (otherUrlType == PT_PREFIX &&
					   implies(otherUrl,url))
				      ((MapValue) qpMap.get(otherUrl)).
					  addQualifier(url);
				  
				  else if (otherUrlType == PT_EXTENSION ||
				       otherUrlType == PT_DEFAULT)
				      ((MapValue) qpMap.get(otherUrl)).
					  addQualifier(url);
				  break;

			      // if the new pattern is an extension pattern,
			      // it must be qualified by every path-prefix
			      // pattern (in the map), and every exact
			      // pattern (in the map) that is implied by
			      // the new pattern.
			      // Also, it must be added as a qualifier of
			      // the defualt pattern, if it exists in the
			      // map.
			      case PT_EXTENSION:
				  if (otherUrlType == PT_PREFIX || 
				       (otherUrlType == PT_EXACT &&
					implies(url,otherUrl)))
				      mValue.addQualifier(otherUrl);

				  else if (otherUrlType == PT_DEFAULT)
				      ((MapValue) qpMap.get(otherUrl)).
					  addQualifier(url); 
				  break;

			      // if the new pattern is the default pattern
			      // it must be qualified by every other pattern
			      // in the map.
			      case PT_DEFAULT:
				  if (otherUrlType != PT_DEFAULT) 
				      mValue.addQualifier(otherUrl);
				  break;

			      // if the new pattern is an exact pattern, it
			      // is not be qualified, but it must be added as 
			      // as a qualifier to the default pattern, and to
			      // every path-prefix or extension pattern (in 
			      // the map) that implies the new pattern.
			      case PT_EXACT:
				  if ((otherUrlType == PT_PREFIX || 
				       otherUrlType == PT_EXTENSION) &&
				      implies(otherUrl,url))
				      ((MapValue) qpMap.get(otherUrl)).
					  addQualifier(url); 
				  else if (otherUrlType == PT_DEFAULT)
				      ((MapValue) qpMap.get(otherUrl)).
					  addQualifier(url);
				  break;
			  }
		      }

		      // add the new pattern and its pattern spec to the map
		      qpMap.put(url, mValue);

		  }

		  String[] methodNames = wrc.getHttpMethodsAsArray();
		  BitSet methods = MethodValue.methodArrayToSet(methodNames);

		  BitSet omittedMethods = null;

		  if (methods.isEmpty()) {
		      String[] omittedNames = 
			  wrc.getHttpMethodOmissionsAsArray();
		      omittedMethods = 
			  MethodValue.methodArrayToSet(omittedNames);
		  }

		  // note that an empty omitted method set is used to represent
		  // the set of all http methods

		  mValue.setMethodOutcomes(roleSet,ac,udc,methods,omittedMethods);

		  if (logger.isLoggable(Level.FINE)){
		      logger.log(Level.FINE,"JACC: constraint translation: end processing url: "+url);
		  }
	      }

	      if (logger.isLoggable(Level.FINE)){
		  logger.log(Level.FINE,"JACC: constraint translation: end parsing web resource collection");
	      }
	  }
	  if (logger.isLoggable(Level.FINE)){
	      logger.log(Level.FINE,"JACC: constraint translation: end parsing security constraint");
	  }
      }

      if (logger.isLoggable(Level.FINE)){
	  logger.exiting("WebPermissionUtil","parseConstraints");
      }

        return qpMap;
    }	

    static void handleExcluded(Permissions collection, MapValue m, String name) {
	String actions = null;
	BitSet excludedMethods = m.getExcludedMethods();
	if (m.otherConstraint.isExcluded()) {
	    BitSet methods = m.getMethodSet();
	    methods.andNot(excludedMethods);
	    if (!methods.isEmpty()) {
		actions = "!" + MethodValue.getActions(methods);
	    }
	} else if (!excludedMethods.isEmpty()) { 
	    actions = MethodValue.getActions(excludedMethods);
	} else {
	    return;
	}

	collection.add(new WebResourcePermission(name,actions));
	collection.add(new WebUserDataPermission(name,actions));

	if (logger.isLoggable(Level.FINE)){
	    logger.log(Level.FINE,"JACC: constraint capture: adding excluded methods: "+ actions);
	}
    }

    static Permissions addToRoleMap(HashMap map,
				    String roleName, Permission p) {
        Permissions collection = map.get(roleName);
	if (collection == null) {
	    collection = new Permissions();
	    map.put(roleName,collection);
	}
	collection.add(p);
	if (logger.isLoggable(Level.FINE)){
	    logger.log(Level.FINE,"JACC: constraint capture: adding methods to role: "+ roleName+" methods: " + p.getActions());
	}
	return collection;
    }
		
    static void handleRoles(HashMap map, MapValue m, 
			    String name) {
	HashMap rMap = m.getRoleMap();
	List roleList = null;
	// handle the roles for the omitted methods
	if (!m.otherConstraint.isExcluded() && m.otherConstraint.isAuthConstrained()) {
	    roleList = m.otherConstraint.roleList;
	    for (String roleName : roleList) {
         	BitSet methods = m.getMethodSet();
		//reduce ommissions for explicit methods granted to role  
		BitSet roleMethods = (BitSet) rMap.get(roleName);
		if (roleMethods != null) {
		    methods.andNot(roleMethods);
		}
		String actions = null;
		if (!methods.isEmpty()) {
		    actions = "!" + MethodValue.getActions(methods);
		}
		addToRoleMap(map,roleName,new WebResourcePermission(name,actions)); 
	    }
	}
	//handle explicit methods, skip roles that were handled above 
	BitSet methods = m.getMethodSet();
	if (!methods.isEmpty()) {
	    Iterator rit = rMap.keySet().iterator();
	    while (rit.hasNext()) {
		String roleName = (String) rit.next();
		if (roleList == null || !roleList.contains(roleName)) {
		    BitSet roleMethods = (BitSet) rMap.get(roleName);
		    if (!roleMethods.isEmpty()) {
			String actions = MethodValue.getActions(roleMethods);
		    	addToRoleMap(map,roleName,new WebResourcePermission(name,actions));
		    }
		}
	    }
	}
    }

    static void handleNoAuth(Permissions collection, MapValue m, 
			     String name) {
	String actions = null;
	BitSet noAuthMethods = m.getNoAuthMethods();
	if (!m.otherConstraint.isAuthConstrained()) {
	    BitSet methods = m.getMethodSet();
	    methods.andNot(noAuthMethods);
	    if (!methods.isEmpty()) {
		actions = "!" + MethodValue.getActions(methods);
	    }
	} else if (!noAuthMethods.isEmpty()) { 
	    actions = MethodValue.getActions(noAuthMethods);
	} else {
	    return;
	}

	collection.add(new WebResourcePermission(name,actions));

	if (logger.isLoggable(Level.FINE)){
	    logger.log(Level.FINE,"JACC: constraint capture: adding unchecked (for authorization) methods: "+ actions);
	}
    }

    static void handleConnections(Permissions collection, MapValue m, 
				  String name) {
	BitSet allConnectMethods = null;
	boolean allConnectAtOther = m.otherConstraint.isConnectAllowed
	    (ConstraintValue.ConnectTypeNone);

	for (int i=0; i rit = roleMap.keySet().iterator();
	while (rit.hasNext()) {
	    String role = rit.next();
	    Permissions pCollection = roleMap.get(role);
	    pc.addToRole(role,pCollection);

	    if (logger.isLoggable(Level.FINE)){
		Enumeration e = pCollection.elements();
		while (e.hasMoreElements()) {
		    Permission p = (Permission) e.nextElement();
		    String ptype = (p instanceof WebResourcePermission) ? "WRP  " : "WUDP ";
		    logger.log(Level.FINE,"JACC: permission("+ role + ") type: "+ ptype + " name: "+ p.getName() + " actions: "+ p.getActions());
		}

	    }
	}

	if (logger.isLoggable(Level.FINE)){
	    logger.exiting("WebPermissionUtil", "processConstraints");
	}

    }
      
    public static void createWebRoleRefPermission(WebBundleDescriptor wbd, 
						  PolicyConfiguration pc)
	throws javax.security.jacc.PolicyContextException 
    {
	if (logger.isLoggable(Level.FINE)){
	    logger.entering("WebPermissionUtil", "createWebRoleRefPermission");
	    logger.log(Level.FINE,"JACC: role-reference translation: Processing WebRoleRefPermission : CODEBASE = "+ pc.getContextID());
	}
	List role = new ArrayList();
	Set roleset = wbd.getRoles();
        Set descs = wbd.getWebComponentDescriptors();
	//V3 Commented for(Enumeration e = wbd.getWebComponentDescriptors(); e.hasMoreElements();){
        for (WebComponentDescriptor comp : descs) {
	    //V3 Commented WebComponentDescriptor comp = (WebComponentDescriptor) e.nextElement();

	    String name = comp.getCanonicalName();
	    Enumeration  esrr = comp.getSecurityRoleReferences();

	    for (; esrr.hasMoreElements();){
		SecurityRoleReference srr = (SecurityRoleReference)esrr.nextElement();
		if(srr != null){
		    String action = srr.getRolename();
		    WebRoleRefPermission wrrp = new WebRoleRefPermission(name, action);
		    role.add(new Role(action));
		    pc.addToRole(srr.getSecurityRoleLink().getName(),wrrp);
		    if (logger.isLoggable(Level.FINE)){
			logger.log(Level.FINE,"JACC: role-reference translation: RoleRefPermission created with name(servlet-name)  = "+ name  + 
				   " and action(Role-name tag) = " + action + " added to role(role-link tag) = "+ srr.getSecurityRoleLink().getName());
		    }

		}
	    }
	    if (logger.isLoggable(Level.FINE)){
		logger.log(Level.FINE,"JACC: role-reference translation: Going through the list of roles not present in RoleRef elements and creating WebRoleRefPermissions ");
	    }
	    for(Iterator it = roleset.iterator(); it.hasNext();){
		Role r = (Role)it.next();
		if (logger.isLoggable(Level.FINE)){
		    logger.log(Level.FINE,"JACC: role-reference translation: Looking at Role =  "+r.getName());
		}
		if(!role.contains(r)){
		    String action = r.getName();
		    WebRoleRefPermission wrrp = new WebRoleRefPermission(name, action);
		    pc.addToRole(action ,wrrp);
		    if (logger.isLoggable(Level.FINE)){
			logger.log(Level.FINE,"JACC: role-reference translation: RoleRef  = "+ action + 
				   " is added for servlet-resource = " + name);
			logger.log(Level.FINE, "JACC: role-reference translation: Permission added for above role-ref =" 
				   + wrrp.getName() +" "+ wrrp.getActions());
		    }
		}
	    }
	}
	if (logger.isLoggable(Level.FINE)){
	    logger.exiting("WebPermissionUtil", "createWebRoleRefPermission");
	}
        
        // START S1AS8PE 4966609
        /**
         * For every security role in the web application add a
         * WebRoleRefPermission to the corresponding role. The name of all such
         * permissions shall be the empty string, and the actions of each 
         * permission shall be the corresponding role name. When checking a 
         * WebRoleRefPermission from a JSP not mapped to a servlet, use a 
         * permission with the empty string as its name
         * and with the argument to isUserInRole as its actions
         */
        for(Iterator it = roleset.iterator(); it.hasNext();){
            Role r = (Role)it.next();
            if (logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE,
                    "JACC: role-reference translation: Looking at Role =  "
                        + r.getName());
            }
            String action = r.getName();
            WebRoleRefPermission wrrp = new WebRoleRefPermission("", action);
            pc.addToRole(action ,wrrp);
            if (logger.isLoggable(Level.FINE)){
                logger.log(Level.FINE,
                    "JACC: role-reference translation: RoleRef  = "
                    + action 
                    + " is added for jsp's that can't be mapped to servlets");
                logger.log(Level.FINE, 
                    "JACC: role-reference translation: Permission added for above role-ref =" 
                     + wrrp.getName() +" "+ wrrp.getActions());
            }
        }
        // END S1AS8PE 4966609
                
    }
    
}

class ConstraintValue {

    static String connectKeys[] = 
    { "NONE",
      "INTEGRAL",
      "CONFIDENTIAL"
    };

    static int ConnectTypeNone = 1;
    static HashMap connectHash = new HashMap();
    static 
    {
	for (int i=0; i roleList;
    int connectSet;

    ConstraintValue() {
	excluded = false;
	ignoreRoleList = false;
	roleList = new ArrayList();
	connectSet = 0;
    }
	
    static boolean bitIsSet(int map , int bit) {
        return (map & bit) == bit ? true : false;
    }

    void setRole(String role) {
	synchronized(roleList) {
	    if (!roleList.contains(role)) {
		roleList.add(role);
	    }
	}
    }   

    void setPredefinedOutcome(boolean outcome) {
	if (!outcome) {
	    excluded = true;
	} else {
	    ignoreRoleList = true;
	}
    }

    void addConnectType(String guarantee) {
	int b = ConnectTypeNone;
	if (guarantee != null) {
	    Integer bit = (Integer) connectHash.get(guarantee);
	    if (bit == null) 
		throw new IllegalArgumentException
		    ("constraint translation error-illegal trx guarantee");
	    b = bit.intValue();
	}

	connectSet |= b;
    }

    boolean isExcluded() {
	return excluded;
    }

    /* ignoreRoleList is true if  there was a security-constraint
     * without an auth-constraint; such a constraint combines to
     * allow access without authentication.
     */
    boolean isAuthConstrained() {
	if (excluded) {
	    return true;
	} else if (ignoreRoleList || roleList.isEmpty()) {
	    return false;
	} 
	return true;
    }

    boolean isTransportConstrained() {
	if (excluded || (connectSet != 0 &&
			 !bitIsSet(connectSet,ConnectTypeNone))) {
	    return true;
	}
	return false;
    }

    boolean isConnectAllowed(int cType) {
	if (!excluded && (connectSet == 0 ||
			  bitIsSet(connectSet,ConnectTypeNone) ||
			  bitIsSet(connectSet,cType))) {
	    return true;
	}
	return false;
    }

    void setOutcome(Set roleSet,
		    AuthorizationConstraint ac, UserDataConstraint udc) {
	if (ac == null) {
	    setPredefinedOutcome(true);
	} else {
	    Enumeration eroles = ac.getSecurityRoles();
	    if (!eroles.hasMoreElements()) {
		setPredefinedOutcome(false);
	    }
	    else while (eroles.hasMoreElements()) {
		SecurityRoleDescriptor srd = 
		    (SecurityRoleDescriptor)eroles.nextElement();
		String roleName = srd.getName();
		if ("*".equals(roleName)) {
		    Iterator it = roleSet.iterator();
		    while(it.hasNext()) {
			setRole(((Role)it.next()).getName());
		    }
		} else {
		    setRole(roleName);
		}
	    }
	}
	addConnectType(udc == null? null :  udc.getTransportGuarantee());

	if (WebPermissionUtil.logger.isLoggable(Level.FINE)){
	    WebPermissionUtil.logger.log
		(Level.FINE,"JACC: setOutcome yields: " + toString());
	}

    }

    void setValue(ConstraintValue constraint) {
	excluded = constraint.excluded;
	ignoreRoleList = constraint.ignoreRoleList;
	roleList = new ArrayList();
	Iterator rit = constraint.roleList.iterator();
	while(rit.hasNext()) {
	    String role = (String) rit.next();
	    roleList.add(role);
	}
	connectSet = constraint.connectSet;
    }

    public String toString() {
	String roles =" roles: ";
	Iterator rit = roleList.iterator();
	while(rit.hasNext()) {
	    roles += (" " + (String) rit.next());
	}
	String transports = "transports: ";
	for (int i=0; i methodNames = new ArrayList();

    int index;

    MethodValue (String methodName) {
	index = getMethodIndex(methodName);
    } 

    MethodValue (String methodName, ConstraintValue constraint) {
	index = getMethodIndex(methodName);
	setValue(constraint);
    } 

    static String getMethodName(int index) {
	synchronized(methodNames) {
	    return methodNames.get(index);
	}
    }

    static int getMethodIndex(String name) {
	synchronized(methodNames) {
	    int index = methodNames.indexOf(name);
	    if (index < 0) {
		index = methodNames.size();
		methodNames.add(index,name);
	    }	
	    return index;
	}
    }

    static String getActions (BitSet methodSet) {
	if (methodSet == null || methodSet.isEmpty()) {
	    return null;
	}
	    
	StringBuffer actions = null;

	for (int i=methodSet.nextSetBit(0); i>=0; i=methodSet.nextSetBit(i+1)){
	    if (actions == null) {
		actions = new StringBuffer();
	    } else {
		actions.append(",");
	    }
	    actions.append(getMethodName(i));
	}

	return (actions == null ? null : actions.toString());
    }

    static String[] getMethodArray (BitSet methodSet) {
	if (methodSet == null || methodSet.isEmpty()) {
	    return null;
	}
	    
	int size = 0;

	ArrayList methods = new ArrayList();

	for (int i=methodSet.nextSetBit(0); i>=0; i=methodSet.nextSetBit(i+1)){
	    methods.add(getMethodName(i));
	    size += 1;
	}

	return (String[]) methods.toArray(new String[size]);
    }

    static BitSet methodArrayToSet(String[] methods) {
	BitSet methodSet = new BitSet();

	for (int i=0; methods != null && i methodValues = 
        new HashMap();

    ConstraintValue otherConstraint; 

    MapValue (String urlPattern) {
	this.patternType = WebPermissionUtil.patternType(urlPattern);
	this.patternLength = urlPattern.length();
	this.irrelevantByQualifier = false;
	this.urlPatternSpec = new StringBuffer(urlPattern);
	this.methodValues = new HashMap();
	otherConstraint = new ConstraintValue();
    } 

    void addQualifier(String urlPattern) {
	if (WebPermissionUtil.implies(urlPattern,
		    this.urlPatternSpec.substring(0,this.patternLength)))
	    this.irrelevantByQualifier = true;
	this.urlPatternSpec.append(":" + urlPattern);
    }

    MethodValue getMethodValue(int methodIndex) {
	String methodName = MethodValue.getMethodName(methodIndex);
	synchronized(methodValues) {
	    MethodValue methodValue = methodValues.get(methodName);
	    if (methodValue == null) {
		methodValue = new MethodValue(methodName,otherConstraint);
		methodValues.put(methodName,methodValue);

		if (WebPermissionUtil.logger.isLoggable(Level.FINE)){
		    WebPermissionUtil.logger.log
			(Level.FINE,"JACC: created MethodValue: " +
			 methodValue); 
		}
	    }
	    return methodValue;
	}
    }

    BitSet getExcludedMethods() {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {
		MethodValue v = (MethodValue) it.next();
		if (v.isExcluded()) {
		    methodSet.set(v.index);
		}
	    }
	}
	return methodSet;
    }

    BitSet getNoAuthMethods() {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {
		MethodValue v = (MethodValue) it.next();
		if (!v.isAuthConstrained()) {
		    methodSet.set(v.index);
		}
	    }
	}
	return methodSet;
    }

    BitSet getAuthConstrainedMethods() {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {
		MethodValue v = (MethodValue) it.next();
		if (v.isAuthConstrained()) {
		    methodSet.set(v.index);
		}
	    }
	}
	return methodSet;
    }

    BitSet getTransportConstrainedMethods() {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {
		MethodValue v = (MethodValue) it.next();
		if (v.isTransportConstrained()) {
		    methodSet.set(v.index);
		}
	    }
	}
	return methodSet;
    }

    /**
     * Map of methods allowed per role
     */
    HashMap getRoleMap() {
	HashMap roleMap = new HashMap();

	synchronized(methodValues) {

	    Collection values = methodValues.values();

	    Iterator it = values.iterator();
	    while (it.hasNext()) {

		MethodValue v = (MethodValue) it.next();
		
		if (!v.isExcluded() && v.isAuthConstrained()) {

		    Iterator rit = v.roleList.iterator();
		    while(rit.hasNext()) {

			String role = (String) rit.next();
			BitSet methodSet = (BitSet) roleMap.get(role);

			if (methodSet == null) {
			    methodSet = new BitSet();
			    roleMap.put(role,methodSet);
			}

			methodSet.set(v.index);
		    }
		}
	    }
	}

	return roleMap;
    }

    BitSet getConnectMap(int cType) {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {

		MethodValue v = (MethodValue) it.next();

		/* 
		 * NOTE WELL: prior version of this method 
		 * could not be called during constraint parsing
		 * because it finalized the connectSet when its 
		 * value was 0 (indicating any connection, until
		 * some specific bit is set)
		 *
		    if (v.connectSet == 0) {
		        v.connectSet = MethodValue.connectTypeNone;
		    }

		*/

		if (v.isConnectAllowed(cType)) {
		    methodSet.set(v.index);
		}
	    }
	}

	return methodSet;
    }

    BitSet getMethodSet() {
	BitSet methodSet = new BitSet();

	synchronized(methodValues) {

	    Collection values = methodValues.values();
	    Iterator it = values.iterator();

	    while (it.hasNext()) {

		MethodValue v = (MethodValue) it.next();
		methodSet.set(v.index);

	    }
	}

	return methodSet;
    }

    void setMethodOutcomes(Set roleSet,
			   AuthorizationConstraint ac, UserDataConstraint udc, 
			   BitSet methods,BitSet omittedMethods) {

	if (omittedMethods != null) {
	    
	    // get the ommitted methodSet
	    BitSet methodsInMap = getMethodSet();

	    BitSet saved = (BitSet) omittedMethods.clone();

	    // determine methods being newly omitted
	    omittedMethods.andNot(methodsInMap);

	    // create values for newly omitted, init from otherConstraint
	    for (int i = omittedMethods.nextSetBit(0); i >= 0; 
		 i = omittedMethods.nextSetBit(i+1)) {
		getMethodValue(i);
	    }
	    
	    //combine this constraint into constraint on all other methods
	    otherConstraint.setOutcome(roleSet,ac,udc);

	    methodsInMap.andNot(saved);

	    // recursive call to combine constraint into prior omitted methods 
	    setMethodOutcomes(roleSet,ac,udc,methodsInMap,null);
	    
	} else {

	    for (int i = methods.nextSetBit(0); i >= 0; 
		 i = methods.nextSetBit(i+1)){
		// create values (and init from otherConstraint) if not in map
		// then combine with this constraint.
		getMethodValue(i).setOutcome(roleSet,ac,udc);
	    }
	}
    }
}








© 2015 - 2025 Weber Informatics LLC | Privacy Policy