From 017ab520a219726318cefa4b8f2bb95d73197d92 Mon Sep 17 00:00:00 2001 From: Julian Raufelder Date: Sat, 12 Feb 2022 22:22:00 +0100 Subject: [PATCH] Preserve Cryptors of the same cloud if the cloud gets updated If e.g. a cloud gets updated during token refresh while browsing files we authenticate, save the updated cloud, update the vault and now no longer lock other vaults from the same cloud but update them too. --- .../crypto/CryptoCloudContentRepositoryFactory.java | 9 +++++++++ .../org/cryptomator/data/cloud/crypto/Cryptors.kt | 11 +++++++++++ .../data/repository/CloudRepositoryImpl.java | 2 +- .../repository/DispatchingCloudContentRepository.kt | 10 ++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepositoryFactory.java b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepositoryFactory.java index 50c53d37..eb6bcaf0 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepositoryFactory.java +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/CryptoCloudContentRepositoryFactory.java @@ -78,4 +78,13 @@ public class CryptoCloudContentRepositoryFactory implements CloudContentReposito throw new IllegalStateException(format("Cryptor already registered for vault %s", vault)); } } + + public void updateCloudInCryptor(Vault vault, Cloud cloud) { + try { + Cryptor cryptor = cryptors.get(vault).get(); + cryptors.replace(vault, Vault.aCopyOf(vault).withCloud(cloud).build(), cryptor); + } catch (MissingCryptorException e) { + // no-op + } + } } diff --git a/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.kt b/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.kt index 485c5078..9e6040fb 100644 --- a/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.kt +++ b/data/src/main/java/org/cryptomator/data/cloud/crypto/Cryptors.kt @@ -20,6 +20,8 @@ abstract class Cryptors internal constructor() { abstract fun putIfAbsent(vault: Vault, cryptor: Cryptor): Boolean + abstract fun replace(old: Vault, updated: Vault, cryptor: Cryptor) + class Delegating : Cryptors() { private val fallback = Default() @@ -65,6 +67,10 @@ abstract class Cryptors internal constructor() { return delegate().putIfAbsent(vault, cryptor) } + override fun replace(old: Vault, updated: Vault, cryptor: Cryptor) { + return delegate().replace(old, updated, cryptor) + } + @Synchronized private fun delegate(): Cryptors { return delegate ?: fallback @@ -108,6 +114,11 @@ abstract class Cryptors internal constructor() { } } + override fun replace(old: Vault, updated: Vault, cryptor: Cryptor) { + cryptors.remove(old) + cryptors[updated] = cryptor + } + fun setOnChangeListener(onChangeListener: Runnable) { this.onChangeListener = onChangeListener } diff --git a/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java b/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java index 61f1307c..aeef7a0b 100644 --- a/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java +++ b/data/src/main/java/org/cryptomator/data/repository/CloudRepositoryImpl.java @@ -68,7 +68,7 @@ class CloudRepositoryImpl implements CloudRepository { Cloud storedCloud = mapper.fromEntity(database.store(mapper.toEntity(cloud))); - dispatchingCloudContentRepository.removeCloudContentRepositoryFor(storedCloud); + dispatchingCloudContentRepository.updateCloudContentRepositoryFor(storedCloud); database.clearCache(); return storedCloud; diff --git a/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.kt b/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.kt index 85e5e5fd..05b61418 100644 --- a/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.kt +++ b/data/src/main/java/org/cryptomator/data/repository/DispatchingCloudContentRepository.kt @@ -204,6 +204,16 @@ class DispatchingCloudContentRepository @Inject constructor( } } + fun updateCloudContentRepositoryFor(cloud: Cloud) { + val clouds = delegates.keys.iterator() + while (clouds.hasNext()) { + val current = clouds.next() + if (cloudIsDelegateOfCryptoCloud(current, cloud)) { + cryptoCloudContentRepositoryFactory.updateCloudInCryptor((current as CryptoCloud).vault, cloud) + } + } + } + private fun cloudIsDelegateOfCryptoCloud(potentialCryptoCloud: Cloud, cloud: Cloud): Boolean { if (potentialCryptoCloud is CryptoCloud) { val delegate = potentialCryptoCloud.vault.cloud