From 6a00e38550fd1745c3377da2099bf5a615f69053 Mon Sep 17 00:00:00 2001 From: Filip Krzywka Date: Tue, 2 Apr 2019 13:01:07 +0200 Subject: [PATCH] Allow reuse of security passwords - moved logic of creating passwords into Validator Change-Id: Ieabab24734250bfacea96eff2b7102465ff8ed57 Issue-ID: DCAEGEN2-1380 Signed-off-by: Filip Krzywka --- .../veshv/config/impl/ConfigurationValidator.kt | 14 ++++++- .../impl/gsonadapters/DurationOfSecondsAdapter.kt | 2 +- .../config/impl/gsonadapters/SecurityAdapter.kt | 23 ++++------- .../veshv/config/impl/partial_configuration.kt | 5 +-- .../config/impl/ConfigurationValidatorTest.kt | 23 +++++++---- .../veshv/ssl/boundary/SecurityKeysPaths.kt | 48 ++++++++++++++++++++++ 6 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 sources/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SecurityKeysPaths.kt diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt index ead5655a..407fd745 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidator.kt @@ -29,6 +29,7 @@ import org.onap.dcae.collectors.veshv.config.api.model.HvVesConfiguration import org.onap.dcae.collectors.veshv.config.api.model.ServerConfiguration import org.onap.dcae.collectors.veshv.config.api.model.ValidationException import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityConfiguration +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import org.onap.dcae.collectors.veshv.utils.arrow.OptionUtils.binding import org.onap.dcae.collectors.veshv.utils.arrow.mapBinding import org.onap.dcae.collectors.veshv.utils.arrow.doOnEmpty @@ -54,7 +55,9 @@ internal class ConfigurationValidator { .doOnEmpty { logger.debug { "Cannot bind cbs configuration" } } .bind() - val securityConfiguration = SecurityConfiguration(partialConfig.security.bind().keys) + val securityConfiguration = validatedSecurityConfiguration(partialConfig) + .doOnEmpty { logger.debug { "Cannot bind security configuration" } } + .bind() val collectorConfiguration = validatedCollectorConfig(partialConfig) .doOnEmpty { logger.debug { "Cannot bind collector configuration" } } @@ -91,7 +94,7 @@ internal class ConfigurationValidator { } } - fun validatedCbsConfiguration(partial: PartialConfiguration) = + internal fun validatedCbsConfiguration(partial: PartialConfiguration) = partial.mapBinding { it.cbs.bind().let { CbsConfiguration( @@ -101,6 +104,13 @@ internal class ConfigurationValidator { } } + private fun validatedSecurityConfiguration(partial: PartialConfiguration) = + partial.mapBinding { + it.security.bind().let { + SecurityConfiguration(it.keys.map(SecurityKeysPaths::asImmutableSecurityKeys)) + } + } + private fun validatedCollectorConfig(partial: PartialConfiguration) = partial.mapBinding { partial.collector.bind().let { diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/DurationOfSecondsAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/DurationOfSecondsAdapter.kt index 99da1102..3bde7089 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/DurationOfSecondsAdapter.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/DurationOfSecondsAdapter.kt @@ -29,7 +29,7 @@ import java.time.Duration * @author Pawel Biniek * @since March 2019 */ -class DurationOfSecondsAdapter : JsonDeserializer { +internal class DurationOfSecondsAdapter : JsonDeserializer { override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext) = Duration.ofSeconds(json.asLong) diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt index 859fd700..bc8cf51c 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/gsonadapters/SecurityAdapter.kt @@ -25,10 +25,7 @@ import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import com.google.gson.JsonObject import org.onap.dcae.collectors.veshv.config.impl.PartialSecurityConfig -import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeys -import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeysStore -import org.onap.dcaegen2.services.sdk.security.ssl.Passwords -import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import java.io.File import java.lang.reflect.Type @@ -50,18 +47,14 @@ internal class SecurityAdapter : JsonDeserializer { private fun hasSslDisableSet(security: JsonObject) = security.has(SSL_DISABLE_KEY) && security[SSL_DISABLE_KEY].asBoolean - private fun JsonObject.securityKeys(f: (JsonObject) -> SecurityKeys) = f(getAsJsonObject(KEYS_OBJECT_KEY)) + private fun JsonObject.securityKeys(f: (JsonObject) -> SecurityKeysPaths) = f(getAsJsonObject(KEYS_OBJECT_KEY)) - private fun asImmutableSecurityKeys(keys: JsonObject) = ImmutableSecurityKeys.builder() - .keyStore(ImmutableSecurityKeysStore.of( - File(keys[KEY_STORE_FILE_KEY].asString).toPath())) - .keyStorePassword( - Passwords.fromString(keys[KEY_STORE_PASSWORD_KEY].asString)) - .trustStore(ImmutableSecurityKeysStore.of( - File(keys[TRUST_STORE_FILE_KEY].asString).toPath())) - .trustStorePassword( - Passwords.fromString(keys[TRUST_STORE_PASSWORD_KEY].asString)) - .build() + private fun asImmutableSecurityKeys(keys: JsonObject) = SecurityKeysPaths( + File(keys[KEY_STORE_FILE_KEY].asString).toPath(), + keys[KEY_STORE_PASSWORD_KEY].asString, + File(keys[TRUST_STORE_FILE_KEY].asString).toPath(), + keys[TRUST_STORE_PASSWORD_KEY].asString + ) companion object { private val SSL_DISABLE_KEY = "sslDisable" diff --git a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt index b4e1bf6b..82cf533a 100644 --- a/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt +++ b/sources/hv-collector-configuration/src/main/kotlin/org/onap/dcae/collectors/veshv/config/impl/partial_configuration.kt @@ -22,9 +22,8 @@ package org.onap.dcae.collectors.veshv.config.impl import arrow.core.None import arrow.core.Option import org.onap.dcae.collectors.veshv.config.api.model.Routing +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import org.onap.dcae.collectors.veshv.utils.logging.LogLevel -import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys -import java.net.InetSocketAddress import java.time.Duration /** @@ -50,7 +49,7 @@ internal data class PartialCbsConfig( val requestIntervalSec: Option = None ) -internal data class PartialSecurityConfig(val keys: Option = None) +internal data class PartialSecurityConfig(val keys: Option = None) internal data class PartialCollectorConfig( val routing: Option = None diff --git a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt index 55d06cdd..682bec5a 100644 --- a/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt +++ b/sources/hv-collector-configuration/src/test/kotlin/org/onap/dcae/collectors/veshv/config/impl/ConfigurationValidatorTest.kt @@ -22,14 +22,19 @@ package org.onap.dcae.collectors.veshv.config.impl import arrow.core.None import arrow.core.Option import arrow.core.Some +import arrow.core.getOrElse import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.fail +import org.assertj.core.api.ObjectAssert import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe import org.jetbrains.spek.api.dsl.it import org.onap.dcae.collectors.veshv.config.api.model.Routing import org.onap.dcae.collectors.veshv.config.impl.ConfigurationValidator.Companion.DEFAULT_LOG_LEVEL +import org.onap.dcae.collectors.veshv.ssl.boundary.SecurityKeysPaths import org.onap.dcae.collectors.veshv.utils.logging.LogLevel import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys import java.time.Duration @@ -85,7 +90,9 @@ internal object ConfigurationValidatorTest : Spek({ describe("validating complete configuration") { val idleTimeoutSec = Duration.ofSeconds(10L) val firstReqDelaySec = Duration.ofSeconds(10L) - val securityKeys = Some(mock()) + val securityKeys = mock() + val immutableSecurityKeys = mock() + whenever(securityKeys.asImmutableSecurityKeys()).thenReturn(immutableSecurityKeys) val config = PartialConfiguration( Some(PartialServerConfig( @@ -98,7 +105,7 @@ internal object ConfigurationValidatorTest : Spek({ Some(Duration.ofSeconds(3)) )), Some(PartialSecurityConfig( - securityKeys + Some(securityKeys) )), Some(PartialCollectorConfig( someFromEmptyRouting @@ -116,8 +123,10 @@ internal object ConfigurationValidatorTest : Spek({ assertThat(it.server.idleTimeout) .isEqualTo(idleTimeoutSec) - assertThat(it.security.keys) - .isEqualTo(securityKeys) + verify(securityKeys).asImmutableSecurityKeys() + assertThat(it.security.keys + .getOrElse { fail("Should be immutableSecurityKeys") }) + .isEqualTo(immutableSecurityKeys) assertThat(it.cbs.firstRequestDelay) .isEqualTo(firstReqDelaySec) @@ -132,7 +141,7 @@ internal object ConfigurationValidatorTest : Spek({ describe("validating configuration with security disabled") { val idleTimeoutSec = Duration.ofSeconds(10) val firstReqDelaySec = Duration.ofSeconds(10) - val securityKeys: Option = None + val missingSecurityKeys: Option = None val config = PartialConfiguration( Some(PartialServerConfig( @@ -145,7 +154,7 @@ internal object ConfigurationValidatorTest : Spek({ Some(Duration.ofSeconds(3)) )), Some(PartialSecurityConfig( - securityKeys + missingSecurityKeys )), Some(PartialCollectorConfig( someFromEmptyRouting @@ -164,7 +173,7 @@ internal object ConfigurationValidatorTest : Spek({ .isEqualTo(idleTimeoutSec) assertThat(it.security.keys) - .isEqualTo(securityKeys) + .isEqualTo(missingSecurityKeys) assertThat(it.cbs.firstRequestDelay) .isEqualTo(firstReqDelaySec) diff --git a/sources/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SecurityKeysPaths.kt b/sources/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SecurityKeysPaths.kt new file mode 100644 index 00000000..21929b05 --- /dev/null +++ b/sources/hv-collector-ssl/src/main/kotlin/org/onap/dcae/collectors/veshv/ssl/boundary/SecurityKeysPaths.kt @@ -0,0 +1,48 @@ +/* + * ============LICENSE_START======================================================= + * dcaegen2-collectors-veshv + * ================================================================================ + * Copyright (C) 2019 NOKIA + * ================================================================================ + * 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.collectors.veshv.ssl.boundary + +import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeys +import org.onap.dcaegen2.services.sdk.security.ssl.ImmutableSecurityKeysStore +import org.onap.dcaegen2.services.sdk.security.ssl.Passwords +import org.onap.dcaegen2.services.sdk.security.ssl.SecurityKeys +import java.nio.file.Path + +data class SecurityKeysPaths( + val keyStore: Path, + val keyStorePassword: String, + val trustStore: Path, + val trustStorePassword: String +) { + fun asImmutableSecurityKeys(): SecurityKeys = ImmutableSecurityKeys.builder() + .keyStore(ImmutableSecurityKeysStore.of(keyStore)) + .keyStorePassword(Passwords.fromString(keyStorePassword)) + .trustStore(ImmutableSecurityKeysStore.of(trustStore)) + .trustStorePassword(Passwords.fromString(trustStorePassword)) + .build() + + override fun toString(): String { + return "SecurityKeysPaths(keyStore='$keyStore', " + + "keyStorePassword=, " + + "trustStore='$trustStore', " + + "trustStorePassword=)" + } + +} -- 2.16.6