Browse Source

add new (optional) "choose masterkey file" step to unlock dialog

Sebastian Stenzel 4 năm trước cách đây
mục cha
commit
b15471b4ff

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

@@ -28,6 +28,7 @@ public enum FxmlFile {
 	REMOVE_VAULT("/fxml/remove_vault.fxml"), //
 	UNLOCK("/fxml/unlock.fxml"),
 	UNLOCK_INVALID_MOUNT_POINT("/fxml/unlock_invalid_mount_point.fxml"), //
+	UNLOCK_SELECT_MASTERKEYFILE("/fxml/unlock_select_masterkeyfile.fxml"), //
 	UNLOCK_SUCCESS("/fxml/unlock_success.fxml"), //
 	VAULT_OPTIONS("/fxml/vault_options.fxml"), //
 	VAULT_STATISTICS("/fxml/stats.fxml"), //

+ 31 - 0
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockModule.java

@@ -24,6 +24,7 @@ import javax.inject.Provider;
 import javafx.scene.Scene;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
+import java.nio.file.Path;
 import java.util.Map;
 import java.util.Optional;
 import java.util.ResourceBundle;
@@ -40,12 +41,23 @@ abstract class UnlockModule {
 		CANCELED
 	}
 
+	public enum MasterkeyFileProvision {
+		MASTERKEYFILE_PROVIDED,
+		CANCELED
+	}
+
 	@Provides
 	@UnlockScoped
 	static UserInteractionLock<PasswordEntry> providePasswordEntryLock() {
 		return new UserInteractionLock<>(null);
 	}
 
+	@Provides
+	@UnlockScoped
+	static UserInteractionLock<MasterkeyFileProvision> provideMasterkeyFileProvisionLock() {
+		return new UserInteractionLock<>(null);
+	}
+
 	@Provides
 	@Named("savedPassword")
 	@UnlockScoped
@@ -62,6 +74,13 @@ abstract class UnlockModule {
 		}
 	}
 
+	@Provides
+	@Named("userProvidedMasterkeyPath")
+	@UnlockScoped
+	static AtomicReference<Path> provideUserProvidedMasterkeyPath() {
+		return new AtomicReference();
+	}
+
 	@Provides
 	@UnlockScoped
 	static AtomicReference<char[]> providePassword(@Named("savedPassword") Optional<char[]> storedPassword) {
@@ -105,6 +124,13 @@ abstract class UnlockModule {
 		return fxmlLoaders.createScene("/fxml/unlock.fxml");
 	}
 
+	@Provides
+	@FxmlScene(FxmlFile.UNLOCK_SELECT_MASTERKEYFILE)
+	@UnlockScoped
+	static Scene provideUnlockSelectMasterkeyFileScene(@UnlockWindow FXMLLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene("/fxml/unlock_select_masterkeyfile.fxml");
+	}
+
 	@Provides
 	@FxmlScene(FxmlFile.UNLOCK_SUCCESS)
 	@UnlockScoped
@@ -126,6 +152,11 @@ abstract class UnlockModule {
 	@FxControllerKey(UnlockController.class)
 	abstract FxController bindUnlockController(UnlockController controller);
 
+	@Binds
+	@IntoMap
+	@FxControllerKey(UnlockSelectMasterkeyFileController.class)
+	abstract FxController bindUnlockSelectMasterkeyFileController(UnlockSelectMasterkeyFileController controller);
+
 	@Binds
 	@IntoMap
 	@FxControllerKey(UnlockSuccessController.class)

+ 76 - 0
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockSelectMasterkeyFileController.java

@@ -0,0 +1,76 @@
+package org.cryptomator.ui.unlock;
+
+import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.UserInteractionLock;
+import org.cryptomator.ui.unlock.UnlockModule.MasterkeyFileProvision;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.fxml.FXML;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import javafx.stage.WindowEvent;
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicReference;
+
+@UnlockScoped
+public class UnlockSelectMasterkeyFileController implements FxController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(UnlockSelectMasterkeyFileController.class);
+
+	private final BooleanProperty proceedButtonDisabled = new SimpleBooleanProperty();
+	private final Stage window;
+	private final AtomicReference<Path> masterkeyPath;
+	private final UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock;
+	private final ResourceBundle resourceBundle;
+
+	@Inject
+	public UnlockSelectMasterkeyFileController(@UnlockWindow Stage window, @Named("userProvidedMasterkeyPath") AtomicReference<Path> masterkeyPath, UserInteractionLock<MasterkeyFileProvision> masterkeyFileProvisionLock, ResourceBundle resourceBundle) {
+		this.window = window;
+		this.masterkeyPath = masterkeyPath;
+		this.masterkeyFileProvisionLock = masterkeyFileProvisionLock;
+		this.resourceBundle = resourceBundle;
+		this.window.setOnHiding(this::windowClosed);
+	}
+
+	@FXML
+	public void cancel() {
+		window.close();
+	}
+
+	private void windowClosed(WindowEvent windowEvent) {
+		// if not already interacted, mark this workflow as cancelled:
+		if (masterkeyFileProvisionLock.awaitingInteraction().get()) {
+			LOG.debug("Unlock canceled by user.");
+			masterkeyFileProvisionLock.interacted(MasterkeyFileProvision.CANCELED);
+		}
+	}
+
+	@FXML
+	public void proceed() {
+		LOG.trace("proceed()");
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setTitle(resourceBundle.getString("unlock.chooseMasterkey.filePickerTitle"));
+		fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
+		File masterkeyFile = fileChooser.showOpenDialog(window);
+		if (masterkeyFile != null) {
+			LOG.debug("Chose masterkey file: {}", masterkeyFile);
+			masterkeyPath.set(masterkeyFile.toPath());
+			masterkeyFileProvisionLock.interacted(MasterkeyFileProvision.MASTERKEYFILE_PROVIDED);
+		}
+	}
+
+	public BooleanProperty proceedButtonDisabledProperty() {
+		return proceedButtonDisabled;
+	}
+
+	public boolean isProceedButtonDisabled() {
+		return proceedButtonDisabled.get();
+	}
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 40 - 10
main/ui/src/main/java/org/cryptomator/ui/unlock/UnlockWorkflow.java


+ 43 - 0
main/ui/src/main/resources/fxml/unlock_select_masterkeyfile.fxml

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.StackPane?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.shape.Circle?>
+<?import org.cryptomator.ui.controls.FormattedLabel?>
+<VBox xmlns:fx="http://javafx.com/fxml"
+	  xmlns="http://javafx.com/javafx"
+	  fx:controller="org.cryptomator.ui.unlock.UnlockSelectMasterkeyFileController"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145"
+	  spacing="12">
+	<padding>
+		<Insets topRightBottomLeft="12"/>
+	</padding>
+	<children>
+		<HBox spacing="12" alignment="CENTER_LEFT" VBox.vgrow="ALWAYS">
+			<StackPane alignment="CENTER" HBox.hgrow="NEVER">
+				<Circle styleClass="glyph-icon-primary" radius="24"/>
+				<FontAwesome5IconView styleClass="glyph-icon-white" glyph="FILE" glyphSize="24"/>
+			</StackPane>
+			<VBox spacing="6">
+				<Label text="Could not find the masterkey file for this vault at its expected location. Please choose the key file manually." wrapText="true" HBox.hgrow="ALWAYS"/>
+			</VBox>
+		</HBox>
+
+		<VBox alignment="BOTTOM_CENTER" VBox.vgrow="ALWAYS">
+			<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
+				<buttons>
+					<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#cancel"/>
+					<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#proceed" disable="${controller.proceedButtonDisabled}"/>
+				</buttons>
+			</ButtonBar>
+		</VBox>
+	</children>
+</VBox>

+ 2 - 0
main/ui/src/main/resources/i18n/strings.properties

@@ -98,6 +98,8 @@ unlock.title=Unlock Vault
 unlock.passwordPrompt=Enter password for "%s":
 unlock.savePassword=Save Password
 unlock.unlockBtn=Unlock
+##
+unlock.chooseMasterkey.filePickerTitle=Select Masterkey File
 ## Success
 unlock.success.message=Unlocked "%s" successfully! Your vault is now accessible.
 unlock.success.rememberChoice=Remember choice, don't show this again