mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-04-22 18:46:53 -04:00
dedup
This commit is contained in:
@@ -6,7 +6,6 @@ import org.cryptomator.cryptofs.VaultConfig;
|
||||
import org.cryptomator.cryptofs.VaultConfigLoadException;
|
||||
import org.cryptomator.cryptofs.VaultKeyInvalidException;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.cryptomator.ui.common.ErrorComponent;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
@@ -73,9 +72,15 @@ public class StartController implements FxController {
|
||||
private void loadKey() {
|
||||
assert !Platform.isFxApplicationThread();
|
||||
assert unverifiedVaultConfig.get() != null;
|
||||
try {
|
||||
keyLoadingStrategy.use(this::verifyVaultConfig);
|
||||
} catch (VaultConfigLoadException e) {
|
||||
throw new LoadingFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyVaultConfig(KeyLoadingStrategy keyLoadingStrategy) throws VaultConfigLoadException {
|
||||
var unverifiedCfg = unverifiedVaultConfig.get();
|
||||
// TODO: dedup keyloading w/ UnlockWorkflow.attemptUnlock()
|
||||
boolean success = false;
|
||||
try (var masterkey = keyLoadingStrategy.loadKey(unverifiedCfg.getKeyId())) {
|
||||
var verifiedCfg = unverifiedCfg.verify(masterkey.getEncoded(), unverifiedCfg.allegedVaultVersion());
|
||||
vaultConfigRef.set(verifiedCfg);
|
||||
@@ -83,18 +88,6 @@ public class StartController implements FxController {
|
||||
if (old != null) {
|
||||
old.destroy();
|
||||
}
|
||||
success = true;
|
||||
} catch (MasterkeyLoadingFailedException e) {
|
||||
if (keyLoadingStrategy.recoverFromException(e)) {
|
||||
// retry
|
||||
loadKey();
|
||||
} else {
|
||||
throw new LoadingFailedException(e);
|
||||
}
|
||||
} catch (VaultConfigLoadException e) {
|
||||
throw new LoadingFailedException(e);
|
||||
} finally {
|
||||
keyLoadingStrategy.cleanup(success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.cryptomator.ui.keyloading;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
@@ -12,6 +14,8 @@ import java.net.URI;
|
||||
@FunctionalInterface
|
||||
public interface KeyLoadingStrategy extends MasterkeyLoader {
|
||||
|
||||
Logger LOG = LoggerFactory.getLogger(KeyLoadingStrategy.class);
|
||||
|
||||
/**
|
||||
* Loads a master key. This might be a long-running operation, as it may require user input or expensive computations.
|
||||
* <p>
|
||||
@@ -60,4 +64,36 @@ public interface KeyLoadingStrategy extends MasterkeyLoader {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given <code>user</code> apply this key loading strategy. If the user fails with a {@link MasterkeyLoadingFailedException},
|
||||
* an attempt is made to {@link #recoverFromException(MasterkeyLoadingFailedException) recover} from it. Any other exception will be rethrown.
|
||||
*
|
||||
* @param user Some method using this strategy. May be invoked multiple times in case of recoverable {@link MasterkeyLoadingFailedException}s
|
||||
* @param <E> Optional exception type thrown by <code>user</code>
|
||||
* @throws MasterkeyLoadingFailedException If a non-recoverable exception is thrown by <code>user</code>
|
||||
* @throws E Exception thrown by <code>user</code> and rethrown by this method
|
||||
*/
|
||||
default <E extends Exception> void use(KeyLoadingStrategyUser<E> user) throws MasterkeyLoadingFailedException, E {
|
||||
boolean success = false;
|
||||
try {
|
||||
user.use(this);
|
||||
} catch (MasterkeyLoadingFailedException e) {
|
||||
if (recoverFromException(e)) {
|
||||
LOG.info("Unlock attempt threw {}. Reattempting...", e.getClass().getSimpleName());
|
||||
use(user);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
cleanup(success);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface KeyLoadingStrategyUser<E extends Exception> {
|
||||
|
||||
void use(KeyLoadingStrategy strategy) throws MasterkeyLoadingFailedException, E;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.cryptomator.ui.unlock;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.mountpoint.InvalidMountPointException;
|
||||
import org.cryptomator.common.vaults.MountPointRequirement;
|
||||
@@ -7,12 +8,10 @@ import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.common.vaults.VaultState;
|
||||
import org.cryptomator.common.vaults.Volume.VolumeException;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.cryptomator.ui.common.ErrorComponent;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
import org.cryptomator.ui.common.FxmlScene;
|
||||
import org.cryptomator.ui.common.VaultService;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingComponent;
|
||||
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -68,20 +67,14 @@ public class UnlockWorkflow extends Task<Boolean> {
|
||||
}
|
||||
|
||||
private void attemptUnlock() throws IOException, VolumeException, InvalidMountPointException, CryptoException {
|
||||
// TODO: dedup keyloading w/ StartController.loadKey()
|
||||
boolean success = false;
|
||||
try {
|
||||
vault.unlock(keyLoadingStrategy);
|
||||
success = true;
|
||||
} catch (MasterkeyLoadingFailedException e) {
|
||||
if (keyLoadingStrategy.recoverFromException(e)) {
|
||||
LOG.info("Unlock attempt threw {}. Reattempting...", e.getClass().getSimpleName());
|
||||
attemptUnlock();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
keyLoadingStrategy.cleanup(success);
|
||||
keyLoadingStrategy.use(vault::unlock);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e, IOException.class);
|
||||
Throwables.propagateIfPossible(e, VolumeException.class);
|
||||
Throwables.propagateIfPossible(e, InvalidMountPointException.class);
|
||||
Throwables.propagateIfPossible(e, CryptoException.class);
|
||||
throw new IllegalStateException("unexpected exception type", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user