Skip to content
Snippets Groups Projects
Unverified Commit 4c0101be authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

QR Code parsing (DEV/EXPOSUREAPP-5841) (#2622)

* Adopt new signedTraceLocationFormat

* QR Code decoding adjustment.

* Adjust failing test & refactoring.

* Fix typo.

* Remove duplicate data class and re-use DefaultTraceLocation.
Adjust to new signature/location bytearray encoding.

* Remove extra interface for TraceLocation and use the dataclass directly.

* Package refactoring

* Fix package import.

* Fix package import in nav graph

* Fix additional package imports.

* Fix additional package imports.
parent 2fee6d34
No related branches found
No related tags found
No related merge requests found
Showing
with 49 additions and 56 deletions
......@@ -30,8 +30,8 @@ class ConfirmCheckInFragment : Fragment(R.layout.fragment_confirm_check_in), Aut
confirmButton.setOnClickListener { viewModel.onConfirmTraceLocation() }
// TODO bind final UI
eventGuid.text = "GUID: %s".format(args.traceLocation.guid)
startTime.text = "Start time: %s".format(args.traceLocation.start)
endTime.text = "End time: %s".format(args.traceLocation.end)
startTime.text = "Start time: %s".format(args.traceLocation.startDate)
endTime.text = "End time: %s".format(args.traceLocation.endDate)
description.text = "Description: %s".format(args.traceLocation.description)
}
......
package de.rki.coronawarnapp.eventregistration.common
package de.rki.coronawarnapp.util
import com.google.common.io.BaseEncoding
import okio.ByteString
......
......@@ -11,7 +11,7 @@
tools:layout="@layout/fragment_confirm_check_in">
<argument
android:name="traceLocation"
app:argType="de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.VerifiedTraceLocation" />
app:argType="de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation" />
</fragment>
<fragment
android:id="@+id/scanCheckInQrCodeFragment"
......
package de.rki.coronawarnapp.eventregistration
import de.rki.coronawarnapp.eventregistration.common.base32
import de.rki.coronawarnapp.eventregistration.common.decodeBase32
import de.rki.coronawarnapp.util.base32
import de.rki.coronawarnapp.util.decodeBase32
import io.kotest.matchers.shouldBe
import okio.ByteString.Companion.toByteString
import org.junit.jupiter.params.ParameterizedTest
......
......@@ -57,7 +57,7 @@ class DefaultCheckInsTransformerTest : BaseTest() {
outCheckIns[0].apply {
signedLocation.apply {
location.apply {
TraceLocationOuterClass.TraceLocation.parseFrom(location).apply {
guid shouldBe "3055331c-2306-43f3-9742-6d8fab54e848"
version shouldBe 1
type shouldBe TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER
......@@ -76,7 +76,7 @@ class DefaultCheckInsTransformerTest : BaseTest() {
outCheckIns[1].apply {
signedLocation.apply {
location.apply {
TraceLocationOuterClass.TraceLocation.parseFrom(location).apply {
guid shouldBe "fca84b37-61c0-4a7c-b2f8-825cadd506cf"
version shouldBe 1
type shouldBe TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_OTHER
......@@ -93,4 +93,4 @@ class DefaultCheckInsTransformerTest : BaseTest() {
// TODO transmissionRiskLevel shouldBe
}
}
}
\ No newline at end of file
}
package de.rki.coronawarnapp.eventregistration.checkins.qrcode
import com.google.protobuf.ByteString
import de.rki.coronawarnapp.eventregistration.common.decodeBase32
import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
import de.rki.coronawarnapp.util.decodeBase32
import io.kotest.matchers.shouldBe
import okio.ByteString.Companion.toByteString
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
@Disabled("Renable after encoding clarification")
class DefaultQRCodeVerifierTest2 : BaseTest() {
@Test
fun `protobuf decoding 1`() {
val signedTraceLocation =
TraceLocationOuterClass.SignedTraceLocation.newBuilder(TraceLocationOuterClass.SignedTraceLocation.getDefaultInstance())
.apply {
signature = ByteString.copyFromUtf8(
"MEYCIQCNSNL6E/XyCaemkM6//CIBo+goZKJi/URimqcvwIKzCgIhAOfZPRAfZBRmwpq4sbxrLs3EhY3i914aO4lJ59XCFhwk"
)
location = TraceLocationOuterClass.TraceLocation.parseFrom(
"BISDGMBVGUZTGMLDFUZDGMBWFU2DGZRTFU4TONBSFU3GIODGMFRDKNDFHA2DQEABDABCEEKNPEQEE2LSORUGIYLZEBIGC4TUPEVAWYLUEBWXSIDQNRQWGZJQ2OD2IAJY66D2IAKAAA".decodeBase32()
.toByteArray()
)
}.build()
TraceLocationOuterClass.SignedTraceLocation.parseFrom(
"BJLAUJBTGA2TKMZTGFRS2MRTGA3C2NBTMYZS2OJXGQZC2NTEHBTGCYRVGRSTQNBYCAARQARCCFGXSICCNFZHI2DEMF4SAUDBOJ2HSKQLMF2CA3LZEBYGYYLDMUYNHB5EAE4PPB5EAFAAAESGGBCAEIDFJJ7KHRO3ZZ2SFMJSBXSUY2ZZKGOIZS27L2D6VPKTA57M6RZY3MBCARR7LXAA2BY3IGNTHNFFAJSMIXF6PP4TEB3I2C3D7P32QUZHVVER"
.decodeBase32().toByteArray()
)
signedTraceLocation.apply {
location.apply {
TraceLocationOuterClass.TraceLocation.parseFrom(location).apply {
guid shouldBe "3055331c-2306-43f3-9742-6d8fab54e848"
version shouldBe 1
typeValue shouldBe 2
......@@ -37,7 +28,8 @@ class DefaultQRCodeVerifierTest2 : BaseTest() {
endTimestamp shouldBe 2687991
defaultCheckInLengthInMinutes shouldBe 0
}
signature.toStringUtf8() shouldBe "MEYCIQCNSNL6E/XyCaemkM6//CIBo+goZKJi/URimqcvwIKzCgIhAOfZPRAfZBRmwpq4sbxrLs3EhY3i914aO4lJ59XCFhwk"
signature.toByteArray().toByteString()
.base64() shouldBe "MEQCIGVKfqPF2851IrEyDeVMazlRnIzLX16H6r1TB37PRzjbAiBGP13ADQcbQZsztKUCZMRcvnv5Mgdo0LY/v3qFMnrUkQ=="
}
signedTraceLocation.location.toByteArray().toByteString()
......@@ -46,18 +38,13 @@ class DefaultQRCodeVerifierTest2 : BaseTest() {
@Test
fun `protobuf decoding 2`() {
val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.newBuilder().apply {
signature = ByteString.copyFromUtf8(
"MEUCIFpHvUqYAIP0Mq86R7kNO4EgRSvGJHbOlDraauKZvkgbAiEAh93bBDYviEtym4q5Oqzd7j6Dp1MLCP7YwCKlVcU2DHc="
)
location = TraceLocationOuterClass.TraceLocation.parseFrom(
"BISGMY3BHA2GEMZXFU3DCYZQFU2GCN3DFVRDEZRYFU4DENLDMFSGINJQGZRWMEABDAASEDKJMNSWG4TFMFWSAU3IN5YCUDKNMFUW4ICTORZGKZLUEAYTAABYABAAU".decodeBase32()
.toByteArray()
)
}.build()
val signedTraceLocation = TraceLocationOuterClass.SignedTraceLocation.parseFrom(
"BJHAUJDGMNQTQNDCGM3S2NRRMMYC2NDBG5RS2YRSMY4C2OBSGVRWCZDEGUYDMY3GCAARQAJCBVEWGZLDOJSWC3JAKNUG64BKBVGWC2LOEBJXI4TFMV2CAMJQAA4AAQAKCJDDARACEA2ZCTGOF2HH2RQU7ODZMCSUTUBBNQYM6AR4NG6FFLC6ISXWEOI5UARADO44YYH3U53ZYL6IYM5DWALXUESAJNWRGRL5KLNLS5BM54SHDDCA"
.decodeBase32().toByteArray()
)
signedTraceLocation.apply {
location.apply {
TraceLocationOuterClass.TraceLocation.parseFrom(location).apply {
guid shouldBe "fca84b37-61c0-4a7c-b2f8-825cadd506cf"
version shouldBe 1
typeValue shouldBe 1
......@@ -67,7 +54,8 @@ class DefaultQRCodeVerifierTest2 : BaseTest() {
endTimestamp shouldBe 0
defaultCheckInLengthInMinutes shouldBe 10
}
signature.toStringUtf8() shouldBe "MEUCIFpHvUqYAIP0Mq86R7kNO4EgRSvGJHbOlDraauKZvkgbAiEAh93bBDYviEtym4q5Oqzd7j6Dp1MLCP7YwCKlVcU2DHc="
signature.toByteArray().toByteString()
.base64() shouldBe "MEQCIDWRTM4ujn1GFPuHlgpUnQIWwwzwI8abxSrF5Er2I5HaAiAbucxg+6d3nC/Iwzo7AXehJAS20TRX1S2rl0LO8kcYxA=="
}
signedTraceLocation.location.toByteArray().toByteString()
......
package de.rki.coronawarnapp.eventregistration.events
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.toTraceLocation
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.toTraceLocations
import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationEntity
import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_OTHER
import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER
import io.kotest.matchers.shouldBe
import okio.ByteString.Companion.toByteString
import org.joda.time.Instant
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
......@@ -21,8 +25,8 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
).toTraceLocation() shouldBe DefaultTraceLocation(
signatureBase64 = "signature".toByteArray().toByteString().base64()
).toTraceLocation() shouldBe TraceLocation(
guid = "TestGuid",
version = 1,
type = LOCATION_TYPE_PERMANENT_OTHER,
......@@ -31,7 +35,7 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
signature = "signature".toByteArray().toByteString()
)
}
......@@ -46,8 +50,8 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
).toTraceLocation() shouldBe DefaultTraceLocation(
signatureBase64 = "signature".toByteArray().toByteString().base64()
).toTraceLocation() shouldBe TraceLocation(
guid = "TestGuid",
version = 1,
type = LOCATION_TYPE_PERMANENT_OTHER,
......@@ -56,7 +60,7 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
signature = "signature".toByteArray().toByteString()
)
}
......@@ -72,7 +76,7 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
signatureBase64 = "signature".toByteArray().toByteString().base64()
),
TraceLocationEntity(
guid = "TestGuid2",
......@@ -83,10 +87,10 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
signatureBase64 = "signature".toByteArray().toByteString().base64()
)
).toTraceLocations() shouldBe listOf(
DefaultTraceLocation(
TraceLocation(
guid = "TestGuid1",
version = 1,
type = LOCATION_TYPE_TEMPORARY_OTHER,
......@@ -95,9 +99,9 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
signature = "signature".toByteArray().toByteString()
),
DefaultTraceLocation(
TraceLocation(
guid = "TestGuid2",
version = 1,
type = LOCATION_TYPE_PERMANENT_OTHER,
......@@ -106,7 +110,7 @@ internal class DefaultTraceLocationKtTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
signature = "signature".toByteArray().toByteString()
)
)
}
......
package de.rki.coronawarnapp.eventregistration.storage.entity
import de.rki.coronawarnapp.eventregistration.events.DefaultTraceLocation
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocation
import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_PERMANENT_OTHER
import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass.TraceLocationType.LOCATION_TYPE_TEMPORARY_OTHER
import io.kotest.matchers.shouldBe
import okio.ByteString.Companion.toByteString
import org.joda.time.Instant
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
......@@ -12,7 +13,7 @@ internal class TraceLocationEntityTest : BaseTest() {
@Test
fun `toTraceLocationEntity() should map to TraceLocationEntity correctly with all arguments`() {
DefaultTraceLocation(
TraceLocation(
guid = "TestGuid",
version = 1,
type = LOCATION_TYPE_TEMPORARY_OTHER,
......@@ -21,7 +22,7 @@ internal class TraceLocationEntityTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
signature = "signature".toByteArray().toByteString()
).toTraceLocationEntity() shouldBe TraceLocationEntity(
guid = "TestGuid",
version = 1,
......@@ -31,13 +32,13 @@ internal class TraceLocationEntityTest : BaseTest() {
startDate = Instant.parse("2021-01-01T12:00:00.000Z"),
endDate = Instant.parse("2021-01-01T18:00:00.000Z"),
defaultCheckInLengthInMinutes = 15,
signature = "signature"
signatureBase64 = "signature".toByteArray().toByteString().base64()
)
}
@Test
fun `toTraceLocationEntity() should map to TraceLocationEntity correctly with some arguments as null`() {
DefaultTraceLocation(
TraceLocation(
guid = "TestGuid",
version = 1,
type = LOCATION_TYPE_PERMANENT_OTHER,
......@@ -46,7 +47,7 @@ internal class TraceLocationEntityTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
signature = "signature".toByteArray().toByteString()
).toTraceLocationEntity() shouldBe TraceLocationEntity(
guid = "TestGuid",
version = 1,
......@@ -56,7 +57,7 @@ internal class TraceLocationEntityTest : BaseTest() {
startDate = null,
endDate = null,
defaultCheckInLengthInMinutes = null,
signature = "signature"
signatureBase64 = "signature".toByteArray().toByteString().base64()
)
}
}
......@@ -20,7 +20,7 @@ message TraceLocation {
}
message SignedTraceLocation {
TraceLocation location = 1;
bytes location = 1;
bytes signature = 2;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment