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
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,29 @@
package de.rki.coronawarnapp.bugreporting.censors.submission

import dagger.Reusable
import de.rki.coronawarnapp.bugreporting.censors.BugCensor
import de.rki.coronawarnapp.srs.core.storage.SrsSubmissionSettings
import kotlinx.coroutines.flow.last
import javax.inject.Inject

@Reusable
class OtpCensor @Inject constructor(
private val srsSubmissionSettings: SrsSubmissionSettings,
) : BugCensor {

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

val otp = srsSubmissionSettings.otp.last()

otp?.uuid?.let {
container = container.censor(it.toString(), "########-####-####-####-########")
}

otp?.expiresAt?.toString()?.let {
container = container.censor(it, "SrsOtp/expiresAt")
}

return container.nullIfEmpty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import de.rki.coronawarnapp.presencetracing.checkins.CheckInRepository
import de.rki.coronawarnapp.presencetracing.storage.repo.TraceLocationRepository
import de.rki.coronawarnapp.profile.storage.ProfileRepository
import de.rki.coronawarnapp.profile.storage.ProfileSettingsDataStore
import de.rki.coronawarnapp.srs.core.storage.SrsSubmissionSettings
import de.rki.coronawarnapp.submission.SubmissionSettings
import io.github.classgraph.ClassGraph
import io.kotest.matchers.collections.shouldContainAll
import io.kotest.matchers.shouldBe
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.flowOf
Expand Down Expand Up @@ -133,4 +135,10 @@ class MockProvider {
fun profileRepository(): ProfileRepository = mockk {
every { profilesFlow } returns flowOf(emptySet())
}

@Singleton
@Provides
fun provideSrsSettingsDataStore(): SrsSubmissionSettings = mockk {
coEvery { getOtp() } returns null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package de.rki.coronawarnapp.bugreporting.censors

import de.rki.coronawarnapp.bugreporting.censors.submission.OtpCensor
import de.rki.coronawarnapp.srs.core.model.SrsOtp
import de.rki.coronawarnapp.srs.core.storage.SrsSubmissionSettings
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
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() {

@MockK lateinit var srsSubmissionSettings: SrsSubmissionSettings

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)

every { srsSubmissionSettings.otp } returns flowOf(srsOtp)
coEvery { srsSubmissionSettings.getOtp() } returns srsOtp
}

private fun createInstance() = OtpCensor(
srsSubmissionSettings
)

@Test
fun `censoring replaces the otp uuid`() = runTest {
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: ########-####-####-####-########"
}

@Test
fun `censoring replaces the otp expiration date`() = runTest {
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: SrsOtp/expiresAt"
}
}