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.net.Uri
import android.os.Handler
import android.widget.Toast
import org.cryptomator.generator.Activity
import org.cryptomator.presentation.BuildConfig
@ -13,6 +14,12 @@ import timber.log.Timber
@Activity
class AuthenticatePCloudActivity : BaseActivity() {
private val startAuthenticationRequestCode = 1232
private val redirectTimeoutAfterAuthenticationAndResumed = 1000L
private var cancelAuthenticationHandler: Handler = Handler()
private var oAuthResultReceived = false
override fun setupView() {
val uri = Uri.parse("https://my.pcloud.com/oauth2/authorize")
.buildUpon()
@ -21,18 +28,27 @@ class AuthenticatePCloudActivity : BaseActivity() {
.appendQueryParameter("redirect_uri", "pcloudoauth://redirect")
.build()
startActivityForResult(Intent(Intent.ACTION_VIEW, uri), 25)
startActivityForResult(Intent(Intent.ACTION_VIEW, uri), startAuthenticationRequestCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: 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) {
super.onNewIntent(intent)
intent.data?.let {
if(it.host == "redirect" && it.scheme == "pcloudoauth") {
if (it.host == "redirect" && it.scheme == "pcloudoauth") {
oAuthResultReceived = true
val parameters = parseUrlFragmentParameters(it)
val accessToken = parameters["access_token"]
val hostname = parameters["hostname"]
@ -41,10 +57,11 @@ class AuthenticatePCloudActivity : BaseActivity() {
result.putExtra(CloudConnectionListPresenter.PCLOUD_OAUTH_AUTH_CODE, accessToken)
result.putExtra(CloudConnectionListPresenter.PCLOUD_HOSTNAME, hostname)
setResult(android.app.Activity.RESULT_OK, result)
finish()
} else {
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 {
Timber.tag("AuthenticatePCloudActivity").e("Tried to call activity using a different redirect scheme")
}
@ -63,4 +80,9 @@ class AuthenticatePCloudActivity : BaseActivity() {
}
return emptyMap()
}
override fun onDestroy() {
super.onDestroy()
cancelAuthenticationHandler.removeCallbacksAndMessages(null)
}
}