mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-20 19:51:27 +00:00
Made masterkey loading strategies reusable
This commit is contained in:
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user