Skip to content
This repository has been archived by the owner on Dec 24, 2022. It is now read-only.

Commit

Permalink
Release 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
afollestad committed Feb 23, 2020
1 parent 17e5c55 commit 84759fd
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 165 deletions.
62 changes: 26 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Assure is a Kotlin library that makes biometric authentication quick and easy.
```gradle
dependencies {
implementation 'com.afollestad.assure:core:0.1.0'
implementation 'com.afollestad.assure:core:0.2.0'
}
```

Expand Down Expand Up @@ -85,12 +85,8 @@ and `Fragment` (from AndroidX). Examples are below.*
```kotlin
val prompt: Prompt = // ...

try {
authenticate(prompt) {
// Do something
}
} catch (e: BiometricErrorException) {
// Handle error with `e.error` and `e.errorMessage`
authenticate(prompt) { error: BiometricErrorException? ->
// If `error` is null, else auth was successful.
}
```

Expand All @@ -102,16 +98,13 @@ val credentials = Credentials("default")
val prompt: Prompt = // ...
val plainTextData: ByteArray = // ...

try {
authenticateForEncrypt(
credentials = credentials,
prompt = prompt
) {
val encryptedData: ByteArray = encrypt(plainTextData)
// Use encryptedData
}
} catch (e: BiometricErrorException) {
// Handle error with `e.error` and `e.errorMessage`
authenticateForEncrypt(
credentials = credentials,
prompt = prompt
) { error: BiometricErrorException? ->
// Use `error.error` and `error.message` if it isn't null, else auth was successful.
val encryptedData: ByteArray = encrypt(plainTextData)
// Use encryptedData
}
```

Expand All @@ -122,16 +115,13 @@ val credentials: Credentials = // ...
val prompt: Prompt = // ...
val encryptedData: ByteArray = // ...

try {
authenticateForDecrypt(
credentials = credentials,
prompt = prompt
) {
val decryptedData: ByteArray = decrypt(encryptedData)
// Use decryptedData
}
} catch (e: BiometricErrorException) {
// Handle error with `e.error` and `e.errorMessage`
authenticateForDecrypt(
credentials = credentials,
prompt = prompt
) { error: BiometricErrorException? ->
// Use `error.error` and `error.message` if it isn't null, else auth was successful.
val decryptedData: ByteArray = decrypt(encryptedData)
// Use decryptedData
}
```

Expand Down Expand Up @@ -209,7 +199,7 @@ interface Decryptor {
```gradle
dependencies {
implementation 'com.afollestad.assure:coroutines:0.1.0'
implementation 'com.afollestad.assure:coroutines:0.2.0'
}
```

Expand Down Expand Up @@ -281,7 +271,7 @@ try {
```gradle
dependencies {
implementation 'com.afollestad.assure:rxjava:0.1.0'
implementation 'com.afollestad.assure:rxjava:0.2.0'
}
```

Expand All @@ -298,11 +288,11 @@ functions \must happen within a `suspend` function or `CoroutineScope`.
import com.afollestad.assure.rxjava.authenticate

val disposable = authenticate(prompt)
.doOnErrorOf<BiometricErrorException> { exception ->
// Handle error with `exception.error` and `exception.errorMessage`
.doOnBiometricError { error ->
// Handle error with `error.error` and `error.errorMessage`
}
.subscribe {
// Do something
// Auth was successful, do something
}

// make sure you manage the subscription
Expand All @@ -320,8 +310,8 @@ val prompt: Prompt = // ...
val plainTextData: ByteArray = // ...

val disposable = authenticateForEncrypt(credentials, prompt)
.doOnErrorOf<BiometricErrorException> { exception ->
// Handle error with `exception.error` and `exception.errorMessage`
.doOnBiometricError { error ->
// Handle error with `error.error` and `error.errorMessage`
}
.map { encryptor ->
encryptor.encrypt(plainTextData)
Expand All @@ -344,8 +334,8 @@ val prompt: Prompt = // ...
val encryptedData: ByteArray = // ...

val disposable = authenticateForDecrypt(credentials, prompt)
.doOnErrorOf<BiometricErrorException> { exception ->
// Handle error with `exception.error` and `exception.errorMessage`
.doOnBiometricError { error ->
// Handle error with `error.error` and `error.errorMessage`
}
.map { decryptor ->
decryptor.decrypt(encryptedData)
Expand Down
5 changes: 3 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
0.1.0
0.2.0

Initial release.
API simplifications. Check out the README. For callback based auth, errors are sent through
the callback rather tha thrown.
2 changes: 1 addition & 1 deletion core/src/main/java/com/afollestad/assure/Activities.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import com.afollestad.assure.crypto.OnEncryptor
*/
fun FragmentActivity.authenticate(
prompt: Prompt,
onAuthentication: () -> Unit
onAuthentication: OnAuthentication
) {
val executor = ContextCompat.getMainExecutor(this)
val callback = createAuthenticateCallback(onAuthentication)
Expand Down
28 changes: 18 additions & 10 deletions core/src/main/java/com/afollestad/assure/Core.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import androidx.lifecycle.OnLifecycleEvent
import com.afollestad.assure.crypto.Credentials
import com.afollestad.assure.crypto.Crypto
import com.afollestad.assure.crypto.CryptoMode
import com.afollestad.assure.crypto.ErrorDecryptor
import com.afollestad.assure.crypto.ErrorEncryptor
import com.afollestad.assure.crypto.OnDecryptor
import com.afollestad.assure.crypto.OnEncryptor
import com.afollestad.assure.crypto.RealDecryptor
Expand All @@ -47,23 +49,25 @@ internal fun BiometricPrompt.cancelAuthOnPause(
lifecycleOwner.lifecycle.addObserver(observer)
}

typealias OnAuthentication = (error: BiometricErrorException?) -> Unit

internal fun createAuthenticateCallback(
callback: () -> Unit
callback: OnAuthentication
): BiometricPrompt.AuthenticationCallback {
return object : BiometricPrompt.AuthenticationCallback() {
override fun onAuthenticationError(
errorCode: Int,
errString: CharSequence
) {
throw BiometricErrorException(errorCode.toBiometricError(), errString.toString())
callback(BiometricErrorException(errorCode.toBiometricError(), errString.toString()))
}

override fun onAuthenticationFailed() {
throw BiometricErrorException(UNKNOWN, "Unknown failure")
callback(BiometricErrorException(UNKNOWN, "Unknown failure"))
}

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
callback()
callback(null)
}
}
}
Expand All @@ -77,18 +81,20 @@ internal fun createEncryptCallback(
errorCode: Int,
errString: CharSequence
) {
throw BiometricErrorException(errorCode.toBiometricError(), errString.toString())
val exception = BiometricErrorException(errorCode.toBiometricError(), errString.toString())
callback(ErrorEncryptor(exception), exception)
}

override fun onAuthenticationFailed() {
throw BiometricErrorException(UNKNOWN, "Unknown failure")
val exception = BiometricErrorException(UNKNOWN, "Unknown failure")
callback(ErrorEncryptor(exception), exception)
}

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
result.cryptoObject?.let {
credentials?.iv = it.cipher?.iv ?: error("Unable to get IV")
}
callback(RealEncryptor(cryptoObject = result.cryptoObject))
callback(RealEncryptor(cryptoObject = result.cryptoObject), null)
}
}
}
Expand All @@ -101,15 +107,17 @@ internal fun createDecryptCallback(
errorCode: Int,
errString: CharSequence
) {
throw BiometricErrorException(errorCode.toBiometricError(), errString.toString())
val exception = BiometricErrorException(errorCode.toBiometricError(), errString.toString())
callback(ErrorDecryptor(exception), exception)
}

override fun onAuthenticationFailed() {
throw BiometricErrorException(UNKNOWN, "Unknown failure")
val exception = BiometricErrorException(UNKNOWN, "Unknown failure")
callback(ErrorDecryptor(exception), exception)
}

override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
callback(RealDecryptor(cryptoObject = result.cryptoObject))
callback(RealDecryptor(cryptoObject = result.cryptoObject), null)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/com/afollestad/assure/Fragments.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import com.afollestad.assure.crypto.OnEncryptor
*/
fun Fragment.authenticate(
prompt: Prompt,
onAuthentication: () -> Unit
onAuthentication: OnAuthentication
) {
val activity = requireActivity()
val executor = ContextCompat.getMainExecutor(activity)
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/com/afollestad/assure/crypto/Decryptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ package com.afollestad.assure.crypto
import android.util.Base64
import androidx.annotation.CheckResult
import androidx.biometric.BiometricPrompt
import com.afollestad.assure.BiometricErrorException
import java.nio.charset.Charset

typealias OnDecryptor = Decryptor.() -> Unit
typealias OnDecryptor = Decryptor.(error: BiometricErrorException?) -> Unit

/**
* A class that can decrypt data.
Expand Down Expand Up @@ -54,6 +55,14 @@ interface Decryptor {
}
}

internal class ErrorDecryptor internal constructor(
private val biometricErrorException: BiometricErrorException
) : Decryptor {
override fun decrypt(data: ByteArray): ByteArray {
throw biometricErrorException
}
}

internal class RealDecryptor internal constructor(
private val cryptoObject: BiometricPrompt.CryptoObject? = null
) : Decryptor {
Expand Down
11 changes: 10 additions & 1 deletion core/src/main/java/com/afollestad/assure/crypto/Encryptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ package com.afollestad.assure.crypto
import android.util.Base64
import androidx.annotation.CheckResult
import androidx.biometric.BiometricPrompt
import com.afollestad.assure.BiometricErrorException
import java.nio.charset.Charset

typealias OnEncryptor = Encryptor.() -> Unit
typealias OnEncryptor = Encryptor.(error: BiometricErrorException?) -> Unit

/**
* A class that can encrypt data.
Expand Down Expand Up @@ -53,6 +54,14 @@ interface Encryptor {
}
}

internal class ErrorEncryptor internal constructor(
private val biometricErrorException: BiometricErrorException
) : Encryptor {
override fun encrypt(data: ByteArray): ByteArray {
throw biometricErrorException
}
}

internal class RealEncryptor internal constructor(
private val cryptoObject: BiometricPrompt.CryptoObject? = null
) : Encryptor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,9 @@ suspend fun FragmentActivity.authenticate(
prompt: Prompt
) {
return suspendCoroutine { continuation ->
try {
authenticate(prompt) {
continuation.resume(Unit)
}
} catch (t: Throwable) {
continuation.resumeWithException(t)
authenticate(prompt) { error ->
error?.let { continuation.resumeWithException(it) }
?: continuation.resume(Unit)
}
}
}
Expand All @@ -67,15 +64,12 @@ suspend fun FragmentActivity.authenticateForEncrypt(
prompt: Prompt
): Encryptor {
return suspendCoroutine { continuation ->
try {
authenticateForEncrypt(
credentials = credentials,
prompt = prompt
) {
continuation.resume(this)
}
} catch (t: Throwable) {
continuation.resumeWithException(t)
authenticateForEncrypt(
credentials = credentials,
prompt = prompt
) { error ->
error?.let { continuation.resumeWithException(it) }
?: continuation.resume(this)
}
}
}
Expand All @@ -95,15 +89,12 @@ suspend fun FragmentActivity.authenticateForDecrypt(
prompt: Prompt
): Decryptor {
return suspendCoroutine { continuation ->
try {
authenticateForDecrypt(
credentials = credentials,
prompt = prompt
) {
continuation.resume(this)
}
} catch (t: Throwable) {
continuation.resumeWithException(t)
authenticateForDecrypt(
credentials = credentials,
prompt = prompt
) { error ->
error?.let { continuation.resumeWithException(it) }
?: continuation.resume(this)
}
}
}
Loading

0 comments on commit 84759fd

Please sign in to comment.