mirror of
https://github.com/android-password-store/Android-Password-Store
synced 2025-08-30 13:57:47 +00:00
refactor: rework BiometricAuthenticator
API
Align internal representation with the AndroidX documentation
This commit is contained in:
@@ -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)
|
||||
//
|
||||
|
@@ -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)
|
||||
|
@@ -36,7 +36,8 @@ class LaunchActivity : AppCompatActivity() {
|
||||
startTargetActivity(false)
|
||||
}
|
||||
is Result.Failure,
|
||||
Result.Cancelled -> {
|
||||
Result.CanceledBySystem,
|
||||
Result.CanceledByUser -> {
|
||||
finish()
|
||||
}
|
||||
is Result.Retry -> {}
|
||||
|
@@ -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 -> {
|
||||
|
@@ -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 -> {
|
||||
|
Reference in New Issue
Block a user