com.denimgroup.threadfix.framework.impl.spring.SpringControllerMappings.java Source code

Java tutorial

Introduction

Here is the source code for com.denimgroup.threadfix.framework.impl.spring.SpringControllerMappings.java

Source

////////////////////////////////////////////////////////////////////////
//
//     Copyright (c) 2009-2015 Denim Group, Ltd.
//
//     The contents of this file are subject to the Mozilla Public License
//     Version 2.0 (the "License"); you may not use this file except in
//     compliance with the License. You may obtain a copy of the License at
//     http://www.mozilla.org/MPL/
//
//     Software distributed under the License is distributed on an "AS IS"
//     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//     License for the specific language governing rights and limitations
//     under the License.
//
//     The Original Code is ThreadFix.
//
//     The Initial Developer of the Original Code is Denim Group, Ltd.
//     Portions created by Denim Group, Ltd. are Copyright (C)
//     Denim Group, Ltd. All Rights Reserved.
//
//     Contributor(s): Denim Group, Ltd.
//
////////////////////////////////////////////////////////////////////////
package com.denimgroup.threadfix.framework.impl.spring;

import com.denimgroup.threadfix.XMLUtils;
import com.denimgroup.threadfix.data.interfaces.Endpoint;
import com.denimgroup.threadfix.exception.RestIOException;
import com.denimgroup.threadfix.framework.engine.full.EndpointGenerator;
import com.denimgroup.threadfix.framework.filefilter.FileExtensionFileFilter;
import com.denimgroup.threadfix.framework.impl.spring.auth.InterceptUrl;
import com.denimgroup.threadfix.framework.impl.spring.auth.SpringSecurityXmlParser;
import com.denimgroup.threadfix.framework.util.EventBasedTokenizerRunner;
import com.denimgroup.threadfix.framework.util.FilePathUtils;
import com.denimgroup.threadfix.framework.util.java.EntityMappings;
import com.denimgroup.threadfix.framework.util.java.EntityParser;
import com.denimgroup.threadfix.logging.SanitizedLogger;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;

import javax.annotation.Nonnull;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.*;

import static com.denimgroup.threadfix.CollectionUtils.*;
import static com.denimgroup.threadfix.data.entities.AuthenticationRequired.ANONYMOUS;
import static com.denimgroup.threadfix.data.entities.AuthenticationRequired.AUTHENTICATED;

public class SpringControllerMappings implements EndpointGenerator {

    @Nonnull
    private final Collection<File> javaFiles;
    @Nonnull
    private final Collection<File> xmlFiles;

    private static final SanitizedLogger LOG = new SanitizedLogger(SpringControllerMappings.class);

    @Nonnull
    private final Map<String, Set<SpringControllerEndpoint>> urlToControllerMethodsMap, controllerToUrlsMap;

    @Nonnull
    private final File rootDirectory;

    @Nonnull
    private List<SpringControllerEndpoint> endpointsList = list();

    @SuppressWarnings("unchecked")
    public SpringControllerMappings(@Nonnull File rootDirectory) {
        this.rootDirectory = rootDirectory;

        urlToControllerMethodsMap = map();
        controllerToUrlsMap = map();

        if (rootDirectory.exists()) {
            javaFiles = getFiles(rootDirectory, "java");
            xmlFiles = getFiles(rootDirectory, "xml");
            generateMaps();
        } else {
            javaFiles = Collections.emptyList();
            xmlFiles = Collections.emptyList();
        }
    }

    private Collection<File> getFiles(File rootDirectory, String extension) {
        return FileUtils.listFiles(rootDirectory, new FileExtensionFileFilter(extension), TrueFileFilter.INSTANCE);
    }

    @Nonnull
    public Set<SpringControllerEndpoint> getEndpointsFromController(String controllerPath) {
        if (controllerToUrlsMap.containsKey(controllerPath)) {
            return controllerToUrlsMap.get(controllerPath);
        } else {
            return set();
        }
    }

    @Nonnull
    public Set<SpringControllerEndpoint> getEndpointsFromUrl(String controllerPath) {
        if (urlToControllerMethodsMap.containsKey(controllerPath)) {
            return urlToControllerMethodsMap.get(controllerPath);
        } else {
            return set();
        }
    }

    private void generateMaps() {
        List<EntityParser> entityParsers = list();

        SpringDataBinderParser globalDataBinderParser = null;

        SpringSecurityXmlParser securityXmlParser = new SpringSecurityXmlParser();
        for (File file : xmlFiles) {
            if (file != null && file.exists() && file.isFile()
                    && file.getAbsolutePath().contains(rootDirectory.getAbsolutePath())) {

                try {
                    XMLUtils.readSAXInput(securityXmlParser, "", new FileInputStream(file));

                    if (!securityXmlParser.urls.isEmpty() || securityXmlParser.prePostEnabled) {
                        break;
                    }

                } catch (FileNotFoundException e) {
                    // this shouldn't happen
                    LOG.error("This is an illegal code path. security.xml results won't be available", e);
                } catch (RestIOException e) {
                    LOG.error("Encountered XML parsing error while parsing file " + file.getAbsolutePath());
                }
            }
        }

        for (File file : javaFiles) {
            if (file != null && file.exists() && file.isFile()
                    && file.getAbsolutePath().contains(rootDirectory.getAbsolutePath())) {

                SpringControllerEndpointParser endpointParser = new SpringControllerEndpointParser(
                        file.getAbsolutePath());
                EntityParser entityParser = new EntityParser();
                SpringDataBinderParser dataBinderParser = new SpringDataBinderParser();
                EventBasedTokenizerRunner.run(file, entityParser, endpointParser, dataBinderParser);

                entityParsers.add(entityParser);
                addEndpointsToMaps(file, endpointParser, dataBinderParser);

                if (dataBinderParser.isGlobal) {
                    globalDataBinderParser = dataBinderParser;
                }
            }
        }

        EntityMappings mappings = new EntityMappings(entityParsers);

        for (SpringControllerEndpoint endpoint : endpointsList) {
            for (InterceptUrl url : securityXmlParser.urls) {
                if (url.matches(endpoint.getUrlPath())) {
                    endpoint.getRequiredPermissions().add(url.role);
                }
            }
            endpoint.expandParameters(mappings, globalDataBinderParser);
            if (endpoint.getRequiredPermissions().contains("IS_AUTHENTICATED_ANONYMOUSLY")) {
                endpoint.setAuthenticationRequired(ANONYMOUS);
            } else if (!endpoint.getRequiredPermissions().isEmpty()) {
                endpoint.setAuthenticationRequired(AUTHENTICATED);
            }
        }
    }

    private String getFileName(File file) {
        String fileNameWithoutRoot = FilePathUtils.getRelativePath(file, rootDirectory);

        if (fileNameWithoutRoot != null && fileNameWithoutRoot.indexOf("/") != 0) {
            fileNameWithoutRoot = "/" + fileNameWithoutRoot;
        }

        return fileNameWithoutRoot;
    }

    private void addEndpointsToMaps(File file, SpringControllerEndpointParser endpointParser,
            SpringDataBinderParser dataBinderParser) {
        if (endpointParser.hasControllerAnnotation) {

            endpointsList.addAll(endpointParser.endpoints);

            for (SpringControllerEndpoint endpoint : endpointParser.endpoints) {
                endpoint.setFileRoot(rootDirectory.getAbsolutePath());
                endpoint.setDataBinderParser(dataBinderParser);
                String urlPath = endpoint.getCleanedUrlPath();
                if (!urlToControllerMethodsMap.containsKey(urlPath)) {
                    urlToControllerMethodsMap.put(urlPath, new TreeSet<SpringControllerEndpoint>());
                }
                urlToControllerMethodsMap.get(endpoint.getCleanedUrlPath()).add(endpoint);
            }

            controllerToUrlsMap.put(getFileName(file), endpointParser.endpoints);
        }
    }

    @Nonnull
    @Override
    public List<Endpoint> generateEndpoints() {
        List<Endpoint> returnEndpoints = list();

        for (Set<SpringControllerEndpoint> endpointList : urlToControllerMethodsMap.values()) {
            for (SpringControllerEndpoint endpoint : endpointList) {
                returnEndpoints.add(endpoint);
            }
        }

        return returnEndpoints;
    }

    @Nonnull
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();

        for (Endpoint endpoint : generateEndpoints()) {
            builder.append(endpoint).append("\n");
        }

        return builder.toString();
    }

    @Override
    public Iterator<Endpoint> iterator() {
        return generateEndpoints().iterator();
    }
}