From c306151980ad7b8d5942b6bae0e1545a76282690 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Wed, 2 Mar 2016 13:10:26 +0100 Subject: [PATCH] fixes #88 --- .../org/cryptomator/ui/CryptomatorModule.java | 3 +- .../ui/controllers/SettingsController.java | 49 ++++++++++++++++--- .../ui/controllers/UnlockController.java | 10 ++-- .../java/org/cryptomator/ui/model/Vault.java | 9 ++-- .../cryptomator/ui/model/VaultFactory.java | 9 +--- .../org/cryptomator/ui/settings/Settings.java | 30 +++++++++++- main/ui/src/main/resources/fxml/settings.fxml | 44 ++++++++++------- .../main/resources/localization.properties | 3 ++ 8 files changed, 112 insertions(+), 45 deletions(-) diff --git a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java index 58629e841..7db4de607 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java @@ -90,7 +90,8 @@ class CryptomatorModule { @Provides @Singleton - FrontendFactory provideFrontendFactory(WebDavServer webDavServer) { + FrontendFactory provideFrontendFactory(WebDavServer webDavServer, Settings settings) { + webDavServer.setPort(settings.getPort()); webDavServer.start(); return closeLater(webDavServer, WebDavServer::stop); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java index fd433fc34..e51c50d4e 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java @@ -14,31 +14,39 @@ import java.util.ResourceBundle; import javax.inject.Inject; import javax.inject.Singleton; +import org.apache.commons.lang3.CharUtils; import org.cryptomator.ui.settings.Settings; import org.fxmisc.easybind.EasyBind; -import javafx.application.Application; import javafx.fxml.FXML; import javafx.scene.control.CheckBox; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyEvent; @Singleton public class SettingsController extends AbstractFXMLViewController { - private final Application app; private final Settings settings; @Inject - public SettingsController(Application app, Settings settings) { - this.app = app; + public SettingsController(Settings settings) { this.settings = settings; } @FXML private CheckBox checkForUpdatesCheckbox; + @FXML + private TextField portField; + @Override public void initialize() { - checkForUpdatesCheckbox.setSelected(settings.isCheckForUpdatesEnabled()); + checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally()); + checkForUpdatesCheckbox.setSelected(settings.isCheckForUpdatesEnabled() && !areUpdatesManagedExternally()); + portField.setText(String.valueOf(settings.getPort())); + portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents); + + EasyBind.subscribe(portField.textProperty(), this::portDidChange); EasyBind.subscribe(checkForUpdatesCheckbox.selectedProperty(), settings::setCheckForUpdatesEnabled); } @@ -52,8 +60,33 @@ public class SettingsController extends AbstractFXMLViewController { return ResourceBundle.getBundle("localization"); } - // private boolean areUpdatesManagedExternally() { - // return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false")); - // } + private void portDidChange(String newValue) { + try { + int port = Integer.parseInt(newValue); + if (port < Settings.MIN_PORT) { + settings.setPort(Settings.DEFAULT_PORT); + } else if (port < Settings.MAX_PORT) { + settings.setPort(port); + } else { + portField.setText(String.valueOf(Settings.MAX_PORT)); + } + } catch (NumberFormatException e) { + portField.setText(String.valueOf(Settings.DEFAULT_PORT)); + } + } + + private void filterNumericKeyEvents(KeyEvent t) { + if (t.getCharacter() == null || t.getCharacter().length() == 0) { + return; + } + char c = CharUtils.toChar(t.getCharacter()); + if (!(CharUtils.isAsciiNumeric(c) || c == '_')) { + t.consume(); + } + } + + private boolean areUpdatesManagedExternally() { + return Boolean.parseBoolean(System.getProperty("cryptomator.updatesManagedExternally", "false")); + } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java index 10692f163..3d92b9f2a 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java @@ -21,6 +21,7 @@ import org.cryptomator.crypto.engine.InvalidPassphraseException; import org.cryptomator.crypto.engine.UnsupportedVaultFormatException; import org.cryptomator.frontend.CommandFailedException; import org.cryptomator.frontend.FrontendCreationFailedException; +import org.cryptomator.frontend.FrontendFactory; import org.cryptomator.frontend.webdav.mount.WindowsDriveLetters; import org.cryptomator.ui.controls.SecPasswordField; import org.cryptomator.ui.model.Vault; @@ -28,6 +29,7 @@ import org.fxmisc.easybind.EasyBind; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import dagger.Lazy; import javafx.application.Application; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; @@ -51,16 +53,18 @@ public class UnlockController extends AbstractFXMLViewController { private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class); - private final ExecutorService exec; private final Application app; + private final ExecutorService exec; + private final Lazy frontendFactory; private final WindowsDriveLetters driveLetters; private final ChangeListener driveLetterChangeListener = this::winDriveLetterDidChange; final ObjectProperty vault = new SimpleObjectProperty<>(); @Inject - public UnlockController(Application app, ExecutorService exec, WindowsDriveLetters driveLetters) { + public UnlockController(Application app, ExecutorService exec, Lazy frontendFactory, WindowsDriveLetters driveLetters) { this.app = app; this.exec = exec; + this.frontendFactory = frontendFactory; this.driveLetters = driveLetters; } @@ -272,7 +276,7 @@ public class UnlockController extends AbstractFXMLViewController { private void unlock(CharSequence password) { try { - vault.get().activateFrontend(password); + vault.get().activateFrontend(frontendFactory.get(), password); vault.get().reveal(); } catch (InvalidPassphraseException e) { Platform.runLater(() -> { diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java index ba7ca9cc9..4b37246d2 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java @@ -45,7 +45,6 @@ import org.cryptomator.ui.util.FXThreads; import com.google.common.collect.ImmutableMap; -import dagger.Lazy; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -59,7 +58,6 @@ public class Vault implements Serializable, CryptoFileSystemDelegate { public static final String VAULT_FILE_EXTENSION = ".cryptomator"; private final Path path; - private final Lazy frontendFactory; private final DeferredCloser closer; private final ShorteningFileSystemFactory shorteningFileSystemFactory; private final CryptoFileSystemFactory cryptoFileSystemFactory; @@ -76,9 +74,8 @@ public class Vault implements Serializable, CryptoFileSystemDelegate { /** * Package private constructor, use {@link VaultFactory}. */ - Vault(Path vaultDirectoryPath, Lazy frontendFactory, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) { + Vault(Path vaultDirectoryPath, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, DeferredCloser closer) { this.path = vaultDirectoryPath; - this.frontendFactory = frontendFactory; this.closer = closer; this.shorteningFileSystemFactory = shorteningFileSystemFactory; this.cryptoFileSystemFactory = cryptoFileSystemFactory; @@ -118,7 +115,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate { } } - public synchronized void activateFrontend(CharSequence passphrase) throws FrontendCreationFailedException { + public synchronized void activateFrontend(FrontendFactory frontendFactory, CharSequence passphrase) throws FrontendCreationFailedException { boolean success = false; try { FileSystem fs = getNioFileSystem(); @@ -127,7 +124,7 @@ public class Vault implements Serializable, CryptoFileSystemDelegate { StatsFileSystem statsFs = new StatsFileSystem(cryptoFs); statsFileSystem = Optional.of(statsFs); String contextPath = StringUtils.prependIfMissing(mountName, "/"); - Frontend frontend = frontendFactory.get().create(statsFs, contextPath); + Frontend frontend = frontendFactory.create(statsFs, contextPath); filesystemFrontend = closer.closeLater(frontend); frontend.mount(getMountParams()); success = true; diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java index 702678b8a..a2c3f8f25 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultFactory.java @@ -15,30 +15,25 @@ import javax.inject.Singleton; import org.cryptomator.filesystem.crypto.CryptoFileSystemFactory; import org.cryptomator.filesystem.shortening.ShorteningFileSystemFactory; -import org.cryptomator.frontend.FrontendFactory; import org.cryptomator.frontend.webdav.mount.WebDavMounter; import org.cryptomator.ui.util.DeferredCloser; -import dagger.Lazy; - @Singleton public class VaultFactory { - private final Lazy frontendFactory; private final ShorteningFileSystemFactory shorteningFileSystemFactory; private final CryptoFileSystemFactory cryptoFileSystemFactory; private final DeferredCloser closer; @Inject - public VaultFactory(Lazy frontendFactory, ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, WebDavMounter mounter, DeferredCloser closer) { - this.frontendFactory = frontendFactory; + public VaultFactory(ShorteningFileSystemFactory shorteningFileSystemFactory, CryptoFileSystemFactory cryptoFileSystemFactory, WebDavMounter mounter, DeferredCloser closer) { this.shorteningFileSystemFactory = shorteningFileSystemFactory; this.cryptoFileSystemFactory = cryptoFileSystemFactory; this.closer = closer; } public Vault createVault(Path path) { - return new Vault(path, frontendFactory, shorteningFileSystemFactory, cryptoFileSystemFactory, closer); + return new Vault(path, shorteningFileSystemFactory, cryptoFileSystemFactory, closer); } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java index 14b195a53..1addad7c4 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java +++ b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java @@ -14,17 +14,26 @@ import java.util.List; import org.cryptomator.ui.model.Vault; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; -@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled"}) +@JsonPropertyOrder(value = {"directories", "checkForUpdatesEnabled", "port"}) public class Settings implements Serializable { private static final long serialVersionUID = 7609959894417878744L; + public static final int MIN_PORT = 1024; + public static final int MAX_PORT = 65535; + public static final int DEFAULT_PORT = 0; + @JsonProperty("directories") private List directories; + @JsonProperty("checkForUpdatesEnabled") private Boolean checkForUpdatesEnabled; + @JsonProperty("port") + private Integer port; + /** * Package-private constructor; use {@link SettingsProvider}. */ @@ -54,4 +63,23 @@ public class Settings implements Serializable { this.checkForUpdatesEnabled = checkForUpdatesEnabled; } + public void setPort(int port) { + if (!isPortValid(port)) { + throw new IllegalArgumentException("Invalid port"); + } + this.port = port; + } + + public int getPort() { + if (port == null || !isPortValid(port)) { + return DEFAULT_PORT; + } else { + return port; + } + } + + private boolean isPortValid(int port) { + return port == DEFAULT_PORT || port >= MIN_PORT && port <= MAX_PORT; + } + } diff --git a/main/ui/src/main/resources/fxml/settings.fxml b/main/ui/src/main/resources/fxml/settings.fxml index 98e82c1ec..b15adfe20 100644 --- a/main/ui/src/main/resources/fxml/settings.fxml +++ b/main/ui/src/main/resources/fxml/settings.fxml @@ -1,6 +1,6 @@ -