Fix sometimes unable to add a pCloud connection which fixes #368

Problem occurs due to a race condition between onNewIntent and onActivityResult:
If the browser is closed and Cryptomator resumed before the redirection call is processed by the intent framework of Android which in return calls the AuthenticatePCloudActivity again in the onNewIntent, it finishes in onActivityResult but should wait until onNewIntent is called to process the OAuth result.
This commit is contained in:
Julian Raufelder 2021-10-24 21:18:48 +02:00
parent 3b641a22d8
commit a83af094aa
No known key found for this signature in database
GPG Key ID: 17EE71F6634E381D

View File

@ -2,6 +2,7 @@ package org.cryptomator.presentation.ui.activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Handler
import android.widget.Toast import android.widget.Toast
import org.cryptomator.generator.Activity import org.cryptomator.generator.Activity
import org.cryptomator.presentation.BuildConfig import org.cryptomator.presentation.BuildConfig
@ -13,6 +14,12 @@ import timber.log.Timber
@Activity @Activity
class AuthenticatePCloudActivity : BaseActivity() { class AuthenticatePCloudActivity : BaseActivity() {
private val startAuthenticationRequestCode = 1232
private val redirectTimeoutAfterAuthenticationAndResumed = 1000L
private var cancelAuthenticationHandler: Handler = Handler()
private var oAuthResultReceived = false
override fun setupView() { override fun setupView() {
val uri = Uri.parse("https://my.pcloud.com/oauth2/authorize") val uri = Uri.parse("https://my.pcloud.com/oauth2/authorize")
.buildUpon() .buildUpon()
@ -21,18 +28,27 @@ class AuthenticatePCloudActivity : BaseActivity() {
.appendQueryParameter("redirect_uri", "pcloudoauth://redirect") .appendQueryParameter("redirect_uri", "pcloudoauth://redirect")
.build() .build()
startActivityForResult(Intent(Intent.ACTION_VIEW, uri), 25) startActivityForResult(Intent(Intent.ACTION_VIEW, uri), startAuthenticationRequestCode)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent) super.onActivityResult(requestCode, resultCode, intent)
finish() if (requestCode == startAuthenticationRequestCode) {
cancelAuthenticationHandler.postDelayed({
if (!oAuthResultReceived) {
Timber.tag("AuthenticatePCloudActivity").i("Authentication canceled or no redirect received after resuming Cryptomator since 1.5s")
Toast.makeText(context(), R.string.error_authentication_failed, Toast.LENGTH_SHORT).show()
finish()
}
}, redirectTimeoutAfterAuthenticationAndResumed)
}
} }
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent) super.onNewIntent(intent)
intent.data?.let { intent.data?.let {
if(it.host == "redirect" && it.scheme == "pcloudoauth") { if (it.host == "redirect" && it.scheme == "pcloudoauth") {
oAuthResultReceived = true
val parameters = parseUrlFragmentParameters(it) val parameters = parseUrlFragmentParameters(it)
val accessToken = parameters["access_token"] val accessToken = parameters["access_token"]
val hostname = parameters["hostname"] val hostname = parameters["hostname"]
@ -41,10 +57,11 @@ class AuthenticatePCloudActivity : BaseActivity() {
result.putExtra(CloudConnectionListPresenter.PCLOUD_OAUTH_AUTH_CODE, accessToken) result.putExtra(CloudConnectionListPresenter.PCLOUD_OAUTH_AUTH_CODE, accessToken)
result.putExtra(CloudConnectionListPresenter.PCLOUD_HOSTNAME, hostname) result.putExtra(CloudConnectionListPresenter.PCLOUD_HOSTNAME, hostname)
setResult(android.app.Activity.RESULT_OK, result) setResult(android.app.Activity.RESULT_OK, result)
finish()
} else { } else {
Toast.makeText(this, R.string.error_authentication_failed, Toast.LENGTH_LONG).show() Toast.makeText(this, R.string.error_authentication_failed, Toast.LENGTH_LONG).show()
Timber.tag("AuthenticatePCloudActivity").i("Authentication failed as the access token or hostname is null")
} }
finish()
} else { } else {
Timber.tag("AuthenticatePCloudActivity").e("Tried to call activity using a different redirect scheme") Timber.tag("AuthenticatePCloudActivity").e("Tried to call activity using a different redirect scheme")
} }
@ -63,4 +80,9 @@ class AuthenticatePCloudActivity : BaseActivity() {
} }
return emptyMap() return emptyMap()
} }
override fun onDestroy() {
super.onDestroy()
cancelAuthenticationHandler.removeCallbacksAndMessages(null)
}
} }