This commit is contained in:
infeo
2018-07-17 18:35:43 +02:00
parent 019b7ac643
commit ee99e9994e
5 changed files with 36 additions and 58 deletions

View File

@@ -9,10 +9,6 @@
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
@@ -22,7 +18,6 @@ import java.util.concurrent.ExecutorService;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
@@ -39,7 +34,6 @@ import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.util.StringConverter;
import org.apache.commons.lang3.CharUtils;
@@ -51,6 +45,7 @@ import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.frontend.webdav.ServerLifecycleException;
import org.cryptomator.keychain.KeychainAccess;
import org.cryptomator.ui.model.InvalidSettingsException;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
@@ -122,18 +117,12 @@ public class UnlockController implements ViewController {
@FXML
private CheckBox useOwnMountPath;
@FXML
private HBox mountPathBox;
@FXML
private Label mountPathLabel;
@FXML
private TextField mountPath;
@FXML
private Button changeMountPathButton;
@FXML
private ProgressIndicator progressIndicator;
@@ -161,13 +150,10 @@ public class UnlockController implements ViewController {
savePassword.setDisable(!keychainAccess.isPresent());
unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not()));
mountPathLabel.setVisible(false);
mountPathBox.visibleProperty().bind(mountPathLabel.visibleProperty());
mountPathBox.managedProperty().bind(mountPathLabel.managedProperty());
mountPath.visibleProperty().bind(mountPathLabel.visibleProperty());
mountPath.managedProperty().bind(mountPathLabel.managedProperty());
changeMountPathButton.visibleProperty().bind(mountPathLabel.visibleProperty());
changeMountPathButton.managedProperty().bind(mountPathLabel.managedProperty());
mountPathLabel.visibleProperty().bind(useOwnMountPath.selectedProperty());
mountPath.visibleProperty().bind(useOwnMountPath.selectedProperty());
mountPath.managedProperty().bind(useOwnMountPath.selectedProperty());
mountPath.textProperty().addListener(this::mountPathDidChange);
if (SystemUtils.IS_OS_WINDOWS) {
winDriveLetter.setConverter(new WinDriveLetterLabelConverter());
@@ -175,7 +161,7 @@ public class UnlockController implements ViewController {
useOwnMountPath.setManaged(false);
mountPathLabel.setManaged(false);
//dirty cheat
mountPathBox.setMouseTransparent(true);
mountPath.setMouseTransparent(true);
} else {
winDriveLetterLabel.setVisible(false);
winDriveLetterLabel.setManaged(false);
@@ -187,10 +173,9 @@ public class UnlockController implements ViewController {
mountPathLabel.setManaged(false);
}
}
changeMountPathButton.disableProperty().bind(Bindings.createBooleanBinding(this::isDirVaild, mountPath.textProperty()).not());
}
@Override
public Parent getRoot() {
return root;
@@ -252,11 +237,8 @@ public class UnlockController implements ViewController {
vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), vaultSettings.revealAfterMount()::set));
vaultSubs = vaultSubs.and(EasyBind.subscribe(useOwnMountPath.selectedProperty(), vaultSettings.usesIndividualMountPath()::set));
changeMountPathButton.visibleProperty().bind(
vaultSettings.individualMountPath().isNotEqualTo(mountPath.textProperty())
);
mountPath.textProperty().setValue(vaultSettings.individualMountPath().getValueSafe());
mountPathLabel.visibleProperty().bind(useOwnMountPath.selectedProperty());
}
@@ -284,28 +266,6 @@ public class UnlockController implements ViewController {
}
}
@FXML
private void didClickchangeMountPathButton(ActionEvent event) {
assert isDirVaild();
vault.setMountPath(mountPath.getText());
}
private boolean isDirVaild() {
try {
if (!mountPath.textProperty().isEmpty().get()) {
Path p = Paths.get(mountPath.textProperty().get());
return Files.isDirectory(p) && Files.isReadable(p) && Files.isWritable(p) && Files.isExecutable(p);
} else {
return false;
}
} catch (InvalidPathException e) {
LOG.info("Invalid path");
return false;
}
}
private void filterAlphanumericKeyEvents(KeyEvent t) {
if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) {
t.consume();
@@ -321,6 +281,10 @@ public class UnlockController implements ViewController {
}
}
private void mountPathDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
vault.setIndividualMountPath(newValue);
}
/**
* Converts 'C' to "C:" to translate between model and GUI.
*/
@@ -420,6 +384,7 @@ public class UnlockController implements ViewController {
@FXML
private void didClickUnlockButton(ActionEvent event) {
advancedOptions.setDisable(true);
advancedOptions.setVisible(false);
progressIndicator.setVisible(true);
CharSequence password = passwordField.getCharacters();
@@ -432,6 +397,10 @@ public class UnlockController implements ViewController {
messageText.setText(null);
downloadsPageLink.setVisible(false);
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
}).onError(InvalidSettingsException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.invalidMountPath"));
advancedOptions.setVisible(true);
mountPath.setStyle("-fx-border-color: red;");
}).onError(InvalidPassphraseException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
passwordField.selectAll();
@@ -451,14 +420,17 @@ public class UnlockController implements ViewController {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).onError(Exception.class, e -> {
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
LOG.error("Unlock failed for technical reasons.", e);
messageText.setText(localization.getString("unlock.errorMessage.unlockFailed"));
}).andFinally(() -> {
if (!savePassword.isSelected()) {
passwordField.swipe();
}
advancedOptions.setDisable(false);
progressIndicator.setVisible(false);
if (advancedOptions.isVisible()) { //dirty programming, but otherwise the focus is wrong
mountPath.requestFocus();
}
}).runOnce(executor);
}

View File

@@ -0,0 +1,5 @@
package org.cryptomator.ui.model;
public class InvalidSettingsException extends RuntimeException {
}

View File

@@ -98,9 +98,12 @@ public class Vault {
CryptoFileSystemProvider.changePassphrase(getPath(), MASTERKEY_FILENAME, oldPassphrase, newPassphrase);
}
public synchronized void unlock(CharSequence passphrase) throws CryptoException, IOException, Volume.VolumeException {
public synchronized void unlock(CharSequence passphrase) throws InvalidSettingsException, CryptoException, IOException, Volume.VolumeException {
Platform.runLater(() -> state.set(State.PROCESSING));
try {
if (vaultSettings.usesIndividualMountPath().and(vaultSettings.individualMountPath().isEmpty()).get()) {
throw new InvalidSettingsException();
}
CryptoFileSystem fs = getCryptoFileSystem(passphrase);
volume = volumeProvider.get();
volume.mount(fs);

View File

@@ -91,11 +91,7 @@
<CheckBox GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" fx:id="useOwnMountPath" text="%unlock.label.useOwnMountPath" cacheShape="true" cache="true" />
<Label GridPane.rowIndex="6" GridPane.columnIndex="0" fx:id="mountPathLabel" text="%unlock.label.mountPath" cacheShape="true" cache="true" />
<HBox GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="mountPathBox" spacing="6.0">
<TextField fx:id="mountPath" cacheShape="true" cache="true" />
<Button text="%unlock.label.mountPathButton" fx:id="changeMountPathButton" onAction="#didClickchangeMountPathButton"/>
</HBox>
<TextField GridPane.rowIndex="6" GridPane.columnIndex="1" fx:id="mountPath" GridPane.hgrow="ALWAYS" maxWidth="Infinity" cacheShape="true" cache="true" />
</GridPane>

View File

@@ -69,8 +69,8 @@ unlock.label.mountName=Drive Name
unlock.label.unlockAfterStartup=Auto-Unlock on Start (Experimental)
unlock.label.revealAfterMount=Reveal Drive
unlock.label.winDriveLetter=Drive Letter
unlock.label.useOwnMountPath=Use own Mount point
unlock.label.mountPath=Mount Path
unlock.label.useOwnMountPath=Use individual mount point
unlock.label.mountPath=Mount path
unlock.label.mountPathButton=Apply
unlock.label.downloadsPageLink=All Cryptomator versions
unlock.label.advancedHeading=Advanced Options
@@ -82,6 +82,8 @@ unlock.savePassword.delete.confirmation.header=Do you really want to delete the
unlock.savePassword.delete.confirmation.content=The saved password of this vault will be immediately deleted from your system keychain. If you'd like to save your password again, you'd have to unlock your vault with the "Save Password" option enabled.
unlock.choicebox.winDriveLetter.auto=Assign automatically
unlock.errorMessage.wrongPassword=Wrong password
unlock.errorMessage.wrongPassword=Wrong Password
unlock.errorMessage.invalidMountPath=Individual mount path is not set.
unlock.errorMessage.unlockFailed=Unlock failed. See log file for details.
unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware=Unsupported vault. This vault has been created with an older version of Cryptomator.
unlock.errorMessage.unsupportedVersion.softwareOlderThanVault=Unsupported vault. This vault has been created with a newer version of Cryptomator.