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.

This commit is contained in:
Severiano Jaramillo 2019-02-20 11:32:15 -06:00
parent 2ea32af377
commit 19ede70c69
2 changed files with 32 additions and 11 deletions

View file

@ -5,6 +5,7 @@ import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat
import cy.agorise.bitsybitshareswallet.R import cy.agorise.bitsybitshareswallet.R
import kotlinx.android.synthetic.main.dialog_pattern_security_lock.* import kotlinx.android.synthetic.main.dialog_pattern_security_lock.*
import com.andrognito.patternlockview.PatternLockView import com.andrognito.patternlockview.PatternLockView
@ -63,16 +64,21 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() {
override fun onComplete(pattern: List<PatternLockView.Dot>) { override fun onComplete(pattern: List<PatternLockView.Dot>) {
if (currentStep == STEP_SECURITY_LOCK_VERIFY) { if (currentStep == STEP_SECURITY_LOCK_VERIFY) {
context?.let { val hashedPattern = CryptoUtils.createSHA256Hash(currentPINPatternSalt +
val hashedPattern = CryptoUtils.createSHA256Hash(currentPINPatternSalt + getStringPattern(pattern))
getStringPattern(pattern)) if (hashedPattern == currentHashedPINPattern) {
if (hashedPattern == currentHashedPINPattern) { // Pattern is correct, proceed
// Pattern is correct, proceed resetIncorrectSecurityLockAttemptsAndTime()
dismiss() dismiss()
mCallback?.onPINPatternEntered(actionIdentifier) mCallback?.onPINPatternEntered(actionIdentifier)
} else { } 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) tvMessage.text = getString(R.string.error__wront_pattern)
} }
setupScreen()
} }
} else if (currentStep == STEP_SECURITY_LOCK_CREATE) { } else if (currentStep == STEP_SECURITY_LOCK_CREATE) {
btnClear.visibility = View.VISIBLE btnClear.visibility = View.VISIBLE
@ -143,6 +149,21 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() {
tvSubTitle.text = getString(R.string.msg__enter_your_pattern) tvSubTitle.text = getString(R.string.msg__enter_your_pattern)
btnClear.visibility = View.GONE btnClear.visibility = View.GONE
btnNext.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 patternLockView.isInStealthMode = true
} }
STEP_SECURITY_LOCK_CREATE -> { STEP_SECURITY_LOCK_CREATE -> {
@ -169,7 +190,7 @@ class PatternSecurityLockDialog : BaseSecurityLockDialog() {
} }
override fun onTimerSecondPassed(errorMessage: String) { override fun onTimerSecondPassed(errorMessage: String) {
tvMessage.error = errorMessage tvMessage.text = errorMessage
} }
override fun onTimerFinished() { override fun onTimerFinished() {

View file

@ -26,11 +26,11 @@ object Constants {
const val KEY_SECURITY_LOCK_SELECTED = "key_security_lock_selected" const val KEY_SECURITY_LOCK_SELECTED = "key_security_lock_selected"
/** Maximum allowed number of incorrect attempts to input the current security lock */ /** 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 /** 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 */ * 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 /** Key used to store the consecutive number of times the user has incorrectly tried to enter the
* current security lock option */ * current security lock option */