Last active
October 16, 2018 15:02
-
-
Save gotev/e645067c4fcf0562a16224fcd0394f91 to your computer and use it in GitHub Desktop.
Smart Login Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Setup project first: https://developers.google.com/identity/smartlock-passwords/android/get-started | |
*/ | |
import android.app.Activity.RESULT_OK | |
import android.content.Intent | |
import androidx.appcompat.app.AppCompatActivity | |
import com.google.android.gms.auth.api.credentials.Credential | |
import com.google.android.gms.auth.api.credentials.CredentialRequest | |
import com.google.android.gms.auth.api.credentials.Credentials | |
import com.google.android.gms.common.api.ResolvableApiException | |
import com.google.android.gms.tasks.Task | |
import java.lang.ref.WeakReference | |
class SmartLoginHelper(private val accountType: String, | |
private val retrieveCredentialsRequestCode: Int, | |
private val saveCredentialsRequestCode: Int, | |
passwordLoginSupported: Boolean, | |
delegate: Delegate) { | |
interface Delegate { | |
fun onRetrievedCredentials(success: Boolean, username: String, password: String?) | |
fun onSavedCredentials(success: Boolean) | |
fun onDeletedCredentials(success: Boolean) | |
} | |
private val credentialsRequest = CredentialRequest.Builder() | |
.setPasswordLoginSupported(passwordLoginSupported) | |
.setAccountTypes(accountType) | |
.build() | |
private val delegate = WeakReference(delegate) | |
private fun <T> Task<T>.then(context: AppCompatActivity, | |
onSuccess: (result: T?) -> Unit, | |
onResolvableApiExceptionCode: Int, | |
onError: (exception: Throwable?) -> Unit) { | |
this.addOnCompleteListener { | |
if (it.isSuccessful) { | |
onSuccess(it.result) | |
return@addOnCompleteListener | |
} | |
if (it.exception is ResolvableApiException) { | |
try { | |
(it.exception as ResolvableApiException).startResolutionForResult(context, onResolvableApiExceptionCode) | |
} catch (exc: Throwable) { | |
onError(exc) | |
} | |
return@addOnCompleteListener | |
} | |
onError(it.exception) | |
} | |
} | |
private fun onCredentialsNotRetrieved() { | |
delegate.get()?.onRetrievedCredentials(success = false, username = "", password = null) | |
} | |
fun retrieveSavedCredentials(context: AppCompatActivity) { | |
Credentials | |
.getClient(context) | |
.request(credentialsRequest) | |
.then(context, { | |
val credential = it?.credential | |
if (credential != null && credential.accountType == accountType) { | |
delegate.get()?.onRetrievedCredentials(success = true, username = credential.id, password = credential.password) | |
} else { | |
onCredentialsNotRetrieved() | |
} | |
}, onResolvableApiExceptionCode = retrieveCredentialsRequestCode, onError = { | |
onCredentialsNotRetrieved() | |
}) | |
} | |
fun saveCredentials(context: AppCompatActivity, username: String, password: String) { | |
val credential = Credential.Builder(username) | |
.setAccountType(accountType) | |
.setPassword(password) | |
.build() | |
Credentials | |
.getClient(context) | |
.save(credential) | |
.then(context, { | |
delegate.get()?.onSavedCredentials(false) | |
}, onResolvableApiExceptionCode = saveCredentialsRequestCode, onError = { | |
delegate.get()?.onSavedCredentials(false) | |
}) | |
} | |
fun deleteCredentials(context: AppCompatActivity, username: String) { | |
val credential = Credential.Builder(username) | |
.setAccountType(accountType) | |
.build() | |
Credentials.getClient(context).delete(credential).addOnCompleteListener { task -> | |
delegate.get()?.onDeletedCredentials(task.isSuccessful) | |
} | |
} | |
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { | |
when (requestCode) { | |
retrieveCredentialsRequestCode -> { | |
if (resultCode == RESULT_OK) { | |
val credential = data.getParcelableExtra<Credential>(Credential.EXTRA_KEY) | |
delegate.get()?.onRetrievedCredentials(success = true, username = credential.id, password = credential.password) | |
} else { | |
onCredentialsNotRetrieved() | |
} | |
} | |
saveCredentialsRequestCode -> { | |
delegate.get()?.onSavedCredentials(resultCode == RESULT_OK) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment