From e0fbf2f0e26cf69fc491102852e3d18e515fe8f3 Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Wed, 12 May 2021 14:14:13 +0200 Subject: [PATCH 1/7] Add ktx library module --- build.gradle | 5 +- gradle/wrapper/gradle-wrapper.properties | 2 +- ktx/.gitignore | 1 + ktx/bintray.gradle | 51 +++++++++++++ ktx/build.gradle | 24 ++++++ ktx/src/main/AndroidManifest.xml | 7 ++ .../infinum/goldfinger/ktx/GoldfingerKtx.kt | 75 +++++++++++++++++++ .../goldfinger/ktx/GoldfingerKtxCallback.kt | 28 +++++++ .../goldfinger/ktx/GoldfingerKtxImpl.kt | 72 ++++++++++++++++++ settings.gradle | 2 +- 10 files changed, 264 insertions(+), 3 deletions(-) create mode 100644 ktx/.gitignore create mode 100644 ktx/bintray.gradle create mode 100644 ktx/build.gradle create mode 100644 ktx/src/main/AndroidManifest.xml create mode 100644 ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt create mode 100644 ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt create mode 100644 ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt diff --git a/build.gradle b/build.gradle index 9bf17ff..ce69909 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,8 @@ buildscript { junit : '4.12', mockito : '2.28.2', rxjava : '2.2.12', + kotlin : '1.4.32', + coroutines: '1.4.3' ] repositories { @@ -20,8 +22,9 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.6.2' + classpath 'com.android.tools.build:gradle:4.2.0' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3a7bb1d..3da65bd 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip diff --git a/ktx/.gitignore b/ktx/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/ktx/.gitignore @@ -0,0 +1 @@ +/build diff --git a/ktx/bintray.gradle b/ktx/bintray.gradle new file mode 100644 index 0000000..bda7a89 --- /dev/null +++ b/ktx/bintray.gradle @@ -0,0 +1,51 @@ +apply plugin: 'maven-publish' +apply plugin: 'com.jfrog.bintray' + +publishing { + publications { + Publication(MavenPublication) { + artifact("$buildDir/outputs/aar/ktx-release.aar") + groupId 'co.infinum' + artifact sourcesJar + artifact javadocsJar + artifactId 'goldfinger-ktx' + version versions.goldfinger + + pom.withXml { + def root = asNode() + def dependenciesNode = root.appendNode('dependencies') + + configurations.implementation.allDependencies.each { + def dependencyNode = dependenciesNode.appendNode('dependency') + if (it.name == 'core') { + dependencyNode.appendNode('groupId', 'co.infinum') + dependencyNode.appendNode('artifactId', 'goldfinger') + dependencyNode.appendNode('version', versions.goldfinger) + } else { + dependencyNode.appendNode('groupId', it.group) + dependencyNode.appendNode('artifactId', it.name) + dependencyNode.appendNode('version', it.version) + } + } + } + } + } +} + +bintray { + user = System.getenv('BINTRAY_USER') + key = System.getenv('BINTRAY_API_KEY') + publish = false + publications = ['Publication'] + + pkg { + repo = 'android' + name = 'goldfinger-ktx' + userOrg = 'infinum' + publicDownloadNumbers = true + + version { + name = versions.goldfinger + } + } +} \ No newline at end of file diff --git a/ktx/build.gradle b/ktx/build.gradle new file mode 100644 index 0000000..6c98fd3 --- /dev/null +++ b/ktx/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion sdk.target + + defaultConfig { + minSdkVersion sdk.min + targetSdkVersion sdk.target + versionName versions.goldfinger + } +} + +dependencies { + implementation project(':core') + implementation "androidx.appcompat:appcompat:${versions.appcompat}" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.coroutines}" + + testImplementation "junit:junit:${versions.junit}" + testImplementation "org.mockito:mockito-core:${versions.mockito}" +} + +apply from: '../tasks.gradle' +apply from: 'bintray.gradle' \ No newline at end of file diff --git a/ktx/src/main/AndroidManifest.xml b/ktx/src/main/AndroidManifest.xml new file mode 100644 index 0000000..c1ac4af --- /dev/null +++ b/ktx/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt new file mode 100644 index 0000000..466a474 --- /dev/null +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt @@ -0,0 +1,75 @@ +package co.infinum.goldfinger.ktx + +import android.content.Context +import co.infinum.goldfinger.Goldfinger +import co.infinum.goldfinger.Goldfinger.PromptParams +import co.infinum.goldfinger.crypto.CipherCrypter +import co.infinum.goldfinger.crypto.CipherFactory +import co.infinum.goldfinger.crypto.MacCrypter +import co.infinum.goldfinger.crypto.MacFactory +import co.infinum.goldfinger.crypto.SignatureCrypter +import co.infinum.goldfinger.crypto.SignatureFactory +import kotlinx.coroutines.flow.Flow + +interface GoldfingerKtx { + + fun hasFingerprintHardware(): Boolean + + fun hasEnrolledFingerprint(): Boolean + + fun canAuthenticate(): Boolean + + suspend fun authenticate( + params: PromptParams, + ): Flow + + suspend fun encrypt( + params: PromptParams, + key: String, + value: String, + ): Flow + + suspend fun decrypt( + params: PromptParams, + key: String, + value: String, + ): Flow + + fun cancel() + + class Builder(private val context: Context) { + + private val baseBuilder: Goldfinger.Builder = Goldfinger.Builder(context) + + fun build(): GoldfingerKtx = + GoldfingerKtxImpl(baseBuilder.build()) + + fun cipherCrypter(cipherCrypter: CipherCrypter?): Builder = apply { + baseBuilder.cipherCrypter(cipherCrypter) + } + + fun cipherFactory(cipherFactory: CipherFactory?): Builder = apply { + baseBuilder.cipherFactory(cipherFactory) + } + + fun logEnabled(logEnabled: Boolean): Builder = apply { + baseBuilder.logEnabled(logEnabled) + } + + fun macCrypter(macCrypter: MacCrypter?): Builder = apply { + baseBuilder.macCrypter(macCrypter) + } + + fun macFactory(macFactory: MacFactory?): Builder = apply { + baseBuilder.macFactory(macFactory) + } + + fun signatureCrypter(signatureCrypter: SignatureCrypter?): Builder = apply { + baseBuilder.signatureCrypter(signatureCrypter) + } + + fun signatureFactory(signatureFactory: SignatureFactory?): Builder = apply { + baseBuilder.signatureFactory(signatureFactory) + } + } +} diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt new file mode 100644 index 0000000..05c2dc5 --- /dev/null +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt @@ -0,0 +1,28 @@ +package co.infinum.goldfinger.ktx + +import co.infinum.goldfinger.Goldfinger +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.ProducerScope + +@ExperimentalCoroutinesApi +class GoldfingerKtxCallback( + private val goldfinger: Goldfinger, + private val producerScope: ProducerScope, +) : Goldfinger.Callback { + override fun onResult(result: Goldfinger.Result) { + with(producerScope) { + if (!isClosedForSend) { + channel.offer(result) + if (result.type() == Goldfinger.Type.SUCCESS || result.type() == Goldfinger.Type.ERROR) { + channel.close() + } + } else { + goldfinger.cancel() + } + } + } + + override fun onError(e: Exception) { + producerScope.channel.close(e) + } +} \ No newline at end of file diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt new file mode 100644 index 0000000..581a176 --- /dev/null +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt @@ -0,0 +1,72 @@ +package co.infinum.goldfinger.ktx + +import co.infinum.goldfinger.Goldfinger +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.buffer +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.cancellable + +@ExperimentalCoroutinesApi +class GoldfingerKtxImpl (private val goldfinger: Goldfinger) : GoldfingerKtx { + + private fun inGoldfingerFlow(doWithCallback: (GoldfingerKtxCallback) -> Unit) = + callbackFlow { + doWithCallback( + GoldfingerKtxCallback( + goldfinger, + this, + ) + ) + awaitClose { goldfinger.cancel() } + } + .buffer( + onBufferOverflow = BufferOverflow.DROP_OLDEST, + ) + .cancellable() + + override fun hasFingerprintHardware(): Boolean = goldfinger.hasFingerprintHardware() + + override fun hasEnrolledFingerprint(): Boolean = goldfinger.hasEnrolledFingerprint() + + override fun canAuthenticate(): Boolean = goldfinger.canAuthenticate() + + override suspend fun authenticate(params: Goldfinger.PromptParams): Flow = inGoldfingerFlow { callback -> + goldfinger.authenticate( + params, + callback, + ) + } + + override suspend fun encrypt( + params: Goldfinger.PromptParams, + key: String, + value: String, + ): Flow = inGoldfingerFlow { callback -> + goldfinger.encrypt( + params, + key, + value, + callback, + ) + } + + override suspend fun decrypt( + params: Goldfinger.PromptParams, + key: String, + value: String, + ): Flow = inGoldfingerFlow { callback -> + goldfinger.decrypt( + params, + key, + value, + callback, + ) + } + + override fun cancel() { + goldfinger.cancel() + } +} diff --git a/settings.gradle b/settings.gradle index e741f1f..e6db287 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':core', ':example', ':rx' +include ':core', ':example', ':rx', ':ktx' From 27d247bb10b15d3fbc2d42e3287d194c1407022f Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:21:59 +0200 Subject: [PATCH 2/7] Remove suspend modifier from GoldfingerKtx methods returning Flows --- .../main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt | 6 +++--- .../java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt index 466a474..3cca820 100644 --- a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt @@ -19,17 +19,17 @@ interface GoldfingerKtx { fun canAuthenticate(): Boolean - suspend fun authenticate( + fun authenticate( params: PromptParams, ): Flow - suspend fun encrypt( + fun encrypt( params: PromptParams, key: String, value: String, ): Flow - suspend fun decrypt( + fun decrypt( params: PromptParams, key: String, value: String, diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt index 581a176..aadb000 100644 --- a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt @@ -33,14 +33,14 @@ class GoldfingerKtxImpl (private val goldfinger: Goldfinger) : GoldfingerKtx { override fun canAuthenticate(): Boolean = goldfinger.canAuthenticate() - override suspend fun authenticate(params: Goldfinger.PromptParams): Flow = inGoldfingerFlow { callback -> + override fun authenticate(params: Goldfinger.PromptParams): Flow = inGoldfingerFlow { callback -> goldfinger.authenticate( params, callback, ) } - override suspend fun encrypt( + override fun encrypt( params: Goldfinger.PromptParams, key: String, value: String, @@ -53,7 +53,7 @@ class GoldfingerKtxImpl (private val goldfinger: Goldfinger) : GoldfingerKtx { ) } - override suspend fun decrypt( + override fun decrypt( params: Goldfinger.PromptParams, key: String, value: String, From 2c1bf90ca8eb435f4c78ae550104c0b599754dbc Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:22:53 +0200 Subject: [PATCH 3/7] Remove context as field from GoldfingerKtx.Builder --- ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt index 3cca820..c4319ca 100644 --- a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt @@ -37,7 +37,7 @@ interface GoldfingerKtx { fun cancel() - class Builder(private val context: Context) { + class Builder(context: Context) { private val baseBuilder: Goldfinger.Builder = Goldfinger.Builder(context) From dfa966f71445dbce2e8d4d0163eda56314e66fb6 Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:24:01 +0200 Subject: [PATCH 4/7] Limit Goldfinger Flows' capacity to single item --- .../main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt index aadb000..87ac49d 100644 --- a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.cancellable @ExperimentalCoroutinesApi -class GoldfingerKtxImpl (private val goldfinger: Goldfinger) : GoldfingerKtx { +class GoldfingerKtxImpl(private val goldfinger: Goldfinger) : GoldfingerKtx { private fun inGoldfingerFlow(doWithCallback: (GoldfingerKtxCallback) -> Unit) = callbackFlow { @@ -23,6 +23,7 @@ class GoldfingerKtxImpl (private val goldfinger: Goldfinger) : GoldfingerKtx { awaitClose { goldfinger.cancel() } } .buffer( + capacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST, ) .cancellable() From 9ce521738612227be5b2fc05182682d20aec657c Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:25:07 +0200 Subject: [PATCH 5/7] Update coroutines to 1.5.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ce69909..20e1f0f 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ buildscript { mockito : '2.28.2', rxjava : '2.2.12', kotlin : '1.4.32', - coroutines: '1.4.3' + coroutines: '1.5.0' ] repositories { From 052bcbcf0f913d5160a53ec1745aa2f3670848f6 Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:25:36 +0200 Subject: [PATCH 6/7] Update kotlin to 1.5.10 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 20e1f0f..dbccb12 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { junit : '4.12', mockito : '2.28.2', rxjava : '2.2.12', - kotlin : '1.4.32', + kotlin : '1.5.10', coroutines: '1.5.0' ] From bc293f4904d4978d0e807582040f9e1653a654c2 Mon Sep 17 00:00:00 2001 From: Marko Docevski Date: Mon, 12 Jul 2021 08:26:00 +0200 Subject: [PATCH 7/7] Replace Channel::offer with trySend in GoldfingerKtxCallback onResult --- .../java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt index 05c2dc5..588cdcd 100644 --- a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt +++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt @@ -12,7 +12,7 @@ class GoldfingerKtxCallback( override fun onResult(result: Goldfinger.Result) { with(producerScope) { if (!isClosedForSend) { - channel.offer(result) + channel.trySend(result) if (result.type() == Goldfinger.Type.SUCCESS || result.type() == Goldfinger.Type.ERROR) { channel.close() }