Compare commits

...

14 Commits
1.4.6 ... 1.4.7

Author SHA1 Message Date
Sebastian Stenzel
a7de849800 Merge branch 'release/1.4.7' 2019-04-12 13:33:00 +02:00
Sebastian Stenzel
c66a8d0cfe Preparing 1.4.7 2019-04-12 13:24:27 +02:00
Sebastian Stenzel
efa7f78ffd Added IDE run configuration
[ci skip]
2019-04-12 13:20:42 +02:00
Sebastian Stenzel
57c858351d Further dependency updates 2019-04-12 12:42:12 +02:00
Sebastian Stenzel
c3e48934b2 fixes #862, fixes #853 2019-04-12 12:40:27 +02:00
Sebastian Stenzel
06b8c7cdf4 Fixes #866 2019-04-12 12:19:54 +02:00
Sebastian Stenzel
cbf677a51c Fixes #776, fixes #791, fixes #837 2019-04-12 12:17:27 +02:00
Sebastian Stenzel
923e58ba18 Simplified I/O graph calculation, reusing datapoints (might be a fix for #827, might also be related to #284) 2019-04-08 17:28:22 +02:00
infeo
65c12d7ae1 fixes #847 2019-04-03 16:56:44 +02:00
Sebastian Stenzel
8e324ef0eb code quality [ci skip] 2019-03-27 09:08:18 +01:00
Sebastian Stenzel
29a0336bf4 code quality [ci skip] 2019-03-27 08:50:20 +01:00
Sebastian Stenzel
44fc6761e3 fixes #858 2019-03-19 15:02:48 +01:00
Armin Schrenk
a4ef082bc4 fixes #854 2019-03-14 11:12:25 +01:00
Tobias Hagemann
1272279b96 Merge branch 'master' into develop 2019-03-01 15:02:37 +01:00
27 changed files with 183 additions and 226 deletions

14
.idea/compiler.xml generated
View File

@@ -7,26 +7,26 @@
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.20/dagger-compiler-2.20.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.20/dagger-2.20.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-compiler/2.22.1/dagger-compiler-2.22.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger/2.22.1/dagger-2.22.1.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/inject/javax.inject/1/javax.inject-1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.20/dagger-producers-2.20.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-producers/2.22.1/dagger-producers-2.22.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/guava/guava/25.0-jre/guava-25.0-jre.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar" />
<entry name="$MAVEN_REPOSITORY$/org/checkerframework/checker-compat-qual/2.5.3/checker-compat-qual-2.5.3.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.1.3/error_prone_annotations-2.1.3.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar" />
<entry name="$MAVEN_REPOSITORY$/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.20/dagger-spi-2.20.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/dagger/dagger-spi/2.22.1/dagger-spi-2.22.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/googlejavaformat/google-java-format/1.5/google-java-format-1.5.jar" />
<entry name="$MAVEN_REPOSITORY$/com/google/errorprone/javac-shaded/9-dev-r4023-3/javac-shaded-9-dev-r4023-3.jar" />
<entry name="$MAVEN_REPOSITORY$/com/squareup/javapoet/1.11.1/javapoet-1.11.1.jar" />
<entry name="$MAVEN_REPOSITORY$/javax/annotation/jsr250-api/1.0/jsr250-api-1.0.jar" />
</processorPath>
<module name="commons" />
<module name="keychain" />
<module name="launcher" />
<module name="commons" />
<module name="ui" />
<module name="launcher" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>

View File

@@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Cryptomator Windows" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="launcher" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/AppData/Roaming/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/AppData/Roaming/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/AppData/Roaming/Cryptomator&quot; -Dcryptomator.keychainPath=&quot;~/AppData/Roaming/Cryptomator/keychain.json&quot; -Xss2m -Xmx512m" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@@ -2,14 +2,8 @@
<configuration default="false" name="Cryptomator macOS" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.cryptomator.launcher.Cryptomator" />
<module name="launcher" />
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.mountPointsDir=&quot;/Volumes/&quot;" />
<option name="WORKING_DIRECTORY" value="$MAVEN_REPOSITORY$" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.cryptomator.launcher.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="VM_PARAMETERS" value="-Duser.language=en -Dcryptomator.settingsPath=&quot;~/Library/Application Support/Cryptomator/settings.json&quot; -Dcryptomator.ipcPortPath=&quot;~/Library/Application Support/Cryptomator/ipcPort.bin&quot; -Dcryptomator.logDir=&quot;~/Library/Logs/Cryptomator&quot; -Dcryptomator.mountPointsDir=&quot;/Volumes/&quot; -Xss2m -Xmx512m" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2">
<option name="Make" enabled="true" />
</method>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
</parent>
<artifactId>buildkit</artifactId>
<packaging>pom</packaging>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
</parent>
<artifactId>commons</artifactId>
<name>Cryptomator Commons</name>

View File

@@ -80,6 +80,7 @@ public class SettingsJsonAdapter extends TypeAdapter<Settings> {
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
break;
}
}
in.endObject();

View File

@@ -8,6 +8,16 @@
*******************************************************************************/
package org.cryptomator.common.settings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.cryptomator.common.Environment;
import org.cryptomator.common.LazyInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -16,8 +26,6 @@ import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
@@ -30,20 +38,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.common.LazyInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Singleton
public class SettingsProvider implements Provider<Settings> {

View File

@@ -76,6 +76,7 @@ class VaultSettingsJsonAdapter {
default:
LOG.warn("Unsupported vault setting found in JSON: " + name);
in.skipValue();
break;
}
}
in.endObject();

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
</parent>
<artifactId>keychain</artifactId>
<name>System Keychain Access</name>

View File

@@ -15,19 +15,17 @@ import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
import org.mockito.stubbing.Answer;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;
import java.util.stream.Stream;
public class WindowsProtectedKeychainAccessTest {
private Path keychainPath;
private WindowsProtectedKeychainAccess keychain;
@BeforeEach
public void setup(@TempDir Path tempDir) throws IOException {
keychainPath = tempDir.resolve("keychainfile.tmp");
public void setup(@TempDir Path tempDir) {
Path keychainPath = tempDir.resolve("keychainfile.tmp");
Environment env = Mockito.mock(Environment.class);
Mockito.when(env.getKeychainPath()).thenReturn(Stream.of(keychainPath));
WinFunctions winFunctions = Mockito.mock(WinFunctions.class);
@@ -40,7 +38,7 @@ public class WindowsProtectedKeychainAccessTest {
}
@Test
public void testStoreAndLoad() throws IOException {
public void testStoreAndLoad() {
String storedPw1 = "topSecret";
String storedPw2 = "bottomSecret";
keychain.storePassphrase("myPassword", storedPw1);

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
</parent>
<artifactId>launcher</artifactId>
<name>Cryptomator Launcher</name>

View File

@@ -6,7 +6,6 @@
package org.cryptomator.launcher;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.logging.DebugMode;
@@ -20,7 +19,6 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
@Singleton
public class Cryptomator {
@@ -56,14 +54,35 @@ public class Cryptomator {
private int run(String[] args) {
logConfig.init();
LOG.info("Starting Cryptomator {} on {} {} ({})", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
debugMode.initialize();
if (sendArgsToRunningInstance(args)) {
LOG.info("Found running application instance. Shutting down...");
return 0;
/*
* Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
* If no external process could be reached, the args will be handled by the loopback IPC endpoint.
*/
try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
if (endpoint.isConnectedToRemote()) {
LOG.info("Found running application instance. Shutting down...");
return 2;
} else {
LOG.debug("Did not find running application instance. Launching GUI...");
return runGuiApplication();
}
} catch (IOException e) {
LOG.error("Failed to initiate inter-process communication.", e);
return runGuiApplication();
}
}
/**
* Launches the JavaFX application and waits until shutdown is requested.
* @return Nonzero exit code in case of an error.
*/
private int runGuiApplication() {
try {
runGuiApplication();
CleanShutdownPerformer.registerShutdownHook();
Application.launch(MainApp.class);
LOG.info("Shutting down...");
return 0;
} catch (Throwable e) {
@@ -72,37 +91,6 @@ public class Cryptomator {
}
}
/**
* Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
* If no external process could be reached, the args will be handled by the loopback IPC endpoint.
*
* @param args Arguments to send to the instance (if possible)
* @return <code>true</code> if a different process could be reached, <code>false</code> otherwise.
*/
private boolean sendArgsToRunningInstance(String[] args) {
try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
return endpoint.isConnectedToRemote();
} catch (IOException e) {
LOG.error("Failed to initiate inter-process communication.", e);
return false;
}
}
/**
* Launches the JavaFX application and waits until shutdown is requested.
*/
private void runGuiApplication() {
debugMode.initialize();
CleanShutdownPerformer.registerShutdownHook();
Application.launch(MainApp.class);
// Platform.startup(() -> {
// assert Platform.isFxApplicationThread();
// FxApplication app = CRYPTOMATOR_COMPONENT.fxApplicationComponent().application();
// app.start();
// });
}
// We need a separate FX Application class, until we can use the module system. See https://stackoverflow.com/q/54756176/4014509
public static class MainApp extends Application {

View File

@@ -2,13 +2,9 @@ package org.cryptomator.launcher;
import dagger.Component;
import org.cryptomator.common.CommonsModule;
import org.cryptomator.common.Environment;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.logging.LoggerModule;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Optional;
@Singleton
@Component(modules = {CryptomatorModule.class, CommonsModule.class, LoggerModule.class})

View File

@@ -6,9 +6,15 @@
*******************************************************************************/
package org.cryptomator.launcher;
import org.cryptomator.ui.model.AppLaunchEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.awt.Desktop;
import java.awt.desktop.OpenFilesEvent;
import java.awt.desktop.QuitStrategy;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
@@ -17,17 +23,8 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.function.Function;
import java.util.stream.Stream;
import org.cryptomator.ui.model.AppLaunchEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@Singleton
class FileOpenRequestHandler {

View File

@@ -10,7 +10,6 @@ import dagger.Subcomponent;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.ui.controllers.ViewControllerLoader;
import javax.inject.Named;

View File

@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
<packaging>pom</packaging>
<name>Cryptomator</name>
@@ -25,29 +25,29 @@
<!-- dependency versions -->
<cryptomator.cryptolib.version>1.2.1</cryptomator.cryptolib.version>
<cryptomator.cryptofs.version>1.7.0</cryptomator.cryptofs.version>
<cryptomator.cryptofs.version>1.8.0</cryptomator.cryptofs.version>
<cryptomator.jni.version>2.0.0</cryptomator.jni.version>
<cryptomator.fuse.version>1.1.1</cryptomator.fuse.version>
<cryptomator.dokany.version>1.1.3</cryptomator.dokany.version>
<cryptomator.fuse.version>1.1.2</cryptomator.fuse.version>
<cryptomator.dokany.version>1.1.6</cryptomator.dokany.version>
<cryptomator.webdav.version>1.0.9</cryptomator.webdav.version>
<javafx.version>11.0.2</javafx.version>
<javafx.version>12</javafx.version>
<commons-io.version>2.6</commons-io.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<easybind.version>1.0.3</easybind.version>
<guava.version>27.0-jre</guava.version>
<dagger.version>2.20</dagger.version>
<guava.version>27.1-jre</guava.version>
<dagger.version>2.22.1</dagger.version>
<gson.version>2.8.5</gson.version>
<slf4j.version>1.7.25</slf4j.version>
<slf4j.version>1.7.26</slf4j.version>
<logback.version>1.2.3</logback.version>
<junit.jupiter.version>5.4.0</junit.jupiter.version>
<mockito.version>2.24.0</mockito.version>
<hamcrest.version>1.3</hamcrest.version>
<junit.jupiter.version>5.4.2</junit.jupiter.version>
<mockito.version>2.27.0</mockito.version>
<hamcrest.version>2.1</hamcrest.version>
</properties>
<repositories>
@@ -212,7 +212,7 @@
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<artifactId>hamcrest</artifactId>
<version>${hamcrest.version}</version>
</dependency>
<dependency>
@@ -236,7 +236,7 @@
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<artifactId>hamcrest</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@@ -4,7 +4,7 @@
<parent>
<groupId>org.cryptomator</groupId>
<artifactId>main</artifactId>
<version>1.4.6</version>
<version>1.4.7</version>
</parent>
<artifactId>ui</artifactId>
<name>Cryptomator GUI</name>

View File

@@ -14,7 +14,6 @@ import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.controllers.ViewControllerModule;

View File

@@ -9,27 +9,9 @@
*******************************************************************************/
package org.cryptomator.ui.controllers;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import javafx.beans.Observable;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.PasswordStrengthUtil;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.event.ActionEvent;
@@ -41,6 +23,21 @@ import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javafx.scene.text.Text;
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.util.PasswordStrengthUtil;
import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Objects;
import java.util.Optional;
public class ChangePasswordController implements ViewController {
@@ -113,7 +110,7 @@ public class ChangePasswordController implements ViewController {
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
}
private void passwordsChanged(Observable observable) {
private void passwordsChanged(@SuppressWarnings("unused") Observable observable) {
boolean oldPasswordEmpty = oldPasswordField.getCharacters().length() == 0;
boolean newPasswordEmpty = newPasswordField.getCharacters().length() == 0;
boolean passwordsEqual = newPasswordField.getCharacters().equals(retypePasswordField.getCharacters());

View File

@@ -9,16 +9,17 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.util.Objects;
import java.util.Optional;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.value.ObservableIntegerValue;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import org.cryptomator.ui.controls.SecPasswordField;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.Vault;
@@ -27,17 +28,11 @@ import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Region;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.FileAlreadyExistsException;
import java.util.Objects;
import java.util.Optional;
public class InitializeController implements ViewController {
@@ -101,7 +96,7 @@ public class InitializeController implements ViewController {
passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
}
private void passwordsChanged(Observable observable) {
private void passwordsChanged(@SuppressWarnings("unused") Observable observable) {
boolean passwordsEmpty = passwordField.getCharacters().length() == 0;
boolean passwordsEqual = passwordField.getCharacters().equals(retypePasswordField.getCharacters());
okButton.setDisable(passwordsEmpty || !passwordsEqual);

View File

@@ -20,7 +20,6 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Side;
import javafx.scene.Parent;
@@ -52,11 +51,11 @@ import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AppLaunchEvent;
import org.cryptomator.ui.model.AutoUnlocker;
import org.cryptomator.ui.model.upgrade.UpgradeStrategies;
import org.cryptomator.ui.model.upgrade.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
import org.cryptomator.ui.model.upgrade.UpgradeStrategies;
import org.cryptomator.ui.model.upgrade.UpgradeStrategy;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.Tasks;
import org.fxmisc.easybind.EasyBind;
@@ -220,12 +219,12 @@ public class MainController implements ViewController {
private void gracefulShutdown() {
vaults.filtered(Vault.NOT_LOCKED).forEach(Vault::prepareForShutdown);
if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
mainWindow.show(); // to keep the application open
ButtonType tryAgainButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.tryAgain"));
ButtonType forceShutdownButtonType = new ButtonType(localization.getString("main.gracefulShutdown.button.forceShutdown"));
Alert gracefulShutdownDialog = DialogBuilderUtil.buildGracefulShutdownDialog(
localization.getString("main.gracefulShutdown.dialog.title"), localization.getString("main.gracefulShutdown.dialog.header"), localization.getString("main.gracefulShutdown.dialog.content"),
forceShutdownButtonType, ButtonType.CANCEL, forceShutdownButtonType, tryAgainButtonType);
Optional<ButtonType> choice = gracefulShutdownDialog.showAndWait();
choice.ifPresent(btnType -> {
if (tryAgainButtonType.equals(btnType)) {
@@ -233,7 +232,11 @@ public class MainController implements ViewController {
} else if (forceShutdownButtonType.equals(btnType)) {
Platform.runLater(Platform::exit);
} else {
return;
if (!vaults.filtered(Vault.NOT_LOCKED).isEmpty()) {
showUnlockedView(vaults.get(0), false); //if there are still unlocked vaults, show one of them
} else {
showUnlockView(UnlockController.State.UNLOCKING); //otherwise show any vault
}
}
});
} else {
@@ -271,7 +274,7 @@ public class MainController implements ViewController {
// ****************************************
@FXML
private void didClickAddVault(ActionEvent event) {
private void didClickAddVault() {
if (addVaultContextMenu.isShowing()) {
addVaultContextMenu.hide();
} else {
@@ -280,7 +283,7 @@ public class MainController implements ViewController {
}
@FXML
private void didClickCreateNewVault(ActionEvent event) {
private void didClickCreateNewVault() {
final FileChooser fileChooser = new FileChooser();
final File file = fileChooser.showSaveDialog(mainWindow);
if (file == null) {
@@ -313,7 +316,7 @@ public class MainController implements ViewController {
}
@FXML
private void didClickAddExistingVaults(ActionEvent event) {
private void didClickAddExistingVaults() {
final FileChooser fileChooser = new FileChooser();
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator"));
final List<File> files = fileChooser.showOpenMultipleDialog(mainWindow);
@@ -356,7 +359,7 @@ public class MainController implements ViewController {
}
@FXML
private void didClickRemoveSelectedEntry(ActionEvent e) {
private void didClickRemoveSelectedEntry() {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("main.directoryList.remove.confirmation.title"), //
localization.getString("main.directoryList.remove.confirmation.header"), //
@@ -375,12 +378,12 @@ public class MainController implements ViewController {
}
@FXML
private void didClickChangePassword(ActionEvent e) {
private void didClickChangePassword() {
showChangePasswordView();
}
@FXML
private void didClickShowSettings(ActionEvent e) {
private void didClickShowSettings() {
toggleShowSettings();
}

View File

@@ -130,7 +130,7 @@ public class SettingsController implements ViewController {
}
@FXML
private void changePort(ActionEvent evt) {
private void changePort() {
assert isPortValid() : "Button must be disabled, if port is invalid.";
try {
int port = Integer.parseInt(portField.getText());
@@ -143,11 +143,8 @@ public class SettingsController implements ViewController {
private boolean isPortValid() {
try {
int port = Integer.parseInt(portField.getText());
if (port == 0 || port >= Settings.MIN_PORT && port <= Settings.MAX_PORT) {
return true;
} else {
return false;
}
return port == 0 // choose port automatically
|| port >= Settings.MIN_PORT && port <= Settings.MAX_PORT; // port within range
} catch (NumberFormatException e) {
return false;
}
@@ -159,7 +156,7 @@ public class SettingsController implements ViewController {
}
}
private void setVisibilityGvfsElements(Observable obs, Object oldValue, Object newValue) {
private void setVisibilityGvfsElements(@SuppressWarnings("unused") Observable obs, @SuppressWarnings("unused")Object oldValue, Object newValue) {
prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX && ((VolumeImpl) newValue).getDisplayName().equals("WebDAV"));
}

View File

@@ -13,7 +13,6 @@ import com.google.common.base.Strings;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Alert;
@@ -287,7 +286,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
public void didClickDownloadsLink(ActionEvent event) {
public void didClickDownloadsLink() {
app.getHostServices().showDocument("https://cryptomator.org/downloads/#allVersions");
}
@@ -296,7 +295,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
private void didClickAdvancedOptionsButton(ActionEvent event) {
private void didClickAdvancedOptionsButton() {
messageText.setText(null);
advancedOptions.setVisible(!advancedOptions.isVisible());
if (advancedOptions.isVisible()) {
@@ -312,7 +311,7 @@ public class UnlockController implements ViewController {
}
}
private void mountNameDidChange(ObservableValue<? extends String> property, String oldValue, String newValue) {
private void mountNameDidChange(@SuppressWarnings("unused") ObservableValue<? extends String> property, @SuppressWarnings("unused")String oldValue, String newValue) {
// newValue is guaranteed to be a-z0-9_, see #filterAlphanumericKeyEvents
if (newValue.isEmpty()) {
mountName.setText(vault.getMountName());
@@ -321,7 +320,8 @@ public class UnlockController implements ViewController {
}
}
public void didClickChooseCustomMountPoint(ActionEvent actionEvent) {
@FXML
public void didClickChooseCustomMountPoint() {
DirectoryChooser dirChooser = new DirectoryChooser();
File file = dirChooser.showDialog(mainWindow);
if (file != null) {
@@ -372,7 +372,7 @@ public class UnlockController implements ViewController {
}
}
private void winDriveLetterDidChange(ObservableValue<? extends Character> property, Character oldValue, Character newValue) {
private void winDriveLetterDidChange(@SuppressWarnings("unused") ObservableValue<? extends Character> property, @SuppressWarnings("unused") Character oldValue, Character newValue) {
vault.setWinDriveLetter(newValue);
}
@@ -396,7 +396,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
private void didClickSavePasswordCheckbox(ActionEvent event) {
private void didClickSavePasswordCheckbox() {
if (!savePassword.isSelected() && hasStoredPassword()) {
Alert confirmDialog = DialogBuilderUtil.buildConfirmationDialog( //
localization.getString("unlock.savePassword.delete.confirmation.title"), //
@@ -427,7 +427,7 @@ public class UnlockController implements ViewController {
// ****************************************
@FXML
private void didClickUnlockButton(ActionEvent event) {
private void didClickUnlockButton() {
advancedOptions.setDisable(true);
advancedOptions.setVisible(false);
advancedOptionsButton.setText(localization.getString("unlock.button.advancedOptions.show"));
@@ -441,9 +441,10 @@ public class UnlockController implements ViewController {
keychainAccess.get().storePassphrase(vault.getId(), password);
}
}).onSuccess(() -> {
messageText.setText(null);
messageText.setText("");
downloadsPageLink.setVisible(false);
listener.ifPresent(lstnr -> lstnr.didUnlock(vault));
passwordField.swipe();
}).onError(InvalidPassphraseException.class, e -> {
messageText.setText(localization.getString("unlock.errorMessage.wrongPassword"));
passwordField.selectAll();
@@ -473,9 +474,6 @@ public class UnlockController implements ViewController {
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);
progressText.setText(null);

View File

@@ -2,16 +2,12 @@
* Copyright (c) 2014, 2017 Sebastian Stenzel
* All rights reserved.
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
*
*
* Contributors:
* Sebastian Stenzel - initial API and implementation
******************************************************************************/
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
@@ -42,6 +38,10 @@ import org.fxmisc.easybind.EasyBind;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import static java.lang.String.format;
public class UnlockedController implements ViewController {
@@ -49,7 +49,7 @@ public class UnlockedController implements ViewController {
private static final Logger LOG = LoggerFactory.getLogger(UnlockedController.class);
private static final int IO_SAMPLING_STEPS = 100;
private static final double IO_SAMPLING_INTERVAL = 0.25;
private static final double IO_SAMPLING_INTERVAL = 0.5;
private final Localization localization;
private final ExecutorService executor;
@@ -103,7 +103,7 @@ public class UnlockedController implements ViewController {
}
@FXML
private void didClickLockVault(ActionEvent event) {
private void didClickLockVault() {
regularLockVault(this::lockVaultSucceeded);
}
@@ -156,7 +156,7 @@ public class UnlockedController implements ViewController {
}
@FXML
private void didClickMoreOptions(ActionEvent event) {
private void didClickMoreOptions() {
if (moreOptionsMenu.isShowing()) {
moreOptionsMenu.hide();
} else {
@@ -166,7 +166,7 @@ public class UnlockedController implements ViewController {
}
@FXML
private void didClickRevealVault(ActionEvent event) {
private void didClickRevealVault() {
revealVault(vault.get());
}
@@ -211,43 +211,42 @@ public class UnlockedController implements ViewController {
private class IoSamplingAnimationHandler implements EventHandler<ActionEvent> {
private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
private static final double SMOOTHING_FACTOR = 0.3;
private static final long EFFECTIVELY_ZERO = 100000; // 100kb
private final Series<Number, Number> decryptedBytes;
private final Series<Number, Number> encryptedBytes;
private int step = 0;
private long oldDecBytes = 0;
private long oldEncBytes = 0;
public IoSamplingAnimationHandler(Series<Number, Number> decryptedBytes, Series<Number, Number> encryptedBytes) {
this.decryptedBytes = decryptedBytes;
this.encryptedBytes = encryptedBytes;
// initialize data once and change value of datapoints later:
for (int i = 0; i < IO_SAMPLING_STEPS; i++) {
decryptedBytes.getData().add(new Data<>(i, 0));
encryptedBytes.getData().add(new Data<>(i, 0));
}
xAxis.setLowerBound(0);
xAxis.setUpperBound(IO_SAMPLING_STEPS);
}
@Override
public void handle(ActionEvent event) {
step++;
// move all values one step:
for (int i = 0; i < IO_SAMPLING_STEPS - 1; i++) {
int j = i + 1;
Number tmp = decryptedBytes.getData().get(j).getYValue();
decryptedBytes.getData().get(i).setYValue(tmp);
tmp = encryptedBytes.getData().get(j).getYValue();
encryptedBytes.getData().get(i).setYValue(tmp);
}
// add latest value:
final long decBytes = vault.get().pollBytesRead();
final double smoothedDecBytes = oldDecBytes + SMOOTHING_FACTOR * (decBytes - oldDecBytes);
final double smoothedDecMb = smoothedDecBytes * BYTES_TO_MEGABYTES_FACTOR;
oldDecBytes = smoothedDecBytes > EFFECTIVELY_ZERO ? (long) smoothedDecBytes : 0l;
decryptedBytes.getData().add(new Data<Number, Number>(step, smoothedDecMb));
if (decryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
decryptedBytes.getData().remove(0);
}
final double decMb = decBytes * BYTES_TO_MEGABYTES_FACTOR;
final long encBytes = vault.get().pollBytesWritten();
final double smoothedEncBytes = oldEncBytes + SMOOTHING_FACTOR * (encBytes - oldEncBytes);
final double smoothedEncMb = smoothedEncBytes * BYTES_TO_MEGABYTES_FACTOR;
oldEncBytes = smoothedEncBytes > EFFECTIVELY_ZERO ? (long) smoothedEncBytes : 0l;
encryptedBytes.getData().add(new Data<Number, Number>(step, smoothedEncMb));
if (encryptedBytes.getData().size() > IO_SAMPLING_STEPS) {
encryptedBytes.getData().remove(0);
}
xAxis.setLowerBound(step - IO_SAMPLING_STEPS);
xAxis.setUpperBound(step);
final double encMb = encBytes * BYTES_TO_MEGABYTES_FACTOR;
decryptedBytes.getData().get(IO_SAMPLING_STEPS - 1).setYValue(decMb);
encryptedBytes.getData().get(IO_SAMPLING_STEPS - 1).setYValue(encMb);
}
}
@@ -269,6 +268,7 @@ public class UnlockedController implements ViewController {
@FunctionalInterface
interface LockListener {
void didLock(UnlockedController ctrl);
}

View File

@@ -16,7 +16,6 @@ import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
import java.nio.file.Path;

View File

@@ -18,7 +18,6 @@ import javafx.beans.property.SimpleObjectProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.LazyInitializer;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.cryptofs.CryptoFileSystem;
import org.cryptomator.cryptofs.CryptoFileSystemProperties;
@@ -52,9 +51,7 @@ public class Vault {
public static final Predicate<Vault> NOT_LOCKED = hasState(State.LOCKED).negate();
private static final Logger LOG = LoggerFactory.getLogger(Vault.class);
private static final String MASTERKEY_FILENAME = "masterkey.cryptomator";
private static final String LOCALHOST_ALIAS = "cryptomator-vault";
private final Settings settings;
private final VaultSettings vaultSettings;
private final Provider<Volume> volumeProvider;
private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>();
@@ -67,8 +64,7 @@ public class Vault {
}
@Inject
Vault(Settings settings, VaultSettings vaultSettings, Provider<Volume> volumeProvider) {
this.settings = settings;
Vault(VaultSettings vaultSettings, Provider<Volume> volumeProvider) {
this.vaultSettings = vaultSettings;
this.volumeProvider = volumeProvider;
}

View File

@@ -7,22 +7,17 @@
Contributors:
Sebastian Stenzel - initial API and implementation
-->
<?import java.net.URL?>
<?import java.lang.String?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.ContextMenu?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.control.ContextMenu?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<VBox fx:controller="org.cryptomator.ui.controllers.UnlockedController" fx:id="root" prefWidth="400.0" prefHeight="400.0" spacing="6.0" xmlns:fx="http://javafx.com/fxml" cacheShape="true" cache="true">
<fx:define>