From ab4d8ba6685ce20b4b3368abb4e84c3a54f6c9b3 Mon Sep 17 00:00:00 2001 From: Lukas Lechner <lukas.lechner@sap.com> Date: Thu, 1 Apr 2021 16:37:06 +0200 Subject: [PATCH] Update CheckIn and CheckInEntity (EXPOSUREAPP-6065) (#2735) * Update from https://github.com/corona-warn-app/cwa-protocol-buffers/commit/8037bb0a273a815c083d4842b412ad141824ad91 * Update from https://github.com/corona-warn-app/cwa-protocol-buffers/commit/4e280653de2dd8a6d32a8ac43ed876879d5803b4 * Fix CheckInsTransformer.kt and TraceTimeIntervalWarningRepository.kt * Delete TraceLocationQRCodeVerifier.kt, Adapt VerifiedTraceLocation.kt * More adaptions * Fix check-in database test * Adapt TraceLocationEntity.kt and tests * Added calculation for tracelocationId to VerifiedTraceLocation Used id in checkin creation * Added initial tests for trace location id generation * Ktlint fixes * Merge branch 'release/2.0.x' into chore/DEV-update-checkin-entity Co-authored-by: corona-warn-app <cwa.technical-user@sap.com> Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Co-authored-by: Kolya Opahle <k.opahle@sap.com> --- .../1.json | 30 +- .../qrcode/VerifiedTraceLocationTest.kt | 293 ++++++++++-------- .../storage/CheckInDatabaseData.kt | 11 +- .../eventregistration/checkins/CheckIn.kt | 16 +- .../checkins/qrcode/VerifiedTraceLocation.kt | 14 + .../entity/TraceLocationCheckInEntity.kt | 11 +- .../storage/entity/TraceLocationEntity.kt | 1 - .../risk/CheckInWarningMatcher.kt | 3 +- .../confirm/ConfirmCheckInViewModel.kt | 5 +- .../checkins/CheckInRepositoryTest.kt | 26 +- .../CheckInTransmissionRiskLevelTest.kt | 6 +- .../checkins/CheckInsTransformerTest.kt | 16 +- .../checkins/split/CheckInSplitterTest.kt | 6 +- .../storage/retention/CheckInCleanerTest.kt | 8 +- .../checkins/checkout/CheckOutHandlerTest.kt | 6 +- .../checkout/auto/AutoCheckOutTest.kt | 6 +- .../risk/CheckInWarningMatcherTest.kt | 14 +- .../presencetracing/risk/FindMatchesTest.kt | 4 +- .../presencetracing/risk/OverlapTest.kt | 34 +- 19 files changed, 328 insertions(+), 182 deletions(-) diff --git a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json index 1ad43a6bf..9e78f2a34 100644 --- a/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json +++ b/Corona-Warn-App/schemas/de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase/1.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 1, - "identityHash": "3017a63593d3342376a56b56743815b7", + "identityHash": "1dc5f8a56361d50b8bb18050bce59d20", "entities": [ { "tableName": "checkin", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `guid` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL)", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `traceLocationIdBase64` TEXT NOT NULL, `traceLocationIdHashBase64` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `cryptographicSeedBase64` TEXT NOT NULL, `cnPublicKey` TEXT NOT NULL, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT NOT NULL, `completed` INTEGER NOT NULL, `createJournalEntry` INTEGER NOT NULL)", "fields": [ { "fieldPath": "id", @@ -15,8 +15,14 @@ "notNull": true }, { - "fieldPath": "guid", - "columnName": "guid", + "fieldPath": "traceLocationIdBase64", + "columnName": "traceLocationIdBase64", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "traceLocationIdHashBase64", + "columnName": "traceLocationIdHashBase64", "affinity": "TEXT", "notNull": true }, @@ -62,6 +68,18 @@ "affinity": "INTEGER", "notNull": false }, + { + "fieldPath": "cryptographicSeedBase64", + "columnName": "cryptographicSeedBase64", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cnPublicKey", + "columnName": "cnPublicKey", + "affinity": "TEXT", + "notNull": true + }, { "fieldPath": "checkInStart", "columnName": "checkInStart", @@ -174,7 +192,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3017a63593d3342376a56b56743815b7')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '1dc5f8a56361d50b8bb18050bce59d20')" ] } -} +} \ No newline at end of file diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt index 81af820c4..8bbe73ab7 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocationTest.kt @@ -1,184 +1,227 @@ package de.rki.coronawarnapp.eventregistration.checkins.qrcode -/*@RunWith(JUnit4::class) +import de.rki.coronawarnapp.environment.EnvironmentSetup +import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass +import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import okio.ByteString.Companion.decodeBase64 +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 +import testhelpers.BaseTestInstrumentation + +@RunWith(JUnit4::class) class VerifiedTraceLocationTest : BaseTestInstrumentation() { -@MockK lateinit var environmentSetup: EnvironmentSetup + @MockK lateinit var environmentSetup: EnvironmentSetup -@Before -fun setUp() { - MockKAnnotations.init(this) - every { environmentSetup.appConfigVerificationKey } returns PUB_KEY -} + @Before + fun setUp() { + MockKAnnotations.init(this) + every { environmentSetup.appConfigVerificationKey } returns PUB_KEY + } + + // TODO: Ugly but kinda works + @Test + fun verifyTraceLocationIdGenerationHash1() { + val base64Payload = "CAESLAgBEhFNeSBCaXJ0aGRheSBQYXJ0eRoLYXQgbXkgcGxhY2Uo04ekAT" + + "D3h6QBGmUIARJbMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc7DEst" + + "cUIRcyk35OYDJ95/hTg3UVhsaDXKT0zK7NhHPXoyzipEnOp3GyNXDVpaPi3" + + "cAfQmxeuFMZAIX2+6A5XhoEMTIzNCIECAEQAg==" + val base64LocationID = "jNcJTCajd9Sen6Tbexl2Yb7O3J7ps47b6k4+QMT4xS0=" -disabled because of incompatibilities due to latest tech spec changes... needs to be re-written anyway + val qrCodePayload = + TraceLocationOuterClass.QRCodePayload.parseFrom(base64Payload.decodeBase64()!!.toByteArray()) + val instance = VerifiedTraceLocation(qrCodePayload) + + instance.traceLocationID.sha256().base64() shouldBe base64LocationID + } + + @Test + fun verifyTraceLocationIdGenerationHash2() { + val base64Payload = "CAESIAgBEg1JY2VjcmVhbSBTaG9wGg1NYWluIFN0cmVldCAxGmUIARJ" + + "bMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc7DEstcUIRcyk35OYDJ95/hTg3UVhsaDXKT" + + "0zK7NhHPXoyzipEnOp3GyNXDVpaPi3cAfQmxeuFMZAIX2+6A5XhoEMTIzNCIGCAEQARgK" + val base64LocationID = "GMuCjqNmOdYyrFhyvFNTVEeLaZh+uShgUoY0LYJo4YQ=" + + val qrCodePayload = + TraceLocationOuterClass.QRCodePayload.parseFrom(base64Payload.decodeBase64()!!.toByteArray()) + val instance = VerifiedTraceLocation(qrCodePayload) + + instance.traceLocationID.sha256().base64() shouldBe base64LocationID + } + + /* disabled because of incompatibilities due to latest tech spec changes... needs to be re-written anyway @Test fun verifyEventSuccess() = runBlockingTest { -val instant = Instant.ofEpochMilli(2687960 * 1_000L) -shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe false - traceLocation.isAfterEndTime(instant) shouldBe false + val instant = Instant.ofEpochMilli(2687960 * 1_000L) + shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe false + traceLocation.isAfterEndTime(instant) shouldBe false + } } } -} @Test fun verifyParcelization() = runBlockingTest { -val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - -val expectedTraceLocation = TraceLocation( - guid = "3055331c-2306-43f3-9742-6d8fab54e848", - version = 1, - type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, - description = "My Birthday Party", - address = "at my place", - startDate = Instant.ofEpochSecond(2687955), - endDate = Instant.ofEpochSecond(2687991), - defaultCheckInLengthInMinutes = 0, - byteRepresentation = verifyResult.traceLocationBytes, - signature = verifyResult.signature.toByteArray().toByteString(), -) - -verifyResult.traceLocation shouldBe expectedTraceLocation - -val bundle = Bundle().apply { - putParcelable("test", verifyResult.traceLocation) -} + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) -val parcelRaw = Parcel.obtain().apply { - writeBundle(bundle) -}.marshall() + val expectedTraceLocation = TraceLocation( + guid = "3055331c-2306-43f3-9742-6d8fab54e848", + version = 1, + type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, + description = "My Birthday Party", + address = "at my place", + startDate = Instant.ofEpochSecond(2687955), + endDate = Instant.ofEpochSecond(2687991), + defaultCheckInLengthInMinutes = 0, + byteRepresentation = verifyResult.traceLocationBytes, + signature = verifyResult.signature.toByteArray().toByteString(), + ) -val restoredParcel = Parcel.obtain().apply { - unmarshall(parcelRaw, 0, parcelRaw.size) - setDataPosition(0) -} + verifyResult.traceLocation shouldBe expectedTraceLocation -val restoredData = restoredParcel.readBundle()!!.run { - classLoader = TraceLocation::class.java.classLoader - getParcelable<TraceLocation>("test") -} -restoredData shouldBe expectedTraceLocation + val bundle = Bundle().apply { + putParcelable("test", verifyResult.traceLocation) + } + + val parcelRaw = Parcel.obtain().apply { + writeBundle(bundle) + }.marshall() + + val restoredParcel = Parcel.obtain().apply { + unmarshall(parcelRaw, 0, parcelRaw.size) + setDataPosition(0) + } + + val restoredData = restoredParcel.readBundle()!!.run { + classLoader = TraceLocation::class.java.classLoader + getParcelable<TraceLocation>("test") + } + restoredData shouldBe expectedTraceLocation } @Test fun verifyEventStartTimeWaning() = runBlockingTest { -val instant = Instant.ofEpochMilli(2687940 * 1_000L) -shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe true - traceLocation.isAfterEndTime(instant) shouldBe false + val instant = Instant.ofEpochMilli(2687940 * 1_000L) + shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe true + traceLocation.isAfterEndTime(instant) shouldBe false + } } } -} @Test fun verifyEventEndTimeWarning() = runBlockingTest { -val instant = Instant.now() -shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - traceLocation.isBeforeStartTime(instant) shouldBe false - traceLocation.isAfterEndTime(instant) shouldBe true + val instant = Instant.now() + shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + traceLocation.isBeforeStartTime(instant) shouldBe false + traceLocation.isAfterEndTime(instant) shouldBe true + } } } -} @Test fun verifyEventWithInvalidKey() = runBlockingTest { -every { environmentSetup.appConfigVerificationKey } returns INVALID_PUB_KEY -shouldThrow<InvalidQRCodeSignatureException> { - traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) -} + every { environmentSetup.appConfigVerificationKey } returns INVALID_PUB_KEY + shouldThrow<InvalidQRCodeSignatureException> { + traceLocationQRCodeVerifier.verify(ENCODED_EVENT1.decodeBase32().toByteArray()) + } } @Test fun eventHasMalformedData() = runBlockingTest { -shouldThrow<InvalidQRCodeDataException> { - traceLocationQRCodeVerifier.verify( - INVALID_ENCODED_EVENT.decodeBase32().toByteArray() - ) -} + shouldThrow<InvalidQRCodeDataException> { + traceLocationQRCodeVerifier.verify( + INVALID_ENCODED_EVENT.decodeBase32().toByteArray() + ) + } } @Test fun decodingTest1() = runBlockingTest { -val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT1.decodeBase32().toByteArray() -) -val expectedSignature = - "MEQCIGVKfqPF2851IrEyDeVMazlRnIzLX16H6r1TB37PRzjbAiBGP13ADQcbQZsztKUCZMRcvnv5Mgdo0LY/v3qFMnrUkQ==" + val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT1.decodeBase32().toByteArray() + ) + val expectedSignature = + "MEQCIGVKfqPF2851IrEyDeVMazlRnIzLX16H6r1TB37PRzjbAiBGP13ADQcbQZsztKUCZMRcvnv5Mgdo0LY/v3qFMnrUkQ==" -val base32 = signedTraceLocation.toByteArray().toByteString().base32() + val base32 = signedTraceLocation.toByteArray().toByteString().base32() -shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) + shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "My Birthday Party" - signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature + verifyResult.apply { + traceLocation.description shouldBe "My Birthday Party" + signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature + } } } -} @Test fun decodingTest2() = runBlockingTest { -val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT2.decodeBase32().toByteArray() -) -val expectedSignature = - "MEQCIDWRTM4ujn1GFPuHlgpUnQIWwwzwI8abxSrF5Er2I5HaAiAbucxg+6d3nC/Iwzo7AXehJAS20TRX1S2rl0LO8kcYxA==" + val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT2.decodeBase32().toByteArray() + ) + val expectedSignature = + "MEQCIDWRTM4ujn1GFPuHlgpUnQIWwwzwI8abxSrF5Er2I5HaAiAbucxg+6d3nC/Iwzo7AXehJAS20TRX1S2rl0LO8kcYxA==" -val base32 = signedTraceLocation.toByteArray().toByteString().base32() + val base32 = signedTraceLocation.toByteArray().toByteString().base32() -shouldNotThrowAny { - val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) + shouldNotThrowAny { + val verifyResult = traceLocationQRCodeVerifier.verify(base32.decodeBase32().toByteArray()) - verifyResult.apply { - traceLocation.description shouldBe "Icecream Shop" - signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature + verifyResult.apply { + traceLocation.description shouldBe "Icecream Shop" + signedTraceLocation.signature.toByteArray().toByteString().base64() shouldBe expectedSignature + } } } -} @Test fun testVerifiedTraceLocationMapping() { -shouldNotThrowAny { - val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( - ENCODED_EVENT1.decodeBase32().toByteArray() - ) - - val traceLocation = TraceLocationOuterClass.TraceLocation.parseFrom( - ENCODED_EVENT1_LOCATION.decodeBase32().toByteArray() - ) - val verifiedTraceLocation = VerifiedTraceLocation( - protoSignedTraceLocation = signedTraceLocation, - protoTraceLocation = traceLocation - ).traceLocation - - verifiedTraceLocation shouldBe TraceLocation( - guid = "3055331c-2306-43f3-9742-6d8fab54e848", - version = 1, - type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, - description = "My Birthday Party", - address = "at my place", - startDate = Instant.ofEpochSecond(2687955), - endDate = Instant.ofEpochSecond(2687991), - defaultCheckInLengthInMinutes = 0, - byteRepresentation = signedTraceLocation.location.toByteArray().toByteString(), - signature = signedTraceLocation.signature.toByteArray().toByteString() - ) -} + shouldNotThrowAny { + val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom( + ENCODED_EVENT1.decodeBase32().toByteArray() + ) + + val traceLocation = TraceLocationOuterClass.TraceLocation.parseFrom( + ENCODED_EVENT1_LOCATION.decodeBase32().toByteArray() + ) + val verifiedTraceLocation = VerifiedTraceLocation( + protoSignedTraceLocation = signedTraceLocation, + protoTraceLocation = traceLocation + ).traceLocation + + verifiedTraceLocation shouldBe TraceLocation( + guid = "3055331c-2306-43f3-9742-6d8fab54e848", + version = 1, + type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER, + description = "My Birthday Party", + address = "at my place", + startDate = Instant.ofEpochSecond(2687955), + endDate = Instant.ofEpochSecond(2687991), + defaultCheckInLengthInMinutes = 0, + byteRepresentation = signedTraceLocation.location.toByteArray().toByteString(), + signature = signedTraceLocation.signature.toByteArray().toByteString() + ) + } } - +*/ companion object { @@ -223,5 +266,3 @@ shouldNotThrowAny { "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc7DEstcUIRcyk35OYDJ95/hTg3UVhsaDXKT0zK7NhHPXoyzipEnOp3GyNXDVpaPi3cAfQmxeuFMZAIX2+6A5Xg==" } } - - */ diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt index ee256cba8..500e91485 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt @@ -2,12 +2,14 @@ package de.rki.coronawarnapp.eventregistration.storage import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass +import okio.ByteString.Companion.encode import org.joda.time.Instant object CheckInDatabaseData { val testCheckIn = TraceLocationCheckInEntity( - guid = "testGuid1", + traceLocationIdBase64 = "traceLocationId1".encode().base64(), + traceLocationIdHashBase64 = "traceLocationIdHash1".encode().base64(), version = 1, type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER.number, description = "testDescription1", @@ -15,6 +17,8 @@ object CheckInDatabaseData { traceLocationStart = Instant.parse("2021-01-01T12:00:00.000Z"), traceLocationEnd = Instant.parse("2021-01-01T15:00:00.000Z"), defaultCheckInLengthInMinutes = 15, + cryptographicSeedBase64 = "cryptographicSeed".encode().base64(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"), checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"), completed = false, @@ -22,7 +26,8 @@ object CheckInDatabaseData { ) val testCheckInWithoutCheckOutTime = TraceLocationCheckInEntity( - guid = "testGuid2", + traceLocationIdBase64 = "traceLocationId1".encode().base64(), + traceLocationIdHashBase64 = "traceLocationIdHash1".encode().base64(), version = 1, type = TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER.number, description = "testDescription2", @@ -30,6 +35,8 @@ object CheckInDatabaseData { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeedBase64 = "cryptographicSeed".encode().base64(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"), checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"), completed = false, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt index 431ec9f8b..eae4e6abe 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt @@ -1,14 +1,15 @@ package de.rki.coronawarnapp.eventregistration.checkins -import com.google.protobuf.ByteString.copyFromUtf8 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity -import de.rki.coronawarnapp.util.HashExtensions.toSHA256 +import okio.ByteString +import okio.ByteString.Companion.encode import org.joda.time.Instant @Suppress("LongParameterList") data class CheckIn( val id: Long = 0L, - val guid: String, + val traceLocationId: ByteString = "TODO: calculate".encode(), + val traceLocationIdHash: ByteString = "TODO: calculate".encode(), val version: Int, val type: Int, val description: String, @@ -16,17 +17,20 @@ data class CheckIn( val traceLocationStart: Instant?, val traceLocationEnd: Instant?, val defaultCheckInLengthInMinutes: Int?, + val cryptographicSeed: ByteString, + val cnPublicKey: String, val checkInStart: Instant, val checkInEnd: Instant, val completed: Boolean, val createJournalEntry: Boolean ) { - val locationGuidHash: com.google.protobuf.ByteString by lazy { copyFromUtf8(guid.toSHA256()) } + // val locationGuidHash: com.google.protobuf.ByteString by lazy { copyFromUtf8(guid.toSHA256()) } } fun CheckIn.toEntity() = TraceLocationCheckInEntity( id = id, - guid = guid, + traceLocationIdBase64 = traceLocationId.base64(), + traceLocationIdHashBase64 = traceLocationIdHash.base64(), version = version, type = type, description = description, @@ -34,6 +38,8 @@ fun CheckIn.toEntity() = TraceLocationCheckInEntity( traceLocationStart = traceLocationStart, traceLocationEnd = traceLocationEnd, defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes, + cryptographicSeedBase64 = cryptographicSeed.base64(), + cnPublicKey = cnPublicKey, checkInStart = checkInStart, checkInEnd = checkInEnd, completed = completed, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt index 40d43c745..6eb4f3645 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/VerifiedTraceLocation.kt @@ -7,6 +7,9 @@ import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parceler import kotlinx.parcelize.Parcelize import kotlinx.parcelize.TypeParceler +import okio.Buffer +import okio.ByteString +import okio.ByteString.Companion.encode import okio.ByteString.Companion.toByteString import org.joda.time.Instant import java.util.concurrent.TimeUnit @@ -37,6 +40,17 @@ data class VerifiedTraceLocation( ) } + @IgnoredOnParcel private val traceLocationHeader: ByteString by lazy { + "CWA-GUID".encode(Charsets.UTF_8) + } + + @IgnoredOnParcel val traceLocationID: ByteString by lazy { + Buffer() + .write(traceLocationHeader) + .write(protoQrCodePayload.toByteArray()) + .readByteString() + } + /** * Converts time in seconds into [Instant] */ diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt index 8417c4df1..2df991c63 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt @@ -4,12 +4,14 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import de.rki.coronawarnapp.eventregistration.checkins.CheckIn +import okio.ByteString.Companion.decodeBase64 import org.joda.time.Instant @Entity(tableName = "checkin") data class TraceLocationCheckInEntity( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0L, - @ColumnInfo(name = "guid") val guid: String, + @ColumnInfo(name = "traceLocationIdBase64") val traceLocationIdBase64: String, + @ColumnInfo(name = "traceLocationIdHashBase64") val traceLocationIdHashBase64: String, @ColumnInfo(name = "version") val version: Int, @ColumnInfo(name = "type") val type: Int, @ColumnInfo(name = "description") val description: String, @@ -17,6 +19,8 @@ data class TraceLocationCheckInEntity( @ColumnInfo(name = "traceLocationStart") val traceLocationStart: Instant?, @ColumnInfo(name = "traceLocationEnd") val traceLocationEnd: Instant?, @ColumnInfo(name = "defaultCheckInLengthInMinutes") val defaultCheckInLengthInMinutes: Int?, + @ColumnInfo(name = "cryptographicSeedBase64") val cryptographicSeedBase64: String, + @ColumnInfo(name = "cnPublicKey") val cnPublicKey: String, @ColumnInfo(name = "checkInStart") val checkInStart: Instant, @ColumnInfo(name = "checkInEnd") val checkInEnd: Instant, @ColumnInfo(name = "completed") val completed: Boolean, @@ -25,7 +29,8 @@ data class TraceLocationCheckInEntity( fun TraceLocationCheckInEntity.toCheckIn() = CheckIn( id = id, - guid = guid, + traceLocationId = traceLocationIdBase64.decodeBase64()!!, + traceLocationIdHash = traceLocationIdHashBase64.decodeBase64()!!, version = version, type = type, description = description, @@ -33,6 +38,8 @@ fun TraceLocationCheckInEntity.toCheckIn() = CheckIn( traceLocationStart = traceLocationStart, traceLocationEnd = traceLocationEnd, defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes, + cryptographicSeed = cryptographicSeedBase64.decodeBase64()!!, + cnPublicKey = cnPublicKey, checkInStart = checkInStart, checkInEnd = checkInEnd, completed = completed, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationEntity.kt index d441d385c..abfdc5698 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationEntity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationEntity.kt @@ -9,7 +9,6 @@ import org.joda.time.Instant @Entity(tableName = "traceLocations") data class TraceLocationEntity( - @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0L, @ColumnInfo(name = "version") val version: Int, @ColumnInfo(name = "type") val type: TraceLocationOuterClass.TraceLocationType, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt index fed793d67..66f82291f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcher.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.withContext +import okio.ByteString.Companion.toByteString import org.joda.time.Instant import timber.log.Timber import java.lang.reflect.Modifier.PRIVATE @@ -134,7 +135,7 @@ internal fun CheckIn.calculateOverlap( traceWarningPackageId: String ): CheckInWarningOverlap? { - if (warning.locationIdHash != locationGuidHash) return null + if (warning.locationIdHash.toByteArray().toByteString() != traceLocationIdHash) return null val warningStartMillis = warning.startIntervalNumber.tenMinIntervalToMillis() val warningEndMillis = (warning.startIntervalNumber + warning.period).tenMinIntervalToMillis() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt index 3451c004c..bd50ffcbe 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/confirm/ConfirmCheckInViewModel.kt @@ -89,7 +89,8 @@ class ConfirmCheckInViewModel @AssistedInject constructor( completed: Boolean = false, createJournalEntry: Boolean = true ): CheckIn = CheckIn( - guid = "", // traceLocation.id, + traceLocationId = verifiedTraceLocation.traceLocationID, + traceLocationIdHash = verifiedTraceLocation.traceLocationID.sha256(), version = traceLocation.version, type = traceLocation.type.number, description = traceLocation.description, @@ -97,6 +98,8 @@ class ConfirmCheckInViewModel @AssistedInject constructor( traceLocationStart = traceLocation.startDate, traceLocationEnd = traceLocation.endDate, defaultCheckInLengthInMinutes = traceLocation.defaultCheckInLengthInMinutes, + cryptographicSeed = traceLocation.cryptographicSeed, + cnPublicKey = traceLocation.cnPublicKey, checkInStart = checkInStart, checkInEnd = checkInEnd, completed = completed, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt index 46fe74481..e869c2869 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runBlockingTest +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -46,7 +47,8 @@ class CheckInRepositoryTest : BaseTest() { shouldThrow<IllegalArgumentException> { val checkIn = CheckIn( id = 1L, - guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf", + traceLocationId = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), + traceLocationIdHash = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), version = 1, type = 2, description = "brothers birthday", @@ -54,6 +56,8 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = Instant.EPOCH, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH, completed = false, @@ -72,7 +76,8 @@ class CheckInRepositoryTest : BaseTest() { createInstance(scope = this).addCheckIn( CheckIn( id = 0L, - guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf", + traceLocationId = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), + traceLocationIdHash = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), version = 1, type = 2, description = "brothers birthday", @@ -80,6 +85,8 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = time, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = time, checkInEnd = end, completed = false, @@ -90,7 +97,8 @@ class CheckInRepositoryTest : BaseTest() { checkInDao.insert( TraceLocationCheckInEntity( id = 0L, - guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf", + traceLocationIdBase64 = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode().base64(), + traceLocationIdHashBase64 = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode().base64(), version = 1, type = 2, description = "brothers birthday", @@ -98,6 +106,8 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = time, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeedBase64 = "cryptographicSeed".encode().base64(), + cnPublicKey = "cnPublicKey", checkInStart = time, checkInEnd = end, completed = false, @@ -132,7 +142,8 @@ class CheckInRepositoryTest : BaseTest() { allEntriesFlow.value = listOf( TraceLocationCheckInEntity( id = 1L, - guid = "6e5530ce-1afc-4695-a4fc-572e6443eacd", + traceLocationIdBase64 = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode().base64(), + traceLocationIdHashBase64 = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode().base64(), version = 1, type = 2, description = "sisters birthday", @@ -140,6 +151,8 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = start, traceLocationEnd = end, defaultCheckInLengthInMinutes = null, + cryptographicSeedBase64 = "cryptographicSeed".encode().base64(), + cnPublicKey = "cnPublicKey", checkInStart = start, checkInEnd = end, completed = false, @@ -150,7 +163,8 @@ class CheckInRepositoryTest : BaseTest() { createInstance(scope = this).allCheckIns.first() shouldBe listOf( CheckIn( id = 1L, - guid = "6e5530ce-1afc-4695-a4fc-572e6443eacd", + traceLocationId = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), + traceLocationIdHash = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), version = 1, type = 2, description = "sisters birthday", @@ -158,6 +172,8 @@ class CheckInRepositoryTest : BaseTest() { traceLocationStart = start, traceLocationEnd = end, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = start, checkInEnd = end, completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt index 00a7739a2..bafd28dd1 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInTransmissionRiskLevelTest.kt @@ -2,6 +2,7 @@ package de.rki.coronawarnapp.eventregistration.checkins import de.rki.coronawarnapp.submission.task.TransmissionRiskVector import io.kotest.matchers.shouldBe +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.Test import testhelpers.BaseTest @@ -10,7 +11,8 @@ class CheckInTransmissionRiskLevelTest : BaseTest() { private val checkIn = CheckIn( id = 1L, - guid = "trace_location_1", + traceLocationId = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), + traceLocationIdHash = "41da2115-eba2-49bd-bf17-adb3d635ddaf".encode(), version = 1, type = 2, description = "restaurant_1", @@ -18,6 +20,8 @@ class CheckInTransmissionRiskLevelTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-03-04T10:20:00Z"), checkInEnd = Instant.parse("2021-03-04T10:30:00Z"), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt index f242f86a7..14d50535d 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInsTransformerTest.kt @@ -23,6 +23,7 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk import kotlinx.coroutines.test.runBlockingTest +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -40,7 +41,8 @@ class CheckInsTransformerTest : BaseTest() { // CheckIn can not be derived private val checkIn1 = CheckIn( id = 1L, - guid = "trace_location_1", + traceLocationId = "traceLocationId1".encode(), + traceLocationIdHash = "traceLocationIdHash1".encode(), version = 1, type = 1, description = "restaurant_1", @@ -48,6 +50,8 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-03-04T10:21:00Z"), checkInEnd = Instant.parse("2021-03-04T10:29:00Z"), completed = false, @@ -62,7 +66,8 @@ class CheckInsTransformerTest : BaseTest() { */ private val checkIn2 = CheckIn( id = 2L, - guid = "trace_location_2", + traceLocationId = "traceLocationId2".encode(), + traceLocationIdHash = "traceLocationIdHash2".encode(), version = 1, type = 2, description = "restaurant_2", @@ -70,6 +75,8 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-03-04T10:20:00Z"), checkInEnd = Instant.parse("2021-03-04T10:30:00Z"), completed = false, @@ -79,7 +86,8 @@ class CheckInsTransformerTest : BaseTest() { // CheckIn that can be derived and can be splitted private val checkIn3 = CheckIn( id = 3L, - guid = "trace_location_3", + traceLocationId = "traceLocationId3".encode(), + traceLocationIdHash = "traceLocationIdHash3".encode(), version = 1, type = 3, description = "restaurant_3", @@ -87,6 +95,8 @@ class CheckInsTransformerTest : BaseTest() { traceLocationStart = Instant.parse("2021-03-04T09:00:00Z"), traceLocationEnd = Instant.parse("2021-03-10T11:00:00Z"), defaultCheckInLengthInMinutes = 10, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse("2021-03-04T09:30:00Z"), checkInEnd = Instant.parse("2021-03-10T09:45:00Z"), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt index 0e3e7ebc0..dc037d1ca 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/split/CheckInSplitterTest.kt @@ -2,6 +2,7 @@ package de.rki.coronawarnapp.eventregistration.checkins.split import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import io.kotest.matchers.shouldBe +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.Test import testhelpers.BaseTest @@ -14,7 +15,8 @@ class CheckInSplitterTest : BaseTest() { private val defaultCheckIn = CheckIn( id = 1L, - guid = "eventOne", + traceLocationId = "traceLocationId1".encode(), + traceLocationIdHash = "traceLocationIdHash1".encode(), version = 1, type = 1, description = "Restaurant", @@ -22,6 +24,8 @@ class CheckInSplitterTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.now(), checkInEnd = Instant.now(), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt index 844daabd8..0dc18d477 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/storage/retention/CheckInCleanerTest.kt @@ -12,6 +12,7 @@ import io.mockk.impl.annotations.MockK import io.mockk.just import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runBlockingTest +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -69,7 +70,8 @@ internal class CheckInCleanerTest : BaseTest() { } private fun createCheckIn(checkOutDate: Instant) = CheckIn( - guid = "", + traceLocationId = "traceLocationId1".encode(), + traceLocationIdHash = "traceLocationIdHash1".encode(), version = 1, type = 1, description = "", @@ -77,7 +79,9 @@ internal class CheckInCleanerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = 30, - // checkInStart not relevant for this that's, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", + // checkInStart not relevant for this checkInStart = Instant.parse("1970-01-01T00:00:00.000Z"), checkInEnd = checkOutDate, completed = true, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt index 80d421ca9..e420e844c 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/CheckOutHandlerTest.kt @@ -10,6 +10,7 @@ import io.mockk.coEvery import io.mockk.every import io.mockk.impl.annotations.MockK import kotlinx.coroutines.test.runBlockingTest +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -23,7 +24,8 @@ class CheckOutHandlerTest : BaseTest() { private val testCheckIn = CheckIn( id = 42L, - guid = "eventOne", + traceLocationId = "traceLocationId1".encode(), + traceLocationIdHash = "traceLocationIdHash1".encode(), version = 1, type = 1, description = "Restaurant", @@ -31,6 +33,8 @@ class CheckOutHandlerTest : BaseTest() { traceLocationStart = null, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH.plus(100), completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt index 0dfb7658a..41c1f47c9 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/checkins/checkout/auto/AutoCheckOutTest.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runBlockingTest +import okio.ByteString.Companion.encode import org.joda.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -36,7 +37,8 @@ class AutoCheckOutTest : BaseTest() { private val baseCheckin = CheckIn( id = 0L, - guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf", + traceLocationId = "traceLocationId1".encode(), + traceLocationIdHash = "traceLocationIdHash1".encode(), version = 1, type = 2, description = "brothers birthday", @@ -44,6 +46,8 @@ class AutoCheckOutTest : BaseTest() { traceLocationStart = Instant.EPOCH, traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.EPOCH, checkInEnd = Instant.EPOCH, completed = false, diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt index 26643e4b4..1a3dcc048 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/CheckInWarningMatcherTest.kt @@ -41,13 +41,13 @@ class CheckInWarningMatcherTest : BaseTest() { fun `reports new matches`() { val checkIn1 = createCheckIn( id = 2L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:15+01:00", endDateStr = "2021-03-04T10:17+01:00" ) val checkIn2 = createCheckIn( id = 3L, - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startDateStr = "2021-03-04T09:15+01:00", endDateStr = "2021-03-04T10:12+01:00" ) @@ -90,13 +90,13 @@ class CheckInWarningMatcherTest : BaseTest() { fun `report empty list if no matches found`() { val checkIn1 = createCheckIn( id = 2L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:15+01:00", endDateStr = "2021-03-04T10:17+01:00" ) val checkIn2 = createCheckIn( id = 3L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:15+01:00", endDateStr = "2021-03-04T10:12+01:00" ) @@ -139,13 +139,13 @@ class CheckInWarningMatcherTest : BaseTest() { fun `report empty list if package is empty`() { val checkIn1 = createCheckIn( id = 2L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:15+01:00", endDateStr = "2021-03-04T10:17+01:00" ) val checkIn2 = createCheckIn( id = 3L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:15+01:00", endDateStr = "2021-03-04T10:12+01:00" ) @@ -212,7 +212,7 @@ class CheckInWarningMatcherTest : BaseTest() { val checkIns = (1L..100L).map { createCheckIn( id = it, - traceLocationGuid = it.toString(), + traceLocationId = it.toString(), startDateStr = "2021-03-04T09:50+01:00", endDateStr = "2021-03-04T10:05:15+01:00" ) diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt index 03c384f2e..cc9d5e580 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/FindMatchesTest.kt @@ -12,13 +12,13 @@ class FindMatchesTest { fun `findMatches works`() { val checkIn1 = createCheckIn( id = 2L, - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:15+01:00", endDateStr = "2021-03-04T10:17+01:00" ) val checkIn2 = createCheckIn( id = 3L, - traceLocationGuid = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", + traceLocationId = "69eb427e1a48133970486244487e31b3f1c5bde47415db9b52cc5a2ece1e0060", startDateStr = "2021-03-04T09:15+01:00", endDateStr = "2021-03-04T10:45+01:00" ) diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt index 59f57bfc7..fa1af775d 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/presencetracing/risk/OverlapTest.kt @@ -5,6 +5,7 @@ import de.rki.coronawarnapp.eventregistration.checkins.CheckIn import de.rki.coronawarnapp.server.protocols.internal.pt.TraceWarning import de.rki.coronawarnapp.util.HashExtensions.toSHA256 import io.kotest.matchers.shouldBe +import okio.ByteString.Companion.encode import org.joda.time.Duration import org.joda.time.Instant import org.junit.Test @@ -17,7 +18,7 @@ class OverlapTest : BaseTest() { @Test fun `returns null if guids do not match`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:30+01:00", endDateStr = "2021-03-04T09:45+01:00" ).calculateOverlap( @@ -34,7 +35,7 @@ class OverlapTest : BaseTest() { @Test fun `returns null if check-in precedes warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:30+01:00", endDateStr = "2021-03-04T09:45+01:00" ).calculateOverlap( @@ -51,7 +52,7 @@ class OverlapTest : BaseTest() { @Test fun `returns null if check-in is preceded by warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T11:15+01:00", endDateStr = "2021-03-04T11:20+01:00" ).calculateOverlap( @@ -68,7 +69,7 @@ class OverlapTest : BaseTest() { @Test fun `returns null if check-in meets warning at the start`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:30+01:00", endDateStr = "2021-03-04T10:00+01:00" ).calculateOverlap( @@ -85,7 +86,7 @@ class OverlapTest : BaseTest() { @Test fun `returns null if check-in meets warning at the end`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T11:00+01:00", endDateStr = "2021-03-04T11:10+01:00" ).calculateOverlap( @@ -102,7 +103,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in overlaps warning at the start`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:30+01:00", endDateStr = "2021-03-04T10:12+01:00" ).calculateOverlap( @@ -119,7 +120,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in overlaps warning at the end`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:45+01:00", endDateStr = "2021-03-04T11:12+01:00" ).calculateOverlap( @@ -136,7 +137,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in starts warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:00+01:00", endDateStr = "2021-03-04T10:13+01:00" ).calculateOverlap( @@ -153,7 +154,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in during warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:15+01:00", endDateStr = "2021-03-04T10:17+01:00" ).calculateOverlap( @@ -170,7 +171,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in finishes warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:30+01:00", endDateStr = "2021-03-04T11:00+01:00" ).calculateOverlap( @@ -187,7 +188,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap if check-in equals warning`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T10:00+01:00", endDateStr = "2021-03-04T11:00+01:00" ).calculateOverlap( @@ -204,7 +205,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap after rounding (up)`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:50+01:00", endDateStr = "2021-03-04T10:05:45+01:00" ).calculateOverlap( @@ -221,7 +222,7 @@ class OverlapTest : BaseTest() { @Test fun `returns overlap after rounding (down)`() { createCheckIn( - traceLocationGuid = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", + traceLocationId = "fe84394e73838590cc7707aba0350c130f6d0fb6f0f2535f9735f481dee61871", startDateStr = "2021-03-04T09:50+01:00", endDateStr = "2021-03-04T10:05:15+01:00" ).calculateOverlap( @@ -238,12 +239,13 @@ class OverlapTest : BaseTest() { fun createCheckIn( id: Long = 1L, - traceLocationGuid: String, + traceLocationId: String, startDateStr: String, endDateStr: String ) = CheckIn( id = id, - guid = traceLocationGuid, + traceLocationId = traceLocationId.toSHA256().encode(), + traceLocationIdHash = traceLocationId.toSHA256().encode(), version = 1, type = 2, description = "My birthday party", @@ -251,6 +253,8 @@ fun createCheckIn( traceLocationStart = Instant.parse(startDateStr), traceLocationEnd = null, defaultCheckInLengthInMinutes = null, + cryptographicSeed = "cryptographicSeed".encode(), + cnPublicKey = "cnPublicKey", checkInStart = Instant.parse(startDateStr), checkInEnd = Instant.parse(endDateStr), completed = false, -- GitLab