From 6e9363adc5f1a5c662078e847c7547fb946ebc2a Mon Sep 17 00:00:00 2001 From: Matthias Urhahn <matthias.urhahn@sap.com> Date: Fri, 2 Oct 2020 16:36:14 +0200 Subject: [PATCH] Federation/EUR key-package file support (EXPOSUREAPP-3025) (#1295) * Support for EUR key packages depending on the enabled environment. * Refactor names and fix tests. * Refactoring names and added missing enum key test. * Additional refactoring. Co-authored-by: harambasicluka <64483219+harambasicluka@users.noreply.github.com> --- .../environment/EnvironmentSetup.kt | 28 +++++++---- .../RetrieveDiagnosisInjectionHelper.kt | 4 +- .../RetrieveDiagnosisKeysTransaction.kt | 14 ++++-- .../environment/EnvironmentSetupTest.kt | 50 +++++++++++++------ .../RetrieveDiagnosisKeysTransactionTest.kt | 42 ++++++++++++++-- 5 files changed, 104 insertions(+), 34 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt index 6b4c9ae3e..ea54dfb6d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/environment/EnvironmentSetup.kt @@ -4,10 +4,12 @@ import android.content.Context import androidx.core.content.edit import com.google.gson.GsonBuilder import com.google.gson.JsonObject -import de.rki.coronawarnapp.environment.EnvironmentSetup.ENVKEY.DOWNLOAD -import de.rki.coronawarnapp.environment.EnvironmentSetup.ENVKEY.SUBMISSION -import de.rki.coronawarnapp.environment.EnvironmentSetup.ENVKEY.VERIFICATION -import de.rki.coronawarnapp.environment.EnvironmentSetup.ENVKEY.VERIFICATION_KEYS +import com.google.gson.JsonPrimitive +import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.DOWNLOAD +import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.SUBMISSION +import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.USE_EUR_KEY_PKGS +import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION +import de.rki.coronawarnapp.environment.EnvironmentSetup.EnvKey.VERIFICATION_KEYS import de.rki.coronawarnapp.environment.EnvironmentSetup.Type.Companion.toEnvironmentType import de.rki.coronawarnapp.util.CWADebug import timber.log.Timber @@ -19,7 +21,8 @@ class EnvironmentSetup @Inject constructor( private val context: Context ) { - enum class ENVKEY(val rawKey: String) { + enum class EnvKey(val rawKey: String) { + USE_EUR_KEY_PKGS("USE_EUR_KEY_PKGS"), SUBMISSION("SUBMISSION_CDN_URL"), VERIFICATION("VERIFICATION_CDN_URL"), DOWNLOAD("DOWNLOAD_CDN_URL"), @@ -29,6 +32,7 @@ class EnvironmentSetup @Inject constructor( enum class Type(val rawKey: String) { PRODUCTION("PROD"), INT("INT"), + INT_FED("INT-FED"), DEV("DEV"), WRU("WRU"), WRU_XA("WRU-XA"), // (aka ACME) @@ -71,7 +75,7 @@ class EnvironmentSetup @Inject constructor( } } - private fun getEnvironmentValue(variableKey: ENVKEY): String = run { + private fun getEnvironmentValue(variableKey: EnvKey): JsonPrimitive = run { try { val targetEnvKey = if (environmentJson.has(currentEnvironment.rawKey)) { currentEnvironment.rawKey @@ -82,7 +86,6 @@ class EnvironmentSetup @Inject constructor( environmentJson .getAsJsonObject(targetEnvKey) .getAsJsonPrimitive(variableKey.rawKey) - .asString } catch (e: Exception) { Timber.e(e, "Failed to retrieve endpoint URL for $currentEnvironment:$variableKey") throw IllegalStateException("Failed to setup test environment", e) @@ -90,14 +93,17 @@ class EnvironmentSetup @Inject constructor( }.also { Timber.v("getEndpointUrl(endpoint=%s): %s", variableKey, it) } val submissionCdnUrl: String - get() = getEnvironmentValue(SUBMISSION) + get() = getEnvironmentValue(SUBMISSION).asString val verificationCdnUrl: String - get() = getEnvironmentValue(VERIFICATION) + get() = getEnvironmentValue(VERIFICATION).asString val downloadCdnUrl: String - get() = getEnvironmentValue(DOWNLOAD) + get() = getEnvironmentValue(DOWNLOAD).asString val appConfigVerificationKey: String - get() = getEnvironmentValue(VERIFICATION_KEYS) + get() = getEnvironmentValue(VERIFICATION_KEYS).asString + + val useEuropeKeyPackageFiles: Boolean + get() = getEnvironmentValue(USE_EUR_KEY_PKGS).asBoolean companion object { private const val PKEY_CURRENT_ENVINROMENT = "environment.current" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisInjectionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisInjectionHelper.kt index 38ff9dc34..5d118d7e7 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisInjectionHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisInjectionHelper.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.transaction +import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.util.GoogleAPIVersion import javax.inject.Inject @@ -10,5 +11,6 @@ import javax.inject.Singleton data class RetrieveDiagnosisInjectionHelper @Inject constructor( val transactionScope: TransactionCoroutineScope, val googleAPIVersion: GoogleAPIVersion, - val cwaEnfClient: ENFClient + val cwaEnfClient: ENFClient, + val environmentSetup: EnvironmentSetup ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt index f0618bf05..6b88e9aef 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransaction.kt @@ -23,6 +23,7 @@ import com.google.android.gms.nearby.exposurenotification.ExposureConfiguration import de.rki.coronawarnapp.diagnosiskeys.download.KeyFileDownloader import de.rki.coronawarnapp.diagnosiskeys.server.LocationCode import de.rki.coronawarnapp.diagnosiskeys.storage.KeyCacheRepository +import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.service.applicationconfiguration.ApplicationConfigurationService @@ -139,6 +140,9 @@ object RetrieveDiagnosisKeysTransaction : Transaction() { private val enfClient: ENFClient get() = AppInjector.component.transRetrieveKeysInjection.cwaEnfClient + private val environmentSetup: EnvironmentSetup + get() = AppInjector.component.transRetrieveKeysInjection.environmentSetup + suspend fun startWithConstraints() { val currentDate = DateTime(Instant.now(), DateTimeZone.UTC) val lastFetch = DateTime( @@ -188,9 +192,13 @@ object RetrieveDiagnosisKeysTransaction : Transaction() { // RETRIEVE RISK SCORE PARAMETERS val exposureConfiguration = executeRetrieveRiskScoreParams() - val countries = requestedCountries ?: ApplicationConfigurationService - .asyncRetrieveApplicationConfiguration() - .supportedCountriesList + val countries = if (environmentSetup.useEuropeKeyPackageFiles) { + listOf("EUR") + } else { + requestedCountries ?: ApplicationConfigurationService + .asyncRetrieveApplicationConfiguration() + .supportedCountriesList + } if (CWADebug.isDebugBuildOrMode) { onKeyFilesDownloadStarted?.invoke() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt index ae27016b8..0bedabb73 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/environment/EnvironmentSetupTest.kt @@ -56,15 +56,16 @@ class EnvironmentSetupTest : BaseTest() { every { CWADebug.buildFlavor } returns CWADebug.BuildFlavor.DEVICE_FOR_TESTERS val envSetup = createEnvSetup() - EnvironmentSetup.Type.values().forEach { type -> + EnvironmentSetup.Type.values().forEach { env -> envSetup.apply { - currentEnvironment = type - currentEnvironment shouldBe type + currentEnvironment = env + currentEnvironment shouldBe env - downloadCdnUrl shouldBe "https://download-${type.rawKey}" - submissionCdnUrl shouldBe "https://submission-${type.rawKey}" - verificationCdnUrl shouldBe "https://verification-${type.rawKey}" - appConfigVerificationKey shouldBe "12345678-${type.rawKey}" + useEuropeKeyPackageFiles shouldBe ENVS_WITH_EUR_PKGS.contains(env) + downloadCdnUrl shouldBe "https://download-${env.rawKey}" + submissionCdnUrl shouldBe "https://submission-${env.rawKey}" + verificationCdnUrl shouldBe "https://verification-${env.rawKey}" + appConfigVerificationKey shouldBe "12345678-${env.rawKey}" } } } @@ -106,55 +107,76 @@ class EnvironmentSetupTest : BaseTest() { @Test fun `test enum mapping values`() { EnvironmentSetup.Type.PRODUCTION.rawKey shouldBe "PROD" - EnvironmentSetup.Type.INT.rawKey shouldBe "INT" EnvironmentSetup.Type.DEV.rawKey shouldBe "DEV" + EnvironmentSetup.Type.INT.rawKey shouldBe "INT" + EnvironmentSetup.Type.INT_FED.rawKey shouldBe "INT-FED" EnvironmentSetup.Type.WRU.rawKey shouldBe "WRU" EnvironmentSetup.Type.WRU_XA.rawKey shouldBe "WRU-XA" EnvironmentSetup.Type.WRU_XD.rawKey shouldBe "WRU-XD" - EnvironmentSetup.Type.values().size shouldBe 6 + EnvironmentSetup.Type.values().size shouldBe 7 - EnvironmentSetup.ENVKEY.SUBMISSION.rawKey shouldBe "SUBMISSION_CDN_URL" - EnvironmentSetup.ENVKEY.VERIFICATION.rawKey shouldBe "VERIFICATION_CDN_URL" - EnvironmentSetup.ENVKEY.DOWNLOAD.rawKey shouldBe "DOWNLOAD_CDN_URL" - EnvironmentSetup.ENVKEY.VERIFICATION_KEYS.rawKey shouldBe "PUB_KEYS_SIGNATURE_VERIFICATION" - EnvironmentSetup.ENVKEY.values().size shouldBe 4 + EnvironmentSetup.EnvKey.USE_EUR_KEY_PKGS.rawKey shouldBe "USE_EUR_KEY_PKGS" + EnvironmentSetup.EnvKey.SUBMISSION.rawKey shouldBe "SUBMISSION_CDN_URL" + EnvironmentSetup.EnvKey.VERIFICATION.rawKey shouldBe "VERIFICATION_CDN_URL" + EnvironmentSetup.EnvKey.DOWNLOAD.rawKey shouldBe "DOWNLOAD_CDN_URL" + EnvironmentSetup.EnvKey.VERIFICATION_KEYS.rawKey shouldBe "PUB_KEYS_SIGNATURE_VERIFICATION" + EnvironmentSetup.EnvKey.values().size shouldBe 5 } companion object { private const val BAD_JSON = "{ environmentType: {\n \"SUBMISSION_CDN_U" + private val ENVS_WITH_EUR_PKGS = listOf( + EnvironmentSetup.Type.PRODUCTION, + EnvironmentSetup.Type.INT_FED, + EnvironmentSetup.Type.WRU_XD, + EnvironmentSetup.Type.WRU_XA + ) private const val GOOD_JSON = """ { "PROD": { + "USE_EUR_KEY_PKGS" : true, "SUBMISSION_CDN_URL": "https://submission-PROD", "DOWNLOAD_CDN_URL": "https://download-PROD", "VERIFICATION_CDN_URL": "https://verification-PROD", "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-PROD" }, "DEV": { + "USE_EUR_KEY_PKGS" : false, "SUBMISSION_CDN_URL": "https://submission-DEV", "DOWNLOAD_CDN_URL": "https://download-DEV", "VERIFICATION_CDN_URL": "https://verification-DEV", "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-DEV" }, "INT": { + "USE_EUR_KEY_PKGS" : false, "SUBMISSION_CDN_URL": "https://submission-INT", "DOWNLOAD_CDN_URL": "https://download-INT", "VERIFICATION_CDN_URL": "https://verification-INT", "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-INT" }, + "INT-FED": { + "USE_EUR_KEY_PKGS" : true, + "SUBMISSION_CDN_URL": "https://submission-INT-FED", + "DOWNLOAD_CDN_URL": "https://download-INT-FED", + "VERIFICATION_CDN_URL": "https://verification-INT-FED", + "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-INT-FED" + }, "WRU": { + "USE_EUR_KEY_PKGS" : false, "SUBMISSION_CDN_URL": "https://submission-WRU", "DOWNLOAD_CDN_URL": "https://download-WRU", "VERIFICATION_CDN_URL": "https://verification-WRU", "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-WRU" }, "WRU-XD": { + "USE_EUR_KEY_PKGS" : true, "SUBMISSION_CDN_URL": "https://submission-WRU-XD", "DOWNLOAD_CDN_URL": "https://download-WRU-XD", "VERIFICATION_CDN_URL": "https://verification-WRU-XD", "PUB_KEYS_SIGNATURE_VERIFICATION": "12345678-WRU-XD" }, "WRU-XA": { + "USE_EUR_KEY_PKGS" : true, "SUBMISSION_CDN_URL": "https://submission-WRU-XA", "DOWNLOAD_CDN_URL": "https://download-WRU-XA", "VERIFICATION_CDN_URL": "https://verification-WRU-XA", diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransactionTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransactionTest.kt index 3140d9c86..81581412b 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransactionTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/transaction/RetrieveDiagnosisKeysTransactionTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.transaction +import de.rki.coronawarnapp.environment.EnvironmentSetup import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.service.applicationconfiguration.ApplicationConfigurationService @@ -7,8 +8,8 @@ import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.util.GoogleAPIVersion import de.rki.coronawarnapp.util.di.AppInjector import de.rki.coronawarnapp.util.di.ApplicationComponent -import io.mockk.MockKAnnotations import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations import io.mockk.Runs import io.mockk.clearAllMocks import io.mockk.coEvery @@ -20,10 +21,10 @@ import io.mockk.just import io.mockk.mockk import io.mockk.mockkObject import kotlinx.coroutines.runBlocking +import org.joda.time.LocalDate import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test -import org.joda.time.LocalDate import java.io.File import java.nio.file.Paths import java.util.Date @@ -34,8 +35,8 @@ import java.util.UUID */ class RetrieveDiagnosisKeysTransactionTest { - @MockK - lateinit var mockEnfClient: ENFClient + @MockK lateinit var mockEnfClient: ENFClient + @MockK lateinit var environmentSetup: EnvironmentSetup @BeforeEach fun setUp() { @@ -46,7 +47,8 @@ class RetrieveDiagnosisKeysTransactionTest { every { transRetrieveKeysInjection } returns RetrieveDiagnosisInjectionHelper( TransactionCoroutineScope(), GoogleAPIVersion(), - mockEnfClient + mockEnfClient, + environmentSetup ) } every { AppInjector.component } returns appComponent @@ -63,6 +65,8 @@ class RetrieveDiagnosisKeysTransactionTest { every { LocalData.lastTimeDiagnosisKeysFromServerFetch() } returns Date() every { LocalData.lastTimeDiagnosisKeysFromServerFetch(any()) } just Runs every { LocalData.googleApiToken() } returns UUID.randomUUID().toString() + + every { environmentSetup.useEuropeKeyPackageFiles } returns false } @AfterEach @@ -123,6 +127,34 @@ class RetrieveDiagnosisKeysTransactionTest { } } + @Test + fun `successful submission with EUR`() { + every { environmentSetup.useEuropeKeyPackageFiles } returns true + val file = Paths.get("src", "test", "resources", "keys.bin").toFile() + coEvery { mockEnfClient.provideDiagnosisKeys(listOf(file), any(), any()) } returns true + val requestedCountries = listOf("EUR") + + coEvery { + RetrieveDiagnosisKeysTransaction["executeFetchKeyFilesFromServer"]( + requestedCountries + ) + } returns listOf(file) + + runBlocking { + RetrieveDiagnosisKeysTransaction.start(requestedCountries) + } + + coVerifyOrder { + RetrieveDiagnosisKeysTransaction["executeSetup"]() + RetrieveDiagnosisKeysTransaction["executeRetrieveRiskScoreParams"]() + RetrieveDiagnosisKeysTransaction["executeFetchKeyFilesFromServer"]( + requestedCountries + ) + mockEnfClient.provideDiagnosisKeys(listOf(file), any(), any()) + RetrieveDiagnosisKeysTransaction["executeFetchDateUpdate"](any<Date>()) + } + } + @Test fun `conversion from date to localdate`() { LocalDate.fromDateFields(Date(0)) shouldBe LocalDate.parse("1970-01-01") -- GitLab