From 1c0ef3d6f67e889fbba4782aa034264b80564c81 Mon Sep 17 00:00:00 2001 From: Fabian-K <fabian.kajzar@sap.com> Date: Thu, 4 Jun 2020 17:16:02 +0200 Subject: [PATCH] QR & TeleTan pattern (#160) * teletan - update texts to match lower and upper case - remove similar character exclusion - filter spaces and non-alpha numeric characters * qr code scan: update required pattern * qr code: refactor GUID parsing --- .../service/submission/SubmissionConstants.kt | 4 ++++ .../service/submission/SubmissionService.kt | 21 +++++++++++-------- .../ui/submission/SubmissionTanViewModel.kt | 10 +-------- .../ui/submission/TanConstants.kt | 6 ++++++ .../coronawarnapp/ui/submission/TanInput.kt | 12 +++++++++++ .../ui/viewmodel/SubmissionViewModel.kt | 4 ++-- .../src/main/res/values/integers.xml | 3 --- .../src/main/res/values/strings.xml | 2 +- .../src/main/res/values/styles.xml | 1 - .../submission/SubmissionServiceTest.kt | 20 ++++++++++++------ 10 files changed, 52 insertions(+), 31 deletions(-) create mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt delete mode 100644 Corona-Warn-App/src/main/res/values/integers.xml diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt index 6edc4ce1b..8df09af8f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt @@ -19,4 +19,8 @@ object SubmissionConstants { val REGISTRATION_TOKEN_URL = "$VERSIONED_VERIFICATION_CDN_URL/$REGISTRATION_TOKEN" val TEST_RESULT_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TEST_RESULT" val TAN_REQUEST_URL = "$VERSIONED_VERIFICATION_CDN_URL/$TAN" + + const val MAX_QR_CODE_LENGTH = 150 + const val MAX_GUID_LENGTH = 80 + const val GUID_SEPARATOR = '?' } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt index d8f6e09de..a521fd889 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt @@ -70,17 +70,20 @@ object SubmissionService { ) } - /** - * extracts the GUID from [scanResult]. Returns null if it does not match the required pattern - */ - fun extractGUID(scanResult: String): String? { - val potentialGUID = scanResult.substringAfterLast("?", "") - return if (potentialGUID.isEmpty()) - null - else - potentialGUID + fun containsValidGUID(scanResult: String): Boolean { + if (scanResult.length > SubmissionConstants.MAX_QR_CODE_LENGTH || + scanResult.count { it == SubmissionConstants.GUID_SEPARATOR } != 1 + ) + return false + + val potentialGUID = extractGUID(scanResult) + + return !(potentialGUID.isEmpty() || potentialGUID.length > SubmissionConstants.MAX_GUID_LENGTH) } + fun extractGUID(scanResult: String): String = + scanResult.substringAfterLast(SubmissionConstants.GUID_SEPARATOR, "") + fun storeTestGUID(guid: String) = LocalData.testGUID(guid) fun deleteTestGUID() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt index 22b63d2d9..c18d49a01 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt @@ -10,21 +10,13 @@ class SubmissionTanViewModel : ViewModel() { companion object { private val TAG: String? = SubmissionTanViewModel::class.simpleName - - private const val TAN_LENGTH = 7 - private val EXCLUDED_TAN_CHARS = listOf('0', 'O', 'I', '1') - private val VALID_TAN_CHARS = - ('a'..'z') - .plus('A'..'Z') - .plus('0'..'9') - .minus(EXCLUDED_TAN_CHARS) } val tan = MutableLiveData<String?>(null) val isValidTanFormat = Transformations.map(tan) { - it != null && it.length == TAN_LENGTH && it.all { c -> VALID_TAN_CHARS.contains(c) } + it != null && it.length == TanConstants.MAX_LENGTH } fun storeTeletan() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt new file mode 100644 index 000000000..b6be13be8 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt @@ -0,0 +1,6 @@ +package de.rki.coronawarnapp.ui.submission + +object TanConstants { + const val MAX_LENGTH = 7 + val ALPHA_NUMERIC_CHARS = ('a'..'z').plus('A'..'Z').plus('0'..'9') +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt index d1a251846..70cc48b68 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt @@ -2,6 +2,7 @@ package de.rki.coronawarnapp.ui.submission import android.content.Context import android.os.Handler +import android.text.InputFilter import android.util.AttributeSet import android.view.inputmethod.InputMethodManager import android.widget.FrameLayout @@ -22,6 +23,15 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att private const val KEYBOARD_TRIGGER_DELAY = 100L } + private val whitespaceFilter = + InputFilter { source, _, _, _, _, _ -> source.filter { !it.isWhitespace() } } + private val alphaNumericFilter = InputFilter { source, _, _, _, _, _ -> + source.filter { + TanConstants.ALPHA_NUMERIC_CHARS.contains(it) + } + } + private val lengthFilter = InputFilter.LengthFilter(TanConstants.MAX_LENGTH) + var listener: ((String?) -> Unit)? = null private var tan: String? = null @@ -29,6 +39,8 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att init { inflate(context, R.layout.view_tan_input, this) + tan_input_edittext.filters = arrayOf(whitespaceFilter, alphaNumericFilter, lengthFilter) + // register listener tan_input_edittext.doOnTextChanged { text, _, _, _ -> updateTan(text) } setOnClickListener { showKeyboard() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt index e11b0c577..de2bb9f50 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt @@ -43,8 +43,8 @@ class SubmissionViewModel : ViewModel() { executeRequestWithState(SubmissionRepository::refreshUIState, _uiStateState) fun validateAndStoreTestGUID(scanResult: String) { - val guid = SubmissionService.extractGUID(scanResult) - if (guid != null) { + if (SubmissionService.containsValidGUID(scanResult)) { + val guid = SubmissionService.extractGUID(scanResult) SubmissionService.storeTestGUID(guid) _scanStatus.value = ScanStatus.SUCCESS } else { diff --git a/Corona-Warn-App/src/main/res/values/integers.xml b/Corona-Warn-App/src/main/res/values/integers.xml deleted file mode 100644 index 92946c030..000000000 --- a/Corona-Warn-App/src/main/res/values/integers.xml +++ /dev/null @@ -1,3 +0,0 @@ -<resources> - <integer name="submission_tan_length">7</integer> -</resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index 0c76b91ea..a43284712 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -575,7 +575,7 @@ <!-- XHED: Page title for TAN submission pge --> <string name="submission_tan_title">TAN Eingabe</string> <!-- YTXT: Body text for the tan submission page --> - <string name="submission_tan_body">Die TAN ist 7-stellig und Groß- und Kleinschreibung muss nicht beachtet werden.</string> + <string name="submission_tan_body">Die TAN ist 7-stellig und Groß- und Kleinschreibung muss beachtet werden.\n\nGeben Sie bitte die Ihnen mitgeteilte TAN ein:</string> <!-- XBUT: Submit TAN button --> <string name="submission_tan_button_text">Weiter</string> diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml index d520458a6..285842c94 100644 --- a/Corona-Warn-App/src/main/res/values/styles.xml +++ b/Corona-Warn-App/src/main/res/values/styles.xml @@ -238,7 +238,6 @@ <item name="android:alpha">0</item> <item name="android:background">@null</item> <item name="android:inputType">textPassword</item> - <item name="android:maxLength">@integer/submission_tan_length</item> <item name="android:singleLine">true</item> </style> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt index ed2a111ce..2d2b758bb 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/SubmissionServiceTest.kt @@ -1,25 +1,33 @@ package de.rki.coronawarnapp.service.submission import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.CoreMatchers.nullValue import org.hamcrest.MatcherAssert.assertThat import org.junit.Test class SubmissionServiceTest { @Test - fun extractGUID() { + fun containsValidGUID() { // valid val guid = "123456-12345678-1234-4DA7-B166-B86D85475064" assertThat( - SubmissionService.extractGUID("https://bs-sd.de/covid-19/?$guid"), - equalTo(guid) + SubmissionService.containsValidGUID("https://bs-sd.de/covid-19/?$guid"), + equalTo(true) ) // invalid assertThat( - SubmissionService.extractGUID("https://no-guid-here"), - nullValue() + SubmissionService.containsValidGUID("https://no-guid-here"), + equalTo(false) + ) + } + + @Test + fun extractGUID() { + val guid = "123456-12345678-1234-4DA7-B166-B86D85475064" + assertThat( + SubmissionService.extractGUID("https://bs-sd.de/covid-19/?$guid"), + equalTo(guid) ) } } -- GitLab