Ver Fonte

Actually run tests from within Sanitizer UI

Sebastian Stenzel há 4 anos atrás
pai
commit
13db1aa9b9

+ 1 - 1
main/pom.xml

@@ -25,7 +25,7 @@
 		<project.jdk.version>16</project.jdk.version>
 
 		<!-- cryptomator dependencies -->
-		<cryptomator.cryptofs.version>2.0.0-beta5</cryptomator.cryptofs.version>
+		<cryptomator.cryptofs.version>2.1.0-beta1</cryptomator.cryptofs.version>
 		<cryptomator.integrations.version>1.0.0-beta2</cryptomator.integrations.version>
 		<cryptomator.integrations.win.version>1.0.0-beta2</cryptomator.integrations.win.version>
 		<cryptomator.integrations.mac.version>1.0.0-beta2</cryptomator.integrations.mac.version>

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

@@ -12,6 +12,7 @@ public enum FxmlFile {
 	ERROR("/fxml/error.fxml"), //
 	FORGET_PASSWORD("/fxml/forget_password.fxml"), //
 	HEALTH_START("/fxml/health_start.fxml"), //
+	HEALTH_CHECK("/fxml/health_check.fxml"), //
 	LOCK_FORCED("/fxml/lock_forced.fxml"), //
 	LOCK_FAILED("/fxml/lock_failed.fxml"), //
 	MAIN_WINDOW("/fxml/main_window.fxml"), //

+ 59 - 0
main/ui/src/main/java/org/cryptomator/ui/health/CheckController.java

@@ -0,0 +1,59 @@
+package org.cryptomator.ui.health;
+
+import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.cryptofs.VaultConfig;
+import org.cryptomator.cryptofs.health.api.DiagnosticResult;
+import org.cryptomator.cryptofs.health.api.HealthCheck;
+import org.cryptomator.cryptolib.api.Masterkey;
+import org.cryptomator.ui.common.FxController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import javafx.fxml.FXML;
+import javafx.stage.Stage;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicReference;
+
+@HealthCheckScoped
+public class CheckController implements FxController {
+
+	private static final Logger LOG = LoggerFactory.getLogger(CheckController.class);
+
+	private final Vault vault;
+	private final Stage window;
+	private final Masterkey masterkey;
+	private final VaultConfig vaultConfig;
+	private final SecureRandom csprng;
+
+	@Inject
+	public CheckController(@HealthCheckWindow Vault vault, @HealthCheckWindow Stage window, AtomicReference<Masterkey> masterkeyRef, AtomicReference<VaultConfig> vaultConfigRef, SecureRandom csprng) {
+		this.vault = vault;
+		this.window = window;
+		this.masterkey = Objects.requireNonNull(masterkeyRef.get());
+		this.vaultConfig = Objects.requireNonNull(vaultConfigRef.get());
+		this.csprng = csprng;
+	}
+
+	@FXML
+	public void runCheck() {
+		// TODO run in background task...
+		try (var cryptor = vaultConfig.getCipherCombo().getCryptorProvider(csprng).withKey(masterkey)) {
+			List<DiagnosticResult> results = new ArrayList<>();
+			HealthCheck.allChecks().forEach(c -> {
+				LOG.info("Running check {}...", c.identifier());
+				results.addAll(c.check(vault.getPath(), vaultConfig, masterkey, cryptor));
+			});
+			results.forEach(r -> {
+				LOG.info("Result: {}", r);
+			});
+		}
+	}
+
+	public VaultConfig getVaultConfig() {
+		return vaultConfig;
+	}
+}

+ 44 - 2
main/ui/src/main/java/org/cryptomator/ui/health/HealthCheckModule.java

@@ -5,6 +5,8 @@ import dagger.Module;
 import dagger.Provides;
 import dagger.multibindings.IntoMap;
 import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.cryptofs.VaultConfig;
+import org.cryptomator.cryptolib.api.Masterkey;
 import org.cryptomator.ui.common.DefaultSceneFactory;
 import org.cryptomator.ui.common.FxController;
 import org.cryptomator.ui.common.FxControllerKey;
@@ -17,15 +19,32 @@ import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
 import org.cryptomator.ui.mainwindow.MainWindow;
 
 import javax.inject.Provider;
+import javafx.beans.Observable;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
 import javafx.scene.Scene;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 import java.util.Map;
+import java.util.Optional;
 import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicReference;
 
 @Module(subcomponents = {KeyLoadingComponent.class})
 abstract class HealthCheckModule {
 
+	@Provides
+	@HealthCheckScoped
+	static AtomicReference<Masterkey> provideMasterkeyRef() {
+		return new AtomicReference<>();
+	}
+
+	@Provides
+	@HealthCheckScoped
+	static AtomicReference<VaultConfig> provideVaultConfigRef() {
+		return new AtomicReference<>();
+	}
+
 	@Provides
 	@HealthCheckWindow
 	@HealthCheckScoped
@@ -43,25 +62,48 @@ abstract class HealthCheckModule {
 	@Provides
 	@HealthCheckWindow
 	@HealthCheckScoped
-	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle) {
+	static Stage provideStage(StageFactory factory, @MainWindow Stage owner, ResourceBundle resourceBundle, ChangeListener<Boolean> showingListener) {
 		Stage stage = factory.create();
 		stage.setTitle(resourceBundle.getString("health.title"));
 		stage.setResizable(false);
 		stage.initModality(Modality.WINDOW_MODAL);
 		stage.initOwner(owner);
+		stage.showingProperty().addListener(showingListener);
 		return stage;
 	}
 
+	@Provides
+	@HealthCheckScoped
+	static ChangeListener<Boolean> provideWindowShowingChangeListener(AtomicReference<Masterkey> masterkey) {
+		return (observable, wasShowing, isShowing) -> {
+			if (!isShowing) {
+				Optional.ofNullable(masterkey.getAndSet(null)).ifPresent(Masterkey::destroy);
+			}
+		};
+	}
+
 	@Provides
 	@FxmlScene(FxmlFile.HEALTH_START)
 	@HealthCheckScoped
-	static Scene provideUnlockSelectMasterkeyFileScene(@HealthCheckWindow FxmlLoaderFactory fxmlLoaders) {
+	static Scene provideHealthStartScene(@HealthCheckWindow FxmlLoaderFactory fxmlLoaders) {
 		return fxmlLoaders.createScene(FxmlFile.HEALTH_START);
 	}
 
+	@Provides
+	@FxmlScene(FxmlFile.HEALTH_CHECK)
+	@HealthCheckScoped
+	static Scene provideHealthCheckScene(@HealthCheckWindow FxmlLoaderFactory fxmlLoaders) {
+		return fxmlLoaders.createScene(FxmlFile.HEALTH_CHECK);
+	}
+
 	@Binds
 	@IntoMap
 	@FxControllerKey(StartController.class)
 	abstract FxController bindStartController(StartController controller);
 
+	@Binds
+	@IntoMap
+	@FxControllerKey(CheckController.class)
+	abstract FxController bindCheckController(CheckController controller);
+
 }

+ 32 - 19
main/ui/src/main/java/org/cryptomator/ui/health/StartController.java

@@ -1,5 +1,6 @@
 package org.cryptomator.ui.health;
 
+import dagger.Lazy;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.cryptofs.VaultConfig;
 import org.cryptomator.cryptofs.VaultConfigLoadException;
@@ -7,6 +8,8 @@ import org.cryptomator.cryptofs.VaultKeyInvalidException;
 import org.cryptomator.cryptolib.api.Masterkey;
 import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
 import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.common.FxmlFile;
+import org.cryptomator.ui.common.FxmlScene;
 import org.cryptomator.ui.fxapp.FxApplication;
 import org.cryptomator.ui.keyloading.KeyLoadingStrategy;
 import org.cryptomator.ui.unlock.UnlockCancelledException;
@@ -16,10 +19,12 @@ import org.slf4j.LoggerFactory;
 import javax.inject.Inject;
 import javafx.application.Platform;
 import javafx.fxml.FXML;
+import javafx.scene.Scene;
 import javafx.stage.Stage;
 import java.net.URI;
 import java.util.Optional;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicReference;
 
 @HealthCheckScoped
 public class StartController implements FxController {
@@ -30,13 +35,19 @@ public class StartController implements FxController {
 	private final Optional<VaultConfig.UnverifiedVaultConfig> unverifiedVaultConfig;
 	private final KeyLoadingStrategy keyLoadingStrategy;
 	private final ExecutorService executor;
+	private final AtomicReference<Masterkey> masterkeyRef;
+	private final AtomicReference<VaultConfig> vaultConfigRef;
+	private final Lazy<Scene> checkScene;
 
 	@Inject
-	public StartController(@HealthCheckWindow Vault vault, @HealthCheckWindow Stage window, @HealthCheckWindow KeyLoadingStrategy keyLoadingStrategy, ExecutorService executor) {
+	public StartController(@HealthCheckWindow Vault vault, @HealthCheckWindow Stage window, @HealthCheckWindow KeyLoadingStrategy keyLoadingStrategy, ExecutorService executor, AtomicReference<Masterkey> masterkeyRef, AtomicReference<VaultConfig> vaultConfigRef, @FxmlScene(FxmlFile.HEALTH_CHECK) Lazy<Scene> checkScene) {
 		this.window = window;
 		this.unverifiedVaultConfig = vault.getUnverifiedVaultConfig();
 		this.keyLoadingStrategy = keyLoadingStrategy;
 		this.executor = executor;
+		this.masterkeyRef = masterkeyRef;
+		this.vaultConfigRef = vaultConfigRef;
+		this.checkScene = checkScene;
 	}
 
 	@FXML
@@ -53,9 +64,16 @@ public class StartController implements FxController {
 
 	private void loadKey() {
 		assert !Platform.isFxApplicationThread();
+		assert unverifiedVaultConfig.isPresent();
 		try (var masterkey = keyLoadingStrategy.masterkeyLoader().loadKey(unverifiedVaultConfig.orElseThrow().getKeyId())) {
-			var clone = masterkey.clone(); // original key will get destroyed
-			Platform.runLater(() -> loadedKey(clone));
+			var unverifiedCfg = unverifiedVaultConfig.get();
+			var verifiedCfg = unverifiedCfg.verify(masterkey.getEncoded(), unverifiedCfg.allegedVaultVersion());
+			vaultConfigRef.set(verifiedCfg);
+			var old = masterkeyRef.getAndSet(masterkey.clone());
+			if (old != null) {
+				old.destroy();
+			}
+			Platform.runLater(this::loadedKey);
 		} catch (MasterkeyLoadingFailedException e) {
 			if (keyLoadingStrategy.recoverFromException(e)) {
 				// retry
@@ -63,29 +81,24 @@ public class StartController implements FxController {
 			} else {
 				Platform.runLater(() -> loadingKeyFailed(e));
 			}
-		}
-	}
-
-	private void loadedKey(Masterkey masterkey) {
-		assert unverifiedVaultConfig.isPresent();
-		var unverifiedCfg = unverifiedVaultConfig.get();
-		try {
-			var verifiedCfg = unverifiedCfg.verify(masterkey.getEncoded(), unverifiedCfg.allegedVaultVersion());
-			LOG.info("Verified vault config with cipher {}", verifiedCfg.getCipherCombo());
 		} catch (VaultKeyInvalidException e) {
-			LOG.error("Invalid key");
-			// TODO show error screen
+			Platform.runLater(() -> loadingKeyFailed(e));
 		} catch (VaultConfigLoadException e) {
-			LOG.error("Failed to verify vault config", e);
-			// TODO show error screen
-		} finally {
-			masterkey.destroy();
+			Platform.runLater(() -> loadingKeyFailed(e));
 		}
 	}
 
-	private void loadingKeyFailed(MasterkeyLoadingFailedException e) {
+	private void loadedKey() {
+		LOG.debug("Loaded valid key");
+		window.setScene(checkScene.get());
+	}
+
+	private void loadingKeyFailed(Exception e) {
 		if (e instanceof UnlockCancelledException) {
 			// ok
+		} else if (e instanceof VaultKeyInvalidException) {
+			LOG.error("Invalid key");
+			// TODO show error screen
 		} else {
 			LOG.error("Failed to load key.", e);
 			// TODO show error screen

+ 27 - 0
main/ui/src/main/resources/fxml/health_check.fxml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.VBox?>
+<VBox xmlns:fx="http://javafx.com/fxml"
+	  xmlns="http://javafx.com/javafx"
+	  fx:controller="org.cryptomator.ui.health.CheckController"
+	  minWidth="400"
+	  maxWidth="400"
+	  minHeight="145"
+	  spacing="12">
+	<padding>
+		<Insets topRightBottomLeft="12"/>
+	</padding>
+	<children>
+		<Label text="${controller.vaultConfig.cipherCombo}"/>
+
+		<ButtonBar buttonMinWidth="120" buttonOrder="+X">
+			<buttons>
+				<Button text="TODO run check" ButtonBar.buttonData="NEXT_FORWARD" defaultButton="true" onAction="#runCheck"/>
+			</buttons>
+		</ButtonBar>
+	</children>
+</VBox>

+ 1 - 1
main/ui/src/main/resources/fxml/health_start.fxml

@@ -25,7 +25,7 @@
 		<ButtonBar buttonMinWidth="120" buttonOrder="+CX">
 			<buttons>
 				<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" cancelButton="true" onAction="#close"/>
-				<Button text="%unlock.unlockBtn" ButtonBar.buttonData="NEXT_FORWARD" disable="${controller.invalidConfig}" defaultButton="true" onAction="#next"/>
+				<Button text="%generic.button.next" ButtonBar.buttonData="NEXT_FORWARD" disable="${controller.invalidConfig}" defaultButton="true" onAction="#next"/>
 			</buttons>
 		</ButtonBar>
 	</children>