Made masterkey loading strategies reusable

This commit is contained in:
Sebastian Stenzel
2021-03-31 16:12:31 +02:00
parent e6d1e4697c
commit e09bd160b7
18 changed files with 209 additions and 152 deletions

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading;
import javax.inject.Qualifier;
import java.lang.annotation.Documented;
@@ -9,6 +9,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Qualifier
@Documented
@Retention(RUNTIME)
@interface MasterkeyFileLoading {
public @interface KeyLoading {
}

View File

@@ -0,0 +1,28 @@
package org.cryptomator.ui.keyloading;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.common.vaults.Vault;
import javafx.stage.Stage;
@KeyLoadingScoped
@Subcomponent(modules = {KeyLoadingModule.class})
public interface KeyLoadingComponent {
@KeyLoading
KeyLoadingStrategy keyloadingStrategy();
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder vault(@KeyLoading Vault vault);
@BindsInstance
Builder window(@KeyLoading Stage window);
KeyLoadingComponent build();
}
}

View File

@@ -0,0 +1,59 @@
package org.cryptomator.ui.keyloading;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig.UnverifiedVaultConfig;
import org.cryptomator.ui.common.DefaultSceneFactory;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingStrategy;
import org.cryptomator.ui.migration.MigrationStartController;
import javax.inject.Provider;
import java.net.URI;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
@Module(includes = {MasterkeyFileLoadingModule.class})
abstract class KeyLoadingModule {
@Provides
@KeyLoading
@KeyLoadingScoped
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@KeyLoading
@KeyLoadingScoped
static Optional<URI> provideKeyId(@KeyLoading Vault vault) {
return vault.getUnverifiedVaultConfig().map(UnverifiedVaultConfig::getKeyId);
}
@Provides
@KeyLoading
@KeyLoadingScoped
static KeyLoadingStrategy provideKeyLoaderProvider(@KeyLoading Optional<URI> keyId, Map<String, KeyLoadingStrategy> strategies) {
if (keyId.isEmpty()) {
return KeyLoadingStrategy.failed(new IllegalArgumentException("No key id provided"));
} else {
String scheme = keyId.get().getScheme();
var fallback = KeyLoadingStrategy.failed(new IllegalArgumentException("Unsupported key id " + scheme));
return strategies.getOrDefault(scheme, fallback);
}
}
@Binds
@IntoMap
@StringKey("masterkeyfile")
abstract KeyLoadingStrategy bindMasterkeyFileLoadingStrategy(MasterkeyFileLoadingStrategy strategy);
}

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading;
import javax.inject.Scope;
import java.lang.annotation.Documented;
@@ -8,6 +8,6 @@ import java.lang.annotation.RetentionPolicy;
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
@interface MasterkeyFileLoadingScoped {
public @interface KeyLoadingScoped {
}

View File

@@ -1,10 +1,9 @@
package org.cryptomator.ui.unlock;
package org.cryptomator.ui.keyloading;
import org.cryptomator.cryptolib.api.MasterkeyLoader;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
@FunctionalInterface
public interface KeyLoadingComponent {
public interface KeyLoadingStrategy {
/**
* @return A reusable masterkey loader, preconfigured with the vault of the current unlock process
@@ -32,9 +31,19 @@ public interface KeyLoadingComponent {
// no-op
}
static KeyLoadingComponent exceptional(Exception exception) {
/**
* A key loading strategy that will always fail by throwing a {@link MasterkeyLoadingFailedException}.
*
* @param exception The cause of the failure. If not alreay an {@link MasterkeyLoadingFailedException}, it will get wrapped.
* @return A new KeyLoadingStrategy that will always fail with an {@link MasterkeyLoadingFailedException}.
*/
static KeyLoadingStrategy failed(Exception exception) {
return () -> {
throw new MasterkeyLoadingFailedException("Can not load key", exception);
if (exception instanceof MasterkeyLoadingFailedException e) {
throw e;
} else {
throw new MasterkeyLoadingFailedException("Can not load key", exception);
}
};
}

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading.masterkeyfile;
import dagger.Lazy;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
@@ -8,9 +8,9 @@ import org.cryptomator.ui.common.Animations;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.cryptomator.ui.unlock.UnlockCancelledException;
import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision;
import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry;
import javax.inject.Inject;
import javafx.application.Platform;
@@ -21,21 +21,21 @@ import java.nio.CharBuffer;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicReference;
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext {
private final Stage window;
private final Lazy<Scene> passphraseEntryScene;
private final Lazy<Scene> selectMasterkeyFileScene;
private final UserInteractionLock<PasswordEntry> passwordEntryLock;
private final UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock;
private final UserInteractionLock<MasterkeyFileLoadingModule.PasswordEntry> passwordEntryLock;
private final UserInteractionLock<MasterkeyFileLoadingModule.MasterkeyFileProvision> masterkeyFileProvisionLock;
private final AtomicReference<char[]> password;
private final AtomicReference<Path> filePath;
private boolean wrongPassword;
@Inject
public MasterkeyFileLoadingContext(@MasterkeyFileLoading Stage window, @FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD) Lazy<Scene> passphraseEntryScene, @FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE) Lazy<Scene> selectMasterkeyFileScene, UserInteractionLock<PasswordEntry> passwordEntryLock, UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock, AtomicReference<char[]> password, AtomicReference<Path> filePath) {
public MasterkeyFileLoadingContext(@KeyLoading Stage window, @FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD) Lazy<Scene> passphraseEntryScene, @FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE) Lazy<Scene> selectMasterkeyFileScene, UserInteractionLock<MasterkeyFileLoadingModule.PasswordEntry> passwordEntryLock, UserInteractionLock<MasterkeyFileLoadingModule.MasterkeyFileProvision> masterkeyFileProvisionLock, AtomicReference<char[]> password, AtomicReference<Path> filePath) {
this.window = window;
this.passphraseEntryScene = passphraseEntryScene;
this.selectMasterkeyFileScene = selectMasterkeyFileScene;
@@ -53,7 +53,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext {
assert filePath.get() == null;
try {
if (askForCorrectMasterkeyFile() == MasterkeyFileProvision.MASTERKEYFILE_PROVIDED) {
if (askForCorrectMasterkeyFile() == MasterkeyFileLoadingModule.MasterkeyFileProvision.MASTERKEYFILE_PROVIDED) {
return filePath.get();
} else {
throw new UnlockCancelledException("Choosing masterkey file cancelled.");
@@ -64,7 +64,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext {
}
}
private MasterkeyFileProvision askForCorrectMasterkeyFile() throws InterruptedException {
private MasterkeyFileLoadingModule.MasterkeyFileProvision askForCorrectMasterkeyFile() throws InterruptedException {
Platform.runLater(() -> {
window.setScene(selectMasterkeyFileScene.get());
window.show();
@@ -87,7 +87,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext {
assert password.get() == null;
try {
if (askForPassphrase() == PasswordEntry.PASSWORD_ENTERED) {
if (askForPassphrase() == MasterkeyFileLoadingModule.PasswordEntry.PASSWORD_ENTERED) {
assert password.get() != null;
return CharBuffer.wrap(password.get());
} else {
@@ -99,7 +99,7 @@ public class MasterkeyFileLoadingContext implements MasterkeyFileLoaderContext {
}
}
private PasswordEntry askForPassphrase() throws InterruptedException {
private MasterkeyFileLoadingModule.PasswordEntry askForPassphrase() throws InterruptedException {
Platform.runLater(() -> {
window.setScene(passphraseEntryScene.get());
window.show();

View File

@@ -1,8 +1,10 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading.masterkeyfile;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,7 +16,7 @@ import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
public class MasterkeyFileLoadingFinisher {
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyFileLoadingFinisher.class);
@@ -26,7 +28,7 @@ public class MasterkeyFileLoadingFinisher {
private final KeychainManager keychain;
@Inject
MasterkeyFileLoadingFinisher(@MasterkeyFileLoading Vault vault, @Named("savedPassword") Optional<char[]> storedPassword, AtomicReference<char[]> enteredPassword, @Named("savePassword")AtomicBoolean shouldSavePassword, KeychainManager keychain) {
MasterkeyFileLoadingFinisher(@KeyLoading Vault vault, @Named("savedPassword") Optional<char[]> storedPassword, AtomicReference<char[]> enteredPassword, @Named("savePassword") AtomicBoolean shouldSavePassword, KeychainManager keychain) {
this.vault = vault;
this.storedPassword = storedPassword;
this.enteredPassword = enteredPassword;

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading.masterkeyfile;
import dagger.Binds;
import dagger.Module;
@@ -17,6 +17,8 @@ import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,7 +33,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@Module(subcomponents = {ForgetPasswordComponent.class})
abstract class MasterkeyFileLoadingModule {
public abstract class MasterkeyFileLoadingModule {
private static final Logger LOG = LoggerFactory.getLogger(MasterkeyFileLoadingModule.class);
@@ -46,27 +48,27 @@ abstract class MasterkeyFileLoadingModule {
}
@Provides
@MasterkeyFileLoadingScoped
static MasterkeyFileLoader provideMasterkeyFileLoader(MasterkeyFileAccess masterkeyFileAccess, @MasterkeyFileLoading Vault vault, MasterkeyFileLoadingContext context) {
@KeyLoadingScoped
static MasterkeyFileLoader provideMasterkeyFileLoader(MasterkeyFileAccess masterkeyFileAccess, @KeyLoading Vault vault, MasterkeyFileLoadingContext context) {
return masterkeyFileAccess.keyLoader(vault.getPath(), context);
}
@Provides
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
static UserInteractionLock<PasswordEntry> providePasswordEntryLock() {
return new UserInteractionLock<>(null);
}
@Provides
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
static UserInteractionLock<MasterkeyFileProvision> provideMasterkeyFileProvisionLock() {
return new UserInteractionLock<>(null);
}
@Provides
@Named("savedPassword")
@MasterkeyFileLoadingScoped
static Optional<char[]> provideStoredPassword(KeychainManager keychain, @MasterkeyFileLoading Vault vault) {
@KeyLoadingScoped
static Optional<char[]> provideStoredPassword(KeychainManager keychain, @KeyLoading Vault vault) {
if (!keychain.isSupported()) {
return Optional.empty();
} else {
@@ -80,42 +82,35 @@ abstract class MasterkeyFileLoadingModule {
}
@Provides
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
static AtomicReference<Path> provideUserProvidedMasterkeyPath() {
return new AtomicReference<>();
}
@Provides
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
static AtomicReference<char[]> providePassword(@Named("savedPassword") Optional<char[]> storedPassword) {
return new AtomicReference<>(storedPassword.orElse(null));
}
@Provides
@Named("savePassword")
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
static AtomicBoolean provideSavePasswordFlag(@Named("savedPassword") Optional<char[]> storedPassword) {
return new AtomicBoolean(storedPassword.isPresent());
}
@Provides
@MasterkeyFileLoading
@MasterkeyFileLoadingScoped
static FxmlLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
return new FxmlLoaderFactory(factories, sceneFactory, resourceBundle);
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_ENTER_PASSWORD)
@MasterkeyFileLoadingScoped
static Scene provideUnlockScene(@MasterkeyFileLoading FxmlLoaderFactory fxmlLoaders) {
@KeyLoadingScoped
static Scene provideUnlockScene(@KeyLoading FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.UNLOCK_ENTER_PASSWORD);
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE)
@MasterkeyFileLoadingScoped
static Scene provideUnlockSelectMasterkeyFileScene(@MasterkeyFileLoading FxmlLoaderFactory fxmlLoaders) {
@KeyLoadingScoped
static Scene provideUnlockSelectMasterkeyFileScene(@KeyLoading FxmlLoaderFactory fxmlLoaders) {
return fxmlLoaders.createScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE);
}
@@ -129,5 +124,4 @@ abstract class MasterkeyFileLoadingModule {
@FxControllerKey(SelectMasterkeyFileController.class)
abstract FxController bindUnlockSelectMasterkeyFileController(SelectMasterkeyFileController controller);
}

View File

@@ -0,0 +1,38 @@
package org.cryptomator.ui.keyloading.masterkeyfile;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.cryptolib.common.MasterkeyFileLoader;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
import javax.inject.Inject;
@KeyLoading
public class MasterkeyFileLoadingStrategy implements KeyLoadingStrategy {
private final MasterkeyFileLoader masterkeyFileLoader;
private final MasterkeyFileLoadingContext context;
private final MasterkeyFileLoadingFinisher finisher;
@Inject
public MasterkeyFileLoadingStrategy(MasterkeyFileLoader masterkeyFileLoader, MasterkeyFileLoadingContext context, MasterkeyFileLoadingFinisher finisher){
this.masterkeyFileLoader = masterkeyFileLoader;
this.context = context;
this.finisher = finisher;
}
@Override
public MasterkeyFileLoader masterkeyLoader() {
return masterkeyFileLoader;
}
@Override
public boolean recoverFromException(MasterkeyLoadingFailedException exception) {
return context.recoverFromException(exception);
}
@Override
public void cleanup(boolean unlockedSuccessfully) {
finisher.cleanup(unlockedSuccessfully);
}
}

View File

@@ -1,4 +1,4 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading.masterkeyfile;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.vaults.Vault;
@@ -7,7 +7,9 @@ import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.common.WeakBindings;
import org.cryptomator.ui.controls.NiceSecurePasswordField;
import org.cryptomator.ui.forgetPassword.ForgetPasswordComponent;
import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule.PasswordEntry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,7 +41,7 @@ import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
public class PassphraseEntryController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(PassphraseEntryController.class);
@@ -67,7 +69,7 @@ public class PassphraseEntryController implements FxController {
public Animation unlockAnimation;
@Inject
public PassphraseEntryController(@MasterkeyFileLoading Stage window, @MasterkeyFileLoading Vault vault, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain) {
public PassphraseEntryController(@KeyLoading Stage window, @KeyLoading Vault vault, AtomicReference<char[]> password, @Named("savePassword") AtomicBoolean savePassword, @Named("savedPassword") Optional<char[]> savedPassword, UserInteractionLock<PasswordEntry> passwordEntryLock, ForgetPasswordComponent.Builder forgetPassword, KeychainManager keychain) {
this.window = window;
this.vault = vault;
this.password = password;

View File

@@ -1,8 +1,10 @@
package org.cryptomator.ui.unlock.masterkeyfile;
package org.cryptomator.ui.keyloading.masterkeyfile;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.UserInteractionLock;
import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision;
import org.cryptomator.ui.keyloading.KeyLoading;
import org.cryptomator.ui.keyloading.KeyLoadingScoped;
import org.cryptomator.ui.keyloading.masterkeyfile.MasterkeyFileLoadingModule.MasterkeyFileProvision;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -16,7 +18,7 @@ import java.nio.file.Path;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicReference;
@MasterkeyFileLoadingScoped
@KeyLoadingScoped
public class SelectMasterkeyFileController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(SelectMasterkeyFileController.class);
@@ -27,7 +29,7 @@ public class SelectMasterkeyFileController implements FxController {
private final ResourceBundle resourceBundle;
@Inject
public SelectMasterkeyFileController(@MasterkeyFileLoading Stage window, AtomicReference<Path> masterkeyPath, UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock, ResourceBundle resourceBundle) {
public SelectMasterkeyFileController(@KeyLoading Stage window, AtomicReference<Path> masterkeyPath, UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock, ResourceBundle resourceBundle) {
this.window = window;
this.masterkeyPath = masterkeyPath;
this.masterkeyFileProvisionLock = masterkeyFileProvisionLock;

View File

@@ -1,43 +0,0 @@
package org.cryptomator.ui.unlock;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptofs.VaultConfig.UnverifiedVaultConfig;
import org.cryptomator.ui.unlock.masterkeyfile.MasterkeyFileLoadingComponent;
import javafx.stage.Stage;
import java.net.URI;
import java.util.Map;
import java.util.Optional;
@Module(subcomponents = {MasterkeyFileLoadingComponent.class})
abstract class KeyLoadingModule {
@Provides
@UnlockScoped
static Optional<URI> provideKeyId(@UnlockWindow Vault vault) {
return vault.getUnverifiedVaultConfig().map(UnverifiedVaultConfig::getKeyId);
}
@Provides
@UnlockScoped
static KeyLoadingComponent provideKeyLoaderProvider(Optional<URI> keyId, Map<String, KeyLoadingComponent> keyLoaderProviders) {
if (keyId.isEmpty()) {
return KeyLoadingComponent.exceptional(new IllegalArgumentException("No key id provided"));
} else {
String scheme = keyId.get().getScheme();
return keyLoaderProviders.getOrDefault(scheme, KeyLoadingComponent.exceptional(new IllegalArgumentException("Unsupported key id " + scheme)));
}
}
@Provides
@IntoMap
@StringKey("masterkeyfile")
static KeyLoadingComponent provideMasterkeyFileLoadingComponet(MasterkeyFileLoadingComponent.Builder compBuilder, @UnlockWindow Stage window, @UnlockWindow Vault vault) {
return compBuilder.unlockWindow(window).vault(vault).build();
}
}

View File

@@ -16,7 +16,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@UnlockScoped
@Subcomponent(modules = {UnlockModule.class, KeyLoadingModule.class})
@Subcomponent(modules = {UnlockModule.class})
public interface UnlockComponent {
ExecutorService defaultExecutorService();

View File

@@ -12,6 +12,8 @@ import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.keyloading.KeyLoadingComponent;
import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
import javax.inject.Named;
import javax.inject.Provider;
@@ -22,7 +24,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
@Module
@Module(subcomponents = {KeyLoadingComponent.class})
abstract class UnlockModule {
@Provides
@@ -48,6 +50,13 @@ abstract class UnlockModule {
return stage;
}
@Provides
@UnlockWindow
@UnlockScoped
static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Builder compBuilder, @UnlockWindow Vault vault, @UnlockWindow Stage window) {
return compBuilder.vault(vault).window(window).build().keyloadingStrategy();
}
@Provides
@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
@UnlockScoped

View File

@@ -12,6 +12,8 @@ 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;
@@ -41,17 +43,17 @@ public class UnlockWorkflow extends Task<Boolean> {
private final Lazy<Scene> successScene;
private final Lazy<Scene> invalidMountPointScene;
private final ErrorComponent.Builder errorComponent;
private final KeyLoadingComponent keyLoadingComp;
private final KeyLoadingStrategy keyLoadingStrategy;
@Inject
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent, KeyLoadingComponent keyLoadingComp) {
UnlockWorkflow(@UnlockWindow Stage window, @UnlockWindow Vault vault, VaultService vaultService, @FxmlScene(FxmlFile.UNLOCK_SUCCESS) Lazy<Scene> successScene, @FxmlScene(FxmlFile.UNLOCK_INVALID_MOUNT_POINT) Lazy<Scene> invalidMountPointScene, ErrorComponent.Builder errorComponent, @UnlockWindow KeyLoadingStrategy keyLoadingStrategy) {
this.window = window;
this.vault = vault;
this.vaultService = vaultService;
this.successScene = successScene;
this.invalidMountPointScene = invalidMountPointScene;
this.errorComponent = errorComponent;
this.keyLoadingComp = keyLoadingComp;
this.keyLoadingStrategy = keyLoadingStrategy;
setOnFailed(event -> {
Throwable throwable = event.getSource().getException();
@@ -78,17 +80,17 @@ public class UnlockWorkflow extends Task<Boolean> {
private void attemptUnlock() throws IOException, VolumeException, InvalidMountPointException, CryptoException {
boolean success = false;
try {
vault.unlock(keyLoadingComp.masterkeyLoader());
vault.unlock(keyLoadingStrategy.masterkeyLoader());
success = true;
} catch (MasterkeyLoadingFailedException e) {
if (keyLoadingComp.recoverFromException(e)) {
if (keyLoadingStrategy.recoverFromException(e)) {
LOG.info("Unlock attempt threw {}. Reattempting...", e.getClass().getSimpleName());
attemptUnlock();
} else {
throw e;
}
} finally {
keyLoadingComp.cleanup(success);
keyLoadingStrategy.cleanup(success);
}
}

View File

@@ -1,45 +0,0 @@
package org.cryptomator.ui.unlock.masterkeyfile;
import dagger.BindsInstance;
import dagger.Subcomponent;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.cryptolib.common.MasterkeyFileLoader;
import org.cryptomator.ui.unlock.KeyLoadingComponent;
import javafx.stage.Stage;
@MasterkeyFileLoadingScoped
@Subcomponent(modules = {MasterkeyFileLoadingModule.class})
public interface MasterkeyFileLoadingComponent extends KeyLoadingComponent {
MasterkeyFileLoadingFinisher finisher();
MasterkeyFileLoadingContext context();
@Override
MasterkeyFileLoader masterkeyLoader();
@Override
default boolean recoverFromException(MasterkeyLoadingFailedException exception) {
return context().recoverFromException(exception);
}
@Override
default void cleanup(boolean unlockedSuccessfully) {
finisher().cleanup(unlockedSuccessfully);
}
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder vault(@MasterkeyFileLoading Vault vault);
@BindsInstance
Builder unlockWindow(@MasterkeyFileLoading Stage unlockWindow);
MasterkeyFileLoadingComponent build();
}
}

View File

@@ -14,7 +14,7 @@
<?import javafx.scene.layout.VBox?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.unlock.masterkeyfile.PassphraseEntryController"
fx:controller="org.cryptomator.ui.keyloading.masterkeyfile.PassphraseEntryController"
minWidth="400"
maxWidth="400"
minHeight="145"

View File

@@ -11,7 +11,7 @@
<?import javafx.scene.shape.Circle?>
<VBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:controller="org.cryptomator.ui.unlock.masterkeyfile.SelectMasterkeyFileController"
fx:controller="org.cryptomator.ui.keyloading.masterkeyfile.SelectMasterkeyFileController"
minWidth="400"
maxWidth="400"
minHeight="145"