From 124e11e9e7ea4652f8a538093ab48df9f575ce2a Mon Sep 17 00:00:00 2001 From: Zlatko Murgoski Date: Wed, 21 Aug 2019 11:14:04 +0200 Subject: Not Secured healtcheck https://jira.onap.org/browse/DCAEGEN2-1539 Issue-ID: DCAEGEN2-1539 Change-Id: I55c9387e64a5a6b710785ecbfa695683d821599a Signed-off-by: Zlatko Murgoski --- dpo/blueprint/blueprint_ves.yaml | 2 +- pom.xml | 868 +++++++++++---------- .../java/org/onap/dcae/ApplicationSettings.java | 1 - .../common/configuration/ApiConfiguration.java | 49 ++ .../onap/dcae/common/configuration/CertAuth.java | 4 +- .../dcae/common/configuration/CertBasicAuth.java | 4 +- .../common/configuration/TomcatHttpConfig.java | 54 ++ .../org/onap/dcae/restapi/ApiAuthInterceptor.java | 44 +- .../java/org/onap/dcae/restapi/SwaggerConfig.java | 2 +- .../java/org/onap/dcae/restapi/WebMvcConfig.java | 4 +- src/test/java/org/onap/dcae/TLSTest.java | 5 + src/test/java/org/onap/dcae/TLSTestBase.java | 19 +- .../onap/dcae/restapi/ApiAuthInterceptionTest.java | 253 +++--- 13 files changed, 710 insertions(+), 599 deletions(-) create mode 100644 src/main/java/org/onap/dcae/common/configuration/ApiConfiguration.java create mode 100644 src/main/java/org/onap/dcae/common/configuration/TomcatHttpConfig.java diff --git a/dpo/blueprint/blueprint_ves.yaml b/dpo/blueprint/blueprint_ves.yaml index 43158f1c..f373acfe 100644 --- a/dpo/blueprint/blueprint_ves.yaml +++ b/dpo/blueprint/blueprint_ves.yaml @@ -242,7 +242,7 @@ node_templates: docker_config: interval: 15s timeout: 1s - type: https + type: http endpoint: /healthcheck image: get_input: tag_version diff --git a/pom.xml b/pom.xml index 25f51cee..a55da042 100644 --- a/pom.xml +++ b/pom.xml @@ -14,436 +14,440 @@ ============LICENSE_END========================================================= --> - 4.0.0 - - org.onap.oparent - oparent - 2.0.0 - - - org.onap.dcaegen2.collectors.ves - VESCollector - 1.5.1-SNAPSHOT - dcaegen2-collectors-ves - VESCollector - - - UTF-8 - UTF-8 - 8 - onap/org.onap.dcaegen2.collectors.ves.vescollector - - true - - false - - https://nexus.onap.org - content/repositories/snapshots/ - content/repositories/releases/ - content/sites/site/org/onap/dcaegen2/collectors/ves/${project.artifactId}/${project.version} - yyyyMMdd'T'HHmmss - nexus3.onap.org:10003 - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - maven-assembly-plugin - 3.1.0 - - - maven-javadoc-plugin - 3.0.1 - - - maven-project-info-reports-plugin - 2.9 - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M1 - - - com.spotify - docker-maven-plugin - 1.2.0 - - - org.apache.maven.plugins - maven-enforcer-plugin - - true - - - - - - - maven-assembly-plugin - - - src/assembly/dep.xml - - false - false - true - - - - make-assembly - package - - single - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - maven-javadoc-plugin - - true - false - false - - - - aggregate - site - - aggregate - - - - attach-javadoc - - jar - - - - - - com.spotify - docker-maven-plugin - - ${onap.nexus.dockerregistry.daily} - ${onap.nexus.dockerregistry.daily}/${docker.image.name} - - ${project.version}-${maven.build.timestamp}Z - ${project.version} - latest - - openjdk:8-jre-slim - vescollector - - /etc/host.aliases - - /opt/app/VESCollector - - - . - ${project.build.directory}/${project.artifactId}-${project.version} - - - - useradd -r -U vescollector - chown -R vescollector:vescollector /opt/app - - chmod +x bin/*.sh - - - - 8080 - 8443 - - bin/docker-entry.sh - - - - - - - - with-system-proxy - - - - com.spotify - docker-maven-plugin - - - ${env.http_proxy} - - - - - - - - - - - maven-project-info-reports-plugin - - - - dependencies - license - - - - - - maven-javadoc-plugin - - false - org.umlgraph.doclet.UmlGraphDoc - - org.umlgraph - umlgraph - 5.6 - - -views - true - - - - - - - - - org.springframework.boot - spring-boot-dependencies - 2.1.0.RELEASE - pom - import - - - - - - - com.googlecode.json-simple - json-simple - 1.1.1 - - - com.github.fge - json-schema-validator - 2.2.6 - - - com.github.fge - json-schema-core - 1.2.5 - - - com.google.code.gson - gson - 2.8.5 - - - org.json - json - 20160810 - - - - com.att.nsa - cambriaClient - 0.0.1 - - - com.mashape.unirest - unirest-java - 1.4.9 - - - - commons-collections - commons-collections - 3.2.2 - - - commons-configuration - commons-configuration - 1.10 - - - io.vavr - vavr - 0.9.2 - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-logging - - - - - org.springframework.boot - spring-boot-starter-log4j2 - 2.1.5.RELEASE - - - io.springfox - springfox-swagger2 - 2.8.0 - - - io.springfox - springfox-swagger-ui - 2.8.0 - compile - - - - org.junit.jupiter - junit-jupiter-api - 5.3.1 - test - - - org.junit.jupiter - junit-jupiter-engine - 5.3.1 - test - - - org.junit.vintage - junit-vintage-engine - 5.3.1 - test - - - org.mockito - mockito-junit-jupiter - 2.23.0 - test - - - org.assertj - assertj-core - 3.8.0 - test - - - com.google.jimfs - jimfs - 1.1 - test - - - com.github.tomakehurst - wiremock-standalone - 2.17.0 - test - - - org.springframework.security - spring-security-test - 5.1.1.RELEASE - test - - - org.springframework.boot - spring-boot-starter-test - 2.1.0.RELEASE - test - - - org.onap.dcaegen2.services.sdk.security.crypt - crypt-password - 1.1.6 - - - org.onap.dcaegen2.services.sdk.standardization - api-custom-header - 1.1.4 - - - - - external-repository - https://oss.sonatype.org/content/repositories - - - - - - JCenter - JCenter Repository - http://jcenter.bintray.com - - - Restlet - Restlet Repository - http://maven.restlet.com - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.onap.oparent + oparent + 2.0.0 + + + org.onap.dcaegen2.collectors.ves + VESCollector + 1.5.1-SNAPSHOT + dcaegen2-collectors-ves + VESCollector + + + UTF-8 + UTF-8 + 8 + onap/org.onap.dcaegen2.collectors.ves.vescollector + + true + + false + + https://nexus.onap.org + content/repositories/snapshots/ + content/repositories/releases/ + content/sites/site/org/onap/dcaegen2/collectors/ves/${project.artifactId}/${project.version} + yyyyMMdd'T'HHmmss + nexus3.onap.org:10003 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + maven-assembly-plugin + 3.1.0 + + + maven-javadoc-plugin + 3.0.1 + + + maven-project-info-reports-plugin + 2.9 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M1 + + + com.spotify + docker-maven-plugin + 1.2.0 + + + org.apache.maven.plugins + maven-enforcer-plugin + + true + + + + + + + maven-assembly-plugin + + + src/assembly/dep.xml + + false + false + true + + + + make-assembly + package + + single + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-javadoc-plugin + + true + false + false + + + + aggregate + site + + aggregate + + + + attach-javadoc + + jar + + + + + + com.spotify + docker-maven-plugin + + ${onap.nexus.dockerregistry.daily} + ${onap.nexus.dockerregistry.daily}/${docker.image.name} + + ${project.version}-${maven.build.timestamp}Z + ${project.version} + latest + + openjdk:8-jre-slim + vescollector + + /etc/host.aliases + + /opt/app/VESCollector + + + . + ${project.build.directory}/${project.artifactId}-${project.version} + + + + useradd -r -U vescollector + chown -R vescollector:vescollector /opt/app + mkdir /opt/app/VESCollector/logs + chown -R vescollector:vescollector /opt/app/VESCollector/logs + chown -R vescollector:vescollector /opt/app/VESCollector/etc + + chmod +x bin/*.sh + + + + + 8080 + 8443 + + bin/docker-entry.sh + + + + + + + + with-system-proxy + + + + com.spotify + docker-maven-plugin + + + ${env.http_proxy} + + + + + + + + + + + maven-project-info-reports-plugin + + + + dependencies + license + + + + + + maven-javadoc-plugin + + false + org.umlgraph.doclet.UmlGraphDoc + + org.umlgraph + umlgraph + 5.6 + + -views + true + + + + + + + + + org.springframework.boot + spring-boot-dependencies + 2.1.0.RELEASE + pom + import + + + + + + + com.googlecode.json-simple + json-simple + 1.1.1 + + + com.github.fge + json-schema-validator + 2.2.6 + + + com.github.fge + json-schema-core + 1.2.5 + + + com.google.code.gson + gson + 2.8.5 + + + org.json + json + 20160810 + + + + com.att.nsa + cambriaClient + 0.0.1 + + + com.mashape.unirest + unirest-java + 1.4.9 + + + + commons-collections + commons-collections + 3.2.2 + + + commons-configuration + commons-configuration + 1.10 + + + io.vavr + vavr + 0.9.2 + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + 2.1.5.RELEASE + + + io.springfox + springfox-swagger2 + 2.8.0 + + + io.springfox + springfox-swagger-ui + 2.8.0 + compile + + + + org.junit.jupiter + junit-jupiter-api + 5.3.1 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.3.1 + test + + + org.junit.vintage + junit-vintage-engine + 5.3.1 + test + + + org.mockito + mockito-junit-jupiter + 2.23.0 + test + + + org.assertj + assertj-core + 3.8.0 + test + + + com.google.jimfs + jimfs + 1.1 + test + + + com.github.tomakehurst + wiremock-standalone + 2.17.0 + test + + + org.springframework.security + spring-security-test + 5.1.1.RELEASE + test + + + org.springframework.boot + spring-boot-starter-test + 2.1.0.RELEASE + test + + + org.onap.dcaegen2.services.sdk.security.crypt + crypt-password + 1.1.6 + + + org.onap.dcaegen2.services.sdk.standardization + api-custom-header + 1.1.4 + + + + + external-repository + https://oss.sonatype.org/content/repositories + + + + + + JCenter + JCenter Repository + http://jcenter.bintray.com + + + Restlet + Restlet Repository + http://maven.restlet.com + + diff --git a/src/main/java/org/onap/dcae/ApplicationSettings.java b/src/main/java/org/onap/dcae/ApplicationSettings.java index 205659c4..5164f878 100644 --- a/src/main/java/org/onap/dcae/ApplicationSettings.java +++ b/src/main/java/org/onap/dcae/ApplicationSettings.java @@ -74,7 +74,6 @@ public class ApplicationSettings { loadedJsonSchemas = loadJsonSchemas(); } - public void reloadProperties() { try { properties.load(configurationFileLocation); diff --git a/src/main/java/org/onap/dcae/common/configuration/ApiConfiguration.java b/src/main/java/org/onap/dcae/common/configuration/ApiConfiguration.java new file mode 100644 index 00000000..52e3a6de --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/ApiConfiguration.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.dcaegen2.collectors.ves + * ================================================================================ + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. + * ================================================================================ + * 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.dcae.common.configuration; + +import org.onap.dcae.ApplicationSettings; +import org.onap.dcae.restapi.ApiAuthInterceptor; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class ApiConfiguration implements WebMvcConfigurer { + + private final ApplicationSettings applicationSettings; + private Logger errorLogger; + + @Autowired + ApiConfiguration(ApplicationSettings applicationSettings, Logger errorLogger) { + this.applicationSettings = applicationSettings; + this.errorLogger = errorLogger; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new ApiAuthInterceptor(applicationSettings, errorLogger)); + } +} diff --git a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java index 6bd924c3..53031142 100644 --- a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java +++ b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java @@ -3,7 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2018 Nokia. All rights reserved.s + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.context.annotation.Configuration; -@Configuration public class CertAuth implements AuthMethod { private static final Logger log = LoggerFactory.getLogger(CertAuth.class); diff --git a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java index 38d5ad5b..fa4a1b2d 100644 --- a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java +++ b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java @@ -3,7 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2018 Nokia. All rights reserved.s + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,9 +26,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.web.server.Ssl.ClientAuth; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; -import org.springframework.context.annotation.Configuration; -@Configuration public class CertBasicAuth implements AuthMethod{ private static final Logger log = LoggerFactory.getLogger(CertAuth.class); diff --git a/src/main/java/org/onap/dcae/common/configuration/TomcatHttpConfig.java b/src/main/java/org/onap/dcae/common/configuration/TomcatHttpConfig.java new file mode 100644 index 00000000..4495f34b --- /dev/null +++ b/src/main/java/org/onap/dcae/common/configuration/TomcatHttpConfig.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2019 Nokia. All rights reserved. + * ================================================================================ + * 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.dcae.common.configuration; + +import org.apache.catalina.connector.Connector; +import org.onap.dcae.ApplicationSettings; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +@Component +public class TomcatHttpConfig { + + @Autowired + private ApplicationSettings settings; + + @Bean + private ServletWebServerFactory servletContainer() { + + TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); + if(!(settings.authMethod().equalsIgnoreCase(AuthMethodType.NO_AUTH.value())) && settings.httpsEnabled()){ + tomcat.addAdditionalTomcatConnectors(getHttpConnector()); + } + return tomcat; + } + + private Connector getHttpConnector() { + Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); + connector.setScheme("http"); + connector.setPort(settings.httpPort()); + connector.setSecure(false); + return connector; + } +} diff --git a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java index 9b387b84..a9281594 100644 --- a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java +++ b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.dcaegen2.collectors.ves * ================================================================================ - * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,6 @@ import io.vavr.control.Option; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.Base64; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.dcae.ApplicationSettings; @@ -37,9 +32,10 @@ import org.onap.dcaegen2.services.sdk.security.CryptPassword; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; @Component -public class ApiAuthInterceptor implements Filter { +public class ApiAuthInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = LoggerFactory.getLogger(ApiAuthInterceptor.class); private static final String CERTIFICATE_X_509 = "javax.servlet.request.X509Certificate"; @@ -53,32 +49,33 @@ public class ApiAuthInterceptor implements Filter { this.errorLogger = errorLogger; } - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws IOException { + SubjectMatcher subjectMatcher = new SubjectMatcher(settings,(X509Certificate[]) request.getAttribute(CERTIFICATE_X_509)); - if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value())){ - if( validateCertRequest((HttpServletResponse )response, subjectMatcher)){ - chain.doFilter(request, response); - return; + if(!settings.authMethod().equalsIgnoreCase(AuthMethodType.NO_AUTH.value()) && request.getServerPort() == settings.httpPort() ){ + if(request.getRequestURI().replaceAll("^/|/$", "").equalsIgnoreCase("healthcheck")){ + return true; } - return; + response.getWriter().write("Operation not permitted"); + response.setStatus(400); + return false; + } + + if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value())){ + return validateCertRequest(response, subjectMatcher); } if(isCertSubject(subjectMatcher)){ - chain.doFilter(request, response); - return; + return true; } if (isBasicAuth() ) { - if(validateBasicHeader((HttpServletRequest)request, (HttpServletResponse)response)){ - chain.doFilter(request, response); - return; - } - return; + return validateBasicHeader(request, response); } - chain.doFilter(request, response); + return true; } private boolean validateBasicHeader(HttpServletRequest request, HttpServletResponse response) @@ -110,6 +107,7 @@ public class ApiAuthInterceptor implements Filter { LOG.info("Cert and subjectDN is valid"); return true; } + LOG.info(String.format(MESSAGE, settings.certSubjectMatcher())); return false; } @@ -129,7 +127,7 @@ public class ApiAuthInterceptor implements Filter { return userRegistered && cryptPassword.matches(providedPassword,maybeSavedPassword.get()); } catch (Exception e) { LOG.warn(String.format("Could not check if user is authorized (header: '%s')), probably malformed header.", - authorizationHeader), e); + authorizationHeader), e); return false; } } diff --git a/src/main/java/org/onap/dcae/restapi/SwaggerConfig.java b/src/main/java/org/onap/dcae/restapi/SwaggerConfig.java index 267db054..03432cf2 100644 --- a/src/main/java/org/onap/dcae/restapi/SwaggerConfig.java +++ b/src/main/java/org/onap/dcae/restapi/SwaggerConfig.java @@ -3,6 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +29,6 @@ import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; -@Configuration @EnableSwagger2 public class SwaggerConfig{ diff --git a/src/main/java/org/onap/dcae/restapi/WebMvcConfig.java b/src/main/java/org/onap/dcae/restapi/WebMvcConfig.java index c3e2a5de..c8dd7ba4 100644 --- a/src/main/java/org/onap/dcae/restapi/WebMvcConfig.java +++ b/src/main/java/org/onap/dcae/restapi/WebMvcConfig.java @@ -3,7 +3,7 @@ * PROJECT * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2018 Nokia. All rights reserved.s + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,12 +22,10 @@ package org.onap.dcae.restapi; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.view.InternalResourceViewResolver; -@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { @Override diff --git a/src/test/java/org/onap/dcae/TLSTest.java b/src/test/java/org/onap/dcae/TLSTest.java index 3cf0a162..49a089cc 100644 --- a/src/test/java/org/onap/dcae/TLSTest.java +++ b/src/test/java/org/onap/dcae/TLSTest.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2018 Nokia. All rights reserved. * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,6 +103,7 @@ public class TLSTest extends TLSTestBase { @Override protected void configureSettings(ApplicationSettings settings) { when(settings.authMethod()).thenReturn(AuthMethodType.NO_AUTH.value()); + when(settings.httpPort()).thenReturn(1111); } } @@ -115,6 +117,7 @@ public class TLSTest extends TLSTestBase { when(settings.keystorePasswordFileLocation()).thenReturn(KEYSTORE_PASSWORD_FILE.toString()); when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); when(settings.validAuthorizationCredentials()).thenReturn(HashMap.of(USERNAME, "$2a$10$51tDgG2VNLde5E173Ay/YO.Fq.aD.LR2Rp8pY3QAKriOSPswvGviy")); + when(settings.httpPort()).thenReturn(1111); } } @@ -126,6 +129,7 @@ public class TLSTest extends TLSTestBase { when(settings.truststoreFileLocation()).thenReturn(TRUSTSTORE.toString()); when(settings.truststorePasswordFileLocation()).thenReturn(TRUSTSTORE_PASSWORD_FILE.toString()); when(settings.certSubjectMatcher()).thenReturn(CERT_SUBJECT_MATCHER.toString()); + when(settings.httpPort()).thenReturn(1111); } } @@ -134,6 +138,7 @@ public class TLSTest extends TLSTestBase { protected void configureSettings(ApplicationSettings settings) { super.configureSettings(settings); when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); + when(settings.httpPort()).thenReturn(1111); } } } \ No newline at end of file diff --git a/src/test/java/org/onap/dcae/TLSTestBase.java b/src/test/java/org/onap/dcae/TLSTestBase.java index df10ead9..1eb5728e 100644 --- a/src/test/java/org/onap/dcae/TLSTestBase.java +++ b/src/test/java/org/onap/dcae/TLSTestBase.java @@ -4,6 +4,7 @@ * ================================================================================ * Copyright (C) 2018 Nokia. All rights reserved. * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +22,20 @@ package org.onap.dcae; -import org.json.JSONObject; +import static org.onap.dcae.TestingUtilities.configureKeyStore; +import static org.onap.dcae.TestingUtilities.createRestTemplateWithSsl; +import static org.onap.dcae.TestingUtilities.readFile; +import static org.onap.dcae.TestingUtilities.rethrow; +import static org.onap.dcae.TestingUtilities.sslBuilderWithTrustStore; + +import java.nio.file.Path; +import java.nio.file.Paths; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mockito; import org.onap.dcae.common.EventSender; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.Bean; @@ -37,12 +46,6 @@ import org.springframework.http.client.support.BasicAuthenticationInterceptor; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.web.client.RestTemplate; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.LinkedBlockingQueue; - -import static org.onap.dcae.TestingUtilities.*; - @Configuration @ExtendWith(SpringExtension.class) public class TLSTestBase { @@ -66,7 +69,7 @@ public class TLSTestBase { protected abstract void configureSettings(final ApplicationSettings settings); } - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) + @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) protected abstract class TestClassBase { @MockBean diff --git a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java index 4398faad..e6d67cf4 100644 --- a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java +++ b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * org.onap.dcaegen2.collectors.ves * ================================================================================ - * Copyright (C) 2018 Nokia. All rights reserved. + * Copyright (C) 2018 - 2019 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,18 +20,8 @@ package org.onap.dcae.restapi; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import io.vavr.collection.HashMap; import io.vavr.collection.Map; -import java.io.IOException; -import java.io.PrintWriter; -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -45,128 +35,143 @@ import org.springframework.http.HttpStatus; import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + @RunWith(MockitoJUnitRunner.Silent.class) public class ApiAuthInterceptionTest { - private static final String USERNAME = "Foo"; - private static final String PASSWORD = "Bar"; - private static final Map CREDENTIALS = HashMap.of(USERNAME, PASSWORD); + private static final String USERNAME = "Foo"; + private static final String PASSWORD = "Bar"; + private static final Map CREDENTIALS = HashMap.of(USERNAME, PASSWORD); - @Mock - private Logger log; + @Mock + private Logger log; - @Mock - private ApplicationSettings settings; + @Mock + private ApplicationSettings settings; - @Mock - private HttpServletResponse response; + @Mock + private HttpServletResponse response; - @Mock - private FilterChain obj; + @Mock + private Object obj; - @Mock - private PrintWriter writer; + @Mock + private PrintWriter writer; - @InjectMocks - private ApiAuthInterceptor sut; + @InjectMocks + private ApiAuthInterceptor sut; - private HttpServletRequest createEmptyRequest() { - return MockMvcRequestBuilders + private HttpServletRequest createEmptyRequest() { + return MockMvcRequestBuilders + .post("") + .buildRequest(null); + } + + private HttpServletRequest createRequestWithAuthorizationHeader() { + return SecurityMockMvcRequestPostProcessors + .httpBasic(USERNAME, PASSWORD) + .postProcessRequest( + MockMvcRequestBuilders .post("") - .buildRequest(null); - } - - private HttpServletRequest createRequestWithAuthorizationHeader() { - return SecurityMockMvcRequestPostProcessors - .httpBasic(USERNAME, PASSWORD) - .postProcessRequest( - MockMvcRequestBuilders - .post("") - .buildRequest(null)); - } - - @Test - public void shouldSucceedWhenAuthorizationIsDisabled() throws IOException, ServletException { - // given - final HttpServletRequest request = createEmptyRequest(); - - when(settings.authMethod()).thenReturn(AuthMethodType.NO_AUTH.value()); - - // when - sut.doFilter(request, response, obj); - - // then - verify(obj, atLeastOnce()).doFilter(request, response); - } - - @Test - public void shouldFailDueToEmptyBasicAuthorizationHeader() throws IOException, ServletException { - // given - final HttpServletRequest request = createEmptyRequest(); - - when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); - when(response.getWriter()).thenReturn(writer); - - // when - sut.doFilter(request, response, obj); - - // then - verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); - verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); - } - - @Test - public void shouldFailDueToBasicAuthenticationUserMissingFromSettings() - throws IOException, ServletException { - // given - final HttpServletRequest request = createRequestWithAuthorizationHeader(); - - when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); - when(response.getWriter()).thenReturn(writer); - - // when - sut.doFilter(request, response, obj); - - // then - verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); - verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); - } - - @Test - public void shouldSucceed() throws IOException, ServletException { - // given - final HttpServletRequest request = createRequestWithAuthorizationHeader(); - when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); - when(settings.validAuthorizationCredentials()).thenReturn( - HashMap.of(USERNAME, "$2a$10$BsZkEynNm/93wbAeeZuxJeu6IHRyQl4XReqDg2BtYOFDhUsz20.3G")); - when(response.getWriter()).thenReturn(writer); - - // when - sut.doFilter(request, response, obj); - - // then - verify(obj, atLeastOnce()).doFilter(request, response); - } - - @Test - public void shouldFailDueToInvalidBasicAuthorizationHeaderValue() - throws IOException, ServletException { - // given - final HttpServletRequest request = - MockMvcRequestBuilders - .post("") - .header(HttpHeaders.AUTHORIZATION, "FooBar") - .buildRequest(null); - - when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); - when(settings.validAuthorizationCredentials()).thenReturn(CREDENTIALS); - when(response.getWriter()).thenReturn(writer); - - // when - sut.doFilter(request, response, obj); - - //then - verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); - verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); - } + .buildRequest(null)); + } + + @Test + public void shouldSucceedWhenAuthorizationIsDisabled() throws IOException { + // given + final HttpServletRequest request = createEmptyRequest(); + + when(settings.authMethod()).thenReturn(AuthMethodType.NO_AUTH.value()); + + // when + final boolean isAuthorized = sut.preHandle(request, response, obj); + + // then + assertTrue(isAuthorized); + } + + @Test + public void shouldFailDueToEmptyBasicAuthorizationHeader() throws IOException { + // given + final HttpServletRequest request = createEmptyRequest(); + + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); + when(response.getWriter()).thenReturn(writer); + + // when + final boolean isAuthorized = sut.preHandle(request, response, obj); + + + // then + assertFalse(isAuthorized); + + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); + verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); + } + + @Test + public void shouldFailDueToBasicAuthenticationUserMissingFromSettings() throws IOException { + // given + final HttpServletRequest request = createRequestWithAuthorizationHeader(); + + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); + when(response.getWriter()).thenReturn(writer); + + // when + final boolean isAuthorized = sut.preHandle(request, response, obj); + + // then + assertFalse(isAuthorized); + + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); + verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); + } + + @Test + public void shouldSucceed() throws IOException { + // given + final HttpServletRequest request = createRequestWithAuthorizationHeader(); + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); + when(settings.validAuthorizationCredentials()).thenReturn( + HashMap.of(USERNAME, "$2a$10$BsZkEynNm/93wbAeeZuxJeu6IHRyQl4XReqDg2BtYOFDhUsz20.3G")); + when(response.getWriter()).thenReturn(writer); + + // when + final boolean isAuthorized = sut.preHandle(request, response, obj); + + // then + assertTrue(isAuthorized); + } + + @Test + public void shouldFailDueToInvalidBasicAuthorizationHeaderValue() throws IOException { + // given + final HttpServletRequest request = + MockMvcRequestBuilders + .post("") + .header(HttpHeaders.AUTHORIZATION, "FooBar") + .buildRequest(null); + + when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); + when(settings.validAuthorizationCredentials()).thenReturn(CREDENTIALS); + when(response.getWriter()).thenReturn(writer); + + // when + final boolean isAuthorized = sut.preHandle(request, response, obj); + + // then + assertFalse(isAuthorized); + + verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); + verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); + } } -- cgit 1.2.3-korg