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

Commit

Permalink
Rki Survey (EXPOSUREAPP-4637) (#2347)
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-cwa authored Feb 15, 2021
1 parent 2180fe1 commit 99a7e5d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class DataDonationTestFragmentViewModel @AssistedInject constructor(
secureRandom.nextBytes(payload)
try {
val result = cwaSafetyNet.attest(object : DeviceAttestation.Request {
override val scenarioPayload: ByteArray = payload
override val scenarioPayload: ByteArray
get() = payload
})
result.requirePass(requirements)
currentValidationInternal.value = requirements to null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ class SurveyException constructor(
) : Exception("$type: $message", cause) {

enum class Type {
ALREADY_PARTICIPATED_THIS_MONTH
ALREADY_PARTICIPATED_THIS_MONTH,
OTP_NOT_AUTHORIZED
}
}

fun SurveyException.errorMsgRes(): Int = when (type) {
SurveyException.Type.ALREADY_PARTICIPATED_THIS_MONTH ->
R.string.datadonation_details_survey_consent_error_ALREADY_PARTICIPATED
SurveyException.Type.OTP_NOT_AUTHORIZED -> R.string.datadonation_details_survey_consent_error_TRY_AGAIN_LATER
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package de.rki.coronawarnapp.datadonation.survey

import de.rki.coronawarnapp.appconfig.AppConfigProvider
import de.rki.coronawarnapp.datadonation.OTPAuthorizationResult
import de.rki.coronawarnapp.datadonation.safetynet.DeviceAttestation
import de.rki.coronawarnapp.datadonation.storage.OTPRepository
import de.rki.coronawarnapp.datadonation.survey.server.SurveyServer
import de.rki.coronawarnapp.util.TimeStamper
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import org.joda.time.Seconds
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class Surveys @Inject constructor(
private val deviceAttestation: DeviceAttestation,
private val appConfigProvider: AppConfigProvider,
private val surveyServer: SurveyServer,
private val oneTimePasswordRepo: OTPRepository,
dispatcherProvider: DispatcherProvider,
private val urlProvider: SurveyUrlProvider
private val urlProvider: SurveyUrlProvider,
private val timeStamper: TimeStamper
) {

val availableSurveys: Flow<Collection<Type>> by lazy {
Expand All @@ -36,18 +38,39 @@ class Surveys @Inject constructor(
}

suspend fun requestDetails(type: Type): Survey {
val config = appConfigProvider.getAppConfig().survey
Timber.v("Requested survey: %s", config)
val now = timeStamper.nowUTC

// TODO adjust for server com
// Just to have a glimpse at the loading spinner
delay(Seconds.THREE.toStandardDuration().millis)
oneTimePasswordRepo.otpAuthorizationResult?.apply {
if (authorized && redeemedAt.toDateTime().monthOfYear() == now.toDateTime().monthOfYear()) {
throw SurveyException(SurveyException.Type.ALREADY_PARTICIPATED_THIS_MONTH)
}
}

// generate OTP
val oneTimePassword = oneTimePasswordRepo.otp ?: oneTimePasswordRepo.generateOTP()

// TODO: generate and authenticate real otp
val otp = UUID.randomUUID()
// check device
val attestationResult = deviceAttestation.attest(object : DeviceAttestation.Request {
override val scenarioPayload: ByteArray
get() = oneTimePassword.payloadForRequest
})
attestationResult.requirePass(config.safetyNetRequirements)

return Survey(
type = Type.HIGH_RISK_ENCOUNTER,
surveyLink = urlProvider.provideUrl(type, otp)
)
// request validation from server
val errorCode = surveyServer.authOTP(oneTimePassword, attestationResult).errorCode
val result = OTPAuthorizationResult(oneTimePassword.uuid, errorCode == null, now)
oneTimePasswordRepo.otpAuthorizationResult = result

if (result.authorized) {
return Survey(
type = Type.HIGH_RISK_ENCOUNTER,
surveyLink = urlProvider.provideUrl(type, oneTimePassword.uuid)
)
} else {
throw SurveyException(SurveyException.Type.OTP_NOT_AUTHORIZED, errorCode)
}
}

fun resetSurvey(type: Type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ class SurveyApiV1Test : BaseTest() {
@Test
fun `server returns 500`(): Unit = runBlocking {
val api = createAPI()
// FIXME Wert vom server abfrägen
"""
{
Expand Down

0 comments on commit 99a7e5d

Please sign in to comment.