mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-08-18 05:06:02 +00:00
fixes #88
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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> frontendFactory;
|
||||
private final WindowsDriveLetters driveLetters;
|
||||
private final ChangeListener<Character> driveLetterChangeListener = this::winDriveLetterDidChange;
|
||||
final ObjectProperty<Vault> vault = new SimpleObjectProperty<>();
|
||||
|
||||
@Inject
|
||||
public UnlockController(Application app, ExecutorService exec, WindowsDriveLetters driveLetters) {
|
||||
public UnlockController(Application app, ExecutorService exec, Lazy<FrontendFactory> 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(() -> {
|
||||
|
||||
@@ -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> 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> 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;
|
||||
|
||||
@@ -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> frontendFactory;
|
||||
private final ShorteningFileSystemFactory shorteningFileSystemFactory;
|
||||
private final CryptoFileSystemFactory cryptoFileSystemFactory;
|
||||
private final DeferredCloser closer;
|
||||
|
||||
@Inject
|
||||
public VaultFactory(Lazy<FrontendFactory> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Vault> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2014 Sebastian Stenzel
|
||||
Copyright (c) 2016 Sebastian Stenzel
|
||||
This file is licensed under the terms of the MIT license.
|
||||
See the LICENSE.txt file for more info.
|
||||
|
||||
@@ -13,23 +13,29 @@
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
<VBox prefWidth="400.0" alignment="TOP_CENTER" spacing="12.0" cacheShape="true" cache="true">
|
||||
<GridPane VBox.vgrow="ALWAYS" vgap="12.0" hgap="12.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints percentWidth="38.2"/>
|
||||
<ColumnConstraints percentWidth="61.8"/>
|
||||
</columnConstraints>
|
||||
|
||||
<columnConstraints>
|
||||
<ColumnConstraints percentWidth="38.2"/>
|
||||
<ColumnConstraints percentWidth="61.8"/>
|
||||
</columnConstraints>
|
||||
|
||||
<children>
|
||||
<!-- Row 0 -->
|
||||
<Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" />
|
||||
</children>
|
||||
</GridPane>
|
||||
|
||||
|
||||
|
||||
<children>
|
||||
<!-- Row 0 -->
|
||||
<Label GridPane.rowIndex="0" GridPane.columnIndex="0" text="%settings.checkForUpdates.label" cacheShape="true" cache="true" />
|
||||
<CheckBox GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="checkForUpdatesCheckbox" cacheShape="true" cache="true" />
|
||||
|
||||
<!-- Row 1 -->
|
||||
<Label GridPane.rowIndex="1" GridPane.columnIndex="0" text="%settings.port.label" cacheShape="true" cache="true" />
|
||||
<TextField GridPane.rowIndex="1" GridPane.columnIndex="1" fx:id="portField" cacheShape="true" cache="true" promptText="%settings.port.prompt" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<Label VBox.vgrow="NEVER" text="%settings.requiresRestartLabel" alignment="CENTER" cacheShape="true" cache="true" />
|
||||
</VBox>
|
||||
@@ -73,6 +73,9 @@ macWarnings.whitelistButton=Decrypt selected anyway
|
||||
|
||||
# settings.fxml
|
||||
settings.checkForUpdates.label=Check for updates
|
||||
settings.port.label=WebDAV Port *
|
||||
settings.port.prompt=0 = Choose automatically
|
||||
settings.requiresRestartLabel=* Restart required
|
||||
|
||||
# tray icon
|
||||
tray.menu.open=Open
|
||||
|
||||
Reference in New Issue
Block a user