Hopefully fix google sign in

This commit is contained in:
Phillip Thelen 2022-06-30 11:55:51 +02:00
parent cf5a420cc4
commit f66eeb94e7
5 changed files with 60 additions and 41 deletions

View file

@ -45,8 +45,11 @@ class ApiClient @Inject constructor(
connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
return when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_USB) -> true
else -> false
}
}
@ -115,9 +118,16 @@ class ApiClient @Inject constructor(
.build()
val response = chain.proceed(request)
if (request.method == "GET") {
response.newBuilder()
.header("Cache-Control", request.header("Cache-Control") ?: "")
.build()
if (response.code == 504) {
// Cache miss. Network might be down, but retry call without cache to be sure.
chain.proceed(request.newBuilder()
.header("Cache-Control", "no-cache")
.build())
} else {
response.newBuilder()
.header("Cache-Control", request.header("Cache-Control") ?: "")
.build()
}
} else {
response
}

View file

@ -3,7 +3,9 @@ package com.habitrpg.wearos.habitica.modules
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.common.habitica.api.HostConfig
import com.habitrpg.common.habitica.helpers.AppTestingLevel
import com.habitrpg.common.habitica.helpers.KeyHelper
import com.habitrpg.shared.habitica.HLogger
import com.habitrpg.wearos.habitica.data.ApiClient
@ -103,4 +105,10 @@ class AppModule {
null
} else KeyHelper.getInstance(context, sharedPreferences, keyStore)
}
@Provides
@Singleton
fun provideTestingLevel(): AppTestingLevel {
return AppTestingLevel.valueOf(BuildConfig.TESTING_LEVEL.uppercase())
}
}

View file

@ -1,6 +1,5 @@
package com.habitrpg.wearos.habitica.ui.activities
import android.accounts.AccountManager
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
@ -9,6 +8,7 @@ import android.text.method.PasswordTransformationMethod
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.view.isVisible
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.ActivityLoginBinding
import com.habitrpg.wearos.habitica.ui.viewmodels.LoginViewModel
@ -72,7 +72,7 @@ class LoginActivity: BaseActivity<ActivityLoginBinding, LoginViewModel>() {
startMainActivity()
}
binding.signInOnPhoneButton.setOnClickListener { }
binding.signInOnPhoneButton.setOnClickListener { openRegisterOnPhone() }
binding.otherButton.setOnClickListener { currentState = State.OTHER }
binding.usernamePasswordButton.setOnClickListener { currentState = State.INPUT }
@ -117,17 +117,16 @@ class LoginActivity: BaseActivity<ActivityLoginBinding, LoginViewModel>() {
}
private val pickAccountResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
viewModel.googleEmail = it?.data?.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
viewModel.handleGoogleLoginResult(this, recoverFromPlayServicesErrorResult)
}
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
viewModel.handleGoogleLoginResult(this, task, recoverFromPlayServicesErrorResult)
}
private val recoverFromPlayServicesErrorResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode != Activity.RESULT_CANCELED) {
viewModel.handleGoogleLoginResult(this, null)
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
viewModel.handleGoogleLoginResult(this, task, null)
}
}

View file

@ -1,36 +1,42 @@
package com.habitrpg.wearos.habitica.ui.viewmodels
import android.accounts.AccountManager
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.SharedPreferences
import androidx.activity.result.ActivityResultLauncher
import androidx.core.content.edit
import androidx.lifecycle.viewModelScope
import com.google.android.gms.auth.GoogleAuthException
import com.google.android.gms.auth.GoogleAuthUtil
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException
import com.google.android.gms.auth.UserRecoverableAuthException
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.common.GooglePlayServicesUtil
import com.google.android.gms.common.Scopes
import com.google.android.gms.common.UserRecoverableException
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task
import com.habitrpg.common.habitica.helpers.KeyHelper
import com.habitrpg.common.habitica.models.auth.UserAuth
import com.habitrpg.common.habitica.models.auth.UserAuthResponse
import com.habitrpg.common.habitica.models.auth.UserAuthSocial
import com.habitrpg.common.habitica.models.auth.UserAuthSocialTokens
import com.habitrpg.wearos.habitica.data.ApiClient
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
import com.habitrpg.wearos.habitica.managers.LoadingManager
import com.habitrpg.wearos.habitica.util.ExceptionHandlerBuilder
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.io.IOException
import javax.inject.Inject
@HiltViewModel
class LoginViewModel @Inject constructor(userRepository: UserRepository,
exceptionBuilder: ExceptionHandlerBuilder,
@ -39,53 +45,48 @@ class LoginViewModel @Inject constructor(userRepository: UserRepository,
val apiClient: ApiClient, loadingManager: LoadingManager
) : BaseViewModel(userRepository, exceptionBuilder, loadingManager) {
lateinit var onLoginCompleted: () -> Unit
var googleEmail: String? = null
fun handleGoogleLogin(
activity: Activity,
pickAccountResult: ActivityResultLauncher<Intent>
) {
if (!checkPlayServices(activity)) {
return
}
val accountTypes = arrayOf("com.google")
val intent = AccountManager.newChooseAccountIntent(
null, null,
accountTypes, true, null, null, null, null
)
try {
pickAccountResult.launch(intent)
} catch (e: ActivityNotFoundException) {
/*val alert = AlertDialog.Builder(activity).create()
alert.setTitle(R.string.authentication_error_title)
alert.setMessage(R.string.google_services_missing)
alert.addCloseButton()
alert.show()*/
}
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build()
val client = GoogleSignIn.getClient(activity, gso)
pickAccountResult.launch(client.signInIntent)
}
fun handleGoogleLoginResult(
activity: Activity,
task: Task<GoogleSignInAccount>,
recoverFromPlayServicesErrorResult: ActivityResultLauncher<Intent>?,
) {
val scopesString = Scopes.PROFILE + " " + Scopes.EMAIL
val scopes = "oauth2:$scopesString"
viewModelScope.launch(exceptionBuilder.userFacing(this)) {
val token = launch(Dispatchers.IO) {
val account = async {
try {
GoogleAuthUtil.getToken(activity, googleEmail ?: "", scopes)
val account: GoogleSignInAccount = task.getResult(
ApiException::class.java
)
return@async account
} catch (e: IOException) {
return@launch
return@async null
} catch (e: GoogleAuthException) {
if (recoverFromPlayServicesErrorResult != null) {
handleGoogleAuthException(e, activity, recoverFromPlayServicesErrorResult)
}
return@launch
return@async null
} catch (e: UserRecoverableException) {
return@launch
return@async null
}
}
val response = apiClient.loginSocial(UserAuthSocial())
}.await()
val auth = UserAuthSocial()
auth.network = "google"
auth.authResponse = UserAuthSocialTokens()
auth.authResponse?.client_id = account?.id
auth.authResponse?.access_token = account?.idToken
val response = apiClient.loginSocial(auth)
handleAuthResponse(response)
}
}

View file

@ -27,9 +27,10 @@ class RYAViewModel @Inject constructor(
init {
viewModelScope.launch(exceptionBuilder.silent()) {
tasks.value = taskRepository.getTasks(TaskType.DAILY)
val taskList: List<Task> = taskRepository.getTasks(TaskType.DAILY)
.map { it.filter { task -> task.isDue == true && !task.completed } }
.first()
tasks.value = taskList
}
}