Skip to content
Snippets Groups Projects
Unverified Commit d9bf515b authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

Disable log-upload in `device` (prod) builds again (DEV) #2580


* Disable log-upload in `device` (prod) builds again ಠ_ಠ

* Typo

Co-authored-by: default avatarharambasicluka <64483219+harambasicluka@users.noreply.github.com>
Co-authored-by: default avatarRalf Gehrer <ralfgehrer@users.noreply.github.com>
parent 3bcda686
No related branches found
No related tags found
No related merge requests found
Showing
with 136 additions and 13 deletions
......@@ -7,6 +7,7 @@ import de.rki.coronawarnapp.appconfig.ConfigData
import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation
import de.rki.coronawarnapp.server.protocols.internal.ppdd.ElsOtp
import de.rki.coronawarnapp.server.protocols.internal.ppdd.ElsOtpRequestAndroid
import de.rki.coronawarnapp.util.CWADebug
import kotlinx.coroutines.flow.first
import org.joda.time.Instant
import timber.log.Timber
......@@ -26,6 +27,11 @@ class LogUploadAuthorizer @Inject constructor(
suspend fun getAuthorizedOTP(otp: UUID = UUID.randomUUID()): LogUploadOtp {
Timber.tag(TAG).d("getAuthorizedOTP() trying to authorize %s", otp)
// TODO ¯\_(ツ)_/¯
if (!CWADebug.isDeviceForTestersBuild) {
throw UnsupportedOperationException()
}
val elsOtp = ElsOtp.ELSOneTimePassword.newBuilder().apply {
setOtp(otp.toString())
}.build()
......
......@@ -6,6 +6,12 @@ import de.rki.coronawarnapp.BuildConfig
@Suppress("MayBeConstant")
object BuildConfigWrap {
val DEBUG: Boolean = BuildConfig.DEBUG
val FLAVOR: String = BuildConfig.FLAVOR
val BUILD_TYPE: String = BuildConfig.BUILD_TYPE
val GIT_COMMIT_SHORT_HASH: String = BuildConfig.GIT_COMMIT_SHORT_HASH
val ENVIRONMENT_JSONDATA = BuildConfig.ENVIRONMENT_JSONDATA
val ENVIRONMENT_TYPE_DEFAULT = BuildConfig.ENVIRONMENT_TYPE_DEFAULT
......
......@@ -57,7 +57,7 @@ class InformationFragment : Fragment(R.layout.fragment_information), AutoInject
setButtonOnClickListener()
setAccessibilityDelegate()
// TODO Hidden until further clarification regarding release schedule is available
// TODO ¯\_(ツ)_/¯
binding.informationDebuglog.rootLayout.isGone = !CWADebug.isDeviceForTestersBuild
}
......
......@@ -4,14 +4,17 @@ import android.annotation.SuppressLint
import android.app.Application
import android.os.Build
import androidx.annotation.VisibleForTesting
import de.rki.coronawarnapp.BuildConfig
import de.rki.coronawarnapp.bugreporting.debuglog.DebugLogger
import de.rki.coronawarnapp.environment.BuildConfigWrap
import de.rki.coronawarnapp.util.debug.UncaughtExceptionLogger
import de.rki.coronawarnapp.util.di.ApplicationComponent
import timber.log.Timber
object CWADebug {
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
var debugLoggerFactory: (Application) -> DebugLogger = { DebugLogger(context = it) }
@SuppressLint("StaticFieldLeak")
lateinit var debugLogger: DebugLogger
......@@ -24,15 +27,19 @@ object CWADebug {
setupExceptionHandler()
debugLogger = DebugLogger(context = application).also {
it.init()
debugLogger = debugLoggerFactory(application).also {
// TODO Disabled until all parties are satisfied, search for ¯\_(ツ)_/¯
if (isDeviceForTestersBuild) it.init()
}
logDeviceInfos()
}
fun initAfterInjection(component: ApplicationComponent) {
debugLogger.setInjectionIsReady(component)
// TODO ¯\_(ツ)_/¯
if (isDeviceForTestersBuild) {
debugLogger.setInjectionIsReady(component)
}
}
val isLogging: Boolean
......@@ -42,12 +49,13 @@ object CWADebug {
}
val isDebugBuildOrMode: Boolean
get() = BuildConfig.DEBUG || buildFlavor == BuildFlavor.DEVICE_FOR_TESTERS
get() = BuildConfigWrap.DEBUG || buildFlavor == BuildFlavor.DEVICE_FOR_TESTERS
val buildFlavor: BuildFlavor
get() = BuildFlavor.values().single { it.rawValue == BuildConfig.FLAVOR }
get() = BuildFlavor.values().single { it.rawValue == BuildConfigWrap.FLAVOR }
val isDeviceForTestersBuild: Boolean = buildFlavor == BuildFlavor.DEVICE_FOR_TESTERS
val isDeviceForTestersBuild: Boolean
get() = buildFlavor == BuildFlavor.DEVICE_FOR_TESTERS
enum class BuildFlavor(val rawValue: String) {
DEVICE("device"),
......@@ -64,8 +72,8 @@ object CWADebug {
}
fun logDeviceInfos() {
Timber.i("CWA version: %s (%s)", BuildConfig.VERSION_CODE, BuildConfig.GIT_COMMIT_SHORT_HASH)
Timber.i("CWA flavor: %s (%s)", BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE)
Timber.i("CWA version: %s (%s)", BuildConfigWrap.VERSION_CODE, BuildConfigWrap.GIT_COMMIT_SHORT_HASH)
Timber.i("CWA flavor: %s (%s)", BuildConfigWrap.FLAVOR, BuildConfigWrap.BUILD_TYPE)
Timber.i("Build.FINGERPRINT: %s", Build.FINGERPRINT)
}
......
......@@ -13,9 +13,13 @@ class UncaughtExceptionLogger(
override fun uncaughtException(thread: Thread, error: Throwable) {
Timber.tag(thread.name).e(error, "Uncaught exception!")
if (CWADebug.isLogging) {
// Make sure this crash is written before killing the app.
Thread.sleep(1500)
try {
if (CWADebug.isLogging) {
// Make sure this crash is written before killing the app.
Thread.sleep(1500)
}
} catch (e: Exception) {
Timber.w("Couldn't delay exception for debug logger.")
}
wrappedHandler?.uncaughtException(thread, error)
}
......
......@@ -6,6 +6,8 @@ import de.rki.coronawarnapp.appconfig.LogUploadConfig
import de.rki.coronawarnapp.appconfig.SafetyNetRequirements
import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation
import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpacAndroid
import de.rki.coronawarnapp.util.CWADebug
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.Runs
......@@ -13,6 +15,7 @@ import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockkObject
import io.mockk.slot
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runBlockingTest
......@@ -46,6 +49,9 @@ class LogUploadAuthorizerTest : BaseIOTest() {
fun setup() {
MockKAnnotations.init(this)
mockkObject(CWADebug)
every { CWADebug.isDeviceForTestersBuild } returns true
every { configData.logUpload } returns logUploadConfig
every { logUploadConfig.safetyNetRequirements } returns safetyNetRequirements
......@@ -82,4 +88,16 @@ class LogUploadAuthorizerTest : BaseIOTest() {
attestationRequestSlot.captured.configData shouldBe configData
attestationRequestSlot.captured.checkDeviceTime shouldBe false
}
@Test
fun `upload is not possible on prod builds`() = runBlockingTest {
every { CWADebug.isDeviceForTestersBuild } returns false
val expectedOtp = UUID.fromString("15cff19f-af26-41bc-94f2-c1a65075e894")
val instance = createInstance()
shouldThrow<UnsupportedOperationException> {
instance.getAuthorizedOTP(otp = expectedOtp)
}
}
}
......@@ -4,9 +4,12 @@ import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository
import de.rki.coronawarnapp.ui.Country
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.verify
import kotlinx.coroutines.flow.flowOf
import org.junit.jupiter.api.BeforeEach
......@@ -25,6 +28,7 @@ class InteroperabilityConfigurationFragmentViewModelTest {
fun setupFreshViewModel() {
MockKAnnotations.init(this)
coEvery { interoperabilityRepository.refreshCountries() } just Runs
every { interoperabilityRepository.countryList } returns flowOf(Country.values().toList())
}
......
package de.rki.coronawarnapp.util
import android.app.Application
import de.rki.coronawarnapp.bugreporting.debuglog.DebugLogger
import de.rki.coronawarnapp.environment.BuildConfigWrap
import de.rki.coronawarnapp.util.di.ApplicationComponent
import io.kotest.matchers.shouldBe
import io.mockk.Called
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.verify
import io.mockk.verifySequence
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
import java.io.File
class CWADebugTest : BaseTest() {
@MockK lateinit var application: Application
@MockK lateinit var appComponent: ApplicationComponent
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
every { application.cacheDir } returns File("cache")
mockkObject(BuildConfigWrap)
every { BuildConfigWrap.FLAVOR } returns "device"
}
@Test
fun `flavor check`() {
CWADebug.isDeviceForTestersBuild shouldBe false
every { BuildConfigWrap.FLAVOR } returns "deviceForTesters"
CWADebug.isDeviceForTestersBuild shouldBe true
CWADebug.buildFlavor shouldBe CWADebug.BuildFlavor.DEVICE_FOR_TESTERS
every { BuildConfigWrap.FLAVOR } returns "device"
CWADebug.buildFlavor shouldBe CWADebug.BuildFlavor.DEVICE
CWADebug.isDeviceForTestersBuild shouldBe false
}
@Test
fun `logging is only initialized on tester builds`() {
val debugLogger: DebugLogger = mockk()
CWADebug.debugLoggerFactory = { debugLogger }
CWADebug.init(application)
CWADebug.initAfterInjection(appComponent)
verify { debugLogger wasNot Called }
}
@Test
fun `logging is initialized on deviceForTester builds`() {
every { BuildConfigWrap.FLAVOR } returns "deviceForTesters"
val debugLogger = mockk<DebugLogger>().apply {
every { init() } just Runs
every { setInjectionIsReady(appComponent) } just Runs
}
CWADebug.debugLoggerFactory = { debugLogger }
CWADebug.init(application)
CWADebug.initAfterInjection(appComponent)
verifySequence {
debugLogger.init()
debugLogger.setInjectionIsReady(appComponent)
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment