Browse Source

Began vault recovery wizard

Sebastian Stenzel 5 years ago
parent
commit
d7edfd13a7

+ 1 - 0
main/ui/src/main/java/org/cryptomator/ui/common/FxmlFile.java

@@ -20,6 +20,7 @@ public enum FxmlFile {
 	PREFERENCES("/fxml/preferences.fxml"), //
 	QUIT("/fxml/quit.fxml"), //
 	RECOVERYKEY_CREATE("/fxml/recoverykey_create.fxml"), //
+	RECOVERYKEY_RECOVER("/fxml/recoverykey_recover.fxml"), //
 	RECOVERYKEY_SUCCESS("/fxml/recoverykey_success.fxml"), //
 	RECOVER_VAULT("/fxml/recovervault.fxml"),// TODO
 	REMOVE_VAULT("/fxml/remove_vault.fxml"), //

+ 0 - 42
main/ui/src/main/java/org/cryptomator/ui/recovervault/RecoverVaultComponent.java

@@ -1,42 +0,0 @@
-package org.cryptomator.ui.recovervault;
-
-import dagger.BindsInstance;
-import dagger.Lazy;
-import dagger.Subcomponent;
-import javafx.scene.Scene;
-import javafx.stage.Stage;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javax.inject.Named;
-
-@RecoverVaultScoped
-@Subcomponent(modules = {RecoverVaultModule.class})
-public interface RecoverVaultComponent {
-
-	@RecoverVaultWindow
-	Stage window();
-
-	@FxmlScene(FxmlFile.RECOVER_VAULT)
-	Lazy<Scene> scene();
-
-	default void showRecoverVaultWindow() {
-		Stage stage = window();
-		stage.setScene(scene().get());
-		stage.sizeToScene();
-		stage.show();
-	}
-
-	@Subcomponent.Builder
-	interface Builder {
-
-		@BindsInstance
-		Builder vault(@RecoverVaultWindow Vault vault);
-
-		@BindsInstance
-		Builder owner(@Named("recoverVaultOwner") Stage owner);
-
-		RecoverVaultComponent build();
-	}
-}

+ 0 - 66
main/ui/src/main/java/org/cryptomator/ui/recovervault/RecoverVaultController.java

@@ -1,66 +0,0 @@
-package org.cryptomator.ui.recovervault;
-
-import dagger.Lazy;
-import javafx.beans.Observable;
-import javafx.beans.property.StringProperty;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Scene;
-import javafx.scene.control.TextArea;
-import javafx.stage.Stage;
-import org.cryptomator.common.vaults.Vault;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-
-@RecoverVaultScoped
-public class RecoverVaultController implements FxController {
-
-
-	private static final Logger LOG = LoggerFactory.getLogger(RecoverVaultController.class);
-
-	private final Stage window;
-	private final Lazy<Scene> successScene;
-	private final Vault vault;
-	private StringProperty recoveryKey;
-
-	public TextArea textarea;
-
-	@Inject
-	public RecoverVaultController(@RecoverVaultWindow Stage window, @FxmlScene(FxmlFile.RECOVER_VAULT) Lazy<Scene> successScene, @RecoverVaultWindow Vault vault, @RecoverVaultWindow StringProperty recoveryKey) {
-		this.window = window;
-		this.successScene = successScene;
-		this.vault = vault;
-		this.recoveryKey = recoveryKey;
-	}
-
-	@FXML
-	public void initialize() {
-		textarea.getParagraphs().addListener(this::updateRecoveryKeyProperty);
-	}
-
-
-	private void updateRecoveryKeyProperty(@SuppressWarnings("unused") Observable observable) {
-		recoveryKey.set(textarea.getText());
-	}
-
-
-	@FXML
-	public void close() {
-		window.close();
-	}
-
-	public void recoverData(ActionEvent actionEvent) {
-		//TODO: CryptoAPI call, show progress bar
-	}
-
-	/* Getter/Setter */
-
-	public Vault getVault() {
-		return vault;
-	}
-}

+ 0 - 73
main/ui/src/main/java/org/cryptomator/ui/recovervault/RecoverVaultModule.java

@@ -1,73 +0,0 @@
-package org.cryptomator.ui.recovervault;
-
-import dagger.Binds;
-import dagger.Module;
-import dagger.Provides;
-import dagger.multibindings.IntoMap;
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.property.StringProperty;
-import javafx.scene.Scene;
-import javafx.scene.image.Image;
-import javafx.stage.Modality;
-import javafx.stage.Stage;
-import org.cryptomator.ui.common.DefaultSceneFactory;
-import org.cryptomator.ui.common.FXMLLoaderFactory;
-import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.common.FxControllerKey;
-import org.cryptomator.ui.common.FxmlFile;
-import org.cryptomator.ui.common.FxmlScene;
-
-import javax.inject.Named;
-import javax.inject.Provider;
-import java.util.List;
-import java.util.Map;
-import java.util.ResourceBundle;
-
-@Module
-abstract class RecoverVaultModule {
-
-	@Provides
-	@RecoverVaultWindow
-	@RecoverVaultScoped
-	static FXMLLoaderFactory provideFxmlLoaderFactory(Map<Class<? extends FxController>, Provider<FxController>> factories, DefaultSceneFactory sceneFactory, ResourceBundle resourceBundle) {
-		return new FXMLLoaderFactory(factories, sceneFactory, resourceBundle);
-	}
-
-	@Provides
-	@RecoverVaultWindow
-	@RecoverVaultScoped
-	static Stage provideStage(ResourceBundle resourceBundle, @Named("windowIcons") List<Image> windowIcons, @Named("recoverVaultOwner") Stage owner) {
-		Stage stage = new Stage();
-		//TODO stage.setTitle(resourceBundle.getString("recoverVault.title"));
-		stage.setTitle("TODO recover Vault");
-		stage.setResizable(false);
-		stage.initModality(Modality.WINDOW_MODAL);
-		stage.initOwner(owner);
-		stage.getIcons().addAll(windowIcons);
-		return stage;
-	}
-
-	@Provides
-	@RecoverVaultWindow
-	@RecoverVaultScoped
-	static StringProperty provideRecoveryKeyProperty() {
-		return new SimpleStringProperty();
-	}
-
-	// ------------------
-
-	@Provides
-	@FxmlScene(FxmlFile.RECOVER_VAULT)
-	@RecoverVaultScoped
-	static Scene provideRecoverVaultScene(@RecoverVaultWindow FXMLLoaderFactory fxmlLoaders) {
-		return fxmlLoaders.createScene("/fxml/recovervault.fxml");
-	}
-
-	// ------------------
-
-	@Binds
-	@IntoMap
-	@FxControllerKey(RecoverVaultController.class)
-	abstract FxController bindRecoverVaultController(RecoverVaultController controller);
-
-}

+ 0 - 13
main/ui/src/main/java/org/cryptomator/ui/recovervault/RecoverVaultScoped.java

@@ -1,13 +0,0 @@
-package org.cryptomator.ui.recovervault;
-
-import javax.inject.Scope;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RecoverVaultScoped {
-
-}

+ 0 - 14
main/ui/src/main/java/org/cryptomator/ui/recovervault/RecoverVaultWindow.java

@@ -1,14 +0,0 @@
-package org.cryptomator.ui.recovervault;
-
-import javax.inject.Qualifier;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface RecoverVaultWindow {
-
-}

+ 12 - 2
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyComponent.java

@@ -21,11 +21,21 @@ public interface RecoveryKeyComponent {
 	Stage window();
 
 	@FxmlScene(FxmlFile.RECOVERYKEY_CREATE)
-	Lazy<Scene> scene();
+	Lazy<Scene> creationScene();
+
+	@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER)
+	Lazy<Scene> recoverScene();
 
 	default void showRecoveryKeyCreationWindow() {
 		Stage stage = window();
-		stage.setScene(scene().get());
+		stage.setScene(creationScene().get());
+		stage.sizeToScene();
+		stage.show();
+	}
+
+	default void showRecoveryKeyRecoverWindow() {
+		Stage stage = window();
+		stage.setScene(recoverScene().get());
 		stage.sizeToScene();
 		stage.show();
 	}

+ 12 - 0
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyModule.java

@@ -70,6 +70,13 @@ abstract class RecoveryKeyModule {
 		return fxmlLoaders.createScene("/fxml/recoverykey_success.fxml");
 	}
 
+	@Provides
+	@FxmlScene(FxmlFile.RECOVERYKEY_RECOVER)
+	@RecoveryKeyScoped
+	static Scene provideRecoveryKeyRecoverScene(@RecoveryKeyWindow FXMLLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene("/fxml/recoverykey_recover.fxml");
+	}
+
 	// ------------------
 
 	@Binds
@@ -84,6 +91,11 @@ abstract class RecoveryKeyModule {
 		return new RecoveryKeyDisplayController(window, vault.getDisplayableName(), recoveryKey.get());
 	}
 
+	@Binds
+	@IntoMap
+	@FxControllerKey(RecoveryKeyRecoverController.class)
+	abstract FxController provideRecoveryKeyRecoverController(RecoveryKeyRecoverController controller);
+
 	@Binds
 	@IntoMap
 	@FxControllerKey(RecoveryKeySuccessController.class)

+ 63 - 0
main/ui/src/main/java/org/cryptomator/ui/recoverykey/RecoveryKeyRecoverController.java

@@ -0,0 +1,63 @@
+package org.cryptomator.ui.recoverykey;
+
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.property.StringProperty;
+import javafx.fxml.FXML;
+import javafx.scene.control.TextArea;
+import javafx.stage.Stage;
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.ui.common.FxController;
+
+import javax.inject.Inject;
+
+@RecoveryKeyScoped
+public class RecoveryKeyRecoverController implements FxController {
+
+	private final Stage window;
+	private final Vault vault;
+	private final StringProperty recoveryKey;
+	private final RecoveryKeyFactory recoveryKeyFactory;
+	private final BooleanBinding validRecoveryKey;
+
+	public TextArea textarea;
+
+	@Inject
+	public RecoveryKeyRecoverController(@RecoveryKeyWindow Stage window, @RecoveryKeyWindow Vault vault, @RecoveryKeyWindow StringProperty recoveryKey, RecoveryKeyFactory recoveryKeyFactory) {
+		this.window = window;
+		this.vault = vault;
+		this.recoveryKey = recoveryKey;
+		this.recoveryKeyFactory = recoveryKeyFactory;
+		this.validRecoveryKey = Bindings.createBooleanBinding(this::isValidRecoveryKey, recoveryKey);
+	}
+
+	@FXML
+	public void initialize() {
+		textarea.textProperty().bindBidirectional(recoveryKey);
+	}
+
+	@FXML
+	public void close() {
+		window.close();
+	}
+
+	@FXML
+	public void recover() {
+		recoveryKeyFactory.validateRecoveryKey(textarea.getText());
+
+	}
+
+	/* Getter/Setter */
+
+	public Vault getVault() {
+		return vault;
+	}
+
+	public BooleanBinding validRecoveryKeyProperty() {
+		return validRecoveryKey;
+	}
+
+	public boolean isValidRecoveryKey() {
+		return recoveryKeyFactory.validateRecoveryKey(recoveryKey.get());
+	}
+}

+ 2 - 0
main/ui/src/main/java/org/cryptomator/ui/recoverykey/WordEncoder.java

@@ -2,6 +2,7 @@ package org.cryptomator.ui.recoverykey;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -78,6 +79,7 @@ class WordEncoder {
 	 * @throws IllegalArgumentException If the encoded string doesn't consist of a multiple of two words or one of the words is unknown to this encoder.
 	 */
 	public byte[] decode(String encoded) {
+		Preconditions.checkArgument(!Strings.isNullOrEmpty(encoded));
 		List<String> splitted = Splitter.on(DELIMITER).omitEmptyStrings().splitToList(encoded);
 		Preconditions.checkArgument(splitted.size() % 2 == 0, "%s needs to be a multiple of two words", encoded);
 		byte[] result = new byte[splitted.size() / 2 * 3];

+ 2 - 5
main/ui/src/main/java/org/cryptomator/ui/vaultoptions/GeneralVaultOptionsController.java

@@ -6,7 +6,6 @@ import javafx.stage.Stage;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.ui.changepassword.ChangePasswordComponent;
 import org.cryptomator.ui.common.FxController;
-import org.cryptomator.ui.recovervault.RecoverVaultComponent;
 import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
 
 import javax.inject.Inject;
@@ -18,16 +17,14 @@ public class GeneralVaultOptionsController implements FxController {
 	private final Stage window;
 	private final ChangePasswordComponent.Builder changePasswordWindow;
 	private final RecoveryKeyComponent.Builder recoveryKeyWindow;
-	private final RecoverVaultComponent.Builder recoverVaultWindow;
 	public CheckBox unlockOnStartupCheckbox;
 
 	@Inject
-	GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Builder recoveryKeyWindow, RecoverVaultComponent.Builder recoverVaultWindow) {
+	GeneralVaultOptionsController(@VaultOptionsWindow Vault vault, @VaultOptionsWindow Stage window, ChangePasswordComponent.Builder changePasswordWindow, RecoveryKeyComponent.Builder recoveryKeyWindow) {
 		this.vault = vault;
 		this.window = window;
 		this.changePasswordWindow = changePasswordWindow;
 		this.recoveryKeyWindow = recoveryKeyWindow;
-		this.recoverVaultWindow = recoverVaultWindow;
 	}
 	
 	@FXML
@@ -47,6 +44,6 @@ public class GeneralVaultOptionsController implements FxController {
 
 	@FXML
 	public void showRecoverVaultDialogue(){
-		recoverVaultWindow.vault(vault).owner(window).build().showRecoverVaultWindow();
+		recoveryKeyWindow.vault(vault).owner(window).build().showRecoveryKeyRecoverWindow();
 	}
 }

+ 1 - 2
main/ui/src/main/java/org/cryptomator/ui/vaultoptions/VaultOptionsModule.java

@@ -17,7 +17,6 @@ import org.cryptomator.ui.common.FxControllerKey;
 import org.cryptomator.ui.common.FxmlFile;
 import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.mainwindow.MainWindow;
-import org.cryptomator.ui.recovervault.RecoverVaultComponent;
 import org.cryptomator.ui.recoverykey.RecoveryKeyComponent;
 
 import javax.inject.Named;
@@ -26,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.ResourceBundle;
 
-@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class, RecoverVaultComponent.class})
+@Module(subcomponents = {ChangePasswordComponent.class, RecoveryKeyComponent.class})
 abstract class VaultOptionsModule {
 
 	@Provides

+ 0 - 36
main/ui/src/main/resources/fxml/recovervault.fxml

@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<?import javafx.geometry.Insets?>
-<?import javafx.scene.control.Button?>
-<?import javafx.scene.control.ButtonBar?>
-<?import javafx.scene.layout.VBox?>
-<?import org.cryptomator.ui.controls.FormattedLabel?>
-<?import javafx.scene.control.CheckBox?>
-<?import javafx.scene.control.TextArea?>
-<VBox xmlns="http://javafx.com/javafx"
-	  xmlns:fx="http://javafx.com/fxml"
-	  fx:controller="org.cryptomator.ui.recovervault.RecoverVaultController"
-	  minWidth="400"
-	  maxWidth="400"
-	  minHeight="145"
-	  spacing="12"
-	  alignment="TOP_CENTER">
-	<padding>
-		<Insets topRightBottomLeft="12"/>
-	</padding>
-	<children>
-		<VBox spacing="6">
-			<FormattedLabel format="TODO If you lost/forgot your password for vault %s, you can get access with your backup passphrase" arg1="${controller.vault.displayableName}" wrapText="true"/>
-			<CheckBox fx:id="confirmation" text="TODO I have understood that all data will be decrypted. This cannot be undone."/>
-			<TextArea editable="true" wrapText="true" prefRowCount="4" fx:id="textarea" promptText="TODO Paste here your backup passphrase."/>
-		</VBox>
-		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
-			<ButtonBar buttonMinWidth="120" buttonOrder="C+X">
-				<buttons>
-					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
-					<Button text="TODO Proceed" ButtonBar.buttonData="NEXT_FORWARD" cancelButton="false" onAction="#recoverData" disable="${!confirmation.selected}"/>
-				</buttons>
-			</ButtonBar>
-		</VBox>
-	</children>
-</VBox>

+ 37 - 0
main/ui/src/main/resources/fxml/recoverykey_recover.fxml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.TextArea?>
+<?import javafx.scene.layout.Region?>
+<?import javafx.scene.layout.VBox?>
+<?import org.cryptomator.ui.controls.FormattedLabel?>
+<?import javafx.geometry.Insets?>
+<VBox xmlns="http://javafx.com/javafx"
+	  xmlns:fx="http://javafx.com/fxml"
+	  fx:controller="org.cryptomator.ui.recoverykey.RecoveryKeyRecoverController"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145"
+	  spacing="12"
+	  alignment="TOP_LEFT">
+	<padding>
+		<Insets topRightBottomLeft="12"/>
+	</padding>
+	<children>
+		<FormattedLabel format="TODO Enter your revoery key for &quot;%s&quot;:" arg1="${controller.vault.displayableName}" wrapText="true"/>
+
+		<TextArea wrapText="true" prefRowCount="4" fx:id="textarea"/>
+
+		<Region VBox.vgrow="ALWAYS"/>
+
+		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
+			<ButtonBar buttonMinWidth="120" buttonOrder="C+X">
+				<buttons>
+					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close" />
+					<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#recover" disable="${!controller.validRecoveryKey}" />
+				</buttons>
+			</ButtonBar>
+		</VBox>
+	</children>
+</VBox>