Parse input certificates

This commit is contained in:
Pierre HUBERT 2022-02-16 10:52:58 +01:00
parent d2847107b4
commit 2b6fe21792
8 changed files with 97 additions and 3 deletions

View File

@ -23,6 +23,8 @@ android {
}
}
compileOptions {
coreLibraryDesugaringEnabled = true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -33,6 +35,15 @@ android {
buildFeatures {
viewBinding = true
}
packagingOptions {
pickFirst 'META-INF/ASL-2.0.txt'
pickFirst 'draftv4/schema'
pickFirst 'draftv3/schema'
pickFirst 'META-INF/LGPL-3.0.txt'
}
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
}
dependencies {
@ -42,8 +53,11 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.preference:preference:1.2.0'
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
implementation 'com.github.eu-digital-green-certificates:dgca-app-core-android:e4ad73eef8'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
}

View File

@ -29,8 +29,22 @@
<!-- Manage certificates -->
<activity
android:name=".activities.CertsManager"
android:exported="false"
android:label="@string/activity_certsmanagers" />
android:exported="true"
android:label="@string/activity_certsmanagers">
<intent-filter android:label="@string/action_import_certificate">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="bonjour.tousanticovid.gouv.fr"
android:pathPrefix="/app/walletdcc"
android:scheme="https" />
</intent-filter>
</activity>
<!-- Fix Qr scanner orientation -->
<activity

View File

@ -0,0 +1,4 @@
package org.communiquons.dccaggregator
// Official URL provided to add certificate to wallet
const val WALLET_URL = "https://bonjour.tousanticovid.gouv.fr/app/walletdcc#"

View File

@ -3,11 +3,16 @@ package org.communiquons.dccaggregator.activities
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanOptions
import org.communiquons.dccaggregator.R
import org.communiquons.dccaggregator.WALLET_URL
import org.communiquons.dccaggregator.databinding.ActivityCertsManagerBinding
import org.communiquons.dccaggregator.models.Certificate
import java.net.URLDecoder
import java.nio.charset.StandardCharsets
class CertsManager : AppCompatActivity() {
@ -25,6 +30,12 @@ class CertsManager : AppCompatActivity() {
binding.scanCertButton.setOnClickListener {
addNewCertificate()
}
intent?.dataString.toString().apply {
if (this.startsWith(WALLET_URL))
processGivenCertificate(this)
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
@ -40,7 +51,7 @@ class CertsManager : AppCompatActivity() {
if (it.contents == null)
return@registerForActivityResult
Log.v(TAG, it.contents)
processGivenCertificate(it.contents)
}
private fun addNewCertificate() {
@ -50,4 +61,24 @@ class CertsManager : AppCompatActivity() {
setPrompt(resources.getString(R.string.scan_qr_prompt))
})
}
private fun processGivenCertificate(input: String) {
// Decode input if required
val decoded = if (input.startsWith(WALLET_URL)) {
URLDecoder.decode(input.replace(WALLET_URL, ""), StandardCharsets.UTF_8.displayName())
} else {
input
}
try {
val cert = Certificate(decoded)
Log.v(TAG, cert.fullName)
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(this, R.string.invalid_certificate, Toast.LENGTH_SHORT).show()
return
}
}
}

View File

@ -0,0 +1,27 @@
package org.communiquons.dccaggregator.models
import dgca.verifier.app.decoder.CertificateDecodingResult
import dgca.verifier.app.decoder.DefaultCertificateDecoder
import dgca.verifier.app.decoder.base45.Base45Decoder
import dgca.verifier.app.decoder.model.GreenCertificate
@OptIn(ExperimentalUnsignedTypes::class)
class Certificate(val encoded: String) {
// Decoded green certificate
val decoded: GreenCertificate;
init {
val res = DefaultCertificateDecoder(Base45Decoder()).decodeCertificate(encoded)
if (res is CertificateDecodingResult.Error)
throw Exception("Failed to read certificate!", res.error.error)
decoded = (res as CertificateDecodingResult.Success).greenCertificate
}
/**
* Get person full name
*/
val fullName get() = "${decoded.person.standardisedGivenName} ${decoded.person.standardisedFamilyName}"
}

View File

@ -3,4 +3,6 @@
<string name="activity_certsmanagers">Input certificates</string>
<string name="add_certificate">Add a new certificate</string>
<string name="scan_qr_prompt">Please present the QrCode of the certificate you want to add</string>
<string name="action_import_certificate">Import certificate</string>
<string name="invalid_certificate">The given certificate could not be decoded!</string>
</resources>

View File

@ -3,6 +3,7 @@ buildscript {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"

View File

@ -3,6 +3,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
jcenter() // Warning: this repository is going to shut down soon
}
}