This repository has been archived by the owner on Jun 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 492
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create Check-in confirmation screen (EXPOSUREAPP-5424) (#2536)
* Refactoring - Add basic setup for attendee and organizer - Renaming and re-packing for already implemented screens * Rename * Add check in tab * lint * Connect scan fragment * Navigate to confirm event * Fix import * lint * Add FAB text * Update MDC version * Catch error * Animate transition * Add space * Connect check-in flow * Parse signed event * Import SingleLiveData * Add test * Clean-up * Delete ConfirmCheckInViewModel.kt * Support new deeplink host and requirements * Validate uri * Update LauncherActivityTest.kt * Renaming * Trace location times are in seconds * Delete redundants * Remove destinations from main graph those destinations are part of attendee graph now * Use hard coded string * Verify uri * Pass QRCodeVerifyResult directly * lint
- Loading branch information
Showing
46 changed files
with
569 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...de/rki/coronawarnapp/ui/eventregistration/attendee/checkin/VerifiedTraceLocationKtTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package de.rki.coronawarnapp.ui.eventregistration.attendee.checkin | ||
|
||
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeVerifyResult | ||
import de.rki.coronawarnapp.eventregistration.common.decodeBase32 | ||
import de.rki.coronawarnapp.server.protocols.internal.evreg.SignedEventOuterClass | ||
import io.kotest.assertions.throwables.shouldNotThrowAny | ||
import io.kotest.matchers.shouldBe | ||
import org.joda.time.Instant | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import org.junit.runners.JUnit4 | ||
import testhelpers.BaseTestInstrumentation | ||
|
||
@RunWith(JUnit4::class) | ||
class VerifiedTraceLocationKtTest : BaseTestInstrumentation() { | ||
|
||
@Test | ||
fun testVerifiedTraceLocationMapping() { | ||
shouldNotThrowAny { | ||
val signedTraceLocation = | ||
SignedEventOuterClass.SignedEvent.parseFrom(DECODED_TRACE_LOCATION.decodeBase32().toByteArray()) | ||
val verifiedTraceLocation = | ||
QRCodeVerifyResult(singedTraceLocation = signedTraceLocation).toVerifiedTraceLocation() | ||
verifiedTraceLocation shouldBe VerifiedTraceLocation( | ||
guid = "Yc48RFi/hfyXKlF4DEDs/w==", | ||
start = Instant.parse("1970-02-01T02:39:15.000Z"), | ||
end = Instant.parse("1970-02-01T02:39:51.000Z"), | ||
defaultCheckInLengthInMinutes = 30, | ||
description = "CWA Launch Party" | ||
) | ||
} | ||
} | ||
|
||
companion object { | ||
private const val DECODED_TRACE_LOCATION = | ||
"BIYAUEDBZY6EIWF7QX6JOKSRPAGEB3H7CIIEGV2BEBGGC5LOMNUCAUDBOJ2HSGGTQ6SACIHXQ6SAC" + | ||
"KA6CJEDARQCEEAPHGEZ5JI2K2T422L5U3SMZY5DGCPUZ2RQACAYEJ3HQYMAFFBU2SQCEEAJAUCJSQJ7WDM6" + | ||
"75MCMOD3L2UL7ECJU7TYERH23B746RQTABO3CTI=" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 0 additions & 45 deletions
45
Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/util/UriTest.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
...-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/qrcode/UriValidator.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package de.rki.coronawarnapp.eventregistration.checkins.qrcode | ||
|
||
import java.net.URI | ||
|
||
private const val SCHEME = "https" | ||
private const val AUTHORITY = "e.coronawarn.app" | ||
private const val PATH_PREFIX = "/c1" | ||
private const val SIGNED_TRACE_LOCATION_BASE_32_REGEX = | ||
"^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?\$" | ||
|
||
/** | ||
* Validate that QRCode scanned uri matches the following formulas: | ||
* https://e.coronawarn.app/c1/SIGNED_TRACE_LOCATION_BASE32 | ||
* HTTPS://E.CORONAWARN.APP/C1/SIGNED_TRACE_LOCATION_BASE32 | ||
*/ | ||
fun String.isValidQRCodeUri(): Boolean = | ||
URI.create(this).run { | ||
scheme.equals(SCHEME, true) && | ||
authority.equals(AUTHORITY, true) && | ||
path.substringBeforeLast("/") | ||
.equals(PATH_PREFIX, true) && | ||
path.substringAfterLast("/") | ||
.matches(Regex(SIGNED_TRACE_LOCATION_BASE_32_REGEX)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
.../main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkin/CheckInsFragment.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package de.rki.coronawarnapp.ui.eventregistration.attendee.checkin | ||
|
||
import android.net.Uri | ||
import android.os.Bundle | ||
import androidx.fragment.app.Fragment | ||
import android.view.View | ||
import androidx.core.net.toUri | ||
import androidx.navigation.fragment.FragmentNavigatorExtras | ||
import androidx.navigation.fragment.findNavController | ||
import androidx.navigation.fragment.navArgs | ||
import com.google.android.material.transition.Hold | ||
import de.rki.coronawarnapp.R | ||
import de.rki.coronawarnapp.databinding.FragmentCheckInsBinding | ||
import de.rki.coronawarnapp.util.di.AutoInject | ||
import de.rki.coronawarnapp.util.ui.doNavigate | ||
import de.rki.coronawarnapp.util.ui.observe2 | ||
import de.rki.coronawarnapp.util.ui.viewBindingLazy | ||
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactoryProvider | ||
import de.rki.coronawarnapp.util.viewmodel.cwaViewModels | ||
import javax.inject.Inject | ||
|
||
class CheckInsFragment : Fragment(R.layout.fragment_check_ins), AutoInject { | ||
|
||
@Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory | ||
private val viewModel: CheckInsViewModel by cwaViewModels { viewModelFactory } | ||
private val binding: FragmentCheckInsBinding by viewBindingLazy() | ||
|
||
// Encoded uri is a one-time use data and then cleared | ||
private val uri: String? | ||
get() = navArgs<CheckInsFragmentArgs>().value | ||
.uri | ||
.also { arguments?.clear() } | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
exitTransition = Hold() | ||
} | ||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
|
||
with(binding.scanCheckinQrcodeFab) { | ||
setOnClickListener { | ||
findNavController().navigate( | ||
R.id.action_checkInsFragment_to_scanCheckInQrCodeFragment, | ||
null, | ||
null, | ||
FragmentNavigatorExtras(this to transitionName) | ||
) | ||
} | ||
} | ||
|
||
uri?.let { viewModel.verifyUri(it) } | ||
viewModel.verifyResult.observe2(this) { | ||
doNavigate( | ||
CheckInsFragmentDirections | ||
.actionCheckInsFragmentToConfirmCheckInFragment(it.toVerifiedTraceLocation()) | ||
) | ||
} | ||
} | ||
|
||
companion object { | ||
fun uri(rootUri: String): Uri = "coronawarnapp://check-ins/$rootUri".toUri() | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...rc/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkin/CheckInsModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package de.rki.coronawarnapp.ui.eventregistration.attendee.checkin | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.multibindings.IntoMap | ||
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel | ||
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory | ||
import de.rki.coronawarnapp.util.viewmodel.CWAViewModelKey | ||
|
||
@Module | ||
abstract class CheckInsModule { | ||
@Binds | ||
@IntoMap | ||
@CWAViewModelKey(CheckInsViewModel::class) | ||
abstract fun checkInsFragment( | ||
factory: CheckInsViewModel.Factory | ||
): CWAViewModelFactory<out CWAViewModel> | ||
} |
43 changes: 43 additions & 0 deletions
43
...main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkin/CheckInsViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package de.rki.coronawarnapp.ui.eventregistration.attendee.checkin | ||
|
||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.MutableLiveData | ||
import dagger.assisted.AssistedFactory | ||
import dagger.assisted.AssistedInject | ||
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeVerifier | ||
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeVerifyResult | ||
import de.rki.coronawarnapp.eventregistration.checkins.qrcode.isValidQRCodeUri | ||
import de.rki.coronawarnapp.exception.ExceptionCategory | ||
import de.rki.coronawarnapp.exception.reporting.report | ||
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider | ||
import de.rki.coronawarnapp.util.viewmodel.CWAViewModel | ||
import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory | ||
import timber.log.Timber | ||
|
||
class CheckInsViewModel @AssistedInject constructor( | ||
dispatcherProvider: DispatcherProvider, | ||
private val qrCodeVerifier: QRCodeVerifier | ||
) : CWAViewModel(dispatcherProvider) { | ||
|
||
private val verifyResultData = MutableLiveData<QRCodeVerifyResult>() | ||
val verifyResult: LiveData<QRCodeVerifyResult> = verifyResultData | ||
|
||
fun verifyUri(uri: String) = launch { | ||
try { | ||
Timber.i("uri: $uri") | ||
if (!uri.isValidQRCodeUri()) | ||
throw IllegalArgumentException("Invalid uri: $uri") | ||
|
||
val encodedEvent = uri.substringAfterLast("/") | ||
val verifyResult = qrCodeVerifier.verify(encodedEvent) | ||
Timber.i("verifyResult: $verifyResult") | ||
verifyResultData.postValue(verifyResult) | ||
} catch (e: Exception) { | ||
Timber.d(e, "TraceLocation verification failed") | ||
e.report(ExceptionCategory.INTERNAL) | ||
} | ||
} | ||
|
||
@AssistedFactory | ||
interface Factory : SimpleCWAViewModelFactory<CheckInsViewModel> | ||
} |
Oops, something went wrong.