From 19ede70c693e6bcfa66e376568900aae2a98ad26 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Wed, 20 Feb 2019 11:32:15 -0600 Subject: [PATCH] Added the option to lock the pattern security lock option when the user has entered it wrong too many times. Once the cooldown timer ends the pattern is re-enabled so the user can try again. --- .../fragments/PatternSecurityLockDialog.kt | 39 ++++++++++++++----- .../bitsybitshareswallet/utils/Constants.kt | 4 +- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/PatternSecurityLockDialog.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/PatternSecurityLockDialog.kt index f8d7667..ed614d3 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/PatternSecurityLockDialog.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/PatternSecurityLockDialog.kt @@ -5,6 +5,7 @@ import android.preference.PreferenceManager import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.content.ContextCompat import cy.agorise.bitsybitshareswallet.R import kotlinx.android.synthetic.main.dialog_pattern_security_lock.* import com.andrognito.patternlockview.PatternLockView @@ -63,16 +64,21 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() { override fun onComplete(pattern: List) { if (currentStep == STEP_SECURITY_LOCK_VERIFY) { - context?.let { - val hashedPattern = CryptoUtils.createSHA256Hash(currentPINPatternSalt + - getStringPattern(pattern)) - if (hashedPattern == currentHashedPINPattern) { - // Pattern is correct, proceed - dismiss() - mCallback?.onPINPatternEntered(actionIdentifier) - } else { + val hashedPattern = CryptoUtils.createSHA256Hash(currentPINPatternSalt + + getStringPattern(pattern)) + if (hashedPattern == currentHashedPINPattern) { + // Pattern is correct, proceed + resetIncorrectSecurityLockAttemptsAndTime() + dismiss() + mCallback?.onPINPatternEntered(actionIdentifier) + } else { + increaseIncorrectSecurityLockAttemptsAndTime() + if (incorrectSecurityLockAttempts < Constants.MAX_INCORRECT_SECURITY_LOCK_ATTEMPTS) { + // Show the error only when the user has not reached the max attempts limit, because if that + // is the case another error is gonna be shown in the setupScreen() method tvMessage.text = getString(R.string.error__wront_pattern) } + setupScreen() } } else if (currentStep == STEP_SECURITY_LOCK_CREATE) { btnClear.visibility = View.VISIBLE @@ -143,6 +149,21 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() { tvSubTitle.text = getString(R.string.msg__enter_your_pattern) btnClear.visibility = View.GONE btnNext.visibility = View.GONE + tvMessage.text = "" + if (incorrectSecurityLockAttempts >= Constants.MAX_INCORRECT_SECURITY_LOCK_ATTEMPTS) { + // User has entered the Pattern incorrectly too many times + val now = System.currentTimeMillis() + if (now <= incorrectSecurityLockTime + Constants.INCORRECT_SECURITY_LOCK_COOLDOWN) { + patternLockView.isInputEnabled = false + startContDownTimer() + return + } else { + resetIncorrectSecurityLockAttemptsAndTime() + } + } + // This is not in an else statement because we also want to enable the EditText and remove the error + // when the cooldown time has been reached + patternLockView.isInputEnabled = true patternLockView.isInStealthMode = true } STEP_SECURITY_LOCK_CREATE -> { @@ -169,7 +190,7 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() { } override fun onTimerSecondPassed(errorMessage: String) { - tvMessage.error = errorMessage + tvMessage.text = errorMessage } override fun onTimerFinished() { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt index 4fa421e..8b28db5 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt @@ -26,11 +26,11 @@ object Constants { const val KEY_SECURITY_LOCK_SELECTED = "key_security_lock_selected" /** Maximum allowed number of incorrect attempts to input the current security lock */ - const val MAX_INCORRECT_SECURITY_LOCK_ATTEMPTS = 1 // TODO 5 + const val MAX_INCORRECT_SECURITY_LOCK_ATTEMPTS = 5 /** Minimum time that the security lock options will be disabled when the user has incorrectly tried to enter * the current security lock option more than MAX_INCORRECT_SECURITY_LOCK_ATTEMPTS times */ - const val INCORRECT_SECURITY_LOCK_COOLDOWN = 2 * 60L * 1000 // 5 seconds TODO 5L * 60 * 1000 // 5 minutes + const val INCORRECT_SECURITY_LOCK_COOLDOWN = 5L * 60 * 1000 // 5 minutes /** Key used to store the consecutive number of times the user has incorrectly tried to enter the * current security lock option */