create captcha module with checking

This commit is contained in:
Rinat Nurmukhametov 2022-03-15 11:46:24 +03:00
parent d907193e41
commit 9a728a9e57
6 changed files with 148 additions and 0 deletions

1
recaptcha/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

12
recaptcha/README.md Normal file
View File

@ -0,0 +1,12 @@
recaptcha
=====
Модуль содержит класс `RecaptchaController` - служит для проверки используемого сервиса (Huawei или Google) и показа диалога с каптчёй
Для использования модуля нужно добавить json файл с сервисами в корневую папку проекта
### Конструктор
`googleRecaptchaKey` - ключ для google recaptcha
`huaweiAppId` - `id` приложения для huawei captcha
`onNewTokenReceived` - callback на успешную проверку каптчи
`processThrowable` - callback на ошибку проверки каптчи

50
recaptcha/build.gradle Normal file
View File

@ -0,0 +1,50 @@
apply from: "../android-configs/lib-config.gradle"
apply plugin: 'com.huawei.agconnect'
dependencies {
implementation project(':kotlin-extensions')
implementation "androidx.core:core"
implementation "androidx.annotation:annotation"
implementation "com.google.android.material:material"
implementation "com.google.android.gms:play-services-safetynet"
implementation "com.google.android.gms:play-services-base"
implementation "com.huawei.hms:safetydetect"
constraints {
implementation("androidx.core:core") {
version {
require '1.0.0'
}
}
implementation("androidx.annotation:annotation") {
version {
require '1.1.0'
}
}
implementation("com.google.android.gms:play-services-safetynet") {
version {
require '17.0.0'
}
}
implementation("com.google.android.gms:play-services-base") {
version {
require '18.0.1'
}
}
implementation("com.huawei.hms:safetydetect") {
version {
require '4.0.3.300'
}
}
implementation("com.google.android.material:material") {
version {
require '1.2.0-rc01'
}
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.touchin.recaptcha">
</manifest>

View File

@ -0,0 +1,60 @@
package ru.touchin.recaptcha
import android.app.Activity
import com.google.android.gms.safetynet.SafetyNet
import com.huawei.hms.support.api.safetydetect.SafetyDetect
import ru.touchin.recaptcha.ServicesUtils.checkGooglePlayServices
import ru.touchin.recaptcha.ServicesUtils.checkHuaweiServices
class RecaptchaController(
private val activity: Activity,
private val googleRecaptchaKey: String? = null,
private val huaweiAppId: String? = null,
private val onNewTokenReceived: (String) -> Unit,
private val processThrowable: (Throwable) -> Unit
) {
fun showRecaptchaAlert() {
when {
checkHuaweiServices(activity) -> showHuaweiCaptcha()
checkGooglePlayServices(activity) -> showGoogleCaptcha()
}
}
private fun showGoogleCaptcha() {
if (googleRecaptchaKey != null) {
SafetyNet.getClient(activity)
.verifyWithRecaptcha(googleRecaptchaKey)
.addOnSuccessListener(activity) { response ->
onServiceTokenResponse(response?.tokenResult)
}
.addOnFailureListener(activity, processThrowable)
}
}
private fun showHuaweiCaptcha() {
if (huaweiAppId != null) {
val huaweiSafetyDetectClient = SafetyDetect.getClient(activity)
huaweiSafetyDetectClient.initUserDetect()
.addOnSuccessListener {
huaweiSafetyDetectClient.userDetection(huaweiAppId)
.addOnSuccessListener { response ->
onServiceTokenResponse(response?.responseToken)
}
.addOnFailureListener(activity, processThrowable)
}
.addOnFailureListener(activity, processThrowable)
}
}
private fun onServiceTokenResponse(newToken: String?) {
if (!newToken.isNullOrBlank()) {
onNewTokenReceived.invoke(newToken)
} else {
processThrowable.invoke(EmptyCaptchaTokenException())
}
}
}
class EmptyCaptchaTokenException : Throwable("Captcha token is empty")

View File

@ -0,0 +1,19 @@
package ru.touchin.recaptcha
import android.content.Context
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.huawei.hms.api.HuaweiApiAvailability
//TODO: in the future move to a module with services
object ServicesUtils {
fun checkHuaweiServices(context: Context): Boolean =
HuaweiApiAvailability.getInstance()
.isHuaweiMobileNoticeAvailable(context) == ConnectionResult.SUCCESS
fun checkGooglePlayServices(context: Context): Boolean =
GoogleApiAvailability.getInstance()
.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
}