Commit 8ed04ad5 authored by aniket's avatar aniket

deals with more edge cases

parent ac5ee24a
......@@ -303,6 +303,7 @@ class LoginPresenter @Inject constructor(
saveAccount(username)
saveToken(token)
registerPushToken()
navigator.toChatList()
} else if (loginType == TYPE_LOGIN_OAUTH) {
navigator.toRegisterUsername(token.userId, token.authToken)
......
......@@ -2,6 +2,7 @@ package chat.rocket.android.authentication.login.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import com.google.android.gms.auth.api.credentials.Credential
interface LoginView : LoadingView, MessageView {
......@@ -223,4 +224,9 @@ interface LoginView : LoadingView, MessageView {
* Alerts the user about a wrong inputted password.
*/
fun alertWrongPassword()
/**
* Save credentials via google smart lock
*/
fun saveSmartLockCredentials(loginCredential: Credential)
}
\ No newline at end of file
......@@ -2,12 +2,15 @@ package chat.rocket.android.authentication.login.ui
import DrawableHelper
import android.app.Activity
import android.app.PendingIntent
import android.content.Intent
import android.content.IntentSender
import android.graphics.PorterDuff
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.text.style.ClickableSpan
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
......@@ -32,9 +35,7 @@ import chat.rocket.android.webview.oauth.ui.INTENT_OAUTH_CREDENTIAL_TOKEN
import chat.rocket.android.webview.oauth.ui.oauthWebViewIntent
import chat.rocket.common.util.ifNull
import com.google.android.gms.auth.api.Auth
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.IdentityProviders
import com.google.android.gms.auth.api.credentials.*
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.Status
......@@ -46,16 +47,9 @@ import javax.inject.Inject
internal const val REQUEST_CODE_FOR_CAS = 1
internal const val REQUEST_CODE_FOR_OAUTH = 2
internal const val MULTIPLE_CREDENTIALS_READ = 3
internal const val NO_CREDENTIALS_EXIST = 4
class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks {
override fun onConnected(p0: Bundle?) {
requestCredentials()
}
override fun onConnectionSuspended(p0: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@Inject
lateinit var presenter: LoginPresenter
private var isOauthViewEnable = false
......@@ -65,6 +59,7 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
private var isGlobalLayoutListenerSetUp = false
private var deepLinkInfo: LoginDeepLinkInfo? = null
private var googleApiClient: GoogleApiClient? = null
private var credentialsToBeSaved: Credential? = null
companion object {
private const val DEEP_LINK_INFO = "DeepLinkInfo"
......@@ -76,6 +71,14 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
}
}
override fun onConnected(p0: Bundle?) {
//add call to the save credentials function here just like in sign up fragment
}
override fun onConnectionSuspended(p0: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidSupportInjection.inject(this)
......@@ -128,17 +131,55 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
} else if (requestCode == MULTIPLE_CREDENTIALS_READ) {
var loginCredentials: Credential = data!!.getParcelableExtra(Credential.EXTRA_KEY)
handleCredential(loginCredentials)
} else if (requestCode == NO_CREDENTIALS_EXIST) {
//use the hints to autofill some info in the sign up or sign in forms
var loginCredentials: Credential = data!!.getParcelableExtra(Credential.EXTRA_KEY)
//pass these info to sign up view to autofill forms
var name = loginCredentials.name
var email = loginCredentials.id
var password = loginCredentials.password
text_username_or_email.setText(email)
text_password.setText(password)
}
}
//cancelled
else if (resultCode == Activity.RESULT_CANCELED) {
}
//create new account to use it as login account (deal with this case carefully, many edge cases)
else if (resultCode == CredentialsApi.ACTIVITY_RESULT_ADD_ACCOUNT) {
//save credentials in this case after user signs up as well as in that case when user signs in
// with a new account other than those saved by smart lock. Also delete and disableAutoSignIn
// need to be implemented. Refer docs.
}
//no hints for user id's exist
else if (resultCode == CredentialsApi.ACTIVITY_RESULT_NO_HINTS_AVAILABLE) {
}
}
override fun onDestroy() {
super.onDestroy()
googleApiClient!!.stopAutoManage(activity!!)
googleApiClient!!.disconnect()
}
private fun buildGoogleApiClient() {
googleApiClient = GoogleApiClient.Builder(context!!)
.enableAutoManage(activity!!, {
Log.d("STATUS", "ERROR: connection to client failed")
})
.addConnectionCallbacks(this)
.addApi(Auth.CREDENTIALS_API)
.build()
}
override fun onStart() {
super.onStart()
requestCredentials()
}
private fun requestCredentials() {
var request: CredentialRequest = CredentialRequest.Builder()
.setPasswordLoginSupported(true)
......@@ -148,19 +189,39 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
Auth.CredentialsApi.request(googleApiClient, request).setResultCallback { credentialRequestResult ->
//hideProgress()
val status = credentialRequestResult.getStatus()
val status = credentialRequestResult.status
if (status.isSuccess) {
// Auto sign-in success
handleCredential(credentialRequestResult.getCredential())
handleCredential(credentialRequestResult.credential)
} else if (status.statusCode == CommonStatusCodes.RESOLUTION_REQUIRED) {
// Getting credential needs to show some UI, start resolution
resolveResult(status, MULTIPLE_CREDENTIALS_READ)
} else if (status.statusCode == CommonStatusCodes.SIGN_IN_REQUIRED) {
//resolveResult(status, NO_CREDENTIALS_EXIST)
//build a dialog for possible account hints
var hintRequest: HintRequest = HintRequest.Builder()
.setHintPickerConfig(CredentialPickerConfig.Builder()
.setShowCancelButton(true)
.build())
.setEmailAddressIdentifierSupported(true)
.setAccountTypes(IdentityProviders.GOOGLE)
.build()
var intent: PendingIntent = Auth.CredentialsApi.getHintPickerIntent(googleApiClient, hintRequest)
try {
startIntentSenderForResult(intent.intentSender, NO_CREDENTIALS_EXIST, null, 0, 0, 0, null)
} catch (e: IntentSender.SendIntentException) {
Log.e("STATUS", "ERROR: Could not start hint picker Intent", e);
}
} else {
Log.d("STATUS", "ERROR: nothing happening")
}
}
}
private fun handleCredential(loginCredentials: Credential) {
if (loginCredentials.accountType == IdentityProviders.GOOGLE) {
if (loginCredentials.accountType == null) {
presenter.authenticateWithUserAndPassword(loginCredentials.id, loginCredentials.password!!)
} else if (loginCredentials.accountType == IdentityProviders.GOOGLE) {
//TODO add SL code for google as custom login method
} else if (loginCredentials.accountType == IdentityProviders.FACEBOOK) {
//TODO add SL code for facebook as custom login method
......@@ -168,8 +229,6 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
//TODO add SL code for twitter as custom login method
} else if (loginCredentials.accountType == IdentityProviders.LINKEDIN) {
//TODO add SL code for linkedin as custom login method
} else {
presenter.authenticateWithUserAndPassword(loginCredentials.id, loginCredentials.password!!)
}
}
......
......@@ -20,6 +20,7 @@ import chat.rocket.core.internal.rest.login
import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.signup
import chat.rocket.core.model.Myself
import com.google.android.gms.auth.api.credentials.Credential
import javax.inject.Inject
class SignupPresenter @Inject constructor(private val view: SignupView,
......@@ -66,6 +67,10 @@ class SignupPresenter @Inject constructor(private val view: SignupView,
localRepository.save(LocalRepository.CURRENT_USERNAME_KEY, me.username)
saveAccount(me)
registerPushToken()
var loginCredentials: Credential = Credential.Builder(email)
.setPassword(password)
.build()
view.saveSmartLockCredentials(loginCredentials)
navigator.toChatList()
} catch (exception: RocketChatException) {
exception.message?.let {
......
......@@ -2,6 +2,7 @@ package chat.rocket.android.authentication.signup.presentation
import chat.rocket.android.core.behaviours.LoadingView
import chat.rocket.android.core.behaviours.MessageView
import com.google.android.gms.auth.api.credentials.Credential
interface SignupView : LoadingView, MessageView {
......@@ -24,4 +25,9 @@ interface SignupView : LoadingView, MessageView {
* Alerts the user about a blank email.
*/
fun alertBlankEmail()
/**
* Save credentials via google smart lock
*/
fun saveSmartLockCredentials(loginCredential: Credential)
}
\ No newline at end of file
package chat.rocket.android.authentication.signup.ui
import DrawableHelper
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.text.style.ClickableSpan
import android.util.Log
import android.view.*
import android.widget.Toast
import chat.rocket.android.R
......@@ -13,12 +16,30 @@ import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.extensions.*
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.credentials.Credential
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.ResolvingResultCallbacks
import com.google.android.gms.common.api.Status
import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_sign_up.*
import javax.inject.Inject
class SignupFragment : Fragment(), SignupView {
@Inject lateinit var presenter: SignupPresenter
internal const val SAVE_CREDENTIALS = 1
class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbacks {
override fun onConnected(p0: Bundle?) {
saveCredentials()
}
override fun onConnectionSuspended(p0: Int) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@Inject
lateinit var presenter: SignupPresenter
private var googleApiClient: GoogleApiClient? = null
private var credentialsToBeSaved: Credential? = null
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
if (KeyboardHelper.isSoftKeyboardShown(relative_layout.rootView)) {
bottom_container.setVisible(false)
......@@ -58,6 +79,12 @@ class SignupFragment : Fragment(), SignupView {
}
}
override fun onDestroy() {
super.onDestroy()
googleApiClient!!.stopAutoManage(activity!!)
googleApiClient!!.disconnect()
}
override fun onDestroyView() {
relative_layout.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
super.onDestroyView()
......@@ -95,6 +122,50 @@ class SignupFragment : Fragment(), SignupView {
}
}
override fun saveSmartLockCredentials(loginCredential: Credential) {
credentialsToBeSaved = loginCredential
googleApiClient = GoogleApiClient.Builder(context!!)
.enableAutoManage(activity!!, {
Log.d("STATUS", "ERROR: connection to client failed")
})
.addConnectionCallbacks(this)
.addApi(Auth.CREDENTIALS_API)
.build()
}
override fun onStart() {
super.onStart()
saveCredentials()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == SAVE_CREDENTIALS) {
if (resultCode == RESULT_OK) {
Toast.makeText(context, "Credentials saved successfully", Toast.LENGTH_SHORT).show()
} else {
Log.e("STATUS", "ERROR: Cancelled by user")
}
}
}
private fun saveCredentials() {
if (credentialsToBeSaved == null) {
return
}
Auth.CredentialsApi.save(googleApiClient, credentialsToBeSaved).setResultCallback(
object : ResolvingResultCallbacks<Status>(activity!!, SAVE_CREDENTIALS) {
override fun onSuccess(status: Status) {
Log.d("STATUS", "save:SUCCESS:$status")
credentialsToBeSaved = null
}
override fun onUnresolvableFailure(status: Status) {
Log.w("STATUS", "save:FAILURE:$status")
credentialsToBeSaved = null
}
})
}
override fun showLoading() {
ui {
enableUserInput(false)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment