diff options
author | Harsh Shandilya <me@msfjarvis.dev> | 2023-07-09 17:22:06 +0530 |
---|---|---|
committer | Harsh Shandilya <me@msfjarvis.dev> | 2023-07-09 17:59:33 +0530 |
commit | fe7aee24d497236d523067536ffdd617c8ce4f05 (patch) | |
tree | 7d1d89a4a529a54aa8dd33b7584982f1db27d89c | |
parent | dfe4b14b4c64006a3515f9b7f1a59ac4f8c00e9e (diff) |
fix: correctly use biometrics result in passphrase cache flow
-rw-r--r-- | app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt | 53 | ||||
-rw-r--r-- | app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt | 35 |
2 files changed, 57 insertions, 31 deletions
diff --git a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt index 8d0cf28a..a7acf11d 100644 --- a/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/autofill/AutofillDecryptActivity.kt @@ -18,6 +18,7 @@ import app.passwordstore.data.passfile.PasswordEntry import app.passwordstore.ui.crypto.BasePGPActivity import app.passwordstore.ui.crypto.PasswordDialog import app.passwordstore.util.auth.BiometricAuthenticator +import app.passwordstore.util.auth.BiometricAuthenticator.Result import app.passwordstore.util.autofill.AutofillPreferences import app.passwordstore.util.autofill.AutofillResponseBuilder import app.passwordstore.util.autofill.DirectoryStructure @@ -70,7 +71,6 @@ class AutofillDecryptActivity : BasePGPActivity() { directoryStructure = AutofillPreferences.directoryStructure(this) logcat { action.toString() } requireKeysExist { - val gpgIdentifiers = getPGPIdentifiers("") ?: return@requireKeysExist if ( features.isEnabled(EnablePGPPassphraseCache) && BiometricAuthenticator.canAuthenticate(this) ) { @@ -78,25 +78,42 @@ class AutofillDecryptActivity : BasePGPActivity() { this, R.string.biometric_prompt_title_gpg_passphrase_cache, ) { authResult -> - if (authResult is BiometricAuthenticator.Result.Success) { - lifecycleScope.launch { - val cachedPassphrase = - passphraseCache.retrieveCachedPassphrase( - this@AutofillDecryptActivity, - gpgIdentifiers.first() - ) - if (cachedPassphrase != null) { - decrypt(File(filePath), clientState, action, cachedPassphrase) - } else { - askPassphrase(filePath, clientState, action) - } - } + decrypt(filePath, clientState, action, authResult) + } + } else { + decrypt(filePath, clientState, action, Result.Cancelled) + } + } + } + + private fun decrypt( + filePath: String, + clientState: Bundle, + action: AutofillAction, + authResult: Result, + ) { + val gpgIdentifiers = getPGPIdentifiers("") ?: return + lifecycleScope.launch(dispatcherProvider.main()) { + when (authResult) { + // Internally handled by the prompt dialog + is Result.Retry -> {} + // If the dialog is dismissed for any reason, prompt for passphrase + is Result.Cancelled, + is Result.Failure, + is Result.HardwareUnavailableOrDisabled -> askPassphrase(filePath, clientState, action) + // + is Result.Success -> { + val cachedPassphrase = + passphraseCache.retrieveCachedPassphrase( + this@AutofillDecryptActivity, + gpgIdentifiers.first() + ) + if (cachedPassphrase != null) { + decryptWithPassphrase(File(filePath), clientState, action, cachedPassphrase) } else { askPassphrase(filePath, clientState, action) } } - } else { - askPassphrase(filePath, clientState, action) } } } @@ -107,7 +124,7 @@ class AutofillDecryptActivity : BasePGPActivity() { withContext(dispatcherProvider.main()) { dialog.password.collectLatest { value -> if (value != null) { - decrypt(File(filePath), clientState, action, value) + decryptWithPassphrase(File(filePath), clientState, action, value) } } } @@ -115,7 +132,7 @@ class AutofillDecryptActivity : BasePGPActivity() { dialog.show(supportFragmentManager, "PASSWORD_DIALOG") } - private suspend fun decrypt( + private suspend fun decryptWithPassphrase( filePath: File, clientState: Bundle, action: AutofillAction, diff --git a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt index ca6cd257..f9646186 100644 --- a/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt +++ b/app/src/main/java/app/passwordstore/ui/crypto/DecryptActivity.kt @@ -18,6 +18,7 @@ import app.passwordstore.data.password.FieldItem import app.passwordstore.databinding.DecryptLayoutBinding import app.passwordstore.ui.adapters.FieldItemAdapter import app.passwordstore.util.auth.BiometricAuthenticator +import app.passwordstore.util.auth.BiometricAuthenticator.Result import app.passwordstore.util.extensions.getString import app.passwordstore.util.extensions.unsafeLazy import app.passwordstore.util.extensions.viewBinding @@ -77,7 +78,7 @@ class DecryptActivity : BasePGPActivity() { requireKeysExist { decrypt(isError = false, authResult) } } } else { - requireKeysExist { decrypt(isError = false, BiometricAuthenticator.Result.Cancelled) } + requireKeysExist { decrypt(isError = false, Result.Cancelled) } } } @@ -149,19 +150,27 @@ class DecryptActivity : BasePGPActivity() { ) } - private fun decrypt(isError: Boolean, authResult: BiometricAuthenticator.Result) { + private fun decrypt(isError: Boolean, authResult: Result) { val gpgIdentifiers = getPGPIdentifiers("") ?: return lifecycleScope.launch(dispatcherProvider.main()) { - if (authResult is BiometricAuthenticator.Result.Success) { - val cachedPassphrase = - passphraseCache.retrieveCachedPassphrase(this@DecryptActivity, gpgIdentifiers.first()) - if (cachedPassphrase != null) { - decryptWithCachedPassphrase(cachedPassphrase, gpgIdentifiers, authResult) - } else { + when (authResult) { + // Internally handled by the prompt dialog + is Result.Retry -> {} + // If the dialog is dismissed for any reason, prompt for passphrase + is Result.Cancelled, + is Result.Failure, + is Result.HardwareUnavailableOrDisabled -> askPassphrase(isError, gpgIdentifiers, authResult) + // + is Result.Success -> { + val cachedPassphrase = + passphraseCache.retrieveCachedPassphrase(this@DecryptActivity, gpgIdentifiers.first()) + if (cachedPassphrase != null) { + decryptWithCachedPassphrase(cachedPassphrase, gpgIdentifiers, authResult) + } else { + askPassphrase(isError, gpgIdentifiers, authResult) + } } - } else { - askPassphrase(isError, gpgIdentifiers, authResult) } } } @@ -169,7 +178,7 @@ class DecryptActivity : BasePGPActivity() { private fun askPassphrase( isError: Boolean, gpgIdentifiers: List<PGPIdentifier>, - authResult: BiometricAuthenticator.Result, + authResult: Result, ) { if (retries < MAX_RETRIES) { retries += 1 @@ -189,7 +198,7 @@ class DecryptActivity : BasePGPActivity() { passwordEntry = entry createPasswordUI(entry) startAutoDismissTimer() - if (authResult is BiometricAuthenticator.Result.Success) { + if (authResult is Result.Success) { passphraseCache.cachePassphrase(this@DecryptActivity, gpgIdentifiers.first(), value) } } @@ -207,7 +216,7 @@ class DecryptActivity : BasePGPActivity() { private suspend fun decryptWithCachedPassphrase( passphrase: String, identifiers: List<PGPIdentifier>, - authResult: BiometricAuthenticator.Result, + authResult: Result, ) { when (val result = decryptWithPassphrase(passphrase, identifiers)) { is Ok -> { |