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

com.sap.cloud.yaas.servicesdk.apiconsole.utils.ApiConsoleLocationProvider Maven / Gradle / Ivy

There is a newer version: 4.17.1
Show newest version
/*
 * © 2016 SAP SE or an SAP affiliate company.
 * All rights reserved.
 * Please see http://www.sap.com/corporate-en/legal/copyright/index.epx for additional trademark information and
 * notices.
 */
package com.sap.cloud.yaas.servicesdk.apiconsole.utils;

import com.sap.cloud.yaas.servicesdk.ramlrewriter.filter.ExternalUrlHeaderUtil;
import com.sap.cloud.yaas.servicesdk.security.PathTraversalException;
import com.sap.cloud.yaas.servicesdk.security.SecurityUtils;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Utility class for providing the path to the API Console (with '?raml' parameter), which is different depending on
 * whether the call comes from inside or outside the proxy.
 */
public class ApiConsoleLocationProvider
{
	/**
	 * Query parameter for specifying a raml file.
	 */
	public static final String RAML_QUERY_PARAM = "raml";

	private static final Logger LOG = LoggerFactory.getLogger(ApiConsoleLocationProvider.class);

	private static final String REQUESTED_RESOURCE_DOES_NOT_EXIST = "Requested resource does not exist.";

	private final RamlFilePathProvider ramlFilePathProvider = new RamlFilePathProvider();

	/**
	 * Redirects to the given URI.
	 *
	 * @param uriToRedirectTo the URI to which to redirect
	 * @return the redirect response
	 */
	public Response processRedirect(final URI uriToRedirectTo)
	{
		return Response.temporaryRedirect(uriToRedirectTo).build();
	}

	/**
	 * Returns the URI of the API Console, e.g.
	 * "http://yaas-test.apigee.net/test/email/v2/api-console/index.html?raml=raml/api/emailservice.raml", or
	 * "http://email-v2.test.cf.hybris.com/api-console/index.html?raml=raml/api/emailservice.raml". It uses
	 * {@link RamlFilePathProvider} for resolving the value of "raml" parameter.
	 *
	 * @param baseUri the original base URI of the console
	 * @param externalUrlHeader the optional header appended by the proxy
	 * @return the full path to the console that will display the RAML-based API
	 */
	public URI getApiConsoleUri(final UriInfo baseUri, final String externalUrlHeader)
	{
		URI result = null;
		if (ExternalUrlHeaderUtil.isExternal(externalUrlHeader))
		{
			result = ExternalUrlHeaderUtil.asExternalUri(externalUrlHeader);
		}
		else
		{
			result = baseUri.getRequestUri();
		}
		return UriBuilder
				.fromUri(result)
				.queryParam(RAML_QUERY_PARAM, RamlFilePathProvider.RAML_RESOURCE_PATH + getRelativeRamlUri())
				.build();
	}

	/**
	 * Returns the URI of the main RAML file, relative to the {@link RamlFilePathProvider#RAML_RESOURCE_PATH}, e.g.
	 * "api/emailservice.raml"
	 *
	 * @return the relative path to the {@link #ramlFilePathProvider.RAML_RESOURCE_PATH} that will provide the RAML
	 */
	public String getRelativeRamlUri()
	{
		return ramlFilePathProvider.getRamlResourcePath();
	}

	/**
	 * Resolves given raml resource in relation to given root folder by assuring that it will not traverse outside the
	 * root folder.
	 * 
	 * @param basePath root folder where the resource will be resolved in
	 * @param resource resource to resolve
	 * @return URL to resolved resource
	 */
	public URL resolveRamlResource(final Path basePath, final String resource)
	{
		final Path path = SecurityUtils.sanitizePath(basePath, stripApiPathFromRamlFile(resource));
		if (!path.toFile().exists())
		{
			if (LOG.isTraceEnabled())
			{
				LOG.trace(String.format("RAML file located in '%s' not found ", path.toString()));
			}
			throw new PathTraversalException(REQUESTED_RESOURCE_DOES_NOT_EXIST);
		}

		try
		{
			return path.toUri().toURL();
		}
		catch (final MalformedURLException e)
		{
			LOG.error(String.format("RAML file located in '%s' not found, invalid url format ", path.toString()), e);
			throw new PathTraversalException(REQUESTED_RESOURCE_DOES_NOT_EXIST, e);
		}
	}

	/**
	 * Strips the prefix for the uri parameter.
	 */
	@SuppressWarnings("PMD.UnusedPrivateMethod")
	private java.nio.file.Path stripApiPathFromRamlFile(final String ramlResource) throws PathTraversalException
	{
		if (ramlResource.startsWith(RamlFilePathProvider.API_RESOURCE_PATH))
		{
			return Paths.get(ramlResource.substring(RamlFilePathProvider.API_RESOURCE_PATH.length()));
		}
		else
		{
			if (LOG.isTraceEnabled())
			{
				LOG.trace("Retrieved RAML resource is not in the context of the api folder :" + ramlResource);
			}
			throw new PathTraversalException("Retrieved RAML resource is not in the context of the api folder.");
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy