diff --git a/app/build.gradle b/app/build.gradle index d0274cdf8b..2762575510 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -181,4 +181,5 @@ dependencies { //Smart LOck authentication implementation "com.google.android.gms:play-services-auth:${rootConfiguration.playServiceAuthVersion}" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${rootConfiguration.kotlinVersion}" + implementation "com.google.android.gms:play-services-safetynet:${rootConfiguration.safetynetVersion}" } diff --git a/app/config.gradle b/app/config.gradle index ebdfdf2fe0..7470a53024 100644 --- a/app/config.gradle +++ b/app/config.gradle @@ -25,4 +25,5 @@ ext { mockitoCoreVersion = '1.10.19' playServiceAuthVersion='16.0.1' shimmerVersion = "0.5.0" + safetynetVersion = "16.0.0" } diff --git a/app/src/main/java/org/fossasia/susi/ai/data/LoginModel.kt b/app/src/main/java/org/fossasia/susi/ai/data/LoginModel.kt index 3766441bfb..cc902839fa 100644 --- a/app/src/main/java/org/fossasia/susi/ai/data/LoginModel.kt +++ b/app/src/main/java/org/fossasia/susi/ai/data/LoginModel.kt @@ -22,10 +22,10 @@ class LoginModel : ILoginModel { private lateinit var authResponseCall: Call private lateinit var userSettingResponseCall: Call - override fun login(email: String, password: String, listener: ILoginModel.OnLoginFinishedListener) { + override fun login(email: String, password: String, recaptcha_response: String, listener: ILoginModel.OnLoginFinishedListener) { authResponseCall = ClientBuilder.susiApi - .login(email, password) + .login(email, password, recaptcha_response) authResponseCall.enqueue(object : Callback { override fun onResponse(call: Call, response: Response) { diff --git a/app/src/main/java/org/fossasia/susi/ai/data/contract/ILoginModel.kt b/app/src/main/java/org/fossasia/susi/ai/data/contract/ILoginModel.kt index dd432acad7..b8e43c5bf1 100644 --- a/app/src/main/java/org/fossasia/susi/ai/data/contract/ILoginModel.kt +++ b/app/src/main/java/org/fossasia/susi/ai/data/contract/ILoginModel.kt @@ -18,7 +18,7 @@ interface ILoginModel { fun onErrorSetting() } - fun login(email: String, password: String, listener: OnLoginFinishedListener) + fun login(email: String, password: String, recaptcha_response: String, listener: OnLoginFinishedListener) fun cancelLogin() diff --git a/app/src/main/java/org/fossasia/susi/ai/login/LoginActivity.kt b/app/src/main/java/org/fossasia/susi/ai/login/LoginActivity.kt index 2bd5447893..42644890ea 100644 --- a/app/src/main/java/org/fossasia/susi/ai/login/LoginActivity.kt +++ b/app/src/main/java/org/fossasia/susi/ai/login/LoginActivity.kt @@ -12,6 +12,9 @@ import android.view.inputmethod.EditorInfo import android.widget.ArrayAdapter import android.widget.Toast import com.google.android.gms.auth.api.credentials.Credential +import com.google.android.gms.safetynet.SafetyNet +import com.google.android.gms.tasks.OnFailureListener +import com.google.android.gms.tasks.OnSuccessListener import kotlinx.android.synthetic.main.activity_login.* import org.fossasia.susi.ai.R import org.fossasia.susi.ai.chat.ChatActivity @@ -22,6 +25,7 @@ import org.fossasia.susi.ai.helper.Utils.hideSoftKeyboard import org.fossasia.susi.ai.login.contract.ILoginPresenter import org.fossasia.susi.ai.login.contract.ILoginView import org.fossasia.susi.ai.signup.SignUpActivity +import timber.log.Timber /** *

The Login activity.

@@ -36,6 +40,7 @@ class LoginActivity : AppCompatActivity(), ILoginView { lateinit var builder: AlertDialog.Builder private lateinit var loginPresenter: ILoginPresenter private lateinit var progressDialog: ProgressDialog + private var recaptcha_response = "" @SuppressLint("InflateParams") override fun onCreate(savedInstanceState: Bundle?) { @@ -166,10 +171,30 @@ class LoginActivity : AppCompatActivity(), ILoginView { private fun logIn() { logIn.setOnClickListener { - startLogin() + if (PrefManager.getBoolean(R.string.login_failed, false)) { + verifyRecaptcha() + } else { + startLogin() + recaptcha_response = "" + } } } + fun verifyRecaptcha() { + SafetyNet.getClient(this).verifyWithRecaptcha(RECAPTCHA_KEY) + .addOnSuccessListener(this, OnSuccessListener { response -> + val userResponseToken = response.tokenResult + if (response.tokenResult?.isNotEmpty() == true) { + Timber.d("User Response Token - " + userResponseToken) + recaptcha_response = userResponseToken + startLogin() + } + }) + .addOnFailureListener(this, OnFailureListener { e -> + Timber.e("Error: " + e) + }) + } + private fun startLogin() { val stringEmail = email.editText?.text.toString() val stringPassword = password.editText?.text.toString() @@ -180,7 +205,7 @@ class LoginActivity : AppCompatActivity(), ILoginView { password.error = null inputUrl.error = null - loginPresenter.login(stringEmail, stringPassword, !customServer.isChecked, stringURL) + loginPresenter.login(stringEmail, stringPassword, recaptcha_response, !customServer.isChecked, stringURL) } private fun cancelLogin() { diff --git a/app/src/main/java/org/fossasia/susi/ai/login/LoginPresenter.kt b/app/src/main/java/org/fossasia/susi/ai/login/LoginPresenter.kt index 1ef0920cbf..4ac5675238 100644 --- a/app/src/main/java/org/fossasia/susi/ai/login/LoginPresenter.kt +++ b/app/src/main/java/org/fossasia/susi/ai/login/LoginPresenter.kt @@ -73,7 +73,7 @@ class LoginPresenter(loginActivity: LoginActivity) : loginView?.skipLogin() } - override fun login(email: String, password: String, isSusiServerSelected: Boolean, url: String) { + override fun login(email: String, password: String, recaptcha_response: String, isSusiServerSelected: Boolean, url: String) { if (email.isEmpty()) { loginView?.invalidCredentials(true, Constant.EMAIL) return @@ -114,7 +114,7 @@ class LoginPresenter(loginActivity: LoginActivity) : this.email = email PrefManager.putString(Constant.EMAIL, this.email) loginView?.showProgress(true) - loginModel.login(email.trim { it <= ' ' }.toLowerCase(), password, this) + loginModel.login(email.trim { it <= ' ' }.toLowerCase(), password, recaptcha_response, this) } override fun cancelLogin() { @@ -147,9 +147,11 @@ class LoginPresenter(loginActivity: LoginActivity) : utilModel.saveEmail(email) utilModel.saveAnonymity(false) loginModel.getUserSetting(this) + PrefManager.putBoolean(R.string.login_failed, false) message = response.body()?.message.toString() } else if (response.code() == 422) { + PrefManager.putBoolean(R.string.login_failed, true) loginView?.showProgress(false) loginView?.onLoginError(utilModel.getString(R.string.invalid_credentials_title), utilModel.getString(R.string.invalid_credentials)) diff --git a/app/src/main/java/org/fossasia/susi/ai/login/contract/ILoginPresenter.kt b/app/src/main/java/org/fossasia/susi/ai/login/contract/ILoginPresenter.kt index 7e5d2e7c24..cee8fd3cdd 100644 --- a/app/src/main/java/org/fossasia/susi/ai/login/contract/ILoginPresenter.kt +++ b/app/src/main/java/org/fossasia/susi/ai/login/contract/ILoginPresenter.kt @@ -11,7 +11,7 @@ interface ILoginPresenter { fun onAttach(loginView: ILoginView) - fun login(email: String, password: String, isSusiServerSelected: Boolean, url: String) + fun login(email: String, password: String, recaptcha_response: String, isSusiServerSelected: Boolean, url: String) fun skipLogin() diff --git a/app/src/main/java/org/fossasia/susi/ai/rest/services/SusiService.kt b/app/src/main/java/org/fossasia/susi/ai/rest/services/SusiService.kt index 9477b6ef85..95824f93e3 100644 --- a/app/src/main/java/org/fossasia/susi/ai/rest/services/SusiService.kt +++ b/app/src/main/java/org/fossasia/susi/ai/rest/services/SusiService.kt @@ -85,7 +85,8 @@ interface SusiService { @POST("/aaa/login.json?type=access-token") fun login( @Query("login") email: String, - @Query("password") password: String + @Query("password") password: String, + @Query("g-recaptcha-response") recaptcha_response: String ): Call /** diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd285be627..5a6df15379 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,6 +12,7 @@ Wallpaper Used Voice before? Hi! How can I help you? + login_failed no_wall