diff options
| author | Harsh Shandilya <me@msfjarvis.dev> | 2021-12-29 16:05:19 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-29 10:35:19 +0000 |
| commit | 4c9413709d58594a6d2c1e2bdbf854ec4a7fc291 (patch) | |
| tree | 927c818c22f0094974a4e0499f335da0260de076 /app/src/main/java/dev/msfjarvis/aps/util | |
| parent | 8b5be3f7857605dd0c152610fbf2fb750f717b67 (diff) | |
| download | HardenedPass-4c9413709d58594a6d2c1e2bdbf854ec4a7fc291.tar.gz HardenedPass-4c9413709d58594a6d2c1e2bdbf854ec4a7fc291.zip | |
Refactor BiometricAuthenticator and add proper support for retries (#1627)
Diffstat (limited to 'app/src/main/java/dev/msfjarvis/aps/util')
| -rw-r--r-- | app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt | 39 | ||||
| -rw-r--r-- | app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt | 9 |
2 files changed, 42 insertions, 6 deletions
diff --git a/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt b/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt index a582337b..50f11b5b 100644 --- a/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt +++ b/app/src/main/java/dev/msfjarvis/aps/util/auth/BiometricAuthenticator.kt @@ -21,10 +21,28 @@ object BiometricAuthenticator { private const val validAuthenticators = Authenticators.DEVICE_CREDENTIAL or Authenticators.BIOMETRIC_WEAK + /** + * Sealed class to wrap [BiometricPrompt]'s [Int]-based return codes into more easily-interpreted + * types. + */ sealed class Result { + + /** Biometric authentication was a success. */ data class Success(val cryptoObject: BiometricPrompt.CryptoObject?) : Result() + + /** Biometric authentication has irreversibly failed. */ data class Failure(val code: Int?, val message: CharSequence) : Result() + + /** + * An incorrect biometric was entered, but the prompt UI is offering the option to retry the + * operation. + */ + object Retry : Result() + + /** The biometric hardware is unavailable or disabled on a software or hardware level. */ object HardwareUnavailableOrDisabled : Result() + + /** The prompt was dismissed. */ object Cancelled : Result() } @@ -56,18 +74,35 @@ object BiometricAuthenticator { BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL -> { Result.HardwareUnavailableOrDisabled } - else -> + BiometricPrompt.ERROR_LOCKOUT, + BiometricPrompt.ERROR_LOCKOUT_PERMANENT, + BiometricPrompt.ERROR_NO_SPACE, + BiometricPrompt.ERROR_TIMEOUT, + BiometricPrompt.ERROR_VENDOR -> { + Result.Failure( + errorCode, + activity.getString(R.string.biometric_auth_error_reason, errString) + ) + } + BiometricPrompt.ERROR_UNABLE_TO_PROCESS -> { + Result.Retry + } + // 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 -> { Result.Failure( errorCode, activity.getString(R.string.biometric_auth_error_reason, errString) ) + } } ) } override fun onAuthenticationFailed() { super.onAuthenticationFailed() - callback(Result.Failure(null, activity.getString(R.string.biometric_auth_error))) + callback(Result.Retry) } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { diff --git a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt index 736b69c2..141de348 100644 --- a/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt +++ b/app/src/main/java/dev/msfjarvis/aps/util/git/operation/GitOperation.kt @@ -22,6 +22,7 @@ import dev.msfjarvis.aps.data.repo.PasswordRepository import dev.msfjarvis.aps.ui.sshkeygen.SshKeyGenActivity import dev.msfjarvis.aps.ui.sshkeygen.SshKeyImportActivity import dev.msfjarvis.aps.util.auth.BiometricAuthenticator +import dev.msfjarvis.aps.util.auth.BiometricAuthenticator.Result.* import dev.msfjarvis.aps.util.git.GitCommandExecutor import dev.msfjarvis.aps.util.git.sshj.ContinuationContainerActivity import dev.msfjarvis.aps.util.git.sshj.SshAuthMethod @@ -172,17 +173,17 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) { BiometricAuthenticator.authenticate( callingActivity, R.string.biometric_prompt_title_ssh_auth - ) { if (it !is BiometricAuthenticator.Result.Failure) cont.resume(it) } + ) { result -> if (result !is Failure) cont.resume(result) } } } when (result) { - is BiometricAuthenticator.Result.Success -> { + is Success -> { registerAuthProviders(SshAuthMethod.SshKey(authActivity)) } - is BiometricAuthenticator.Result.Cancelled -> { + is Cancelled -> { return Err(SSHException(DisconnectReason.AUTH_CANCELLED_BY_USER)) } - is BiometricAuthenticator.Result.Failure -> { + is Failure -> { throw IllegalStateException("Biometric authentication failures should be ignored") } else -> { |
