From 5aa8aec689a399e7803e84e531532d0c61631ec1 Mon Sep 17 00:00:00 2001 From: Instrumental Date: Wed, 7 Nov 2018 20:52:15 -0600 Subject: Fix/Renable sidecar builds Issue-ID: AAF-613 Change-Id: Ic13411eebbf3c1c9b6d8492aff1b37db37a965e4 Signed-off-by: Instrumental --- .../ReverseProxyEntryExitLoggingAspect.java | 45 +++++ .../rpoxy/logging/ReverseProxyMethodLogTime.java | 51 +++++ .../ReverseProxyMethodLogTimeAnnotation.java | 30 +++ .../sidecar/rproxy/ReverseProxyApplication.java | 182 +++++++++++++++++ .../rproxy/ReverseProxyAuthorizationFilter.java | 216 +++++++++++++++++++++ .../cadi/sidecar/rproxy/ReverseProxyService.java | 167 ++++++++++++++++ .../cadi/sidecar/rproxy/config/CadiProperties.java | 41 ++++ .../rproxy/config/ForwardProxyProperties.java | 67 +++++++ .../rproxy/config/PrimaryServiceProperties.java | 58 ++++++ .../rproxy/config/ReverseProxySSLProperties.java | 56 ++++++ .../ReverseProxyURIAuthorizationProperties.java | 38 ++++ .../rproxy/mocks/ReverseProxyMockCadiFilter.java | 143 ++++++++++++++ .../rproxy/utils/ReverseProxyAuthorization.java | 34 ++++ .../sidecar/rproxy/utils/ReverseProxyUtils.java | 29 +++ 14 files changed, 1157 insertions(+) create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyEntryExitLoggingAspect.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTime.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTimeAnnotation.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyApplication.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyService.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/CadiProperties.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ForwardProxyProperties.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/PrimaryServiceProperties.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxySSLProperties.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxyURIAuthorizationProperties.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/mocks/ReverseProxyMockCadiFilter.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java create mode 100644 sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyUtils.java (limited to 'sidecar/rproxy/src/main/java/org/onap/aaf/cadi') diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyEntryExitLoggingAspect.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyEntryExitLoggingAspect.java new file mode 100644 index 0000000..b6e2f85 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyEntryExitLoggingAspect.java @@ -0,0 +1,45 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rpoxy.logging; + +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class ReverseProxyEntryExitLoggingAspect { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReverseProxyEntryExitLoggingAspect.class); + + @Before("execution(* org.onap.platform.security.*.*(..))") + public void before(JoinPoint joinPoint) { + LOGGER.info("Entry of {}#{}", joinPoint.getTarget().getClass(), joinPoint.getSignature().getName()); + } + + @After("execution(* org.onap.platform.security.*.*(..))") + public void after(JoinPoint joinPoint) { + LOGGER.info("Exit of {}#{}", joinPoint.getTarget().getClass(), joinPoint.getSignature().getName()); + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTime.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTime.java new file mode 100644 index 0000000..bc3a489 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTime.java @@ -0,0 +1,51 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rpoxy.logging; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Configuration; + +@Aspect +@Configuration +public class ReverseProxyMethodLogTime { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReverseProxyMethodLogTime.class); + + @Around("@annotation(org.onap.aaf.rproxy.logging.ReverseProxyMethodLogTimeAnnotation)") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + + long startTime = System.currentTimeMillis(); + + Object object = joinPoint.proceed(); + + long duration = System.currentTimeMillis() - startTime; + + LOGGER.info("Time taken by {} is {} ms", joinPoint, duration); + + return object; + } + + + +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTimeAnnotation.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTimeAnnotation.java new file mode 100644 index 0000000..ddd6fe9 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rpoxy/logging/ReverseProxyMethodLogTimeAnnotation.java @@ -0,0 +1,30 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rpoxy.logging; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ReverseProxyMethodLogTimeAnnotation { +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyApplication.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyApplication.java new file mode 100644 index 0000000..3e36935 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyApplication.java @@ -0,0 +1,182 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.HashMap; +import java.util.Properties; +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.net.ssl.SSLContext; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.eclipse.jetty.util.security.Password; +import org.onap.aaf.cadi.filter.CadiFilter; +import org.onap.aaf.cadi.sidecar.rproxy.config.ForwardProxyProperties; +import org.onap.aaf.cadi.sidecar.rproxy.config.PrimaryServiceProperties; +import org.onap.aaf.cadi.sidecar.rproxy.config.ReverseProxySSLProperties; +import org.onap.aaf.cadi.sidecar.rproxy.mocks.ReverseProxyMockCadiFilter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.web.servlet.RegistrationBean; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.util.ResourceUtils; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication +@ServletComponentScan +@EnableConfigurationProperties(ReverseProxySSLProperties.class) +@PropertySource("file:${CONFIG_HOME}/reverse-proxy.properties") +public class ReverseProxyApplication extends SpringBootServletInitializer { + + private static final String CADI_TRUSTSTORE_PASS = "cadi_truststore_password"; + + @Autowired + private Environment env; + + /** + * Spring Boot Initialisation. + * + * @param args main args + */ + public static void main(String[] args) { + String keyStorePassword = System.getProperty("KEY_STORE_PASSWORD"); + if (keyStorePassword == null || keyStorePassword.isEmpty()) { + throw new IllegalArgumentException("Env property KEY_STORE_PASSWORD not set"); + } + HashMap props = new HashMap<>(); + props.put("server.ssl.key-store-password", Password.deobfuscate(keyStorePassword)); + new ReverseProxyApplication() + .configure(new SpringApplicationBuilder(ReverseProxyApplication.class).properties(props)).run(args); + } + + /** + * Set required trust store system properties using values from application.properties + */ + @PostConstruct + public void setSystemProperties() { + String keyStorePath = env.getProperty("server.ssl.key-store"); + if (keyStorePath != null) { + String keyStorePassword = env.getProperty("server.ssl.key-store-password"); + + if (keyStorePassword != null) { + System.setProperty("javax.net.ssl.keyStore", keyStorePath); + System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword); + System.setProperty("javax.net.ssl.trustStore", keyStorePath); + System.setProperty("javax.net.ssl.trustStorePassword", keyStorePassword); + } else { + throw new IllegalArgumentException("Env property server.ssl.key-store-password not set"); + } + } + } + + @Resource + private ReverseProxySSLProperties reverseProxySSLProperties; + + @Resource + Properties cadiProps; + + @Bean(name = "ForwardProxyProperties") + public ForwardProxyProperties forwardProxyProperties() { + return new ForwardProxyProperties(); + } + + @Bean(name = "PrimaryServiceProperties") + public PrimaryServiceProperties primaryServiceProperties() { + return new PrimaryServiceProperties(); + } + + @Profile("secure") + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) throws GeneralSecurityException, IOException { + return new RestTemplate(new HttpComponentsClientHttpRequestFactory(getClientBuilder().build())); + } + + @Profile("noHostVerification") + @Bean + public RestTemplate restTemplateNoHostVerification(RestTemplateBuilder builder) + throws GeneralSecurityException, IOException { + return new RestTemplate(new HttpComponentsClientHttpRequestFactory( + getClientBuilder().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build())); + } + + private HttpClientBuilder getClientBuilder() throws GeneralSecurityException, IOException { + + SSLContext sslContext = SSLContextBuilder.create() + .loadKeyMaterial(ResourceUtils.getFile(reverseProxySSLProperties.getClientcert()), + reverseProxySSLProperties.getKeystorePassword().toCharArray(), + reverseProxySSLProperties.getKeystorePassword().toCharArray()) + .loadTrustMaterial(ResourceUtils.getFile(reverseProxySSLProperties.getKeystore()), + reverseProxySSLProperties.getKeystorePassword().toCharArray()) + .build(); + + return HttpClients.custom().setSSLContext(sslContext); + } + + @Profile("cadi") + @Bean + public FilterRegistrationBean registerCADIFilter() { + + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(); + + filterRegistrationBean.setFilter(new CadiFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.setName("CADIFilter"); + filterRegistrationBean.setOrder(RegistrationBean.HIGHEST_PRECEDENCE); + + // Deobfuscate truststore password + String trustStorePassword = cadiProps.getProperty(CADI_TRUSTSTORE_PASS); + if (trustStorePassword != null) { + cadiProps.setProperty(CADI_TRUSTSTORE_PASS, Password.deobfuscate(trustStorePassword)); + } + + // Add filter init params + cadiProps.forEach((k, v) -> filterRegistrationBean.addInitParameter((String) k, (String) v)); + + return filterRegistrationBean; + } + + @Profile("mockCadi") + @Bean + public FilterRegistrationBean registerMockCADIFilter() { + + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(); + + filterRegistrationBean.setFilter(new ReverseProxyMockCadiFilter()); + filterRegistrationBean.addUrlPatterns("/*"); + filterRegistrationBean.setName("CADIFilter"); + filterRegistrationBean.setOrder(RegistrationBean.HIGHEST_PRECEDENCE); + + return filterRegistrationBean; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java new file mode 100644 index 0000000..2ef4cc0 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java @@ -0,0 +1,216 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import javax.annotation.Resource; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.http.HttpStatus; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.sidecar.rproxy.config.ReverseProxyURIAuthorizationProperties; +import org.onap.aaf.cadi.sidecar.rproxy.utils.ReverseProxyAuthorization; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(1) +@EnableConfigurationProperties(ReverseProxyURIAuthorizationProperties.class) +public class ReverseProxyAuthorizationFilter implements Filter { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReverseProxyAuthorizationFilter.class); + + private List reverseProxyAuthorizations = new ArrayList<>(); + + @Resource + private ReverseProxyURIAuthorizationProperties reverseProxyURIAuthorizationProperties; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + // Read in the URI Authorisation configuration file + String authFilePath = reverseProxyURIAuthorizationProperties.getConfigurationFile(); + if (authFilePath != null) { + try (InputStream inputStream = + new FileInputStream(new File(reverseProxyURIAuthorizationProperties.getConfigurationFile())); + JsonReader jsonReader = new JsonReader(new InputStreamReader(inputStream))) { + List untrimmedList = new Gson().fromJson(jsonReader, + new TypeToken>() {}.getType()); + untrimmedList.removeAll(Collections.singleton(null)); + reverseProxyAuthorizations = untrimmedList; + } catch (IOException e) { + throw new ServletException("Authorizations config file not found.", e); + } + } + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + + CadiWrap cadiWrap = (CadiWrap) servletRequest; + Principal principal = cadiWrap.getUserPrincipal(); + List grantedPermissions = new ArrayList<>(); + cadiWrap.getLur().fishAll(principal, grantedPermissions); + + if (LOGGER.isDebugEnabled()) { + logNeededPermissions(); + } + + String requestPath; + try { + requestPath = new URI(((HttpServletRequest) servletRequest).getRequestURI()).getPath(); + } catch (URISyntaxException e) { + throw new ServletException("Request URI not valid", e); + } + + if (authorizeRequest(grantedPermissions, requestPath)) { + LOGGER.info("Authorized"); + filterChain.doFilter(servletRequest, servletResponse); + } else { + LOGGER.info("Unauthorized"); + ((HttpServletResponse) servletResponse).setStatus(HttpStatus.FORBIDDEN_403); + ((HttpServletResponse) servletResponse).setContentType("application/json"); + ((HttpServletResponse) servletResponse).sendError(HttpStatus.FORBIDDEN_403, + "Sorry, the request is not allowed"); + } + } + + /** + * Check if the granted permissions for the request path matches the configured needed permissions. + * + * @param grantedPermissions The granted permissions for the request path + * @param requestPath The request path + * @return true if permissions match + */ + private boolean authorizeRequest(List grantedPermissions, String requestPath) { + boolean authorized = false; + for (ReverseProxyAuthorization reverseProxyAuthorization : reverseProxyAuthorizations) { + if (requestPath.matches(reverseProxyAuthorization.getUri())) { + LOGGER.debug("The URI:{} matches:{}", requestPath, reverseProxyAuthorization.getUri()); + if (checkPermissionsMatch(grantedPermissions, reverseProxyAuthorization)) { + authorized = true; + break; + } + } else { + LOGGER.debug("The URI:{} doesn't match any in the configuration:{}", requestPath, + reverseProxyAuthorization.getUri()); + } + } + return authorized; + } + + /** + * Check all needed permissions match the granted permissions. + * + * @param grantedPermissions the granted permissions + * @param reverseProxyAuthorization the bean that contains the needed permissions + * @return true if all needed permissions match + */ + private boolean checkPermissionsMatch(List grantedPermissions, + ReverseProxyAuthorization reverseProxyAuthorization) { + + boolean matchedAllPermissions = true; + for (String neededPermission : reverseProxyAuthorization.getPermissions()) { + + // Check needed permission is granted + boolean matchedNeededPermission = false; + for (Permission grantedPermission : grantedPermissions) { + if (checkGrantedPermission(neededPermission, grantedPermission.getKey())) { + LOGGER.debug("Permission match found - needed permission:{}, granted permission:{}", + neededPermission, grantedPermission.getKey()); + matchedNeededPermission = true; + break; + } + } + if (!matchedNeededPermission) { + matchedAllPermissions = false; + break; + } + } + return matchedAllPermissions; + } + + /** + * Check whether an AAF style permission matches a needed permission. Wildcards (*) are supported. + * + * @param neededPermission, the needed permission + * @param grantedPermission, the granted permission + * + * @return true if the needed permission matches a granted permission + */ + private boolean checkGrantedPermission(String neededPermission, String grantedPermission) { + boolean permissionMatch = false; + if (grantedPermission.matches(neededPermission)) { + permissionMatch = true; + } else if (grantedPermission.contains("*")) { + String[] splitNeededPermission = neededPermission.split("\\\\\\|"); + String[] splitGrantedPermission = grantedPermission.split("\\|"); + if ((splitGrantedPermission[0].matches(splitNeededPermission[0])) + && (splitGrantedPermission[1].equals("*") + || splitGrantedPermission[1].matches(splitNeededPermission[1])) + && (splitGrantedPermission[2].equals("*") + || splitGrantedPermission[2].matches(splitNeededPermission[2]))) { + permissionMatch = true; + } + } + return permissionMatch; + } + + /** + * Log the needed permissions for each URL configured. + */ + private void logNeededPermissions() { + for (ReverseProxyAuthorization reverseProxyAuthorization : reverseProxyAuthorizations) { + LOGGER.debug("URI For authorization: {}", reverseProxyAuthorization.getUri()); + for (String permission : reverseProxyAuthorization.getPermissions()) { + LOGGER.debug("\t Needed permission:{}", permission); + } + } + } + + @Override + public void destroy() { + // No op + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyService.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyService.java new file mode 100644 index 0000000..e15fb2a --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyService.java @@ -0,0 +1,167 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Enumeration; +import java.util.UUID; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +import org.onap.aaf.cadi.sidecar.fproxy.data.CredentialCacheData; +import org.onap.aaf.cadi.sidecar.fproxy.data.CredentialCacheData.CredentialType; +import org.onap.aaf.cadi.sidecar.rpoxy.logging.ReverseProxyMethodLogTimeAnnotation; +import org.onap.aaf.cadi.sidecar.rproxy.config.ForwardProxyProperties; +import org.onap.aaf.cadi.sidecar.rproxy.config.PrimaryServiceProperties; +import org.onap.aaf.cadi.sidecar.rproxy.utils.ReverseProxyUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +@RestController +@EnableConfigurationProperties({ForwardProxyProperties.class, PrimaryServiceProperties.class}) +public class ReverseProxyService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReverseProxyService.class); + + private String validatedTransactionId; + + @Resource(name = "ForwardProxyProperties") + private ForwardProxyProperties forwardProxyProperties; + + @Resource(name = "PrimaryServiceProperties") + private PrimaryServiceProperties primaryServiceProperties; + + @Autowired + private RestTemplate restTemplate; + + @Value("${transactionid.header.name}") + private String transactionIdHeader; + + @RequestMapping("/**") + @ReverseProxyMethodLogTimeAnnotation + public ResponseEntity handleRequest(HttpServletRequest request, + @RequestHeader(value = "${transactionid.header.name}", defaultValue = "") String transactionId, + @RequestBody(required = false) String requestBody, HttpMethod requestMethod) throws URISyntaxException { + validatedTransactionId = getValidTransactionId(transactionId); + + // Extract Request Permissions and store in Forward Proxy cache + CredentialCacheData credentialCacheData = getCredentialDataFromRequest(request); + if (credentialCacheData != null) { + postCredentialsToCache(credentialCacheData); + } + + // Call out to Primary Service & Return Response + URI requestURI = new URI(request.getRequestURI()); + + LOGGER.debug("Request URI: {}", request.getRequestURI()); + + // Get Request Endpoint & substitute in local values + URI primaryServiceURI = new URI(primaryServiceProperties.getProtocol(), requestURI.getUserInfo(), + primaryServiceProperties.getHost(), Integer.parseInt(primaryServiceProperties.getPort()), + requestURI.getPath(), requestURI.getQuery(), requestURI.getFragment()); + + LOGGER.debug("Primary Service URI:{}, HTTP Method: {}", primaryServiceURI, requestMethod); + + HttpHeaders requestHeaders = setForwardedRequestHeaders(request); + HttpEntity httpEntity = new HttpEntity<>(requestBody, requestHeaders); + + return restTemplate.exchange(primaryServiceURI, requestMethod, httpEntity, String.class); + } + + private String getValidTransactionId(String transactionId) { + LOGGER.debug("Request transaction ID: {}", transactionId); + if (transactionId == null || !ReverseProxyUtils.validTransactionId(transactionId)) { + transactionId = UUID.randomUUID().toString(); + } + LOGGER.debug("Validated transaction ID: {}", transactionId); + return transactionId; + } + + private HttpHeaders setForwardedRequestHeaders(HttpServletRequest httpServletRequest) { + HttpHeaders httpHeaders = new HttpHeaders(); + Enumeration headerNames = httpServletRequest.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + if (!headerName.equals(transactionIdHeader)) { + httpHeaders.set(headerName, httpServletRequest.getHeader(headerName)); + } + } + // Always set transaction ID + httpHeaders.set(transactionIdHeader, validatedTransactionId); + + return httpHeaders; + } + + /** + * Retrieves credential data from request. + * + * @param request The request to retrieve credentials from + * @return The retrieved credential data, or null if no credentials are found in request + */ + private CredentialCacheData getCredentialDataFromRequest(HttpServletRequest request) { + CredentialCacheData credentialCacheData = null; + String authValue = request.getHeader(HttpHeaders.AUTHORIZATION); + if (authValue != null) { + credentialCacheData = new CredentialCacheData(HttpHeaders.AUTHORIZATION, authValue, CredentialType.HEADER); + } + return credentialCacheData; + } + + /** + * Posts credential data to credential cache endpoint + * + * @param credentialCacheData The credential data to post + * @throws URISyntaxException + */ + private void postCredentialsToCache(CredentialCacheData credentialCacheData) throws URISyntaxException { + URI forwardProxyURI = new URI(forwardProxyProperties.getProtocol(), null, forwardProxyProperties.getHost(), + forwardProxyProperties.getPort(), forwardProxyProperties.getCacheurl() + "/" + validatedTransactionId, + null, null); + + ResponseEntity response = + restTemplate.postForEntity(forwardProxyURI, credentialCacheData, String.class); + + if (!response.getStatusCode().is2xxSuccessful()) { + throw new HttpClientErrorException(response.getStatusCode(), + "Error posting to credential cache. Message: " + response.getBody()); + } + } + + @Override + public String toString() { + return this.getClass().getName() + ": Forward proxy host:" + forwardProxyProperties.getHost() + + ": Primary service host:" + primaryServiceProperties.getHost(); + + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/CadiProperties.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/CadiProperties.java new file mode 100644 index 0000000..841d8d8 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/CadiProperties.java @@ -0,0 +1,41 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.config; + +import java.net.MalformedURLException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.PropertiesFactoryBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.UrlResource; + +@Configuration +public class CadiProperties { + + @Value("${CONFIG_HOME}") + private String configHome; + + @Bean(name = "cadiProps") + public PropertiesFactoryBean mapper() throws MalformedURLException { + PropertiesFactoryBean bean = new PropertiesFactoryBean(); + bean.setLocation(new UrlResource("file:" + configHome + "/cadi.properties")); + return bean; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ForwardProxyProperties.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ForwardProxyProperties.java new file mode 100644 index 0000000..5c0d2c8 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ForwardProxyProperties.java @@ -0,0 +1,67 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("file:${CONFIG_HOME}/forward-proxy.properties") +@ConfigurationProperties(prefix = "forward-proxy") +public class ForwardProxyProperties { + + private String protocol; + private String host; + private int port; + private String cacheurl; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getCacheurl() { + return cacheurl; + } + + public void setCacheurl(String cacheurl) { + this.cacheurl = cacheurl; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/PrimaryServiceProperties.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/PrimaryServiceProperties.java new file mode 100644 index 0000000..e201ae6 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/PrimaryServiceProperties.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("file:${CONFIG_HOME}/primary-service.properties") +@ConfigurationProperties(prefix = "primary-service") +public class PrimaryServiceProperties { + + private String protocol; + private String host; + private String port; + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPort() { + return port; + } + + public void setPort(String port) { + this.port = port; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxySSLProperties.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxySSLProperties.java new file mode 100644 index 0000000..ee7a240 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxySSLProperties.java @@ -0,0 +1,56 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "server.ssl") +public class ReverseProxySSLProperties { + + private String keystore; + private String keystorePassword; + private String clientcert; + + public String getKeystore() { + return keystore; + } + + public void setKeystore(String keystore) { + this.keystore = keystore; + } + + public String getClientcert() { + return clientcert; + } + + public void setClientcert(String clientcert) { + this.clientcert = clientcert; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxyURIAuthorizationProperties.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxyURIAuthorizationProperties.java new file mode 100644 index 0000000..193d753 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/config/ReverseProxyURIAuthorizationProperties.java @@ -0,0 +1,38 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "uri.authorization") +public class ReverseProxyURIAuthorizationProperties { + + private String configurationFile; + + public String getConfigurationFile() { + return configurationFile; + } + + public void setConfigurationFile(String configurationFile) { + this.configurationFile = configurationFile; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/mocks/ReverseProxyMockCadiFilter.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/mocks/ReverseProxyMockCadiFilter.java new file mode 100644 index 0000000..1c4de92 --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/mocks/ReverseProxyMockCadiFilter.java @@ -0,0 +1,143 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.mocks; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.security.Principal; +import java.util.List; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.onap.aaf.cadi.CadiWrap; +import org.onap.aaf.cadi.Lur; +import org.onap.aaf.cadi.Permission; +import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.principal.TaggedPrincipal; +import org.onap.aaf.cadi.taf.TafResp; + +public class ReverseProxyMockCadiFilter implements Filter { + + private FakeLur fakeLur = new FakeLur(); + + static class FakeLur implements Lur { + + @Override + public void fishAll(Principal bait, List permissions) { + + final String WildcardPermissionType = "test.wildcard.access"; + final String MultiplePermissionType = "test.multiple.access"; + final String TestAuthAccessPermissionType = "test.auth.access"; + final String PermissionAction = "permission"; + + String principalName = bait.getName(); + + if (principalName != null && principalName.equals("UserWithInstanceActionWildcardPermissionGranted")) { + permissions.add(new AAFPermission(null, WildcardPermissionType, "*", "*")); + } + else + if (principalName != null && principalName.equals("UserWithInstanceWildcardPermissionGranted")) { + permissions.add(new AAFPermission(null, WildcardPermissionType, "*", PermissionAction)); + } + else + if (principalName != null && principalName.equals("UserWithActionWildcardPermissionGranted")) { + permissions.add(new AAFPermission(null, WildcardPermissionType, "first", "*")); + } + else { + + // For single permission test + permissions.add(new AAFPermission(null, "test.single.access", "single", PermissionAction)); + + // For multiple permission test + permissions.add(new AAFPermission(null, MultiplePermissionType, "first", PermissionAction)); + permissions.add(new AAFPermission(null, MultiplePermissionType, "second", PermissionAction)); + permissions.add(new AAFPermission(null, MultiplePermissionType, "third", PermissionAction)); + + // For transaction id test + permissions.add(new AAFPermission(null, TestAuthAccessPermissionType, "rest", "write")); + permissions.add(new AAFPermission(null, TestAuthAccessPermissionType, "rpc", "write")); + } + } + + @Override + public Permission createPerm(String p) { + return null; + } + + @Override + public boolean fish(Principal bait, Permission... pond) { + return false; + } + + @Override + public void destroy() { + // Mock implementation + } + + @Override + public boolean handlesExclusively(Permission... pond) { + return false; + } + + @Override + public boolean handles(Principal principal) { + return false; + } + + @Override + public void clear(Principal p, StringBuilder report) { + // Mock implementation + } + + } + + @Override + public void destroy() { + // Mock implementation + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + + String userName = ((HttpServletRequest)servletRequest).getHeader("PermissionsUser"); + + TaggedPrincipal mockTaggedPrincipal = mock(TaggedPrincipal.class); + when(mockTaggedPrincipal.getName()).thenReturn(userName); + + TafResp tafResponseMock = mock(TafResp.class); + when(tafResponseMock.getPrincipal()).thenReturn(mockTaggedPrincipal); + + CadiWrap cadiWrap = new CadiWrap((HttpServletRequest) servletRequest, tafResponseMock, fakeLur); + filterChain.doFilter(cadiWrap, servletResponse); + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // Mock implementation + } + +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java new file mode 100644 index 0000000..fd9db8e --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java @@ -0,0 +1,34 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.utils; + +public class ReverseProxyAuthorization { + + private String uri; + private String[] permissions; + + public String getUri() { + return uri; + } + + public String[] getPermissions() { + return permissions; + } +} diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyUtils.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyUtils.java new file mode 100644 index 0000000..495a78c --- /dev/null +++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyUtils.java @@ -0,0 +1,29 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aaf + * ================================================================================ + * Copyright © 2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aaf.cadi.sidecar.rproxy.utils; + +public class ReverseProxyUtils { + + public static boolean validTransactionId(String transactionId) { + return transactionId.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"); + } + + private ReverseProxyUtils() {} +} -- cgit 1.2.3-korg