Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
SailReal committed Apr 24, 2021
2 parents f3322f3 + 5c8b006 commit 724f9e9
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 13 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ allprojects {
ext {
androidApplicationId = 'org.cryptomator'
androidVersionCode = getVersionCode()
androidVersionName = '1.5.16'
androidVersionName = '1.5.17'
}
repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
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;
Expand All @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions fastlane/metadata/android/de-DE/changelogs/default.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
- Fehler beim Erstellen neuer Tresore in pCloud behoben
- Fehler in der Lizenz-Anzeige der Einstellungen behoben
- Problem bei der pCloud-Anmeldung in der F-Droid-Variante behoben
3 changes: 1 addition & 2 deletions fastlane/metadata/android/en-US/changelogs/default.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
- Fixed creating new vaults in pCloud
- Fixed license screen in settings
- Fixed pCloud login using F-Droid
3 changes: 1 addition & 2 deletions fastlane/release-notes.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<ul>
<li>Fixed creating new vaults in pCloud</li>
<li>Fixed license screen in settings</li>
<li>Fixed pCloud login using F-Droid</li>
</ul>
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,75 @@ 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
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) {

private val strategies = arrayOf( //
DropboxAuthStrategy(), //
OnedriveAuthStrategy(), //
PCloudAuthStrategy(), //
WebDAVAuthStrategy(), //
LocalStorageAuthStrategy() //
)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -342,6 +465,6 @@ class AuthenticateCloudPresenter @Inject constructor( //
}

init {
unsubscribeOnDestroy(addOrChangeCloudConnectionUseCase, getUsernameUseCase)
unsubscribeOnDestroy(addOrChangeCloudConnectionUseCase, getCloudsUseCase, getUsernameUseCase)
}
}

0 comments on commit 724f9e9

Please sign in to comment.