Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Add otp censor (EXPOSUREAPP-14190) #5708

Merged
merged 9 commits into from
Nov 16, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import de.rki.coronawarnapp.bugreporting.censors.presencetracing.TraceLocationCe
import de.rki.coronawarnapp.bugreporting.censors.profile.ProfileCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.CoronaTestCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.CoronaTestCertificateCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.OtpCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.PcrQrCodeCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.PcrTeleTanCensor
import de.rki.coronawarnapp.bugreporting.censors.submission.RACoronaTestCensor
Expand Down Expand Up @@ -163,5 +164,9 @@ object BugReportingSharedModule {
@Binds
@IntoSet
fun familyTestCensor(censor: FamilyTestCensor): BugCensor

@Binds
@IntoSet
fun otpCensor(censor: OtpCensor): BugCensor
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package de.rki.coronawarnapp.bugreporting.censors.submission

import dagger.Reusable
import de.rki.coronawarnapp.bugreporting.censors.BugCensor
import de.rki.coronawarnapp.srs.core.model.SrsOtp
import javax.inject.Inject

@Reusable
class OtpCensor @Inject constructor() : BugCensor {

override suspend fun checkLog(message: String): BugCensor.CensorContainer? {
var container = BugCensor.CensorContainer(message)

otp?.uuid?.let {
container = container.censor(it.toString(), OTP_MASK)
}

otp?.expiresAt?.toString()?.let {
container = container.censor(it, DATE_MASK)
}

return container.nullIfEmpty()
}

companion object {
var otp: SrsOtp? = null
const val OTP_MASK = "########-####-####-####-########"
const val DATE_MASK = "SrsOtp/expiresAt"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey
import de.rki.coronawarnapp.appconfig.AppConfigProvider
import de.rki.coronawarnapp.appconfig.ConfigData
import de.rki.coronawarnapp.appconfig.getSupportedCountries
import de.rki.coronawarnapp.bugreporting.censors.submission.OtpCensor
import de.rki.coronawarnapp.datadonation.safetynet.AttestationContainer
import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation
import de.rki.coronawarnapp.datadonation.safetynet.SafetyNetException
Expand Down Expand Up @@ -55,7 +56,7 @@ class SrsSubmissionRepository @Inject constructor(
Timber.tag(TAG).d("submit(type=%s)", type)
val appConfig = appConfigProvider.getAppConfig()
val nowUtc = timeStamper.nowUTC
var srsOtp = currentOtp(nowUtc)
var srsOtp = currentOtp(nowUtc).also { OtpCensor.otp = it }
val attestResult = attest(appConfig, srsOtp, srsDevSettings.checkLocalPrerequisites())
if (!srsOtp.isValid(nowUtc)) {
Timber.d("Authorize new srsOtp=%s", srsOtp)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.rki.coronawarnapp.bugreporting.censors

import de.rki.coronawarnapp.bugreporting.censors.submission.OtpCensor
import de.rki.coronawarnapp.srs.core.model.SrsOtp
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
import java.time.Instant
import java.util.UUID

class OtpCensorTest : BaseTest() {

private val srsOtp = SrsOtp(
uuid = UUID.fromString("73a373fd-3a7b-49b9-b71c-2ae7a2824760"),
expiresAt = Instant.parse("2023-11-07T12:10:10Z")
)

@BeforeEach
fun setup() {
MockKAnnotations.init(this)
}

@AfterEach
fun teardown() {
OtpCensor.otp = null
}

private fun createInstance() = OtpCensor()

@Test
fun `censoring replaces the otp uuid`() = runTest {
OtpCensor.otp = srsOtp
val instance = createInstance()
val censored = "This is the very secret otp: ${srsOtp.uuid}"
instance.checkLog(censored)!!
.compile()!!.censored shouldBe "This is the very secret otp: ${OtpCensor.OTP_MASK}"
}

@Test
fun `censoring replaces the otp expiration date`() = runTest {
OtpCensor.otp = srsOtp
val instance = createInstance()
val censored = "This is the expiration date of the secret otp: ${srsOtp.expiresAt}"
instance.checkLog(censored)!!
.compile()!!.censored shouldBe "This is the expiration date of the secret otp: ${OtpCensor.DATE_MASK}"
}
}