Commit e528cdf2 authored by aniket's avatar aniket

deals with all email and password cases

parent 8ed04ad5
...@@ -17,6 +17,7 @@ import chat.rocket.common.model.Token ...@@ -17,6 +17,7 @@ import chat.rocket.common.model.Token
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.* import chat.rocket.core.internal.rest.*
import com.google.android.gms.auth.api.credentials.Credential
import kotlinx.coroutines.experimental.delay import kotlinx.coroutines.experimental.delay
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
...@@ -303,7 +304,10 @@ class LoginPresenter @Inject constructor( ...@@ -303,7 +304,10 @@ class LoginPresenter @Inject constructor(
saveAccount(username) saveAccount(username)
saveToken(token) saveToken(token)
registerPushToken() registerPushToken()
var loginCredentials: Credential = Credential.Builder(usernameOrEmail)
.setPassword(password)
.build()
view.saveSmartLockCredentials(loginCredentials)
navigator.toChatList() navigator.toChatList()
} else if (loginType == TYPE_LOGIN_OAUTH) { } else if (loginType == TYPE_LOGIN_OAUTH) {
navigator.toRegisterUsername(token.userId, token.authToken) navigator.toRegisterUsername(token.userId, token.authToken)
......
...@@ -228,5 +228,5 @@ interface LoginView : LoadingView, MessageView { ...@@ -228,5 +228,5 @@ interface LoginView : LoadingView, MessageView {
/** /**
* Save credentials via google smart lock * Save credentials via google smart lock
*/ */
fun saveSmartLockCredentials(loginCredential: Credential) fun saveSmartLockCredentials(loginCredential: Credential?)
} }
\ No newline at end of file
...@@ -15,10 +15,7 @@ import android.view.LayoutInflater ...@@ -15,10 +15,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.widget.Button import android.widget.*
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.ScrollView
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.postDelayed import androidx.core.view.postDelayed
import chat.rocket.android.R import chat.rocket.android.R
...@@ -38,6 +35,7 @@ import com.google.android.gms.auth.api.Auth ...@@ -38,6 +35,7 @@ import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.credentials.* import com.google.android.gms.auth.api.credentials.*
import com.google.android.gms.common.api.CommonStatusCodes import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.GoogleApiClient 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 com.google.android.gms.common.api.Status
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_authentication_log_in.* import kotlinx.android.synthetic.main.fragment_authentication_log_in.*
...@@ -48,6 +46,9 @@ internal const val REQUEST_CODE_FOR_CAS = 1 ...@@ -48,6 +46,9 @@ internal const val REQUEST_CODE_FOR_CAS = 1
internal const val REQUEST_CODE_FOR_OAUTH = 2 internal const val REQUEST_CODE_FOR_OAUTH = 2
internal const val MULTIPLE_CREDENTIALS_READ = 3 internal const val MULTIPLE_CREDENTIALS_READ = 3
internal const val NO_CREDENTIALS_EXIST = 4 internal const val NO_CREDENTIALS_EXIST = 4
internal const val SAVE_CREDENTIALS = 5
var googleApiClient: GoogleApiClient? = null
class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks { class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks {
@Inject @Inject
...@@ -58,7 +59,6 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks ...@@ -58,7 +59,6 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
} }
private var isGlobalLayoutListenerSetUp = false private var isGlobalLayoutListenerSetUp = false
private var deepLinkInfo: LoginDeepLinkInfo? = null private var deepLinkInfo: LoginDeepLinkInfo? = null
private var googleApiClient: GoogleApiClient? = null
private var credentialsToBeSaved: Credential? = null private var credentialsToBeSaved: Credential? = null
companion object { companion object {
...@@ -72,7 +72,7 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks ...@@ -72,7 +72,7 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
} }
override fun onConnected(p0: Bundle?) { override fun onConnected(p0: Bundle?) {
//add call to the save credentials function here just like in sign up fragment saveSmartLockCredentials(credentialsToBeSaved)
} }
override fun onConnectionSuspended(p0: Int) { override fun onConnectionSuspended(p0: Int) {
...@@ -132,30 +132,35 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks ...@@ -132,30 +132,35 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
var loginCredentials: Credential = data!!.getParcelableExtra(Credential.EXTRA_KEY) var loginCredentials: Credential = data!!.getParcelableExtra(Credential.EXTRA_KEY)
handleCredential(loginCredentials) handleCredential(loginCredentials)
} else if (requestCode == NO_CREDENTIALS_EXIST) { } else if (requestCode == NO_CREDENTIALS_EXIST) {
//use the hints to autofill some info in the sign up or sign in forms //use the hints to autofill sign in forms to reduce the info to be filled
var loginCredentials: Credential = data!!.getParcelableExtra(Credential.EXTRA_KEY) 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 email = loginCredentials.id
var password = loginCredentials.password var password = loginCredentials.password
text_username_or_email.setText(email) text_username_or_email.setText(email)
text_password.setText(password) text_password.setText(password)
} else if (requestCode == SAVE_CREDENTIALS) {
Toast.makeText(context, "Credentials saved successfully", Toast.LENGTH_SHORT).show()
} }
} else if (requestCode == SAVE_CREDENTIALS) {
Log.e("STATUS", "ERROR: Cancelled by user")
} else if (requestCode == MULTIPLE_CREDENTIALS_READ) {
Log.d("STATUS", "failed ")
} }
//cancelled
else if (resultCode == Activity.RESULT_CANCELED) {
//cancel button pressed by the user in case of reading from smart lock
else if (resultCode == Activity.RESULT_CANCELED) {
//add shared preference so that the dialog is not shown always
} }
//create new account to use it as login account (deal with this case carefully, many edge cases) //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) { 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 //no hints for user id's exist
else if (resultCode == CredentialsApi.ACTIVITY_RESULT_NO_HINTS_AVAILABLE) { else if (resultCode == CredentialsApi.ACTIVITY_RESULT_NO_HINTS_AVAILABLE) {
} else {
Log.d("Status", "nothing happening")
} }
} }
...@@ -188,16 +193,14 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks ...@@ -188,16 +193,14 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
.build() .build()
Auth.CredentialsApi.request(googleApiClient, request).setResultCallback { credentialRequestResult -> Auth.CredentialsApi.request(googleApiClient, request).setResultCallback { credentialRequestResult ->
//hideProgress()
val status = credentialRequestResult.status val status = credentialRequestResult.status
if (status.isSuccess) { if (status.isSuccess) {
// Auto sign-in success // Auto sign-in success
handleCredential(credentialRequestResult.credential) handleCredential(credentialRequestResult.credential)
} else if (status.statusCode == CommonStatusCodes.RESOLUTION_REQUIRED) { } else if (status.statusCode == CommonStatusCodes.RESOLUTION_REQUIRED) {
// Getting credential needs to show some UI, start resolution
resolveResult(status, MULTIPLE_CREDENTIALS_READ) resolveResult(status, MULTIPLE_CREDENTIALS_READ)
} else if (status.statusCode == CommonStatusCodes.SIGN_IN_REQUIRED) { } else if (status.statusCode == CommonStatusCodes.SIGN_IN_REQUIRED) {
//resolveResult(status, NO_CREDENTIALS_EXIST)
//build a dialog for possible account hints //build a dialog for possible account hints
var hintRequest: HintRequest = HintRequest.Builder() var hintRequest: HintRequest = HintRequest.Builder()
.setHintPickerConfig(CredentialPickerConfig.Builder() .setHintPickerConfig(CredentialPickerConfig.Builder()
...@@ -233,8 +236,31 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks ...@@ -233,8 +236,31 @@ class LoginFragment : Fragment(), LoginView, GoogleApiClient.ConnectionCallbacks
} }
private fun resolveResult(status: Status, requestCode: Int) { private fun resolveResult(status: Status, requestCode: Int) {
//TODO surround with a try/catch block try {
status.startResolutionForResult(activity, requestCode) status.startResolutionForResult(activity, requestCode)
} catch (e: IntentSender.SendIntentException) {
Log.e("STATUS", "Failed to send Credentials intent.", e)
}
}
override fun saveSmartLockCredentials(loginCredential: Credential?) {
credentialsToBeSaved = loginCredential
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
}
})
} }
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
......
...@@ -29,5 +29,5 @@ interface SignupView : LoadingView, MessageView { ...@@ -29,5 +29,5 @@ interface SignupView : LoadingView, MessageView {
/** /**
* Save credentials via google smart lock * Save credentials via google smart lock
*/ */
fun saveSmartLockCredentials(loginCredential: Credential) fun saveSmartLockCredentials(loginCredential: Credential?)
} }
\ No newline at end of file
...@@ -8,9 +8,13 @@ import android.os.Bundle ...@@ -8,9 +8,13 @@ import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import android.util.Log import android.util.Log
import android.view.* import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.Toast import android.widget.Toast
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.authentication.login.ui.googleApiClient
import chat.rocket.android.authentication.signup.presentation.SignupPresenter import chat.rocket.android.authentication.signup.presentation.SignupPresenter
import chat.rocket.android.authentication.signup.presentation.SignupView import chat.rocket.android.authentication.signup.presentation.SignupView
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
...@@ -18,7 +22,6 @@ import chat.rocket.android.helper.TextHelper ...@@ -18,7 +22,6 @@ import chat.rocket.android.helper.TextHelper
import chat.rocket.android.util.extensions.* import chat.rocket.android.util.extensions.*
import com.google.android.gms.auth.api.Auth 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.Credential
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.ResolvingResultCallbacks import com.google.android.gms.common.api.ResolvingResultCallbacks
import com.google.android.gms.common.api.Status import com.google.android.gms.common.api.Status
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
...@@ -27,18 +30,10 @@ import javax.inject.Inject ...@@ -27,18 +30,10 @@ import javax.inject.Inject
internal const val SAVE_CREDENTIALS = 1 internal const val SAVE_CREDENTIALS = 1
class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbacks { class SignupFragment : Fragment(), SignupView {
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 @Inject
lateinit var presenter: SignupPresenter lateinit var presenter: SignupPresenter
private var googleApiClient: GoogleApiClient? = null
private var credentialsToBeSaved: Credential? = null private var credentialsToBeSaved: Credential? = null
private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener { private val layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
if (KeyboardHelper.isSoftKeyboardShown(relative_layout.rootView)) { if (KeyboardHelper.isSoftKeyboardShown(relative_layout.rootView)) {
...@@ -79,12 +74,6 @@ class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbac ...@@ -79,12 +74,6 @@ class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbac
} }
} }
override fun onDestroy() {
super.onDestroy()
googleApiClient!!.stopAutoManage(activity!!)
googleApiClient!!.disconnect()
}
override fun onDestroyView() { override fun onDestroyView() {
relative_layout.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener) relative_layout.viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
super.onDestroyView() super.onDestroyView()
...@@ -122,20 +111,11 @@ class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbac ...@@ -122,20 +111,11 @@ class SignupFragment : Fragment(), SignupView, GoogleApiClient.ConnectionCallbac
} }
} }
override fun saveSmartLockCredentials(loginCredential: Credential) { override fun saveSmartLockCredentials(loginCredential: Credential?) {
credentialsToBeSaved = loginCredential credentialsToBeSaved = loginCredential
googleApiClient = GoogleApiClient.Builder(context!!) if (googleApiClient!!.isConnected) {
.enableAutoManage(activity!!, { saveCredentials()
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?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
......
...@@ -43,6 +43,14 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -43,6 +43,14 @@ class AuthenticationActivity : AppCompatActivity(), HasSupportFragmentInjector {
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
if (currentFragment!=null){
currentFragment.onActivityResult(requestCode, resultCode, data)
}
}
override fun onDestroy() { override fun onDestroy() {
job.cancel() job.cancel()
super.onDestroy() super.onDestroy()
......
...@@ -105,11 +105,12 @@ class MainPresenter @Inject constructor( ...@@ -105,11 +105,12 @@ class MainPresenter @Inject constructor(
disconnect() disconnect()
removeAccountInteractor.remove(currentServer) removeAccountInteractor.remove(currentServer)
tokenRepository.remove(currentServer) tokenRepository.remove(currentServer)
view.disableAutoSignIn()
navigator.toNewServer() navigator.toNewServer()
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.d(ex, "Error cleaning up the session...") Timber.d(ex, "Error cleaning up the session...")
} }
view.disableAutoSignIn()
navigator.toNewServer() navigator.toNewServer()
} }
} }
......
...@@ -24,4 +24,9 @@ interface MainView : MessageView, VersionCheckView { ...@@ -24,4 +24,9 @@ interface MainView : MessageView, VersionCheckView {
fun setupNavHeader(viewModel: NavHeaderViewModel, accounts: List<Account>) fun setupNavHeader(viewModel: NavHeaderViewModel, accounts: List<Account>)
fun closeServerSelection() fun closeServerSelection()
/**
* callback to disable auto sign in for google smart lock when the user logs out
*/
fun disableAutoSignIn()
} }
\ No newline at end of file
...@@ -6,6 +6,7 @@ import android.os.Bundle ...@@ -6,6 +6,7 @@ import android.os.Bundle
import android.support.v4.app.Fragment import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.view.Gravity import android.view.Gravity
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
...@@ -22,6 +23,8 @@ import chat.rocket.android.util.extensions.fadeOut ...@@ -22,6 +23,8 @@ import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.rotateBy import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.common.model.UserStatus import chat.rocket.common.model.UserStatus
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.gcm.GoogleCloudMessaging import com.google.android.gms.gcm.GoogleCloudMessaging
import com.google.android.gms.iid.InstanceID import com.google.android.gms.iid.InstanceID
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
...@@ -37,18 +40,29 @@ import kotlinx.coroutines.experimental.launch ...@@ -37,18 +40,29 @@ import kotlinx.coroutines.experimental.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupportFragmentInjector { class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupportFragmentInjector, GoogleApiClient.ConnectionCallbacks {
@Inject lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity> override fun onConnected(p0: Bundle?) {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment> }
@Inject lateinit var presenter: MainPresenter
override fun onConnectionSuspended(p0: Int) {
}
@Inject
lateinit var activityDispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
@Inject
lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
@Inject
lateinit var presenter: MainPresenter
private var isFragmentAdded: Boolean = false private var isFragmentAdded: Boolean = false
private var expanded = false private var expanded = false
private var googleApiClient: GoogleApiClient? = null
private val headerLayout by lazy { view_navigation.getHeaderView(0) } private val headerLayout by lazy { view_navigation.getHeaderView(0) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this) AndroidInjection.inject(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
buildGoogleApiClient()
launch(CommonPool) { launch(CommonPool) {
try { try {
...@@ -66,6 +80,31 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -66,6 +80,31 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
setupNavigationView() setupNavigationView()
} }
private fun buildGoogleApiClient() {
googleApiClient = GoogleApiClient.Builder(this)
.enableAutoManage(this, {
Log.d("STATUS", "ERROR: connection to client failed")
})
.addConnectionCallbacks(this)
.addApi(Auth.CREDENTIALS_API)
.build()
}
override fun onStart() {
super.onStart()
if (googleApiClient!!.isConnected) {
Log.d("STATUS", "google api client connected successfully")
}
}
override fun disableAutoSignIn() {
if (googleApiClient!!.isConnected) {
Auth.CredentialsApi.disableAutoSignIn(googleApiClient)
} else {
Log.e("STATUS", "Failed to disable auto sign in")
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (!isFragmentAdded) { if (!isFragmentAdded) {
...@@ -84,7 +123,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -84,7 +123,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
override fun showUserStatus(userStatus: UserStatus) { override fun showUserStatus(userStatus: UserStatus) {
headerLayout.apply { headerLayout.apply {
image_user_status.setImageDrawable( image_user_status.setImageDrawable(
DrawableHelper.getUserStatusDrawable(userStatus, this.context) DrawableHelper.getUserStatusDrawable(userStatus, this.context)
) )
} }
} }
...@@ -95,7 +134,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -95,7 +134,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
with(viewModel) { with(viewModel) {
if (userStatus != null) { if (userStatus != null) {
image_user_status.setImageDrawable( image_user_status.setImageDrawable(
DrawableHelper.getUserStatusDrawable(userStatus, context) DrawableHelper.getUserStatusDrawable(userStatus, context)
) )
} }
if (userDisplayName != null) { if (userDisplayName != null) {
......
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