refactor: rework BiometricAuthenticator API

Align internal representation with the AndroidX documentation
This commit is contained in:
Harsh Shandilya 2023-12-17 18:36:34 +05:30
parent 38f63c6304
commit d9a7c46ba9
No known key found for this signature in database
5 changed files with 57 additions and 30 deletions

View File

@ -81,7 +81,7 @@ class AutofillDecryptActivity : BasePGPActivity() {
decrypt(filePath, clientState, action, authResult)
}
} else {
decrypt(filePath, clientState, action, Result.Cancelled)
decrypt(filePath, clientState, action, Result.CanceledByUser)
}
}
}
@ -98,7 +98,8 @@ class AutofillDecryptActivity : BasePGPActivity() {
// 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.CanceledBySystem,
is Result.CanceledByUser,
is Result.Failure,
is Result.HardwareUnavailableOrDisabled -> askPassphrase(filePath, clientState, action)
//

View File

@ -78,7 +78,7 @@ class DecryptActivity : BasePGPActivity() {
requireKeysExist { decrypt(isError = false, authResult) }
}
} else {
requireKeysExist { decrypt(isError = false, Result.Cancelled) }
requireKeysExist { decrypt(isError = false, Result.CanceledByUser) }
}
}
@ -158,7 +158,8 @@ class DecryptActivity : BasePGPActivity() {
// 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.CanceledByUser,
is Result.CanceledBySystem,
is Result.Failure,
is Result.HardwareUnavailableOrDisabled ->
askPassphrase(isError, gpgIdentifiers, authResult)

View File

@ -36,7 +36,8 @@ class LaunchActivity : AppCompatActivity() {
startTargetActivity(false)
}
is Result.Failure,
Result.Cancelled -> {
Result.CanceledBySystem,
Result.CanceledByUser -> {
finish()
}
is Result.Retry -> {}

View File

@ -42,8 +42,11 @@ object BiometricAuthenticator {
/** The biometric hardware is unavailable or disabled on a software or hardware level. */
data object HardwareUnavailableOrDisabled : Result()
/** The prompt was dismissed. */
data object Cancelled : Result()
/** The biometric prompt was canceled due to a user-initiated action. */
data object CanceledByUser : Result()
/** The biometric prompt was canceled by the system. */
data object CanceledBySystem : Result()
}
fun canAuthenticate(activity: FragmentActivity): Boolean {
@ -84,32 +87,51 @@ object BiometricAuthenticator {
super.onAuthenticationError(errorCode, errString)
logcat(TAG) { "onAuthenticationError(errorCode=$errorCode, msg=$errString)" }
when (errorCode) {
BiometricPrompt.ERROR_CANCELED,
BiometricPrompt.ERROR_USER_CANCELED,
BiometricPrompt.ERROR_NEGATIVE_BUTTON -> {
callback(Result.Cancelled)
}
BiometricPrompt.ERROR_HW_NOT_PRESENT,
BiometricPrompt.ERROR_HW_UNAVAILABLE,
BiometricPrompt.ERROR_NO_BIOMETRICS,
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> {
callback(Result.HardwareUnavailableOrDisabled)
}
BiometricPrompt.ERROR_LOCKOUT,
BiometricPrompt.ERROR_LOCKOUT_PERMANENT,
BiometricPrompt.ERROR_NO_SPACE,
BiometricPrompt.ERROR_TIMEOUT,
BiometricPrompt.ERROR_VENDOR -> {
/** Keep in sync with [androidx.biometric.BiometricPrompt.AuthenticationError] */
BiometricPrompt.ERROR_HW_UNAVAILABLE -> callback(Result.HardwareUnavailableOrDisabled)
BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> callback(Result.Retry)
BiometricPrompt.ERROR_TIMEOUT ->
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
}
BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> {
callback(Result.Retry)
}
BiometricPrompt.ERROR_NO_SPACE ->
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
BiometricPrompt.ERROR_CANCELED -> callback(Result.CanceledBySystem)
BiometricPrompt.ERROR_LOCKOUT ->
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
BiometricPrompt.ERROR_VENDOR ->
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
BiometricPrompt.ERROR_LOCKOUT_PERMANENT ->
callback(
Result.Failure(
errorCode,
activity.getString(R.string.biometric_auth_error_reason, errString)
)
)
BiometricPrompt.ERROR_USER_CANCELED -> callback(Result.CanceledByUser)
BiometricPrompt.ERROR_NO_BIOMETRICS -> callback(Result.HardwareUnavailableOrDisabled)
BiometricPrompt.ERROR_HW_NOT_PRESENT -> callback(Result.HardwareUnavailableOrDisabled)
BiometricPrompt.ERROR_NEGATIVE_BUTTON -> callback(Result.CanceledByUser)
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL ->
callback(Result.HardwareUnavailableOrDisabled)
// We cover all guaranteed values above, but [errorCode] is still an Int
// at the end of the day so a catch-all else will always be required.
else -> {

View File

@ -12,7 +12,8 @@ import app.passwordstore.data.repo.PasswordRepository
import app.passwordstore.ui.sshkeygen.SshKeyGenActivity
import app.passwordstore.ui.sshkeygen.SshKeyImportActivity
import app.passwordstore.util.auth.BiometricAuthenticator
import app.passwordstore.util.auth.BiometricAuthenticator.Result.Cancelled
import app.passwordstore.util.auth.BiometricAuthenticator.Result.CanceledBySystem
import app.passwordstore.util.auth.BiometricAuthenticator.Result.CanceledByUser
import app.passwordstore.util.auth.BiometricAuthenticator.Result.Failure
import app.passwordstore.util.auth.BiometricAuthenticator.Result.Retry
import app.passwordstore.util.auth.BiometricAuthenticator.Result.Success
@ -183,10 +184,11 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
is Success -> {
registerAuthProviders(SshAuthMethod.SshKey(authActivity))
}
is Cancelled -> {
is CanceledByUser -> {
return Err(SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER))
}
is Failure -> {
is Failure,
is CanceledBySystem -> {
throw IllegalStateException("Biometric authentication failures should be ignored")
}
else -> {