Skip to content
This repository has been archived by the owner on May 16, 2023. It is now read-only.

Feat: Migrating DCC relevant stuff to DGC-Lib #221

Merged
merged 15 commits into from
Jan 27, 2022
Merged
16 changes: 8 additions & 8 deletions .github/workflows/ci-dockerfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ name: ci-dockerfile
on:
push:
branches:
- master
- master
paths:
- Dockerfile
pull_request:
types:
- Dockerfile
pull_request:
types:
- opened
- synchronize
- reopened
paths:
paths:
- Dockerfile
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker pull hadolint/hadolint
- run: docker run --rm --interactive hadolint/hadolint < Dockerfile
- uses: actions/checkout@v2
- run: docker pull hadolint/hadolint
- run: docker run --rm --interactive hadolint/hadolint < Dockerfile
13 changes: 8 additions & 5 deletions .github/workflows/ci-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ jobs:
VERSION=${APP_TAG}-${APP_SHA};
echo "VERSION=${VERSION}" >> ${GITHUB_ENV};
- name: docker build
run: |
docker build \
--tag docker.pkg.github.com/${GITHUB_REPOSITORY}/cwa-quick-test-backend:latest \
--tag docker.pkg.github.com/${GITHUB_REPOSITORY}/cwa-quick-test-backend:${VERSION} \
--tag ${TRUSTED_URL}/${TRUSTED_REPOSITORY}/cwa-quick-test-backend:${VERSION} \
run: docker build
--tag docker.pkg.github.com/${GITHUB_REPOSITORY}/cwa-quick-test-backend:latest
--tag docker.pkg.github.com/${GITHUB_REPOSITORY}/cwa-quick-test-backend:${VERSION}
--tag ${TRUSTED_URL}/${TRUSTED_REPOSITORY}/cwa-quick-test-backend:${VERSION}
--build-arg MAVEN_PASSWORD=${APP_PACKAGES_PASSWORD}
--build-arg MAVEN_USERNAME=${APP_PACKAGES_USERNAME}
.
env:
TRUSTED_URL: ${{ secrets.TRUSTED_URL }}
TRUSTED_REPOSITORY: ${{ secrets.TRUSTED_REPOSITORY }}
APP_PACKAGES_USERNAME: ${{ github.actor }}
APP_PACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
- name: docker push github
run: |
echo ${GITHUB_TOKEN} | docker login docker.pkg.github.com -u ${GITHUB_REPOSITORY_OWNER} --password-stdin
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/ci-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: docker build
run: docker build .
run: docker build
--build-arg MAVEN_PASSWORD=${APP_PACKAGES_PASSWORD}
--build-arg MAVEN_USERNAME=${APP_PACKAGES_USERNAME}
.
env:
APP_PACKAGES_USERNAME: ${{ github.actor }}
APP_PACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
10 changes: 9 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
FROM maven:3-openjdk-11 as build

ARG MAVEN_PASSWORD
ARG MAVEN_USERNAME

WORKDIR /

COPY . .
RUN mvn clean install

RUN mvn clean install \
--settings ./settings.xml \
--define app.packages.username=${MAVEN_USERNAME} \
--define app.packages.password=${MAVEN_PASSWORD}

FROM gcr.io/distroless/java-debian10:11 as run

Expand Down
30 changes: 21 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.8</version>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>app.coronawarn</groupId>
Expand All @@ -16,21 +16,29 @@
<organization>
<name>T-Systems International GmbH</name>
</organization>

<repositories>
<repository>
<id>dgc-github</id>
<url>https://maven.pkg.github.com/eu-digital-green-certificates/*</url>
</repository>
</repositories>

<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.5</spring-cloud.version>
<spring-cloud.version>2021.0.0</spring-cloud.version>
<keycloak.version>14.0.0</keycloak.version>
<springdoc.version>1.5.9</springdoc.version>
<liquibase.version>4.4.1</liquibase.version>
<liquibase.version>4.6.2</liquibase.version>
<pdfbox.version>2.0.24</pdfbox.version>
<google-zxing.version>3.4.1</google-zxing.version>
<opencsv.version>5.5</opencsv.version>
<springTestAddons.version>2.5.6</springTestAddons.version>
<shedlock.version>4.25.0</shedlock.version>
<opencsv.version>5.5.2</opencsv.version>
<springTestAddons.version>3.1.13-jdk11</springTestAddons.version>
<shedlock.version>4.30.0</shedlock.version>
<!-- plugins -->
<plugin.checkstyle.version>3.1.2</plugin.checkstyle.version>
<license.projectName>Corona-Warn-App / cwa-quick-test-backend</license.projectName>
<license.inceptionYear>2022</license.inceptionYear>
<license.inceptionYear>2021</license.inceptionYear>
<license.licenseName>apache_v2</license.licenseName>
<log4j2.version>2.17.1</log4j2.version>
</properties>
Expand Down Expand Up @@ -188,14 +196,18 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
<scope>test</scope>
</dependency>
<!-- dgc -->
<dependency>
<groupId>com.upokecenter</groupId>
<artifactId>cbor</artifactId>
<version>4.4.4</version>
<version>4.5.1</version>
</dependency>
<dependency>
<groupId>eu.europa.ec.dgc</groupId>
<artifactId>dgc-lib</artifactId>
<version>1.1.9</version>
</dependency>

<!-- DB drivers -->
Expand Down
12 changes: 12 additions & 0 deletions settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<interactiveMode>false</interactiveMode>
<servers>
<server>
<id>dgc-github</id>
<username>${app.packages.username}</username>
<password>${app.packages.password}</password>
</server>
</servers>
</settings>
44 changes: 0 additions & 44 deletions src/main/java/app/coronawarn/quicktest/config/DccBeanConfig.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package eu.europa.ec.dgc;
package app.coronawarn.quicktest.dgc;

import com.fasterxml.jackson.databind.JsonNode;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package eu.europa.ec.dgc;
package app.coronawarn.quicktest.dgc;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.upokecenter.cbor.CBORObject;
import com.upokecenter.cbor.CBORType;
import eu.europa.ec.dgc.generation.Base45Encoder;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.zip.InflaterInputStream;
import org.springframework.stereotype.Service;

/**
* Small utility to decode date from dcc.
* It does not verify the CBOR signature and has only some structure checks.
* It is opposite to {@link DgcGenerator}
* It is opposite to {@link eu.europa.ec.dgc.generation.DgcGenerator}
*/
@Service
public class DccDecoder {

/**
* decode dcc.
*
Expand Down Expand Up @@ -97,7 +101,7 @@ private CBORObject checkElemType(CBORObject certData, int key, CBORType valueTyp
} else {
if (cborValue.getType() != valueType) {
throw new IllegalArgumentException("wrong type of: " + objectName + " is: "
+ cborValue.getType() + " expected: " + valueType);
+ cborValue.getType() + " expected: " + valueType);
}
}
return cborValue;
Expand All @@ -106,9 +110,9 @@ private CBORObject checkElemType(CBORObject certData, int key, CBORType valueTyp
private CBORObject decodeTestCbor(byte[] unzippedCose) {
CBORObject cborObject = CBORObject.DecodeFromBytes(unzippedCose);
if (cborObject.getType() != CBORType.Array
|| cborObject.size() < 4
|| !cborObject.isTagged()
|| 18 != cborObject.getMostInnerTag().ToInt32Checked()) {
|| cborObject.size() < 4
|| !cborObject.isTagged()
|| 18 != cborObject.getMostInnerTag().ToInt32Checked()) {
throw new IllegalArgumentException("unexpected cose structure");
}
if (cborObject.get(2).getType() != CBORType.ByteString) {
Expand Down
41 changes: 22 additions & 19 deletions src/main/java/app/coronawarn/quicktest/service/DccService.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
import app.coronawarn.quicktest.utils.DccPdfGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.europa.ec.dgc.DccTestBuilder;
import eu.europa.ec.dgc.DgcCryptedPublisher;
import eu.europa.ec.dgc.DgcGenerator;
import eu.europa.ec.dgc.dto.DgcData;
import eu.europa.ec.dgc.dto.DgcInitData;
import eu.europa.ec.dgc.generation.DccTestBuilder;
import eu.europa.ec.dgc.generation.DgcCryptedPublisher;
import eu.europa.ec.dgc.generation.DgcGenerator;
import eu.europa.ec.dgc.generation.dto.DgcData;
import eu.europa.ec.dgc.generation.dto.DgcInitData;
import feign.FeignException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand All @@ -49,6 +49,7 @@
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Base64;
Expand Down Expand Up @@ -79,12 +80,13 @@ public class DccService {

// TODO to be scheduled look up for keys, then generate dcc and prepare for upload
// should open transaction pro quick test

/**
* collect public keys.
*/
@Scheduled(fixedDelayString = "${dcc.searchPublicKeysJob.fixedDelayString}")
@SchedulerLock(name = "QuickTestSearchPublicKeys", lockAtLeastFor = "PT0S",
lockAtMostFor = "${dcc.searchPublicKeysJob.lockLimit}")
lockAtMostFor = "${dcc.searchPublicKeysJob.lockLimit}")
public void collectPublicKeys() {
Map<String, QuickTest> quickTestMap = new HashMap<>();
MessageDigest digest = createSha256Digest();
Expand Down Expand Up @@ -120,7 +122,7 @@ public void collectPublicKeys() {
}
} else {
log.warn("got public key for " + dccPublicKey.getTestId()
+ " which in not in state pendingPublicKey");
+ " which in not in state pendingPublicKey");
}
}
} else {
Expand All @@ -130,13 +132,14 @@ public void collectPublicKeys() {

/**
* create sha256 digest.
*
* @return the digest.
*/
public MessageDigest createSha256Digest() {
try {
return MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("have no SHA-256 digest",e);
throw new IllegalArgumentException("have no SHA-256 digest", e);
}
}

Expand All @@ -145,7 +148,7 @@ public MessageDigest createSha256Digest() {
*/
@Scheduled(fixedDelayString = "${dcc.uploadDccJob.fixedDelayString}")
@SchedulerLock(name = "QuickTestUploadDcc", lockAtLeastFor = "PT0S",
lockAtMostFor = "${dcc.uploadDccJob.lockLimit}")
lockAtMostFor = "${dcc.uploadDccJob.lockLimit}")
public void uploadDccData() {
ObjectMapper objectMapper = new ObjectMapper();
MessageDigest digest = createSha256Digest();
Expand All @@ -157,31 +160,31 @@ public void uploadDccData() {
try {
DccUploadData dccUploadData = objectMapper.readValue(quickTest.getDccSignData(), DccUploadData.class);
String testIdHashHex = Hex.toHexString(digest.digest(
quickTest.getTestResultServerHash().getBytes(StandardCharsets.UTF_8)));
quickTest.getTestResultServerHash().getBytes(StandardCharsets.UTF_8)));
digest.reset();
DccUploadResult dccUploadResult = dccServerClient.uploadDcc(testIdHashHex, dccUploadData);
byte[] coseSigned = dgcGenerator.dgcSetCosePartial(
Base64.getDecoder().decode(quickTest.getDccUnsigned()),
Base64.getDecoder().decode(dccUploadResult.getPartialDcc()));
Base64.getDecoder().decode(quickTest.getDccUnsigned()),
Base64.getDecoder().decode(dccUploadResult.getPartialDcc()));
Optional<QuickTestArchive> quickTestArchive =
quickTestArchiveRepository.findByHashedGuid(quickTest.getHashedGuid());
quickTestArchiveRepository.findByHashedGuid(quickTest.getHashedGuid());
if (quickTestArchive.isPresent()) {
String dcc = dgcGenerator.coseToQrCode(coseSigned);
quickTestArchive.get().setDcc(dcc);
try {
ByteArrayOutputStream pdf =
dccPdfGenerator.appendCertificatePage(quickTestArchive.get().getPdf(), quickTest, dcc);
dccPdfGenerator.appendCertificatePage(quickTestArchive.get().getPdf(), quickTest, dcc);
quickTestArchive.get().setPdf(pdf.toByteArray());
} catch (IOException exception) {
log.warn("Appending Certificate to PDF failed for quicktest hashedGuid=[{}]",
quickTest.getHashedGuid());
quickTest.getHashedGuid());
} catch (Exception exception) {
log.warn("General Exception while appending certificate to PDF for quicktest hashedGuid=[{}]",
quickTest.getHashedGuid());
quickTest.getHashedGuid());
}
quickTestArchiveRepository.saveAndFlush(quickTestArchive.get());
} else {
log.warn("can not find quick test archive {}",quickTest.getHashedGuid());
log.warn("can not find quick test archive {}", quickTest.getHashedGuid());
}
quickTestRepository.delete(quickTest);
} catch (FeignException e) {
Expand Down Expand Up @@ -220,7 +223,7 @@ private String dccJsonFromQuickTest(QuickTest quickTest, String dgci) {
DccTestBuilder dccTestBuilder = new DccTestBuilder();
dccTestBuilder.fn(quickTest.getLastName()).gn(quickTest.getFirstName());
dccTestBuilder.fnt(quickTest.getStandardisedFamilyName()).gnt(quickTest.getStandardisedGivenName());
dccTestBuilder.dob(quickTest.getBirthday());
dccTestBuilder.dob(LocalDate.parse(quickTest.getBirthday()));
boolean covidDetected;
switch (quickTest.getTestResult()) {
case 7:
Expand All @@ -236,7 +239,7 @@ private String dccJsonFromQuickTest(QuickTest quickTest, String dgci) {
dccTestBuilder.detected(covidDetected)
.testTypeRapid(true)
.dgci(dgci)
.countryOfTest(dccConfig.getCountry())
.country(dccConfig.getCountry())
.testingCentre(quickTest.getPocId())
.testIdentifier(quickTest.getTestBrandId())
.sampleCollection(quickTest.getUpdatedAt())
Expand Down
Loading