From 76fb5a50b5258caa1bc2d5c83a06da3a9bfeb480 Mon Sep 17 00:00:00 2001 From: Michael Schulte <65006436+mschulte-tsi@users.noreply.github.com> Date: Thu, 8 Jul 2021 16:01:26 +0200 Subject: [PATCH] feat/Add cors (#23) * added vault * Update ci-main.yml * Update ci-main.yml * fix vault name * Add Upload Script * Update ci-main.yml * Update ci-main.yml * Update ci-main.yml * Update ci-main.yml * Downgraded cloud version * fix db driver * added info state * Update Sign-And-Upload Script * Delete ci-sonar.yml * added vault properties * added vault properties * added cors * fix test * checkstyle Co-authored-by: Felix Dittrich Co-authored-by: Felix Dittrich <31076102+f11h@users.noreply.github.com> --- .github/workflows/ci-main.yml | 17 +++++++- .github/workflows/ci-sonar.yml | 39 ------------------- pom.xml | 15 ++++++- scripts/Readme.md | 28 +++++++++++++ scripts/sign-and-upload.bat | 26 +++++++++++++ .../dgc/businessrule/config/CorsConfig.java | 24 ++++++++++++ .../config/DgcConfigProperties.java | 2 + .../config/WebSecurityConfig.java | 15 +++++++ src/main/resources/application-cloud.yml | 31 ++++++++++++--- src/main/resources/application.yml | 22 ++++++++++- src/main/resources/bootstrap-cloud.yaml | 30 ++++++++++++++ src/main/resources/bootstrap.yaml | 5 +++ src/test/resources/application.yml | 1 + 13 files changed, 206 insertions(+), 49 deletions(-) delete mode 100644 .github/workflows/ci-sonar.yml create mode 100644 scripts/Readme.md create mode 100644 scripts/sign-and-upload.bat create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/config/CorsConfig.java create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/config/WebSecurityConfig.java create mode 100644 src/main/resources/bootstrap-cloud.yaml create mode 100644 src/main/resources/bootstrap.yaml diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index ba2bbde..d2c7fa5 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -1,5 +1,6 @@ name: ci-main on: + workflow_dispatch: push: branches: - main @@ -48,9 +49,23 @@ jobs: --password-stdin docker build . \ --file ./Dockerfile \ - --tag "${APP_PACKAGES_URL}:${APP_VERSION}" + --tag "${APP_PACKAGES_URL}:${APP_VERSION}" \ + --tag "${TRUSTED_URL}/${TRUSTED_REPOSITORY}/cwa-dcc-rules:${APP_VERSION}" docker push "${APP_PACKAGES_URL}:${APP_VERSION}" env: APP_PACKAGES_URL: docker.pkg.github.com/${{ github.repository }}/dgca-businessrule-service APP_PACKAGES_USERNAME: ${{ github.actor }} APP_PACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + TRUSTED_URL: ${{ secrets.TRUSTED_URL }} + TRUSTED_REPOSITORY: ${{ secrets.TRUSTED_REPOSITORY }} + - name: docker push trusted + run: | + echo ${TRUSTED_TOKEN} | docker login ${TRUSTED_URL} -u ${TRUSTED_USER} --password-stdin + docker push ${TRUSTED_URL}/${TRUSTED_REPOSITORY}/cwa-dcc-rules:${APP_VERSION} + env: + TRUSTED_KEY: ${{ secrets.TRUSTED_KEY }} + TRUSTED_URL: ${{ secrets.TRUSTED_URL }} + TRUSTED_SERVER_URL: ${{ secrets.TRUSTED_SERVER_URL }} + TRUSTED_REPOSITORY: ${{ secrets.TRUSTED_REPOSITORY }} + TRUSTED_USER: ${{ secrets.TRUSTED_USER }} + TRUSTED_TOKEN: ${{ secrets.TRUSTED_TOKEN }} diff --git a/.github/workflows/ci-sonar.yml b/.github/workflows/ci-sonar.yml deleted file mode 100644 index f278a1e..0000000 --- a/.github/workflows/ci-sonar.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: ci-sonar -on: - push: - branches: - - main - pull_request: - types: - - opened - - synchronize - - reopened -jobs: - sonar: - runs-on: ubuntu-20.04 - steps: - - uses: actions/setup-java@v2 - with: - java-version: 11 - distribution: adopt - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: actions/cache@v2 - with: - path: | - ~/.m2/repository - key: ${{ runner.os }}-${{ hashFiles('**/pom.xml') }} - - name: mvn - run: |- - mvn verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \ - --batch-mode \ - --file ./pom.xml \ - --settings ./settings.xml \ - --define app.packages.username="${APP_PACKAGES_USERNAME}" \ - --define app.packages.password="${APP_PACKAGES_PASSWORD}" - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - APP_PACKAGES_USERNAME: ${{ github.actor }} - APP_PACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index a6009f9..b67a248 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ 6.1.1 2.4.4 - 2020.0.2 + 2020.0.1 5.3.5 5.4.6 1.18.20 @@ -107,6 +107,7 @@ pom import + org.projectlombok lombok @@ -158,6 +159,14 @@ org.springframework.boot spring-boot-starter-actuator + + org.springframework.cloud + spring-cloud-starter-vault-config + + + org.springframework.cloud + spring-cloud-starter-bootstrap + org.springframework.boot spring-boot-test @@ -265,6 +274,10 @@ nimbus-jose-jwt 9.9.2 + + org.springframework.boot + spring-boot-starter-security + diff --git a/scripts/Readme.md b/scripts/Readme.md new file mode 100644 index 0000000..68a6222 --- /dev/null +++ b/scripts/Readme.md @@ -0,0 +1,28 @@ +# DCC Rules Upload Script + +This Batch script allows to upload multiple DCC-Validation Rules with one CMD command. + +## Preparation + +Install DGC-CLI on your computer. Follow all the steps described in Readme file. +https://github.com/eu-digital-green-certificates/dgc-cli + +Copy your DCC-Validation Rules in a directory next to the Batch-File. +The Rules can be placed within a directory structure. +A rule file MUST have the filename ```rule.json```. All other files will be ignored. + +Copy you Upload- and MTLS-Certificate into the directory. + +Open the Batch-File with a Text-Editor of your choice and set the following Values + +| Variable | Value | +| --- | --- | +| DGCG_ENDPOINT | URL of rules upload endpoint (should end with /rules) | +| SIGNING_KEY | Path to PrivateKeyFile of your Upload Certificate | +| SIGNING_CERT | Path to PEM-File of your Upload Certificate | +| TLS_KEY | Path to PrivateKeyFile of your TLS Certificate | +| TLS_CERT | Path to PEM-File of your TLS Certificate | + +## Upload Rules + +Just execute the Batch Script and all Rules will be uploaded. \ No newline at end of file diff --git a/scripts/sign-and-upload.bat b/scripts/sign-and-upload.bat new file mode 100644 index 0000000..654277d --- /dev/null +++ b/scripts/sign-and-upload.bat @@ -0,0 +1,26 @@ +@echo off +REM Change this values according to your needs +SET DGCG_ENDPOINT="https://example.org/rules" +SET SIGNING_KEY="upload_key.pem" +SET SIGNING_CERT="upload.pem" +SET TLS_KEY="auth_key.pem" +SET TLS_CERT="auth.pem" + + +REM DO NOT CHANGE ANYTHING BELOW THIS! + +echo Search rule files and sign with Upload Certificate and Upload to DGCG + +for /f "usebackq delims=|" %%f in (`dir /s/b rule.json`) do (call :upload %%f) + +echo deleting temporary file +del -f tmp.cms + +goto :eof + +:upload +echo Processing JSON file %1 +call dgc signing sign-string -c %SIGNING_CERT% -k %SIGNING_KEY% -i "%1" -o tmp.cms +call curl --no-progress-bar --request POST "%DGCG_ENDPOINT%" --header "Content-Type: application/cms-text" --header "Accept: application/json" --data-binary @tmp.cms --cert %TLS_CERT% --key %TLS_KEY% +echo. +echo. diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/CorsConfig.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/CorsConfig.java new file mode 100644 index 0000000..4cc9aaa --- /dev/null +++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/CorsConfig.java @@ -0,0 +1,24 @@ +package eu.europa.ec.dgc.businessrule.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebSecurity +public class CorsConfig implements WebMvcConfigurer { + + @Bean + CorsConfigurationSource corsConfigurationSource(DgcConfigProperties dgcConfigProperties) { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues(); + corsConfiguration.addAllowedOrigin(dgcConfigProperties.getCorsUrl()); + source.registerCorsConfiguration("/**",corsConfiguration); + return source; + } + +} \ No newline at end of file diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java index 962da8a..9f79d28 100644 --- a/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java +++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java @@ -35,6 +35,8 @@ public class DgcConfigProperties { private final GatewayDownload countryListDownload = new GatewayDownload(); + private String corsUrl; + @Getter @Setter public static class GatewayDownload { diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/WebSecurityConfig.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/WebSecurityConfig.java new file mode 100644 index 0000000..c2a471b --- /dev/null +++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/WebSecurityConfig.java @@ -0,0 +1,15 @@ +package eu.europa.ec.dgc.businessrule.config; + +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors(); + } + +} \ No newline at end of file diff --git a/src/main/resources/application-cloud.yml b/src/main/resources/application-cloud.yml index 4659664..35186fc 100644 --- a/src/main/resources/application-cloud.yml +++ b/src/main/resources/application-cloud.yml @@ -1,11 +1,30 @@ spring: - h2: - console: - enabled: false datasource: driver-class-name: org.postgresql.Driver - url: jdbc:postgresql://localhost:5432/postgres - username: postgres - password: postgres + url: jdbc:postgresql://${POSTGRESQL_SERVICE_HOST}:${POSTGRESQL_SERVICE_PORT}/${POSTGRESQL_DATABASE} + username: ${POSTGRESQL_USER} + password: ${POSTGRESQL_PASSWORD} jpa: database-platform: org.hibernate.dialect.PostgreSQLDialect +springdoc: + api-docs: + enabled: false +dgc: + corsUrl: ${DGC_CORS_ENABLED_URL} + gateway: + connector: + enabled: true + endpoint: ${DGC_GATEWAY_CONNECTOR_ENDPOINT} + proxy: + enabled: false + tls-trust-store: + password: ${DGC_GATEWAY_CONNECTOR_TLSTRUSTSTORE_PASSWORD} + path: ${DGC_GATEWAY_CONNECTOR_TLSTRUSTSTORE_PATH} + tls-key-store: + alias: ${DGC_GATEWAY_CONNECTOR_TLSKEYSTORE_ALIAS} + password: ${DGC_GATEWAY_CONNECTOR_TLSKEYSTORE_PASSWORD} + path: ${DGC_GATEWAY_CONNECTOR_TLSKEYSTORE_PATH} + trust-anchor: + alias: ${DGC_GATEWAY_CONNECTOR_TRUSTANCHOR_ALIAS} + password: ${DGC_GATEWAY_CONNECTOR_TRUSTANCHOR_PASSWORD} + path: ${DGC_GATEWAY_CONNECTOR_TRUSTANCHOR_PATH} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a9e0409..74bd26f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -25,17 +25,34 @@ spring: pool: size: 5 management: + server: + ssl: + enabled: false + port: 8081 endpoint: info: enabled: true health: enabled: true + metrics: + enabled: true + prometheus: + enabled: true endpoints: enabled-by-default: false web: - base-path: /management exposure: - include: info,health + include: info,health,metrics,prometheus + jmx: + exposure: + include: info,health,metrics,prometheus + health: + probes: + enabled: true + metrics: + export: + prometheus: + enabled: true info: name: ${spring.application.name} profiles: ${spring.profiles.active} @@ -46,6 +63,7 @@ springdoc: swagger-ui: path: /swagger dgc: + corsUrl: https://dgc-gateway.example.com businessRulesDownload: timeInterval: 1800000 lockLimit: 3600000 diff --git a/src/main/resources/bootstrap-cloud.yaml b/src/main/resources/bootstrap-cloud.yaml new file mode 100644 index 0000000..83c0b08 --- /dev/null +++ b/src/main/resources/bootstrap-cloud.yaml @@ -0,0 +1,30 @@ +--- +spring: + application: + name: cwa-dcc-rules + cloud: + vault: + ssl: + trust-store: file:${SSL_VAULT_TRUSTSTORE_PATH} + trust-store-password: ${SSL_VAULT_TRUSTSTORE_PASSWORD} + enabled: true + generic: + enabled: false + kv: + enabled: true + backend: ${VAULT_BACKEND} + profile-separator: '/' + application-name: 'cwa-dcc-rules' + default-context: '' + profiles: cloud + fail-fast: true + authentication: KUBERNETES + kubernetes: + role: ${VAULT_ROLE} + kubernetes-path: kubernetes + service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token + uri: ${VAULT_URI} + connection-timeout: 5000 + read-timeout: 15000 + config: + order: -10 diff --git a/src/main/resources/bootstrap.yaml b/src/main/resources/bootstrap.yaml new file mode 100644 index 0000000..4eed0ce --- /dev/null +++ b/src/main/resources/bootstrap.yaml @@ -0,0 +1,5 @@ +--- +spring: + cloud: + vault: + enabled: false diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 338cdf0..bbbd95f 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -11,6 +11,7 @@ spring: main: allow-bean-definition-overriding: true dgc: + corsUrl: "localhost" businessRulesDownload: timeInterval: 1800000 lockLimit: 3600000