Package org.geowebcache.security

Source Code of org.geowebcache.security.RESTfulDefinitionSource$RESTfulDefinitionSourceMapping

/**
* This code is taken from Spring and therefore presumably licensed under Apache 2.0
*
* http://www.apache.org/licenses/LICENSE-2.0.html
*
* @author Chris Berry
*         http://opensource.atlassian.com/projects/spring/browse/SEC-531
*/

package org.geowebcache.security;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.SecurityConfig;
import org.acegisecurity.intercept.web.FilterInvocation;
import org.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
import org.acegisecurity.util.StringSplitUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;


public class RESTfulDefinitionSource implements
        FilterInvocationDefinitionSource {

    static private Log log = LogFactory.getLog(RESTfulDefinitionSource.class);

    static private final String[] validMethodNames =
        { "GET", "PUT", "DELETE", "POST", "HEAD" };

    /**
     * Underlying objectDefinitionSource object
     */
    private RESTfulPathBasedFilterInvocationDefinitionMap delegate = null;

    /**
     * Override the method in AbstractFilterInvocationDefinitionSource
     */
    public ConfigAttributeDefinition getAttributes(Object object)
            throws IllegalArgumentException {
        if ((object == null) || !this.supports(object.getClass())) {
            throw new IllegalArgumentException(
                    "Object must be a FilterInvocation");
        }

        String url = ((FilterInvocation) object).getRequestUrl();
        String method = ((FilterInvocation) object).getHttpRequest()
                .getMethod();

        return delegate.lookupAttributes(url, method);
    }

    public ConfigAttributeDefinition lookupAttributes(String url, String method) {
        return delegate.lookupAttributes(url, method);
    }

    public Iterator getConfigAttributeDefinitions() {
        return delegate.getConfigAttributeDefinitions();
    }

    /**
     * Duplicated from AbstractFilterInvocationDefinitionSource
     */
    public boolean supports(Class clazz) {
        return FilterInvocation.class.isAssignableFrom(clazz);
    }

    /**
     * Creates a proxy to a PathBasedFilterInvocationDefinitionMap to delegate
     * calls. Initializations of the delegate is done here.
     */
    public RESTfulDefinitionSource(String pathToRoleList)
            throws IllegalArgumentException {
        delegate = new RESTfulPathBasedFilterInvocationDefinitionMap();
        processPathList(pathToRoleList);
    }

    /**
     * this is completely bogus. I am duplicating code in
     * FilterInvocationDefinitionSourceEditor
     */
    private void processPathList(String pathToRoleList)
            throws IllegalArgumentException {
        delegate.setConvertUrlToLowercaseBeforeComparison(true);

        BufferedReader br = new BufferedReader(new StringReader(pathToRoleList));
        int counter = 0;
        String line;

        List mappings = new ArrayList<String>();

        while (true) {
            counter++;
            try {
                line = br.readLine();
            } catch (IOException ioe) {
                throw new IllegalArgumentException(ioe.getMessage());
            }

            if (line == null) {
                break;
            }

            line = line.trim();

            if (log.isDebugEnabled()) {
                log.debug("Line " + counter + ": " + line);
            }

            if (line.startsWith("//")) {
                continue;
            }

            // Skip lines that are not directives
            if (line.lastIndexOf('=') == -1) {
                continue;
            }

            if (line.lastIndexOf("==") != -1) {
                throw new IllegalArgumentException(
                        "Only single equals should be used in line " + line);
            }

            // Tokenize the line into its name/value tokens
            // As per SEC-219, use the LAST equals as the delimiter between LHS
            // and RHS
            String name = StringSplitUtils.substringBeforeLast(line, "=");
            String value = StringSplitUtils.substringAfterLast(line, "=");

            if (!StringUtils.hasText(name) || !StringUtils.hasText(value)) {
                throw new IllegalArgumentException(
                        "Failed to parse a valid name/value pair from " + line);
            }

            String antPath = name;
            String methods = null;

            int firstColonIndex = name.indexOf(":");
            if (log.isDebugEnabled())
                log.debug("~~~~~~~~~~ name= " + name + " firstColonIndex= "
                        + firstColonIndex);

            if (firstColonIndex != -1) {
                antPath = name.substring(0, firstColonIndex);
                methods = name.substring((firstColonIndex + 1), name.length());
            }
            if (log.isDebugEnabled())
                log.debug("~~~~~~~~~~ name= " + name + " antPath= " + antPath
                        + " methods= " + methods);

            String[] methodList = null;
            if (methods != null) {
                methodList = methods.split(",");

                // Verify methodList is valid
                for (int ii = 0; ii < methodList.length; ii++) {
                    boolean matched = false;
                    for (int jj = 0; jj < validMethodNames.length; jj++) {
                        if (methodList[ii].equals(validMethodNames[jj])) {
                            matched = true;
                            break;
                        }
                    }
                    if (!matched) {
                        throw new IllegalArgumentException(
                                "The HTTP Method Name ("
                                        + methodList[ii]
                                        + " does NOT equal a valid name (GET,PUT,POST,DELETE)");
                    }
                }
            }
            if (log.isDebugEnabled()) {
                log.debug("methodList = " + Arrays.toString(methodList));
                if (methodList != null) {
                    for (int ii = 0; ii < methodList.length; ii++)
                        log.debug("method[" + ii + "]: " + methodList[ii]);
                }
            }

            // Should all be lowercase; check each character
            // We only do this for Ant (regexp have control chars)
            for (int i = 0; i < antPath.length(); i++) {
                String character = antPath.substring(i, i + 1);
                if (!character.toLowerCase().equals(character)) {
                    throw new IllegalArgumentException(
                            "You are using Ant Paths, yet you have specified an uppercase character in line: "
                                    + line + " (character '" + character + "')");
                }
            }

            RESTfulDefinitionSourceMapping mapping = new RESTfulDefinitionSourceMapping();
            mapping.setUrl(antPath);
            mapping.setHttpMethods(methodList);

            String[] tokens = StringUtils
                    .commaDelimitedListToStringArray(value);

            for (int i = 0; i < tokens.length; i++) {
                mapping.addConfigAttribute(tokens[i].trim());
            }
            mappings.add(mapping);
        }

        // This will call the addSecureUrl in
        // RESTfulPathBasedFilterInvocationDefinitionMap
        // which is how this whole convoluted beast gets wired together
        // source.setMappings(mappings);
        setMappings(mappings);
    }

    public void setMappings(List mappings) {
        Iterator it = mappings.iterator();
        while (it.hasNext()) {
            RESTfulDefinitionSourceMapping mapping = (RESTfulDefinitionSourceMapping) it.next();
            ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();

            Iterator configAttributesIt = mapping.getConfigAttributes().iterator();
            while (configAttributesIt.hasNext()) {
                String s = (String) configAttributesIt.next();
                configDefinition.addConfigAttribute(new SecurityConfig(s));
            }
            delegate.addSecureUrl(mapping.getUrl(), mapping.getHttpMethods(),
                    configDefinition);
        }
    }

    // ++++++++++++++++++++++++
    static public class RESTfulDefinitionSourceMapping {
        private String url = null;

        private List configAttributes = new ArrayList<String>();

        private String[] httpMethods = null;

        public void setHttpMethods(String[] httpMethods) {
            this.httpMethods = httpMethods;
        }

        /**
         * A null httpMethods implies that ALL methods are accepted
         */
        public String[] getHttpMethods() {
            return httpMethods;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getUrl() {
            return url;
        }

        public void setConfigAttributes(List roles) {
            this.configAttributes = roles;
        }

        public List getConfigAttributes() {
            return configAttributes;
        }

        public void addConfigAttribute(String configAttribute) {
            configAttributes.add(configAttribute);
        }
    }

}
TOP

Related Classes of org.geowebcache.security.RESTfulDefinitionSource$RESTfulDefinitionSourceMapping

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.