#307 fix pCloud login in F-Droid
This commit is contained in:
parent
9a1d9b7e61
commit
4f8f817808
@ -4,6 +4,7 @@ import org.cryptomator.data.cloud.crypto.CryptoCloudContentRepositoryFactory;
|
||||
import org.cryptomator.data.cloud.dropbox.DropboxCloudContentRepositoryFactory;
|
||||
import org.cryptomator.data.cloud.local.LocalStorageContentRepositoryFactory;
|
||||
import org.cryptomator.data.cloud.onedrive.OnedriveCloudContentRepositoryFactory;
|
||||
import org.cryptomator.data.cloud.pcloud.PCloudContentRepositoryFactory;
|
||||
import org.cryptomator.data.cloud.webdav.WebDavCloudContentRepositoryFactory;
|
||||
import org.cryptomator.data.repository.CloudContentRepositoryFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -23,12 +24,14 @@ public class CloudContentRepositoryFactories implements Iterable<CloudContentRep
|
||||
@Inject
|
||||
public CloudContentRepositoryFactories(DropboxCloudContentRepositoryFactory dropboxFactory, //
|
||||
OnedriveCloudContentRepositoryFactory oneDriveFactory, //
|
||||
PCloudContentRepositoryFactory pCloudFactory, //
|
||||
CryptoCloudContentRepositoryFactory cryptoFactory, //
|
||||
LocalStorageContentRepositoryFactory localStorageFactory, //
|
||||
WebDavCloudContentRepositoryFactory webDavFactory) {
|
||||
|
||||
factories = asList(dropboxFactory, //
|
||||
oneDriveFactory, //
|
||||
pCloudFactory, //
|
||||
cryptoFactory, //
|
||||
localStorageFactory, //
|
||||
webDavFactory);
|
||||
|
@ -2,17 +2,34 @@ package org.cryptomator.presentation.presenter
|
||||
|
||||
import android.Manifest
|
||||
import android.accounts.AccountManager
|
||||
import android.content.Intent
|
||||
import android.widget.Toast
|
||||
import com.dropbox.core.android.Auth
|
||||
import com.pcloud.sdk.AuthorizationActivity
|
||||
import com.pcloud.sdk.AuthorizationData
|
||||
import com.pcloud.sdk.AuthorizationRequest
|
||||
import com.pcloud.sdk.AuthorizationResult
|
||||
import org.cryptomator.data.cloud.onedrive.OnedriveClientFactory
|
||||
import org.cryptomator.data.cloud.onedrive.graph.ClientException
|
||||
import org.cryptomator.data.cloud.onedrive.graph.ICallback
|
||||
import org.cryptomator.data.util.X509CertificateHelper
|
||||
import org.cryptomator.domain.*
|
||||
import org.cryptomator.domain.Cloud
|
||||
import org.cryptomator.domain.CloudType
|
||||
import org.cryptomator.domain.DropboxCloud
|
||||
import org.cryptomator.domain.GoogleDriveCloud
|
||||
import org.cryptomator.domain.OnedriveCloud
|
||||
import org.cryptomator.domain.PCloud
|
||||
import org.cryptomator.domain.WebDavCloud
|
||||
import org.cryptomator.domain.di.PerView
|
||||
import org.cryptomator.domain.exception.FatalBackendException
|
||||
import org.cryptomator.domain.exception.NetworkConnectionException
|
||||
import org.cryptomator.domain.exception.authentication.*
|
||||
import org.cryptomator.domain.exception.authentication.AuthenticationException
|
||||
import org.cryptomator.domain.exception.authentication.WebDavCertificateUntrustedAuthenticationException
|
||||
import org.cryptomator.domain.exception.authentication.WebDavNotSupportedException
|
||||
import org.cryptomator.domain.exception.authentication.WebDavServerNotFoundException
|
||||
import org.cryptomator.domain.exception.authentication.WrongCredentialsException
|
||||
import org.cryptomator.domain.usecases.cloud.AddOrChangeCloudConnectionUseCase
|
||||
import org.cryptomator.domain.usecases.cloud.GetCloudsUseCase
|
||||
import org.cryptomator.domain.usecases.cloud.GetUsernameUseCase
|
||||
import org.cryptomator.generator.Callback
|
||||
import org.cryptomator.presentation.BuildConfig
|
||||
@ -20,23 +37,32 @@ import org.cryptomator.presentation.R
|
||||
import org.cryptomator.presentation.exception.ExceptionHandlers
|
||||
import org.cryptomator.presentation.exception.PermissionNotGrantedException
|
||||
import org.cryptomator.presentation.intent.AuthenticateCloudIntent
|
||||
import org.cryptomator.presentation.model.*
|
||||
import org.cryptomator.presentation.model.CloudModel
|
||||
import org.cryptomator.presentation.model.CloudTypeModel
|
||||
import org.cryptomator.presentation.model.ProgressModel
|
||||
import org.cryptomator.presentation.model.ProgressStateModel
|
||||
import org.cryptomator.presentation.model.WebDavCloudModel
|
||||
import org.cryptomator.presentation.model.mappers.CloudModelMapper
|
||||
import org.cryptomator.presentation.ui.activity.view.AuthenticateCloudView
|
||||
import org.cryptomator.presentation.workflow.*
|
||||
import org.cryptomator.presentation.workflow.ActivityResult
|
||||
import org.cryptomator.presentation.workflow.AddExistingVaultWorkflow
|
||||
import org.cryptomator.presentation.workflow.CreateNewVaultWorkflow
|
||||
import org.cryptomator.presentation.workflow.PermissionsResult
|
||||
import org.cryptomator.presentation.workflow.Workflow
|
||||
import org.cryptomator.util.ExceptionUtil
|
||||
import org.cryptomator.util.crypto.CredentialCryptor
|
||||
import timber.log.Timber
|
||||
import java.security.cert.CertificateEncodingException
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
@PerView
|
||||
class AuthenticateCloudPresenter @Inject constructor( //
|
||||
exceptionHandlers: ExceptionHandlers, //
|
||||
private val cloudModelMapper: CloudModelMapper, //
|
||||
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
|
||||
private val getCloudsUseCase: GetCloudsUseCase, //
|
||||
private val getUsernameUseCase: GetUsernameUseCase, //
|
||||
private val addExistingVaultWorkflow: AddExistingVaultWorkflow, //
|
||||
private val createNewVaultWorkflow: CreateNewVaultWorkflow) : Presenter<AuthenticateCloudView>(exceptionHandlers) {
|
||||
@ -44,6 +70,7 @@ class AuthenticateCloudPresenter @Inject constructor( //
|
||||
private val strategies = arrayOf( //
|
||||
DropboxAuthStrategy(), //
|
||||
OnedriveAuthStrategy(), //
|
||||
PCloudAuthStrategy(), //
|
||||
WebDAVAuthStrategy(), //
|
||||
LocalStorageAuthStrategy() //
|
||||
)
|
||||
@ -221,6 +248,102 @@ class AuthenticateCloudPresenter @Inject constructor( //
|
||||
}
|
||||
}
|
||||
|
||||
private inner class PCloudAuthStrategy : AuthStrategy {
|
||||
|
||||
private var authenticationStarted = false
|
||||
|
||||
override fun supports(cloud: CloudModel): Boolean {
|
||||
return cloud.cloudType() == CloudTypeModel.PCLOUD
|
||||
}
|
||||
|
||||
override fun resumed(intent: AuthenticateCloudIntent) {
|
||||
when {
|
||||
ExceptionUtil.contains(intent.error(), WrongCredentialsException::class.java) -> {
|
||||
if (!authenticationStarted) {
|
||||
startAuthentication()
|
||||
Toast.makeText(
|
||||
context(),
|
||||
String.format(getString(R.string.error_authentication_failed_re_authenticate), intent.cloud().username()),
|
||||
Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Timber.tag("AuthicateCloudPrester").e(intent.error())
|
||||
failAuthentication(intent.cloud().name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun startAuthentication() {
|
||||
authenticationStarted = true
|
||||
val authIntent: Intent = AuthorizationActivity.createIntent(
|
||||
context(),
|
||||
AuthorizationRequest.create()
|
||||
.setType(AuthorizationRequest.Type.TOKEN)
|
||||
.setClientId(BuildConfig.PCLOUD_CLIENT_ID)
|
||||
.setForceAccessApproval(true)
|
||||
.addPermission("manageshares")
|
||||
.build())
|
||||
requestActivityResult(ActivityResultCallbacks.pCloudReAuthenticationFinished(), //
|
||||
authIntent)
|
||||
}
|
||||
}
|
||||
|
||||
@Callback
|
||||
fun pCloudReAuthenticationFinished(activityResult: ActivityResult) {
|
||||
val authData: AuthorizationData = AuthorizationActivity.getResult(activityResult.intent())
|
||||
val result: AuthorizationResult = authData.result
|
||||
|
||||
when (result) {
|
||||
AuthorizationResult.ACCESS_GRANTED -> {
|
||||
val accessToken: String = CredentialCryptor //
|
||||
.getInstance(context()) //
|
||||
.encrypt(authData.token)
|
||||
val pCloudSkeleton: PCloud = PCloud.aPCloud() //
|
||||
.withAccessToken(accessToken)
|
||||
.withUrl(authData.apiHost)
|
||||
.build();
|
||||
getUsernameUseCase //
|
||||
.withCloud(pCloudSkeleton) //
|
||||
.run(object : DefaultResultHandler<String>() {
|
||||
override fun onSuccess(username: String?) {
|
||||
prepareForSavingPCloud(PCloud.aCopyOf(pCloudSkeleton).withUsername(username).build())
|
||||
}
|
||||
})
|
||||
}
|
||||
AuthorizationResult.ACCESS_DENIED -> {
|
||||
Timber.tag("CloudConnListPresenter").e("Account access denied")
|
||||
view?.showMessage(String.format(getString(R.string.screen_authenticate_auth_authentication_failed), getString(R.string.cloud_names_pcloud)))
|
||||
}
|
||||
AuthorizationResult.AUTH_ERROR -> {
|
||||
Timber.tag("CloudConnListPresenter").e("""Account access grant error: ${authData.errorMessage}""".trimIndent())
|
||||
view?.showMessage(String.format(getString(R.string.screen_authenticate_auth_authentication_failed), getString(R.string.cloud_names_pcloud)))
|
||||
}
|
||||
AuthorizationResult.CANCELLED -> {
|
||||
Timber.tag("CloudConnListPresenter").i("Account access grant cancelled")
|
||||
view?.showMessage(String.format(getString(R.string.screen_authenticate_auth_authentication_failed), getString(R.string.cloud_names_pcloud)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun prepareForSavingPCloud(cloud: PCloud) {
|
||||
getCloudsUseCase //
|
||||
.withCloudType(cloud.type()) //
|
||||
.run(object : DefaultResultHandler<List<Cloud>>() {
|
||||
override fun onSuccess(clouds: List<Cloud>) {
|
||||
clouds.firstOrNull {
|
||||
(it as PCloud).username() == cloud.username()
|
||||
}?.let {
|
||||
it as PCloud
|
||||
succeedAuthenticationWith(PCloud.aCopyOf(it) //
|
||||
.withUrl(cloud.url())
|
||||
.withAccessToken(cloud.accessToken())
|
||||
.build())
|
||||
} ?: succeedAuthenticationWith(cloud)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private inner class WebDAVAuthStrategy : AuthStrategy {
|
||||
|
||||
override fun supports(cloud: CloudModel): Boolean {
|
||||
@ -342,6 +465,6 @@ class AuthenticateCloudPresenter @Inject constructor( //
|
||||
}
|
||||
|
||||
init {
|
||||
unsubscribeOnDestroy(addOrChangeCloudConnectionUseCase, getUsernameUseCase)
|
||||
unsubscribeOnDestroy(addOrChangeCloudConnectionUseCase, getCloudsUseCase, getUsernameUseCase)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user