From 4c8b7fcff636f135b33fed7af73666cfb32fb007 Mon Sep 17 00:00:00 2001 From: oleksandrsarapulovgl <82441124+oleksandrsarapulovgl@users.noreply.github.com> Date: Wed, 28 Jul 2021 23:04:53 +0300 Subject: [PATCH] Added trimming whitespaces (#53) * Added trimming whitespaces * Update * Update * Update --- .../app/decoder/DefaultCertificateDecoder.kt | 27 ++++---- .../app/decoder/cbor/DefaultCborService.kt | 17 +++-- .../cbor/DefaultGreenCertificateMapper.kt | 49 +++++++++++++++ .../decoder/cbor/GreenCertificateMapper.kt | 30 +++++++++ .../app/decoder/CertificateTestRunner.kt | 4 +- .../dgca/verifier/app/decoder/QrCodeTests.kt | 8 ++- .../cbor/DefaultGreenCertificateMapperTest.kt | 62 +++++++++++++++++++ 7 files changed, 171 insertions(+), 26 deletions(-) create mode 100644 decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapper.kt create mode 100644 decoder/src/main/java/dgca/verifier/app/decoder/cbor/GreenCertificateMapper.kt create mode 100644 decoder/src/test/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapperTest.kt diff --git a/decoder/src/main/java/dgca/verifier/app/decoder/DefaultCertificateDecoder.kt b/decoder/src/main/java/dgca/verifier/app/decoder/DefaultCertificateDecoder.kt index f684501..9be48fb 100644 --- a/decoder/src/main/java/dgca/verifier/app/decoder/DefaultCertificateDecoder.kt +++ b/decoder/src/main/java/dgca/verifier/app/decoder/DefaultCertificateDecoder.kt @@ -23,17 +23,18 @@ package dgca.verifier.app.decoder import COSE.HeaderKeys -import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper import com.upokecenter.cbor.CBORObject import dgca.verifier.app.decoder.base45.Base45Decoder +import dgca.verifier.app.decoder.cbor.DefaultGreenCertificateMapper +import dgca.verifier.app.decoder.cbor.GreenCertificateMapper import dgca.verifier.app.decoder.cwt.CwtHeaderKeys import dgca.verifier.app.decoder.model.CoseData import dgca.verifier.app.decoder.model.GreenCertificate import java.util.zip.InflaterInputStream @ExperimentalUnsignedTypes -class DefaultCertificateDecoder(private val base45Decoder: Base45Decoder) : - CertificateDecoder { +class DefaultCertificateDecoder(private val base45Decoder: Base45Decoder, private val greenCertificateMapper: GreenCertificateMapper = DefaultGreenCertificateMapper()) : + CertificateDecoder { companion object { const val PREFIX = "HC1:" } @@ -62,7 +63,7 @@ class DefaultCertificateDecoder(private val base45Decoder: Base45Decoder) : coseData.cbor.decodeGreenCertificate() } catch (error: Throwable) { return CertificateDecodingResult.Error(CertificateDecodingError.GreenCertificateDecodingError(error)) - } ?: return CertificateDecodingResult.Error(CertificateDecodingError.EmptyGreenCertificate) + } return CertificateDecodingResult.Success(greenCertificate) @@ -72,11 +73,11 @@ class DefaultCertificateDecoder(private val base45Decoder: Base45Decoder) : private fun ByteArray.decompressBase45DecodedData(): ByteArray { // ZLIB magic headers return if (this.size >= 2 && this[0] == 0x78.toByte() && ( - this[1] == 0x01.toByte() || // Level 1 - this[1] == 0x5E.toByte() || // Level 2 - 5 - this[1] == 0x9C.toByte() || // Level 6 - this[1] == 0xDA.toByte() - ) + this[1] == 0x01.toByte() || // Level 1 + this[1] == 0x5E.toByte() || // Level 2 - 5 + this[1] == 0x9C.toByte() || // Level 6 + this[1] == 0xDA.toByte() + ) ) { InflaterInputStream(this.inputStream()).readBytes() } else this @@ -97,12 +98,12 @@ class DefaultCertificateDecoder(private val base45Decoder: Base45Decoder) : return CoseData(content, objProtected) } - private fun ByteArray.decodeGreenCertificate(): GreenCertificate? { + private fun ByteArray.decodeGreenCertificate(): GreenCertificate { val map = CBORObject.DecodeFromBytes(this) val hcert = map[CwtHeaderKeys.HCERT.asCBOR()] - val hcertv1 = hcert[CBORObject.FromObject(1)].EncodeToBytes() + val cborObject = hcert[CBORObject.FromObject(1)] - return CBORMapper() - .readValue(hcertv1, GreenCertificate::class.java) + return greenCertificateMapper + .readValue(cborObject) } } \ No newline at end of file diff --git a/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultCborService.kt b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultCborService.kt index 235c3c1..7c1dd9d 100644 --- a/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultCborService.kt +++ b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultCborService.kt @@ -22,7 +22,6 @@ package dgca.verifier.app.decoder.cbor -import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper import com.upokecenter.cbor.CBORObject import dgca.verifier.app.decoder.cwt.CwtHeaderKeys import dgca.verifier.app.decoder.model.GreenCertificate @@ -33,16 +32,16 @@ import java.time.ZoneOffset /** * Decodes input as a CBOR structure */ -class DefaultCborService : CborService { +class DefaultCborService(private val greenCertificateMapper: GreenCertificateMapper = DefaultGreenCertificateMapper()) : CborService { override fun decode( - input: ByteArray, - verificationResult: VerificationResult + input: ByteArray, + verificationResult: VerificationResult ): GreenCertificate? = decodeData(input, verificationResult)?.greenCertificate override fun decodeData( - input: ByteArray, - verificationResult: VerificationResult + input: ByteArray, + verificationResult: VerificationResult ): GreenCertificateData? { verificationResult.cborDecoded = false return try { @@ -59,11 +58,9 @@ class DefaultCborService : CborService { val hcert = map[CwtHeaderKeys.HCERT.asCBOR()] val cborObject = hcert[CBORObject.FromObject(1)] - val hcertv1 = cborObject.EncodeToBytes() - val greenCertificate: GreenCertificate = CBORMapper() - .readValue(hcertv1, GreenCertificate::class.java) - .also { verificationResult.cborDecoded = true } + val greenCertificate: GreenCertificate = greenCertificateMapper.readValue(cborObject) + .also { verificationResult.cborDecoded = true } GreenCertificateData(issuingCountry, cborObject.ToJSONString(), greenCertificate, issuedAt.atZone(ZoneOffset.UTC), expirationTime.atZone(ZoneOffset.UTC)) } catch (e: Throwable) { null diff --git a/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapper.kt b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapper.kt new file mode 100644 index 0000000..d763e1e --- /dev/null +++ b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapper.kt @@ -0,0 +1,49 @@ +/* + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-android + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + * + * Created by osarapulov on 7/28/21 1:23 PM + */ + +package dgca.verifier.app.decoder.cbor + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper +import com.upokecenter.cbor.CBORObject +import dgca.verifier.app.decoder.model.GreenCertificate + +class DefaultGreenCertificateMapper : GreenCertificateMapper, CBORMapper() { + + init { + SimpleModule().apply { + addDeserializer(String::class.java, object : JsonDeserializer() { + override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): String? = p?.valueAsString?.trim() + }) + registerModule(this) + } + + } + + override fun readValue(cborObject: CBORObject): GreenCertificate { + val bytes = cborObject.EncodeToBytes() + return readValue(bytes, GreenCertificate::class.java) + } +} \ No newline at end of file diff --git a/decoder/src/main/java/dgca/verifier/app/decoder/cbor/GreenCertificateMapper.kt b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/GreenCertificateMapper.kt new file mode 100644 index 0000000..06f132f --- /dev/null +++ b/decoder/src/main/java/dgca/verifier/app/decoder/cbor/GreenCertificateMapper.kt @@ -0,0 +1,30 @@ +/* + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-android + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + * + * Created by osarapulov on 7/28/21 1:19 PM + */ + +package dgca.verifier.app.decoder.cbor + +import com.upokecenter.cbor.CBORObject +import dgca.verifier.app.decoder.model.GreenCertificate + +interface GreenCertificateMapper { + fun readValue(cborObject: CBORObject): GreenCertificate +} \ No newline at end of file diff --git a/decoder/src/test/java/dgca/verifier/app/decoder/CertificateTestRunner.kt b/decoder/src/test/java/dgca/verifier/app/decoder/CertificateTestRunner.kt index 0e6a42a..973d9ee 100644 --- a/decoder/src/test/java/dgca/verifier/app/decoder/CertificateTestRunner.kt +++ b/decoder/src/test/java/dgca/verifier/app/decoder/CertificateTestRunner.kt @@ -5,6 +5,7 @@ import dgca.verifier.app.decoder.base45.Base45Service import dgca.verifier.app.decoder.base45.DefaultBase45Service import dgca.verifier.app.decoder.cbor.CborService import dgca.verifier.app.decoder.cbor.DefaultCborService +import dgca.verifier.app.decoder.cbor.GreenCertificateMapper import dgca.verifier.app.decoder.compression.CompressorService import dgca.verifier.app.decoder.compression.DefaultCompressorService import dgca.verifier.app.decoder.cose.CoseService @@ -37,6 +38,7 @@ class CertificateTestRunner { private lateinit var cryptoService: CryptoService private lateinit var coseService: CoseService private lateinit var schemaValidator: SchemaValidator + private lateinit var greenCertificateMapper: GreenCertificateMapper private lateinit var cborService: CborService @BeforeEach @@ -47,7 +49,7 @@ class CertificateTestRunner { cryptoService = VerificationCryptoService(X509()) coseService = DefaultCoseService() schemaValidator = DefaultSchemaValidator() - cborService = DefaultCborService() + cborService = DefaultCborService(greenCertificateMapper) } @ParameterizedTest diff --git a/decoder/src/test/java/dgca/verifier/app/decoder/QrCodeTests.kt b/decoder/src/test/java/dgca/verifier/app/decoder/QrCodeTests.kt index 521e641..a2d6220 100644 --- a/decoder/src/test/java/dgca/verifier/app/decoder/QrCodeTests.kt +++ b/decoder/src/test/java/dgca/verifier/app/decoder/QrCodeTests.kt @@ -6,6 +6,8 @@ import dgca.verifier.app.decoder.base45.Base45Service import dgca.verifier.app.decoder.base45.DefaultBase45Service import dgca.verifier.app.decoder.cbor.CborService import dgca.verifier.app.decoder.cbor.DefaultCborService +import dgca.verifier.app.decoder.cbor.DefaultGreenCertificateMapper +import dgca.verifier.app.decoder.cbor.GreenCertificateMapper import dgca.verifier.app.decoder.compression.CompressorService import dgca.verifier.app.decoder.compression.DefaultCompressorService import dgca.verifier.app.decoder.cose.CoseService @@ -45,7 +47,8 @@ class QrCodeTests { val compressorService: CompressorService = DefaultCompressorService() val validator: SchemaValidator = DefaultSchemaValidator() val coseservice: CoseService = DefaultCoseService() - val cborservice: CborService = DefaultCborService() + val greenCertificateMapper: GreenCertificateMapper = DefaultGreenCertificateMapper() + val cborservice: CborService = DefaultCborService(greenCertificateMapper) val base45 = prefService.decode(prefix!!, result) val compressed = b45Service.decode(base45, result) val cose: ByteArray = compressorService.decode(compressed, result)!! @@ -134,7 +137,8 @@ class QrCodeTests { val compressorService: CompressorService = DefaultCompressorService() val validator: SchemaValidator = DefaultSchemaValidator() val coseservice: CoseService = DefaultCoseService() - val cborservice: CborService = DefaultCborService() + val greenCertificateMapper: GreenCertificateMapper = DefaultGreenCertificateMapper() + val cborservice: CborService = DefaultCborService(greenCertificateMapper) val base45 = prefService.decode(hCert, result) val compressed = b45Service.decode(base45, result) val cose: ByteArray = compressorService.decode(compressed, result)!! diff --git a/decoder/src/test/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapperTest.kt b/decoder/src/test/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapperTest.kt new file mode 100644 index 0000000..7ac9d93 --- /dev/null +++ b/decoder/src/test/java/dgca/verifier/app/decoder/cbor/DefaultGreenCertificateMapperTest.kt @@ -0,0 +1,62 @@ +/* + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-android + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + * + * Created by osarapulov on 7/28/21 1:32 PM + */ + +package dgca.verifier.app.decoder.cbor + +import com.upokecenter.cbor.CBORObject +import dgca.verifier.app.decoder.model.GreenCertificate +import org.junit.Assert.assertEquals +import org.junit.Test + +internal class DefaultGreenCertificateMapperTest { + val JSON = "{\n" + + " \"t\": [\n" + + " {\n" + + " \"sc\": \" 2021-07-26T21:00:00Z \",\n" + + " \"ma\": \" 1223 \",\n" + + " \"tt\": \" LP217198-3 \",\n" + + " \"tc\": \" Custom Testing Centre \",\n" + + " \"co\": \" FR \",\n" + + " \"ci\": \" URN:UVCI:V1:DE:O39BNVCVNHTRMKY0E9DYT4A43T \",\n" + + " \"is\": \" Custom Issuer Certifcate \",\n" + + " \"tg\": \" 840539006 \",\n" + + " \"tr\": \" 260415000 \"\n" + + " }\n" + + " ],\n" + + " \"nam\": {\n" + + " \"fnt\": \" STANDARDISEDFAMILY \"\n" + + " },\n" + + " \"ver\": \" 1.3.0 \",\n" + + " \"dob\": \" \"\n" + + "}" + + + @Test + fun test() { + val greenCertificateMapper = DefaultGreenCertificateMapper() + val cborObject = CBORObject.FromJSONString(JSON) + val greenCertificate: GreenCertificate = + greenCertificateMapper.readValue(cborObject) + val testingCenter: String = greenCertificate.tests!!.first().testingCentre + assertEquals(testingCenter.trim(), testingCenter) + } +} \ No newline at end of file