diff options
-rw-r--r-- | INFO.yaml | 10 | ||||
-rwxr-xr-x | etc/collector.properties | 2 | ||||
-rw-r--r-- | pom.xml | 10 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java | 2 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/BasicAuth.java | 48 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/CertAuth.java | 49 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java | 2 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/NoAuth.java | 4 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java | 2 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java | 69 | ||||
-rw-r--r-- | src/main/java/org/onap/dcae/restapi/ServletConfig.java | 4 | ||||
-rw-r--r-- | src/test/java/org/onap/dcae/TLSTest.java | 58 | ||||
-rw-r--r-- | src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java | 127 | ||||
-rw-r--r-- | version.properties | 2 |
14 files changed, 93 insertions, 296 deletions
@@ -28,7 +28,7 @@ meetings: repeats: 'weekly' time: '13:00 UTC (DST), 15:30 UTC (post DST)' repositories: - - 'dcaegen2-collectors-ves' + - 'dcaegen2/collectors/ves' committers: - <<: *onap_dcaegen2_ptl - name: 'Lusheng Ji' @@ -61,14 +61,12 @@ committers: company: 'ATT' id: 'jflucas' timezone: 'America/New_York' - - name: 'Zlatko Murgoski' - email: 'zlatko.murgoski@nokia.com' - company: 'Nokia' - id: 'ZlatkoMurgoski' - timezone: 'Europe/Warsaw' tsc: approval: 'https://lists.onap.org/pipermail/onap-tsc' changes: - type: 'Addition' name: 'Zlatko Murgoski' link: 'https://lists.onap.org/g/onap-tsc/message/4771' + - type: 'Removal' + name: 'Zlatko Murgoski' + link: 'https://lists.onap.org/g/onap-tsc/message/5539' diff --git a/etc/collector.properties b/etc/collector.properties index ae15cd98..7fe35ffe 100755 --- a/etc/collector.properties +++ b/etc/collector.properties @@ -25,8 +25,6 @@ collector.service.secure.port=8443 # auth.method flags:
#
# noAuth - default option - no security (http)
-# certOnly - auth by certificate (https)
-# basicAuth - auth by basic auth username and password (https)
# certBasicAuth - auth by certificate and basic auth username / password (https)
auth.method=noAuth
@@ -24,7 +24,7 @@ </parent>
<groupId>org.onap.dcaegen2.collectors.ves</groupId>
<artifactId>VESCollector</artifactId>
- <version>1.5.1-SNAPSHOT</version>
+ <version>1.5.2-SNAPSHOT</version>
<name>dcaegen2-collectors-ves</name>
<description>VESCollector</description>
<properties>
@@ -353,6 +353,12 @@ <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.1.5.RELEASE</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-slf4j-impl</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
@@ -423,7 +429,7 @@ <dependency>
<groupId>org.onap.dcaegen2.services.sdk.security.crypt</groupId>
<artifactId>crypt-password</artifactId>
- <version>1.1.6</version>
+ <version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.onap.dcaegen2.services.sdk.standardization</groupId>
diff --git a/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java b/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java index 7eb1b414..027b1895 100644 --- a/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java +++ b/src/main/java/org/onap/dcae/common/configuration/AuthMethodType.java @@ -23,7 +23,7 @@ package org.onap.dcae.common.configuration; public enum AuthMethodType { - NO_AUTH("noAuth"),CERT_ONLY("certOnly"),CERT_BASIC_AUTH("certBasicAuth"),BASIC_AUTH("basicAuth"); + NO_AUTH("noAuth"),CERT_BASIC_AUTH("certBasicAuth"); private final String value; diff --git a/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java b/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java deleted file mode 100644 index c3730512..00000000 --- a/src/main/java/org/onap/dcae/common/configuration/BasicAuth.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2018 Nokia. All rights reserved.s - * ================================================================================ - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; - -public class BasicAuth implements AuthMethod { - - private static final Logger log = LoggerFactory.getLogger(BasicAuth.class); - private final ConfigurableServletWebServerFactory container; - private final ApplicationSettings properties; - - public BasicAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { - this.container = container; - this.properties = properties; - } - - @Override - public void configure() { - SslContextCreator sslContextCreator = new SslContextCreator(properties); - container.setPort(properties.httpsPort()); - container.setSsl(sslContextCreator.simpleHttpsContext()); - log.info(String.format("Application work in %s mode on %s port.", - properties.authMethod(), properties.httpsPort())); - } -} diff --git a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java b/src/main/java/org/onap/dcae/common/configuration/CertAuth.java deleted file mode 100644 index 53031142..00000000 --- a/src/main/java/org/onap/dcae/common/configuration/CertAuth.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * PROJECT - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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. - * 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.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.web.server.Ssl.ClientAuth; -import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; - -public class CertAuth implements AuthMethod { - - private static final Logger log = LoggerFactory.getLogger(CertAuth.class); - private final ConfigurableServletWebServerFactory container; - private final ApplicationSettings properties; - - public CertAuth(ConfigurableServletWebServerFactory container, ApplicationSettings properties) { - this.container = container; - this.properties = properties; - } - - @Override - public void configure() { - SslContextCreator sslContextCreator = new SslContextCreator(properties); - container.setSsl(sslContextCreator.httpsContextWithTlsAuthentication(ClientAuth.NEED)); - container.setPort(properties.httpsPort()); - log.info(String.format("Application work in %s mode on %s port.", - properties.authMethod(), properties.httpsPort())); - } -} 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 fa4a1b2d..73d69859 100644 --- a/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java +++ b/src/main/java/org/onap/dcae/common/configuration/CertBasicAuth.java @@ -29,7 +29,7 @@ import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerF public class CertBasicAuth implements AuthMethod{ - private static final Logger log = LoggerFactory.getLogger(CertAuth.class); + private static final Logger log = LoggerFactory.getLogger(CertBasicAuth.class); private final ConfigurableServletWebServerFactory container; private final ApplicationSettings properties; diff --git a/src/main/java/org/onap/dcae/common/configuration/NoAuth.java b/src/main/java/org/onap/dcae/common/configuration/NoAuth.java index a64749c0..c91ce04b 100644 --- a/src/main/java/org/onap/dcae/common/configuration/NoAuth.java +++ b/src/main/java/org/onap/dcae/common/configuration/NoAuth.java @@ -51,9 +51,7 @@ public class NoAuth implements AuthMethod { } private boolean validateAuthMethod() { - return properties.authMethod().equalsIgnoreCase(AuthMethodType.BASIC_AUTH.value()) - || properties.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value()) - || properties.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); + return properties.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); } private void logContainerConfiguration(int port) { diff --git a/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java b/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java index f0e470be..75b0e6f9 100644 --- a/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java +++ b/src/main/java/org/onap/dcae/common/configuration/SslContextCreator.java @@ -41,7 +41,7 @@ import org.springframework.boot.web.server.Ssl.ClientAuth; public class SslContextCreator { - private static final Logger log = LoggerFactory.getLogger(CertAuth.class); + private static final Logger log = LoggerFactory.getLogger(SslContextCreator.class); private final ApplicationSettings properties; public SslContextCreator(ApplicationSettings properties) { diff --git a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java index a9281594..8c5fb82a 100644 --- a/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java +++ b/src/main/java/org/onap/dcae/restapi/ApiAuthInterceptor.java @@ -22,7 +22,9 @@ package org.onap.dcae.restapi; import io.vavr.control.Option; import java.io.IOException; import java.security.cert.X509Certificate; +import java.util.Arrays; import java.util.Base64; +import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.onap.dcae.ApplicationSettings; @@ -53,10 +55,11 @@ public class ApiAuthInterceptor extends HandlerInterceptorAdapter { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { - SubjectMatcher subjectMatcher = new SubjectMatcher(settings,(X509Certificate[]) request.getAttribute(CERTIFICATE_X_509)); + X509Certificate[] certificates = (X509Certificate[]) request.getAttribute(CERTIFICATE_X_509); + SubjectMatcher subjectMatcher = new SubjectMatcher(settings, certificates); - if(!settings.authMethod().equalsIgnoreCase(AuthMethodType.NO_AUTH.value()) && request.getServerPort() == settings.httpPort() ){ - if(request.getRequestURI().replaceAll("^/|/$", "").equalsIgnoreCase("healthcheck")){ + if(isHttpPortCalledWithAuthTurnedOn(request)){ + if(isHealthcheckCalledFromInsideCluster(request)){ return true; } response.getWriter().write("Operation not permitted"); @@ -64,20 +67,33 @@ public class ApiAuthInterceptor extends HandlerInterceptorAdapter { return false; } - if(settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_ONLY.value())){ - return validateCertRequest(response, subjectMatcher); - } - if(isCertSubject(subjectMatcher)){ + LOG.debug("Cert and subjectDN is valid. Subject: " + extractSubject(certificates)); return true; } - if (isBasicAuth() ) { + if (isBasicAuth()) { return validateBasicHeader(request, response); } return true; } + private String extractSubject(X509Certificate[] certs) { + return Arrays.stream(certs) + .map(e -> e.getSubjectDN().getName()) + .collect(Collectors.joining(",")); + } + + private boolean isHttpPortCalledWithAuthTurnedOn(HttpServletRequest request) { + return !settings.authMethod().equalsIgnoreCase(AuthMethodType.NO_AUTH.value()) + && request.getLocalPort() == settings.httpPort(); + } + + private boolean isHealthcheckCalledFromInsideCluster(HttpServletRequest request) { + return request.getRequestURI().replaceAll("^/|/$", "").equalsIgnoreCase("healthcheck") + && request.getServerPort() == settings.httpPort(); + } + private boolean validateBasicHeader(HttpServletRequest request, HttpServletResponse response) throws IOException { String authorizationHeader = request.getHeader("Authorization"); @@ -87,24 +103,12 @@ public class ApiAuthInterceptor extends HandlerInterceptorAdapter { response.getWriter().write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); return false; } - LOG.info("Request is authorized by basic auth"); - return true; - } - - private boolean validateCertRequest(HttpServletResponse response, SubjectMatcher subjectMatcher) - throws IOException { - if (!isCertSubject(subjectMatcher)) { - response.setStatus(HttpServletResponse.SC_FORBIDDEN); - response.getWriter().write(String.format(MESSAGE, settings.certSubjectMatcher())); - return false; - } - LOG.info("Cert and subjectDN is valid"); + LOG.debug("Request is authorized by basic auth. User: " + extractUser(decodeCredentials(authorizationHeader))); return true; } private boolean isCertSubject(SubjectMatcher subjectMatcher) { if(subjectMatcher.isCert() && subjectMatcher.match()){ - LOG.info("Cert and subjectDN is valid"); return true; } LOG.info(String.format(MESSAGE, settings.certSubjectMatcher())); @@ -112,16 +116,14 @@ public class ApiAuthInterceptor extends HandlerInterceptorAdapter { } private boolean isBasicAuth() { - return settings.authMethod().equalsIgnoreCase(AuthMethodType.BASIC_AUTH.value()) - || settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); + return settings.authMethod().equalsIgnoreCase(AuthMethodType.CERT_BASIC_AUTH.value()); } private boolean isAuthorized(String authorizationHeader) { try { - String encodedData = authorizationHeader.split(" ")[1]; - String decodedData = new String(Base64.getDecoder().decode(encodedData)); - String providedUser = decodedData.split(":")[0].trim(); - String providedPassword = decodedData.split(":")[1].trim(); + String decodeCredentials = decodeCredentials(authorizationHeader); + String providedUser = extractUser(decodeCredentials); + String providedPassword = extractPassword(decodeCredentials); Option<String> maybeSavedPassword = settings.validAuthorizationCredentials().get(providedUser); boolean userRegistered = maybeSavedPassword.isDefined(); return userRegistered && cryptPassword.matches(providedPassword,maybeSavedPassword.get()); @@ -131,4 +133,17 @@ public class ApiAuthInterceptor extends HandlerInterceptorAdapter { return false; } } + + private String extractPassword(String decodeCredentials) { + return decodeCredentials.split(":")[1].trim(); + } + + private String extractUser(String decodeCredentials) { + return decodeCredentials.split(":")[0].trim(); + } + + private String decodeCredentials(String authorizationHeader) { + String encodedData = authorizationHeader.split(" ")[1]; + return new String(Base64.getDecoder().decode(encodedData)); + } }
\ No newline at end of file diff --git a/src/main/java/org/onap/dcae/restapi/ServletConfig.java b/src/main/java/org/onap/dcae/restapi/ServletConfig.java index e68ddcdf..9af3eed8 100644 --- a/src/main/java/org/onap/dcae/restapi/ServletConfig.java +++ b/src/main/java/org/onap/dcae/restapi/ServletConfig.java @@ -27,8 +27,6 @@ import org.onap.dcae.ApplicationException; import org.onap.dcae.ApplicationSettings; import org.onap.dcae.common.configuration.AuthMethod; import org.onap.dcae.common.configuration.AuthMethodType; -import org.onap.dcae.common.configuration.BasicAuth; -import org.onap.dcae.common.configuration.CertAuth; import org.onap.dcae.common.configuration.CertBasicAuth; import org.onap.dcae.common.configuration.NoAuth; import org.springframework.beans.factory.annotation.Autowired; @@ -50,8 +48,6 @@ public class ServletConfig implements WebServerFactoryCustomizer<ConfigurableSer private Map<String, AuthMethod> provideAuthConfigurations(ConfigurableServletWebServerFactory container) { Map<String, AuthMethod> authMethods = new HashMap<>(); - authMethods.put(AuthMethodType.CERT_ONLY.value(), new CertAuth(container, properties)); - authMethods.put(AuthMethodType.BASIC_AUTH.value(), new BasicAuth(container, properties)); authMethods.put(AuthMethodType.CERT_BASIC_AUTH.value(), new CertBasicAuth(container, properties)); authMethods.put(AuthMethodType.NO_AUTH.value(), new NoAuth(container, properties)); return authMethods; diff --git a/src/test/java/org/onap/dcae/TLSTest.java b/src/test/java/org/onap/dcae/TLSTest.java index 49a089cc..e55b6052 100644 --- a/src/test/java/org/onap/dcae/TLSTest.java +++ b/src/test/java/org/onap/dcae/TLSTest.java @@ -32,8 +32,8 @@ import org.springframework.http.HttpStatus; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; -import static org.onap.dcae.TLSTest.HttpsConfiguration.USERNAME; -import static org.onap.dcae.TLSTest.HttpsConfiguration.PASSWORD; +import static org.onap.dcae.TLSTest.HttpsConfigurationWithTLSAuthenticationAndBasicAuth.USERNAME; +import static org.onap.dcae.TLSTest.HttpsConfigurationWithTLSAuthenticationAndBasicAuth.PASSWORD; public class TLSTest extends TLSTestBase { @@ -53,37 +53,6 @@ public class TLSTest extends TLSTestBase { } @Nested - @Import(HttpsConfiguration.class) - class HttpsTest extends TestClassBase { - - - @Test - public void shouldHttpsRequestWithoutBasicAuthFail() { - assertThrows(Exception.class, this::makeHttpsRequest); - } - - @Test - public void shouldHttpsRequestWithBasicAuthSucceed() { - assertEquals(HttpStatus.OK, makeHttpsRequestWithBasicAuth(USERNAME, PASSWORD).getStatusCode()); - } - } - - @Nested - @Import(HttpsConfigurationWithTLSAuthentication.class) - class HttpsWithTLSAuthenticationTest extends TestClassBase { - - @Test - public void shouldHttpsRequestWithoutCertificateFail() { - assertThrows(Exception.class, this::makeHttpsRequest); - } - - @Test - public void shouldHttpsRequestWithCertificateSucceed() { - assertEquals(HttpStatus.OK, makeHttpsRequestWithClientCert().getStatusCode()); - } - } - - @Nested @Import(HttpsConfigurationWithTLSAuthenticationAndBasicAuth.class) class HttpsWithTLSAuthenticationAndBasicAuthTest extends TestClassBase { @@ -107,38 +76,19 @@ public class TLSTest extends TLSTestBase { } } - static class HttpsConfiguration extends TLSTestBase.ConfigurationBase { + static class HttpsConfigurationWithTLSAuthenticationAndBasicAuth extends TLSTestBase.ConfigurationBase { public static final String USERNAME = "TestUser"; public static final String PASSWORD = "TestPassword"; - @Override protected void configureSettings(ApplicationSettings settings) { when(settings.keystoreFileLocation()).thenReturn(KEYSTORE.toString()); 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); - } - } - - static class HttpsConfigurationWithTLSAuthentication extends HttpsConfiguration { - @Override - protected void configureSettings(ApplicationSettings settings) { - super.configureSettings(settings); - when(settings.authMethod()).thenReturn(AuthMethodType.CERT_ONLY.value()); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); 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); } } - - static class HttpsConfigurationWithTLSAuthenticationAndBasicAuth extends HttpsConfigurationWithTLSAuthentication { - @Override - 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/restapi/ApiAuthInterceptionTest.java b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java index c80b56cb..67193617 100644 --- a/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java +++ b/src/test/java/org/onap/dcae/restapi/ApiAuthInterceptionTest.java @@ -20,8 +20,6 @@ package org.onap.dcae.restapi; -import io.vavr.collection.HashMap; -import io.vavr.collection.Map; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; @@ -30,9 +28,8 @@ import org.mockito.junit.MockitoJUnitRunner; import org.onap.dcae.ApplicationSettings; import org.onap.dcae.common.configuration.AuthMethodType; import org.slf4j.Logger; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import javax.servlet.http.HttpServletRequest; @@ -47,9 +44,9 @@ 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<String, String> CREDENTIALS = HashMap.of(USERNAME, PASSWORD); + private static final int HTTP_PORT = 8080; + private static final int OUTSIDE_PORT = 30235; + private static final String HEALTHCHECK_URL = "/healthcheck"; @Mock private Logger log; @@ -70,21 +67,6 @@ public class ApiAuthInterceptionTest { private ApiAuthInterceptor sut; - private HttpServletRequest createEmptyRequest() { - return MockMvcRequestBuilders - .post("") - .buildRequest(null); - } - - private HttpServletRequest createRequestWithAuthorizationHeader() { - return SecurityMockMvcRequestPostProcessors - .httpBasic(USERNAME, PASSWORD) - .postProcessRequest( - MockMvcRequestBuilders - .post("") - .buildRequest(null)); - } - @Test public void shouldSucceedWhenAuthorizationIsDisabled() throws IOException { // given @@ -100,51 +82,12 @@ public class ApiAuthInterceptionTest { } @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 { + public void shouldSucceedForHealthcheckOnHealthcheckPortWhenRequestFromInsideCluster() 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); + final HttpServletRequest request = createRequestWithPorts(HTTP_PORT, HTTP_PORT, HEALTHCHECK_URL); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); + when(settings.httpPort()).thenReturn(HTTP_PORT); // when final boolean isAuthorized = sut.preHandle(request, response, obj); @@ -153,16 +96,12 @@ public class ApiAuthInterceptionTest { } @Test - public void shouldFailDueToInvalidBasicAuthorizationHeaderValue() throws IOException { + public void shouldFailForHealthcheckOnHealthcheckPortWhenRequestFromOutsideCluster() throws IOException { // given - final HttpServletRequest request = - MockMvcRequestBuilders - .post("") - .header(HttpHeaders.AUTHORIZATION, "FooBar") - .buildRequest(null); + final HttpServletRequest request = createRequestWithPorts(HTTP_PORT, OUTSIDE_PORT, HEALTHCHECK_URL); - when(settings.authMethod()).thenReturn(AuthMethodType.BASIC_AUTH.value()); - when(settings.validAuthorizationCredentials()).thenReturn(CREDENTIALS); + when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); + when(settings.httpPort()).thenReturn(HTTP_PORT); when(response.getWriter()).thenReturn(writer); // when @@ -170,36 +109,16 @@ public class ApiAuthInterceptionTest { // then assertFalse(isAuthorized); - - verify(response).setStatus(HttpStatus.UNAUTHORIZED.value()); - verify(writer).write(ApiException.UNAUTHORIZED_USER.toJSON().toString()); - } - - @Test - public void shouldSucceedForHealthcheckOnHealthcheckPort() throws IOException { - // given - final HttpServletRequest request = - MockMvcRequestBuilders - .get("/healthcheck") - .buildRequest(null); - - when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); - when(settings.httpPort()).thenReturn(request.getServerPort()); - - // when - final boolean isAuthorized = sut.preHandle(request, response, obj); - - // then - assertTrue(isAuthorized); + verify(response).setStatus(HttpStatus.BAD_REQUEST.value()); } @Test public void shouldFailDueToNotPermittedOperationOnHealthcheckPort() throws IOException { // given - final HttpServletRequest request = createEmptyRequest(); + final HttpServletRequest request = createRequestWithPorts(HTTP_PORT, HTTP_PORT, "/"); when(settings.authMethod()).thenReturn(AuthMethodType.CERT_BASIC_AUTH.value()); - when(settings.httpPort()).thenReturn(request.getServerPort()); + when(settings.httpPort()).thenReturn(HTTP_PORT); when(response.getWriter()).thenReturn(writer); // when @@ -210,4 +129,18 @@ public class ApiAuthInterceptionTest { verify(response).setStatus(HttpStatus.BAD_REQUEST.value()); } -} + private HttpServletRequest createEmptyRequest() { + return MockMvcRequestBuilders + .post("") + .buildRequest(null); + } + + private HttpServletRequest createRequestWithPorts(int localPort, int serverPort, String urlTemplate) { + MockHttpServletRequest healthcheckRequest = MockMvcRequestBuilders + .get(urlTemplate) + .buildRequest(null); + healthcheckRequest.setLocalPort(localPort); + healthcheckRequest.setServerPort(serverPort); + return healthcheckRequest; + } +}
\ No newline at end of file diff --git a/version.properties b/version.properties index 303a703f..3f9d877d 100644 --- a/version.properties +++ b/version.properties @@ -1,6 +1,6 @@ major=1 minor=5 -patch=1 +patch=2 base_version=${major}.${minor}.${patch} release_version=${base_version} snapshot_version=${base_version}-SNAPSHOT |