mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-22 12:41:27 +00:00
@@ -25,6 +25,7 @@ public class Environment {
|
||||
private static final Path RELATIVE_HOME_DIR = Paths.get("~");
|
||||
private static final Path ABSOLUTE_HOME_DIR = Paths.get(USER_HOME);
|
||||
private static final char PATH_LIST_SEP = ':';
|
||||
private static final int DEFAULT_MIN_PW_LENGTH = 8;
|
||||
|
||||
@Inject
|
||||
public Environment() {
|
||||
@@ -37,6 +38,7 @@ public class Environment {
|
||||
LOG.debug("cryptomator.keychainPath: {}", System.getProperty("cryptomator.keychainPath"));
|
||||
LOG.debug("cryptomator.logDir: {}", System.getProperty("cryptomator.logDir"));
|
||||
LOG.debug("cryptomator.mountPointsDir: {}", System.getProperty("cryptomator.mountPointsDir"));
|
||||
LOG.debug("cryptomator.minPwLength: {}", System.getProperty("cryptomator.minPwLength"));
|
||||
}
|
||||
|
||||
public boolean useCustomLogbackConfig() {
|
||||
@@ -63,6 +65,19 @@ public class Environment {
|
||||
return getPath("cryptomator.mountPointsDir").map(this::replaceHomeDir);
|
||||
}
|
||||
|
||||
public int getMinPwLength() {
|
||||
return getInt("cryptomator.minPwLength", DEFAULT_MIN_PW_LENGTH);
|
||||
}
|
||||
|
||||
private int getInt(String propertyName, int defaultValue) {
|
||||
String value = System.getProperty(propertyName);
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) { // includes "null" values
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Path> getPath(String propertyName) {
|
||||
String value = System.getProperty(propertyName);
|
||||
return Optional.ofNullable(value).map(Paths::get);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import com.nulabinc.zxcvbn.Zxcvbn;
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.cryptomator.ui.fxapp.FxApplicationScoped;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -20,30 +21,33 @@ public class PasswordStrengthUtil {
|
||||
|
||||
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length
|
||||
private static final String RESSOURCE_PREFIX = "passwordStrength.messageLabel.";
|
||||
private static final List<String> SANITIZED_INPUTS = List.of("cryptomator");
|
||||
|
||||
private final Zxcvbn zxcvbn;
|
||||
private final List<String> sanitizedInputs;
|
||||
private final ResourceBundle resourceBundle;
|
||||
private final int minPwLength;
|
||||
private final Zxcvbn zxcvbn;
|
||||
|
||||
@Inject
|
||||
public PasswordStrengthUtil(ResourceBundle resourceBundle) {
|
||||
public PasswordStrengthUtil(ResourceBundle resourceBundle, Environment environment) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.minPwLength = environment.getMinPwLength();
|
||||
this.zxcvbn = new Zxcvbn();
|
||||
this.sanitizedInputs = List.of("cryptomator");
|
||||
}
|
||||
|
||||
public int computeRate(CharSequence password) {
|
||||
if (password == null || password.length() == 0) {
|
||||
if (password == null || password.length() < minPwLength) {
|
||||
return -1;
|
||||
} else {
|
||||
int numCharsToRate = Math.min(PW_TRUNC_LEN, password.length());
|
||||
return zxcvbn.measure(password.subSequence(0, numCharsToRate), sanitizedInputs).getScore();
|
||||
return zxcvbn.measure(password.subSequence(0, numCharsToRate), SANITIZED_INPUTS).getScore();
|
||||
}
|
||||
}
|
||||
|
||||
public String getStrengthDescription(Number score) {
|
||||
if (resourceBundle.containsKey(RESSOURCE_PREFIX + score.intValue())) {
|
||||
return resourceBundle.getString("passwordStrength.messageLabel." + score.intValue());
|
||||
if (score.intValue() == -1) {
|
||||
return String.format(resourceBundle.getString(RESSOURCE_PREFIX + "tooShort"), minPwLength);
|
||||
} else if (resourceBundle.containsKey(RESSOURCE_PREFIX + score.intValue())) {
|
||||
return resourceBundle.getString(RESSOURCE_PREFIX + score.intValue());
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -193,6 +193,7 @@ newPassword.promptText=Enter a new password
|
||||
newPassword.reenterPassword=Confirm the new password
|
||||
newPassword.passwordsMatch=Passwords match!
|
||||
newPassword.passwordsDoNotMatch=Passwords do not match
|
||||
passwordStrength.messageLabel.tooShort=Use at least %d characters
|
||||
passwordStrength.messageLabel.0=Very weak
|
||||
passwordStrength.messageLabel.1=Weak
|
||||
passwordStrength.messageLabel.2=Fair
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -13,7 +14,7 @@ public class PasswordStrengthUtilTest {
|
||||
|
||||
@Test
|
||||
public void testLongPasswords() {
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class));
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class), Mockito.mock(Environment.class));
|
||||
String longPw = Strings.repeat("x", 10_000);
|
||||
Assertions.assertTimeout(Duration.ofSeconds(5), () -> {
|
||||
util.computeRate(longPw);
|
||||
@@ -21,9 +22,9 @@ public class PasswordStrengthUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("waiting on upstream fix")
|
||||
@Disabled("waiting on upstream fix") // https://github.com/nulab/zxcvbn4j/issues/54
|
||||
public void testIssue979() {
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class));
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class), Mockito.mock(Environment.class));
|
||||
int result1 = util.computeRate("backed derrick buckling mountains glove client procedures desire destination sword hidden ram");
|
||||
int result2 = util.computeRate("backed derrick buckling mountains glove client procedures desire destination sword hidden ram escalation");
|
||||
Assertions.assertEquals(4, result1);
|
||||
|
||||
Reference in New Issue
Block a user