Commit 6ae30d25 authored by stopcovid@lunabee.com's avatar stopcovid@lunabee.com
Browse files

Update to 3.7.0

- Blacklist for 2d-doc
- Try to fix vanishing certificates
- DOM are French too
parent a0600595
......@@ -144,13 +144,20 @@ object ConfigConstant {
const val LOCAL_FILENAME: String = "calibrationBle.json"
}
object Blacklist {
object BlacklistDCC {
const val FILENAME: String = "certlist.json"
const val FOLDER: String = "CertList/"
const val URL: String = VERSIONED_SERVER_URL + FOLDER + FILENAME
const val ASSET_FILE_PATH: String = FOLDER + FILENAME
}
object Blacklist2DDOC {
const val FILENAME: String = "2ddoc_list.json"
const val FOLDER: String = "CertList/"
const val URL: String = VERSIONED_SERVER_URL + FOLDER + FILENAME
const val ASSET_FILE_PATH: String = FOLDER + FILENAME
}
object Store {
const val GOOGLE: String = "market://details?id=fr.gouv.android.stopcovid"
const val HUAWEI: String = "appmarket://details?id=fr.gouv.android.stopcovid"
......
......@@ -106,6 +106,7 @@ class InGroupeDatasourceTest {
val convertResult = runBlocking {
inGroupeDatasource.convertCertificateV2(
robertManager,
inputString,
WalletCertificateType.Format.WALLET_2D,
WalletCertificateType.Format.WALLET_DCC,
......@@ -137,6 +138,7 @@ class InGroupeDatasourceTest {
val convertResult = runBlocking {
inGroupeDatasource.convertCertificateV2(
robertManager,
inputString,
WalletCertificateType.Format.WALLET_2D,
WalletCertificateType.Format.WALLET_DCC,
......
......@@ -175,10 +175,13 @@ class LocalCryptoManager(private val appContext: Context) {
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()
)
sharedPreferences.edit {
putBoolean(SECRET_KEY_GENERATED_SHARED_PREFERENCE, true)
val newSecretKey = generator.generateKey()
if (keyStore.containsAlias(AES_LOCAL_PROTECTION_KEY_ALIAS)) {
sharedPreferences.edit {
putBoolean(SECRET_KEY_GENERATED_SHARED_PREFERENCE, true)
}
}
generator.generateKey()
newSecretKey
} else {
Timber.e(
"Secret key couldn't be found in the KeyStore but data are already encrypted with it\nkeystore aliases = ${
......
......@@ -246,11 +246,11 @@ class SecureKeystoreDataSource(context: Context, private val cryptoManager: Loca
val decryptedString = cryptoManager.decryptToString(encryptedText)
gson.fromJson<T>(decryptedString, type)
}
}.getOrNull()
if (useCache) {
cache[key] = result
}
result
if (useCache && result.isSuccess) {
cache[key] = result.getOrNull()
}
result.getOrNull()
} else {
null
}
......@@ -288,9 +288,11 @@ class SecureKeystoreDataSource(context: Context, private val cryptoManager: Loca
return if (text != null) {
val result = kotlin.runCatching {
gson.fromJson<T>(text, type)
}.getOrNull()
cache[key] = result
result
}
if (result.isSuccess) {
cache[key] = result.getOrNull()
}
result.getOrNull()
} else {
null
}
......
......@@ -35,7 +35,6 @@ import timber.log.Timber
class InGroupeDatasource(
private val context: Context,
private val sharedCryptoDataSource: SharedCryptoDataSource,
private val robertManager: RobertManager,
baseUrl: String,
) : RemoteCertificateDataSource {
......@@ -92,6 +91,7 @@ class InGroupeDatasource(
}
override suspend fun convertCertificateV2(
robertManager: RobertManager,
encodedCertificate: String,
from: WalletCertificateType.Format,
to: WalletCertificateType.Format
......
......@@ -11,6 +11,7 @@
package com.lunabeestudio.robert.datasource
import com.lunabeestudio.domain.model.WalletCertificateType
import com.lunabeestudio.robert.RobertManager
import com.lunabeestudio.robert.model.RobertResultData
interface RemoteCertificateDataSource {
......@@ -21,6 +22,7 @@ interface RemoteCertificateDataSource {
): RobertResultData<String>
suspend fun convertCertificateV2(
robertManager: RobertManager,
encodedCertificate: String,
from: WalletCertificateType.Format,
to: WalletCertificateType.Format
......
......@@ -18,16 +18,17 @@ import com.lunabeestudio.robert.model.RobertResultData
import timber.log.Timber
class CertificateRepository(
private val remoteDataSource: RemoteCertificateDataSource,
private val robertManager: RobertManager,
var remoteDataSource: RemoteCertificateDataSource,
) {
suspend fun convertCertificate(
robertManager: RobertManager,
certificate: RawWalletCertificate,
to: WalletCertificateType.Format
): RobertResultData<String> {
val robertResultData = if (robertManager.configuration.conversionApiVersion == 2) {
remoteDataSource.convertCertificateV2(
robertManager = robertManager,
encodedCertificate = certificate.value,
from = certificate.type.format,
to = to
......
......@@ -9,7 +9,7 @@
*/
plugins {
id("de.fayard.refreshVersions") version "0.10.1"
id("de.fayard.refreshVersions") version "0.11.0"
}
rootProject.name = 'TousAntiCovid'
......
......@@ -45,8 +45,8 @@ android {
applicationId "fr.gouv.android.stopcovid"
minSdkVersion 21
targetSdkVersion 30
versionCode 326
versionName "3.6.1"
versionCode 328
versionName "3.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
......
[
"7459877044d92cea191246d36b84de1c357dc583d7b499be16eb291a4eb317f1",
"829d46117e8008cd7ded8e568c9ab3cb7a2426acb8fa48d49fa59954e3c11e26"
]
\ No newline at end of file
["afe98db8c94a83ec77e973acc7be55a994f3c160be27ce233e52e69760970b5c", "64027d2f1d6fdb211422398d3c01dacf5c3a60e41b9a2658cfb256a144eea8cd"]
\ No newline at end of file
[
"afe98db8c94a83ec77e973acc7be55a994f3c160be27ce233e52e69760970b5c",
"64027d2f1d6fdb211422398d3c01dacf5c3a60e41b9a2658cfb256a144eea8cd",
"442144ef4acf47d71a469e04e10d58081dbdde67fb2ef4f94c6d0f02407d89bf",
"1b0c8a6f44326c5f44f74388d2403cac2f3df9127709c1685469991e9012b855",
"61182c3262bd8f472a94e360fa24686d94a76ee0462747e831aac54dc5c4d20a",
"194fad873c5dfe7816819203063607ee496c2520e8a54b1d543bd8bd65dd2704",
"7c719083052144206256f36ff90cfd2781e57da74123cb733bd154d2ddb294c2",
"7d465e9fbd7fd0b8e7bb1f59507648817cbff0d1459d1bf4dfdb83782fa5bab2",
"cd7cbbaaba00f2c5ebf21b6d0aad5b0d7e517e0ed3edf41c20203101af4cccf7"
]
\ No newline at end of file
......@@ -2,11 +2,11 @@
"config": [
{
"name": "lastUpdate",
"value": "29 Jul 2021"
"value": "31 Jul 2021"
},
{
"name": "version",
"value": 77
"value": 84
},
{
"name": "versionCalibrationBle",
......@@ -93,7 +93,7 @@
},
{
"name": "app.wallet.testCertificateValidityThresholds",
"value": [48, 72]
"value": [24, 48, 72]
},
{
"name": "app.walletPubKeys",
......@@ -141,7 +141,7 @@
},
{
"name": "app.displayAttestation",
"value": false
"value": true
},
{
"name": "app.push.displayOnSuccess",
......@@ -288,7 +288,7 @@
},
{
"name": "app.wallet.conversionApiVersion",
"value": 1
"value": 2
},
{
"name": "ble.serviceUUID",
......
[
{
"section": "Sources",
"description": "Les données sanitaires proviennent des sources suivantes :\n- les données issues de la base SI-DEP,\n- les données remontées par les établissements de santé participant à SI-VIC et au réseau OSCOUR®,\n- les données issues de la base Vaccin Covid.\n\nToutes ces données sont agrégées et analysées par Santé Publique France (SpF) et mises à disposition sur Data.gouv.fr",
"description": "Health data comes from the following sources:\n- data from the SI-DEP database,\n- data reported by health centers participating in SI-VIC and the OSCOUR® network,\n- data from the Vaccin Covid database.\n\nAll these data are aggregated and analyzed by Santé publique France (SpF) and made available on Data.gouv.fr",
"links": [
{
"label": "Sources sur Data.gouv.fr",
"label": "Sources on Data.gouv.fr",
"url": "https://bonjour.tousanticovid.gouv.fr/app.html#chiffres"
}
]
},
{
"section": "Comment interpréter",
"description": "Depuis le 8 décembre, tous les résultats de tests, RT-PCR ou TAg (test antigénique), entrent dans la production des indicateurs SI-DEP (taux d’incidence, taux de positivité et taux de dépistage). \n\nL’approche épidémiologique de Santé Publique France privilégie des indicateurs (taux d’incidence, de positivité, de dépistage) centrés sur les personnes. Les méthodes de calcul actuelles appliquées par Santé publique France sont les suivantes :\n\n- nombre de personnes testées : calculé sur une période donnée (7 jours par exemple), il correspond au nombre de personnes ayant eu au moins un test pendant cette période et qui n‘ont jamais été testées positives dans les 60 jours précédents ;\n\n- nombre de personnes testées positives : une personne qui présente un test positif soit pour la première fois, soit plus de 60 jours après un précédent test positif sera compté comme un nouveau cas.\n\nDe manière générale, les indicateurs doivent être interprétés avec précaution et dans leur globalité.\n\nPour plus d’information sur l’analyse de la situation sanitaire, veuillez consulter le point épidémiologique hebdomadaire de Santé publique France (SpF) disponible sur santepubliquefrance.fr",
"section": "How to interpret",
"description": "Since December 8 2020, all test results, RT-PCR or TAg (antigen test), enter into the production of SI-DEP indicators (incidence rate, positivity rate and screening rate).\n\nThe epidemiological approach of Santé publique France favors indicators (incidence rate, positivity, screening) focused on people. The current calculation methods applied by Santé publique France are as follows:\n\n- number of people tested: calculated over a given period (7 days for example), it corresponds to the number of people having had at least one test during this period and who have never tested positive in the previous 60 days;\n\n- number of people who tested positive: a person who tests positive either for the first time or more than 60 days after a previous positive test will be counted as a new case.\n\nIn general, the indicators should be interpreted with caution and in their entirety.\n\nFor more information on the analysis of the health situation, please consult the weekly epidemiological point of Santé publique France (SpF) available on santepubliquefrance.fr",
"links": [
{
"label": "Santé publique France",
......
[
{
"section": "Sources",
"description": "Les données sanitaires proviennent des sources suivantes :\n- les données issues de la base SI-DEP,\n- les données remontées par les établissements de santé participant à SI-VIC et au réseau OSCOUR®,\n- les données issues de la base Vaccin Covid.\n\nToutes ces données sont agrégées et analysées par Santé Publique France (SpF) et mises à disposition sur Data.gouv.fr",
"description": "Les données sanitaires proviennent des sources suivantes :\n- les données issues de la base SI-DEP,\n- les données remontées par les établissements de santé participant à SI-VIC et au réseau OSCOUR®,\n- les données issues de la base Vaccin Covid.\n\nToutes ces données sont agrégées et analysées par Santé Publique France (SpF) et mises à disposition sur Data.gouv.fr",
"links": [
{
"label": "Sources sur Data.gouv.fr",
......@@ -11,7 +11,7 @@
},
{
"section": "Comment interpréter",
"description": "Depuis le 8 décembre, tous les résultats de tests, RT-PCR ou TAg (test antigénique), entrent dans la production des indicateurs SI-DEP (taux d’incidence, taux de positivité et taux de dépistage). \n\nL’approche épidémiologique de Santé Publique France privilégie des indicateurs (taux d’incidence, de positivité, de dépistage) centrés sur les personnes. Les méthodes de calcul actuelles appliquées par Santé publique France sont les suivantes :\n\n- nombre de personnes testées : calculé sur une période donnée (7 jours par exemple), il correspond au nombre de personnes ayant eu au moins un test pendant cette période et qui n‘ont jamais été testées positives dans les 60 jours précédents ;\n\n- nombre de personnes testées positives : une personne qui présente un test positif soit pour la première fois, soit plus de 60 jours après un précédent test positif sera compté comme un nouveau cas.\n\nDe manière générale, les indicateurs doivent être interprétés avec précaution et dans leur globalité.\n\nPour plus d’information sur l’analyse de la situation sanitaire, veuillez consulter le point épidémiologique hebdomadaire de Santé publique France (SpF) disponible sur santepubliquefrance.fr",
"description": "Depuis le 8 décembre 2020, tous les résultats de tests, RT-PCR ou TAg (test antigénique), entrent dans la production des indicateurs SI-DEP (taux d’incidence, taux de positivité et taux de dépistage). \n\nL’approche épidémiologique de Santé Publique France privilégie des indicateurs (taux d’incidence, de positivité, de dépistage) centrés sur les personnes. Les méthodes de calcul actuelles appliquées par Santé publique France sont les suivantes :\n\n- nombre de personnes testées : calculé sur une période donnée (7 jours par exemple), il correspond au nombre de personnes ayant eu au moins un test pendant cette période et qui n‘ont jamais été testées positives dans les 60 jours précédents ;\n\n- nombre de personnes testées positives : une personne qui présente un test positif soit pour la première fois, soit plus de 60 jours après un précédent test positif sera compté comme un nouveau cas.\n\nDe manière générale, les indicateurs doivent être interprétés avec précaution et dans leur globalité.\n\nPour plus d’information sur l’analyse de la situation sanitaire, veuillez consulter le point épidémiologique hebdomadaire de Santé publique France (SpF) disponible sur santepubliquefrance.fr",
"links": [
{
"label": "Santé publique France",
......
......@@ -68,7 +68,8 @@ import com.lunabeestudio.stopcovid.extension.isObsolete
import com.lunabeestudio.stopcovid.extension.lastVersionCode
import com.lunabeestudio.stopcovid.manager.AppMaintenanceManager
import com.lunabeestudio.stopcovid.manager.AttestationsManager
import com.lunabeestudio.stopcovid.manager.BlacklistManager
import com.lunabeestudio.stopcovid.manager.Blacklist2DDOCManager
import com.lunabeestudio.stopcovid.manager.BlacklistDCCManager
import com.lunabeestudio.stopcovid.manager.CalibDataSource
import com.lunabeestudio.stopcovid.manager.CertificatesDocumentsManager
import com.lunabeestudio.stopcovid.manager.ConfigDataSource
......@@ -114,6 +115,16 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
override val isolationManager: IsolationManager by lazy { IsolationManager(this, robertManager, secureKeystoreDataSource) }
val certificateRepository: CertificateRepository by lazy {
CertificateRepository(
InGroupeDatasource(
this,
cryptoDataSource,
EnvConstant.Prod.conversionBaseUrl,
)
)
}
private val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
Timber.e(throwable)
}
......@@ -162,8 +173,6 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
private val cryptoDataSource = BouncyCastleCryptoDataSource()
lateinit var certificateRepository: CertificateRepository
private var firstResume = false
private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
......@@ -196,6 +205,8 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
ConfigManager.clearLocal(this)
CalibrationManager.clearLocal(this)
FormManager.clearLocal(this)
BlacklistDCCManager.clearLocal(this)
Blacklist2DDOCManager.clearLocal(this)
secureKeystoreDataSource.configuration = secureKeystoreDataSource.configuration?.apply {
version = 0
}
......@@ -212,16 +223,6 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
}
}
certificateRepository = CertificateRepository(
InGroupeDatasource(
this,
cryptoDataSource,
robertManager,
EnvConstant.Prod.conversionBaseUrl,
),
robertManager,
)
appCoroutineScope.launch {
MoreKeyFiguresManager.initialize(this@StopCovid)
}
......@@ -251,7 +252,10 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
RisksLevelManager.initialize(this@StopCovid)
}
appCoroutineScope.launch {
BlacklistManager.initialize(this@StopCovid)
BlacklistDCCManager.initialize(this@StopCovid)
}
appCoroutineScope.launch {
Blacklist2DDOCManager.initialize(this@StopCovid)
}
appCoroutineScope.launch {
AppMaintenanceManager.initialize(
......@@ -316,7 +320,10 @@ class StopCovid : Application(), LifecycleObserver, RobertApplication, Isolation
RisksLevelManager.onAppForeground(this@StopCovid)
}
appCoroutineScope.launch {
BlacklistManager.onAppForeground(this@StopCovid)
BlacklistDCCManager.onAppForeground(this@StopCovid)
}
appCoroutineScope.launch {
Blacklist2DDOCManager.onAppForeground(this@StopCovid)
}
appCoroutineScope.launch {
FormManager.onAppForeground(this@StopCovid)
......
......@@ -42,8 +42,9 @@ val GreenCertificate.countryCode: String?
else -> null
}
// French Polynesia, New Caledonia, Wallis and Futuna, and Saint Pierre and Miquelon are French territory
val GreenCertificate.isFrench: Boolean
get() = this.countryCode == Locale.FRANCE.country
get() = listOf(Locale.FRANCE.country, "NC", "WF", "PM", "PF").contains(this.countryCode)
val GreenCertificate.vaccineMedicinalProduct: String?
get() = vaccinations?.lastOrNull()?.medicinalProduct?.trim()
......
......@@ -217,7 +217,7 @@ class AttestationsFragment : MainFragment() {
AttestationsFragmentDirections.actionAttestationsFragmentToFullscreenQRCodeFragment(
attestation.qrCode,
BarcodeFormat.QR_CODE,
attestation.qrCodeString
attestation.qrCodeString,
)
)
}
......
......@@ -52,6 +52,7 @@ class FullscreenQRCodeFragment : ForceLightFragment(R.layout.fragment_fullscreen
binding?.topSpace?.isVisible = args.qrCodeFormat == BarcodeFormat.DATA_MATRIX
binding?.formatTextView?.setTextOrHide(formatText())
binding?.textView?.text = args.qrCodeValueDisplayed
binding?.sha256TextView?.setTextOrHide(args.qrCodeSha256)
}
private fun formatText(): String? {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment