From 689dbdc412e9905657b64fa5b501fcbe652b3255 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Wed, 4 Aug 2021 22:57:31 -0400 Subject: [PATCH] =?UTF-8?q?#8=20Les=20configurations=20s=C3=A9curitaires?= =?UTF-8?q?=20retournent=20leur=20informations=20sans=20leur=20contenu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DatabaseVersioning.kt | 8 +++-- .../model/Configuration.kt | 4 +++ .../rest/ConfigurationController.kt | 10 +++--- .../service/MaterialService.kt | 2 +- .../service/RecipeService.kt | 4 +-- .../service/TouchUpKitService.kt | 6 ++-- .../service/config/ConfigurationService.kt | 32 +++++++++++++++---- 7 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/DatabaseVersioning.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/DatabaseVersioning.kt index a355f4b..5f020fb 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/DatabaseVersioning.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/DatabaseVersioning.kt @@ -3,23 +3,24 @@ package dev.fyloz.colorrecipesexplorer import dev.fyloz.colorrecipesexplorer.databasemanager.CreDatabase import dev.fyloz.colorrecipesexplorer.databasemanager.databaseContext import dev.fyloz.colorrecipesexplorer.databasemanager.databaseUpdaterProperties +import dev.fyloz.colorrecipesexplorer.model.Configuration import dev.fyloz.colorrecipesexplorer.model.ConfigurationType import dev.fyloz.colorrecipesexplorer.service.config.ConfigurationService import org.slf4j.Logger import org.springframework.boot.jdbc.DataSourceBuilder import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.DependsOn import org.springframework.context.annotation.Profile import org.springframework.core.env.ConfigurableEnvironment import javax.sql.DataSource +import org.springframework.context.annotation.Configuration as SpringConfiguration const val SUPPORTED_DATABASE_VERSION = 5 const val ENV_VAR_ENABLE_DATABASE_UPDATE_NAME = "CRE_ENABLE_DB_UPDATE" val DATABASE_NAME_REGEX = Regex("(\\w+)$") @Profile("!emergency") -@Configuration +@SpringConfiguration @DependsOn("configurationsInitializer", "configurationService") class DataSourceConfiguration { @Bean(name = ["dataSource"]) @@ -29,7 +30,8 @@ class DataSourceConfiguration { configurationService: ConfigurationService ): DataSource { fun getConfiguration(type: ConfigurationType) = - configurationService.get(type).content + if (type.secure) configurationService.getSecure(type) + else configurationService.getContent(type) val databaseUrl = "jdbc:" + getConfiguration(ConfigurationType.DATABASE_URL) val databaseUsername = getConfiguration(ConfigurationType.DATABASE_USER) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt index 3f6f8f8..a701661 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt @@ -81,6 +81,10 @@ fun configuration( configuration(type = key.toConfigurationType(), content = content) } +fun secureConfiguration( + configuration: Configuration +) = SecureConfiguration(configuration.type, configuration.lastUpdated) + enum class ConfigurationType( val key: String, val defaultContent: Any? = null, diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/ConfigurationController.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/ConfigurationController.kt index 1cad0ee..1e7cff4 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/ConfigurationController.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/rest/ConfigurationController.kt @@ -1,6 +1,6 @@ package dev.fyloz.colorrecipesexplorer.rest -import dev.fyloz.colorrecipesexplorer.model.Configuration +import dev.fyloz.colorrecipesexplorer.model.ConfigurationBase import dev.fyloz.colorrecipesexplorer.model.ConfigurationDto import dev.fyloz.colorrecipesexplorer.model.ConfigurationImageDto import dev.fyloz.colorrecipesexplorer.model.account.Permission @@ -20,13 +20,11 @@ class ConfigurationController(val configurationService: ConfigurationService) { fun getAll(@RequestParam(required = false) keys: String?, authentication: Authentication?) = ok(with(configurationService) { if (keys != null) getAll(keys) else getAll() - }.filter { - !it.type.secure && authentication.hasAuthority(it) - }) + }.filter { authentication.hasAuthority(it) }) @GetMapping("{key}") fun get(@PathVariable key: String, authentication: Authentication?) = with(configurationService.get(key)) { - if (!this.type.secure && authentication.hasAuthority(this)) ok(this) else forbidden() + if (authentication.hasAuthority(this)) ok(this) else forbidden() } @PutMapping @@ -48,7 +46,7 @@ class ConfigurationController(val configurationService: ConfigurationService) { } } -private fun Authentication?.hasAuthority(configuration: Configuration) = when { +private fun Authentication?.hasAuthority(configuration: ConfigurationBase) = when { configuration.type.public -> true this != null && Permission.ADMIN.toAuthority() in this.authorities -> true else -> false diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt index 6802776..7d752f9 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/MaterialService.kt @@ -59,7 +59,7 @@ class MaterialServiceImpl( isMixType = this.isMixType, materialType = this.materialType!!, simdutUrl = if (fileService.exists(this.simdutFilePath)) - "${configService.get(ConfigurationType.INSTANCE_URL).content}$FILE_CONTROLLER_PATH?path=${ + "${configService.getContent(ConfigurationType.INSTANCE_URL)}$FILE_CONTROLLER_PATH?path=${ URLEncoder.encode( this.simdutFilePath, StandardCharsets.UTF_8 diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt index 3b44f8a..4dcda07 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeService.kt @@ -78,7 +78,7 @@ class RecipeServiceImpl( }.toSet(), this.groupsInformation, recipeImageService.getAllImages(this) - .map { this.imageUrl(configService.get(ConfigurationType.INSTANCE_URL).content, it) } + .map { this.imageUrl(configService.getContent(ConfigurationType.INSTANCE_URL), it) } .toSet() ) @@ -87,7 +87,7 @@ class RecipeServiceImpl( repository.existsByNameAndCompany(name, company) override fun isApprobationExpired(recipe: Recipe): Boolean? = - with(Period.parse(configService.get(ConfigurationType.RECIPE_APPROBATION_EXPIRATION).content)) { + with(Period.parse(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION))) { recipe.approbationDate?.plus(this)?.isBefore(LocalDate.now()) } diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt index acd1600..b966525 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitService.kt @@ -48,7 +48,7 @@ class TouchUpKitServiceImpl( touchUpKitRepository ), TouchUpKitService { private val cacheGeneratedFiles by lazy { - configService.get(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF).content == true.toString() + configService.getContent(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF) == true.toString() } override fun idNotFoundException(id: Long) = touchUpKitIdNotFoundException(id) @@ -90,7 +90,7 @@ class TouchUpKitServiceImpl( } override fun isExpired(touchUpKit: TouchUpKit) = - with(Period.parse(configService.get(ConfigurationType.TOUCH_UP_KIT_EXPIRATION).content)) { + with(Period.parse(configService.getContent(ConfigurationType.TOUCH_UP_KIT_EXPIRATION))) { touchUpKit.completed && touchUpKit.completionDate!!.plus(this) < LocalDate.now() } @@ -144,5 +144,5 @@ class TouchUpKitServiceImpl( "$TOUCH_UP_KIT_FILES_PATH/$this.pdf" private fun TouchUpKit.pdfUrl() = - "${configService.get(ConfigurationType.INSTANCE_URL).content}$TOUCH_UP_KIT_CONTROLLER_PATH/pdf?job=$project" + "${configService.getContent(ConfigurationType.INSTANCE_URL)}$TOUCH_UP_KIT_CONTROLLER_PATH/pdf?job=$project" } diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/config/ConfigurationService.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/config/ConfigurationService.kt index 03eef2f..8e5d0c2 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/config/ConfigurationService.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/service/config/ConfigurationService.kt @@ -12,22 +12,28 @@ import org.springframework.stereotype.Service interface ConfigurationService { /** Gets all set configurations. */ - fun getAll(): List + fun getAll(): List /** * Gets all configurations with keys contained in the given [formattedKeyList]. * The [formattedKeyList] contains wanted configuration keys separated by a semi-colon. */ - fun getAll(formattedKeyList: String): List + fun getAll(formattedKeyList: String): List /** * Gets the configuration with the given [key]. * If the [key] does not exists, an [InvalidConfigurationKeyException] will be thrown. */ - fun get(key: String): Configuration + fun get(key: String): ConfigurationBase /** Gets the configuration with the given [type]. */ - fun get(type: ConfigurationType): Configuration + fun get(type: ConfigurationType): ConfigurationBase + + /** Gets the content of the configuration with the given [type]. */ + fun getContent(type: ConfigurationType): String + + /** Gets the content of the secure configuration with the given [type]. Should not be accessible to the users. */ + fun getSecure(type: ConfigurationType): String /** Sets the content of each configuration in the given [configurations] list. */ fun set(configurations: List) @@ -89,18 +95,32 @@ class ConfigurationServiceImpl( override fun get(key: String) = get(key.toConfigurationType()) - override fun get(type: ConfigurationType): Configuration { + override fun get(type: ConfigurationType): ConfigurationBase { // Encryption salt should never be returned, but cannot be set as "secure" without encrypting it if (type == ConfigurationType.GENERATED_ENCRYPTION_SALT) throw InvalidConfigurationKeyException(type.key) val configuration = configurationSource.get(type) ?: throw ConfigurationNotSetException(type) return if (type.secure) { - decryptConfiguration(configuration) + secureConfiguration(configuration) } else { configuration } } + override fun getContent(type: ConfigurationType): String { + val configuration = get(type) + if (configuration is SecureConfiguration) throw UnsupportedOperationException("Cannot get '${type.key}' configuration content because it is secure") + + return (configuration as Configuration).content + } + + override fun getSecure(type: ConfigurationType): String { + if (!type.secure) throw UnsupportedOperationException("Cannot get configuration of type '${type.key}' because it is not a secure configuration") + + val configuration = configurationSource.get(type) ?: throw ConfigurationNotSetException(type) + return decryptConfiguration(configuration).content + } + override fun set(configurations: List) { configurationSource.set( configurations