From ae5c19faca8a8d07758c30f27dc0d1e7cd7eb3d1 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Wed, 4 Aug 2021 21:54:17 -0400 Subject: [PATCH 1/7] =?UTF-8?q?#8=20Ajout=20de=20ConfigurationBase,=20dont?= =?UTF-8?q?=20Configuration=20et=20SecureConfiguration=20h=C3=A9ritent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/Configuration.kt | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt index c1c4384..3f6f8f8 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt @@ -12,20 +12,25 @@ import javax.persistence.Id import javax.persistence.Table import javax.validation.constraints.NotBlank -data class Configuration( +sealed class ConfigurationBase( @JsonIgnore val type: ConfigurationType, - val content: String, val lastUpdated: LocalDateTime ) { val key = type.key val requireRestart = type.requireRestart val editable = !type.computed +} +class Configuration(type: ConfigurationType, val content: String, lastUpdated: LocalDateTime) : + ConfigurationBase(type, lastUpdated) { fun toEntity() = ConfigurationEntity(key, content, lastUpdated) } +class SecureConfiguration(type: ConfigurationType, lastUpdated: LocalDateTime) : + ConfigurationBase(type, lastUpdated) + @Entity @Table(name = "configuration") data class ConfigurationEntity( @@ -92,7 +97,13 @@ enum class ConfigurationType( DATABASE_URL("database.url", defaultContent = "mysql://localhost/cre", file = true, requireRestart = true), DATABASE_USER("database.user", defaultContent = "cre", file = true, requireRestart = true), - DATABASE_PASSWORD("database.password", defaultContent = "asecurepassword", file = true, requireRestart = true, secure = true), + DATABASE_PASSWORD( + "database.password", + defaultContent = "asecurepassword", + file = true, + requireRestart = true, + secure = true + ), DATABASE_SUPPORTED_VERSION("database.version.supported", computed = true), RECIPE_APPROBATION_EXPIRATION("recipe.approbation.expiration", defaultContent = 4.months), @@ -128,15 +139,15 @@ class InvalidConfigurationKeyException(val key: String) : ) class InvalidImageConfigurationException(val type: ConfigurationType) : - RestException( - "invalid-configuration-image", - "Invalid image configuration", - HttpStatus.BAD_REQUEST, - "The configuration with the key '${type.key}' does not accept images as content", - mapOf( - "key" to type.key - ) - ) + RestException( + "invalid-configuration-image", + "Invalid image configuration", + HttpStatus.BAD_REQUEST, + "The configuration with the key '${type.key}' does not accept images as content", + mapOf( + "key" to type.key + ) + ) class ConfigurationNotSetException(val type: ConfigurationType) : RestException( From 689dbdc412e9905657b64fa5b501fcbe652b3255 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Wed, 4 Aug 2021 22:57:31 -0400 Subject: [PATCH 2/7] =?UTF-8?q?#8=20Les=20configurations=20s=C3=A9curitair?= =?UTF-8?q?es=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 From a07c72b90140fd08f5fbffb4af4a76d0fb8ee489 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Thu, 5 Aug 2021 23:00:42 -0400 Subject: [PATCH 3/7] =?UTF-8?q?#8=20Mise=20=C3=A0=20jour=20des=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/Configuration.kt | 7 ++- .../service/ConfigurationServiceTest.kt | 56 +++++++++++++++++-- .../service/RecipeServiceTest.kt | 12 ++-- .../service/TouchUpKitServiceTest.kt | 5 +- 4 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt index a701661..b913523 100644 --- a/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt +++ b/src/main/kotlin/dev/fyloz/colorrecipesexplorer/model/Configuration.kt @@ -81,9 +81,14 @@ fun configuration( configuration(type = key.toConfigurationType(), content = content) } +fun secureConfiguration( + type: ConfigurationType, + lastUpdated: LocalDateTime? = null +) = SecureConfiguration(type, lastUpdated ?: LocalDateTime.now()) + fun secureConfiguration( configuration: Configuration -) = SecureConfiguration(configuration.type, configuration.lastUpdated) +) = secureConfiguration(configuration.type, configuration.lastUpdated) enum class ConfigurationType( val key: String, diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationServiceTest.kt index 8c4df85..e49fc60 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/ConfigurationServiceTest.kt @@ -10,6 +10,7 @@ import io.mockk.* import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import kotlin.UnsupportedOperationException import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -165,7 +166,47 @@ class ConfigurationServiceTest { } @Test - fun `get(type) decrypts configuration content when the given ConfigurationType is secure`() { + fun `get(type) returns a SecureConfiguration when the given ConfigurationType is secure`() { + val type = ConfigurationType.DATABASE_PASSWORD + val configuration = configuration( + type = type, + content = "securepassword".encrypt(type.key, securityProperties.configSalt!!) + ) + + every { configurationSource.get(type) } returns configuration + + val found = service.get(type) + + assertTrue { found is SecureConfiguration } + } + + @Test + fun `getContent(type) returns configuration content`() { + val type = ConfigurationType.INSTANCE_NAME + val configuration = configuration( + type = type, + content = "content" + ) + + every { service.get(type) } returns configuration + + val found = service.getContent(type) + + assertEquals(configuration.content, found) + } + + @Test + fun `getContent(type) throws UnsupportedOperationException when configuration is secure`() { + val type = ConfigurationType.DATABASE_PASSWORD + val configuration = secureConfiguration(type) + + every { service.get(type) } returns configuration + + assertThrows { service.getContent(type) } + } + + @Test + fun `getSecure(type) returns decrypted configuration content`() { val type = ConfigurationType.DATABASE_PASSWORD val content = "securepassword" val configuration = configuration( @@ -175,9 +216,16 @@ class ConfigurationServiceTest { every { configurationSource.get(type) } returns configuration - val found = service.get(type) + val found = service.getSecure(type) - assertEquals(content, found.content) + assertEquals(content, found) + } + + @Test + fun `getSecure(type) throws UnsupportedOperationException when configuration is not secure`() { + val type = ConfigurationType.INSTANCE_NAME + + assertThrows { service.getSecure(type) } } @Test @@ -197,7 +245,7 @@ class ConfigurationServiceTest { fun `set(configuration) encrypts secure configurations`() { val type = ConfigurationType.DATABASE_PASSWORD val content = "securepassword" - val encryptedContent =content.encrypt(type.key, securityProperties.configSalt!!) + val encryptedContent = content.encrypt(type.key, securityProperties.configSalt!!) val configuration = configuration(type = type, content = content) mockkStatic(String::encrypt) diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt index 58a1193..0e055ad 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/RecipeServiceTest.kt @@ -80,9 +80,9 @@ class RecipeServiceTest : @Test fun `isApprobationExpired() returns false when the approbation date of the given recipe is within the configured period`() { val period = Period.ofMonths(4) - val config = configuration(type = ConfigurationType.RECIPE_APPROBATION_EXPIRATION, content = period.toString()) val recipe = recipe(approbationDate = LocalDate.now()) - whenever(configService.get(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(config) + + whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) val approbationExpired = service.isApprobationExpired(recipe) @@ -93,9 +93,9 @@ class RecipeServiceTest : @Test fun `isApprobationExpired() returns true when the approbation date of the given recipe is outside the configured period`() { val period = Period.ofMonths(4) - val config = configuration(type = ConfigurationType.RECIPE_APPROBATION_EXPIRATION, content = period.toString()) val recipe = recipe(approbationDate = LocalDate.now().minus(period).minusMonths(1)) - whenever(configService.get(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(config) + + whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) val approbationExpired = service.isApprobationExpired(recipe) @@ -106,9 +106,9 @@ class RecipeServiceTest : @Test fun `isApprobationExpired() returns null when the given recipe as no approbation date`() { val period = Period.ofMonths(4) - val config = configuration(type = ConfigurationType.RECIPE_APPROBATION_EXPIRATION, content = period.toString()) val recipe = recipe(approbationDate = null) - whenever(configService.get(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(config) + + whenever(configService.getContent(ConfigurationType.RECIPE_APPROBATION_EXPIRATION)).doReturn(period.toString()) val approbationExpired = service.isApprobationExpired(recipe) diff --git a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitServiceTest.kt b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitServiceTest.kt index c913d45..f6b5ba2 100644 --- a/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitServiceTest.kt +++ b/src/test/kotlin/dev/fyloz/colorrecipesexplorer/service/TouchUpKitServiceTest.kt @@ -131,10 +131,7 @@ class TouchUpKitServiceTest { this.setCachePdf(false) private fun TouchUpKitServiceTestContext.setCachePdf(enabled: Boolean) { - every { configService.get(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF) } returns configuration( - type = ConfigurationType.TOUCH_UP_KIT_CACHE_PDF, - enabled.toString() - ) + every { configService.getContent(ConfigurationType.TOUCH_UP_KIT_CACHE_PDF) } returns enabled.toString() } private fun test(test: TouchUpKitServiceTestContext.() -> Unit) { From 16d1f2afda49639e28d7a8afecdca80a9f868cc1 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Thu, 5 Aug 2021 23:36:48 -0400 Subject: [PATCH 4/7] =?UTF-8?q?#8=20Mise=20=C3=A0=20jour=20CI/CD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 11 ++++++++++ .drone.yml | 55 ++++++++++++++++++++++++++++++----------------- Dockerfile | 22 +++++++++++++------ gradle.Dockerfile | 10 --------- todo.txt | 15 ------------- 5 files changed, 62 insertions(+), 51 deletions(-) create mode 100644 .dockerignore delete mode 100644 gradle.Dockerfile delete mode 100644 todo.txt diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8cdfa43 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +.gradle +.idea +**/build +**/data +**/gradle +**/logs +.gitignore +.gitlab-ci.yml +docker-compose.yml +Dockerfile +gradlew** diff --git a/.drone.yml b/.drone.yml index abd9354..c3a9b41 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,38 +1,51 @@ +--- +global-variables: + environment: &environment + JAVA_VERSION: 11 + GRADLE_VERSION: 7.1 + CRE_VERSION: dev-${DRONE_BUILD_NUMBER} + CRE_ARTIFACT_NAME: ColorRecipesExplorer + CRE_REGISTRY_IMAGE: registry.fyloz.dev:5443/colorrecipesexplorer/backend + CRE_PORT: 9101 + gradle-image: &gradle-image gradle:7.1-jdk11 + alpine-image: &alpine-image alpine:latest + docker-registry-repo: &docker-registry-repo registry.fyloz.dev:5443/colorrecipesexplorer/backend + kind: pipeline name: default type: docker -environment: - CRE_VERSION: ${DRONE_BUILD_NUMBER} - CRE_ARTIFACT_NAME: ColorRecipesExplorer - CRE_REGISTRY_IMAGE: registry.fyloz.dev:5443/colorrecipesexplorer/backend - CRE_PORT: 9101 - steps: - - name: test - image: gradle:7.1-jdk11 + - name: set-docker-tags + image: *alpine-image + environment: + <<: *environment commands: - - gradle test + - echo -n "latest,dev-$CRE_VERSION" > .tags + - cat .tags when: branch: develop events: push - - name: build - image: gradle:7.1-jdk11 + - name: gradle-test + image: *gradle-image commands: - - gradle bootJar -Pversion=$CRE_VERSION - - mv build/libs/ColorRecipesExplorer-$CRE_VERSION.jar $CRE_ARTIFACT_NAME.jar - - echo -n "latest,$CRE_VERSION" > .tags + - gradle test when: - branch: master - events: push + branch: develop + events: [push, pull_request] - name: containerize image: plugins/docker + environment: + <<: *environment settings: - build_args: - - JAVA_VERSION=11 - repo: registry.fyloz.dev:5443/colorrecipesexplorer/backend + build_args_from_env: + - GRADLE_VERSION + - JAVA_VERSION + - CRE_VERSION + - CRE_PORT + repo: *docker-registry-repo when: branch: master events: push @@ -40,6 +53,8 @@ steps: - name: deploy image: alpine:latest environment: + <<: *environment + CRE_REGISTRY_IMAGE: *docker-registry-repo DEPLOY_SERVER: from_secret: deploy_server DEPLOY_SERVER_USERNAME: @@ -64,7 +79,7 @@ steps: - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' - ssh -p $DEPLOY_SERVER_SSH_PORT $DEPLOY_SERVER_USERNAME@$DEPLOY_SERVER "docker stop $DEPLOY_CONTAINER_NAME || true && docker rm $DEPLOY_CONTAINER_NAME || true" - ssh -p $DEPLOY_SERVER_SSH_PORT $DEPLOY_SERVER_USERNAME@$DEPLOY_SERVER "docker pull $CRE_REGISTRY_IMAGE:latest" - - ssh -p $DEPLOY_SERVER_SSH_PORT $DEPLOY_SERVER_USERNAME@$DEPLOY_SERVER "docker run -d -p $CRE_PORT:9090 --name=$DEPLOY_CONTAINER_NAME -v $DEPLOY_DATA_VOLUME:/usr/bin/cre/data -v $DEPLOY_CONFIG_VOLUME:/usr/bin/cre/config -e spring_profiles_active=$DEPLOY_SPRING_PROFILES $CRE_REGISTRY_IMAGE" + - ssh -p $DEPLOY_SERVER_SSH_PORT $DEPLOY_SERVER_USERNAME@$DEPLOY_SERVER "docker run -d -p $CRE_PORT:9090 --name=$DEPLOY_CONTAINER_NAME -v $DEPLOY_DATA_VOLUME:/usr/bin/data -v $DEPLOY_CONFIG_VOLUME:/usr/bin/config -e spring_profiles_active=$DEPLOY_SPRING_PROFILES $CRE_REGISTRY_IMAGE" when: branch: master events: push diff --git a/Dockerfile b/Dockerfile index 3f4a504..66b5bba 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,21 @@ +ARG GRADLE_VERSION=7.1 ARG JAVA_VERSION=11 +ARG CRE_VERSION=dev -FROM openjdk:$JAVA_VERSION +FROM gradle:$GRADLE_VERSION-jdk$JAVA_VERSION AS build +WORKDIR /usr/src -WORKDIR /usr/bin/cre/ +COPY . . +RUN gradle bootJar -Pversion=$CRE_VERSION -ARG CRE_ARTIFACT_NAME=ColorRecipesExplorer -COPY $CRE_ARTIFACT_NAME.jar ColorRecipesExplorer.jar +FROM alpine:latest +WORKDIR /usr/bin + +ARG JAVA_VERSION +RUN apk add --no-cache openjdk$JAVA_VERSION + +ARG CRE_VERSION +COPY --from=build /usr/src/build/libs/ColorRecipesExplorer.jar ColorRecipesExplorer.jar ARG CRE_PORT=9090 EXPOSE $CRE_PORT @@ -16,7 +26,7 @@ ENV spring_datasource_url=jdbc:h2:mem:cre ENV spring_datasource_username=root ENV spring_datasource_password=pass -VOLUME /usr/bin/cre/data -VOLUME /usr/bin/cre/config +VOLUME /usr/bin/data +VOLUME /usr/bin/config ENTRYPOINT ["java", "-jar", "ColorRecipesExplorer.jar"] diff --git a/gradle.Dockerfile b/gradle.Dockerfile deleted file mode 100644 index 2538416..0000000 --- a/gradle.Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -ARG JDK_VERSION=11 -ARG GRADLE_VERSION=7.1 - -FROM gradle:$GRADLE_VERSION-jdk$JDK_VERSION -WORKDIR /usr/src/cre/ - -COPY build.gradle.kts build.gradle.kts -COPY settings.gradle.kts settings.gradle.kts -COPY src src - diff --git a/todo.txt b/todo.txt deleted file mode 100644 index e940649..0000000 --- a/todo.txt +++ /dev/null @@ -1,15 +0,0 @@ -== Icônes pour recettes non-approuvés / quantité faible == -== Texte SIMDUT inexistant (fiche signalitique) pour les matériaux == - - - -== Comptes == -No employé - Permissions - Employés - - - -== Kits de retouche == -No Job - No Dossier - Qté - Description - Case à cocher - Note - Bouton compléter si tout est coché/imprimé ? - -Enregistrer localdatetime/personne pendant une certaine durée From 44185b0e5018b344bfdf4c4613326f159a0cb392 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Thu, 5 Aug 2021 23:40:49 -0400 Subject: [PATCH 5/7] =?UTF-8?q?#8=20Mise=20=C3=A0=20jour=20CI/CD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.drone.yml b/.drone.yml index c3a9b41..9acf5ab 100644 --- a/.drone.yml +++ b/.drone.yml @@ -84,4 +84,9 @@ steps: branch: master events: push + trigger: + branch: + - develop + - master + From b7a15b6ce45e380d4e302020f7e397cf5a05ff69 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Thu, 5 Aug 2021 23:42:20 -0400 Subject: [PATCH 6/7] =?UTF-8?q?#8=20Mise=20=C3=A0=20jour=20CI/CD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.drone.yml b/.drone.yml index 9acf5ab..1fcc813 100644 --- a/.drone.yml +++ b/.drone.yml @@ -86,7 +86,7 @@ steps: trigger: branch: - - develop - - master + - develop + - master From f196868bd32c54ada084bf0bfb973af4d81132b1 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Thu, 5 Aug 2021 23:42:50 -0400 Subject: [PATCH 7/7] =?UTF-8?q?#8=20Mise=20=C3=A0=20jour=20CI/CD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.drone.yml b/.drone.yml index 1fcc813..35a4870 100644 --- a/.drone.yml +++ b/.drone.yml @@ -84,9 +84,9 @@ steps: branch: master events: push - trigger: - branch: - - develop - - master +trigger: + branch: + - develop + - master