From e66e5b1d967da71399de21b56293e71bcc8aa94e Mon Sep 17 00:00:00 2001 From: jncharon Date: Tue, 12 Apr 2016 21:27:31 +0200 Subject: [PATCH] Added the password strength indicator in the change password window --- .../controllers/ChangePasswordController.java | 72 +++++++++++++++++++ .../ui/controllers/InitializeController.java | 7 +- .../main/resources/fxml/change_password.fxml | 15 ++-- 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java index 33f7ae11f..21dca9911 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/ChangePasswordController.java @@ -11,11 +11,19 @@ package org.cryptomator.ui.controllers; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; +import com.nulabinc.zxcvbn.Strength; +import com.nulabinc.zxcvbn.Zxcvbn; +import javafx.scene.control.Label; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; +import org.apache.commons.lang3.StringUtils; import org.cryptomator.crypto.engine.InvalidPassphraseException; import org.cryptomator.crypto.engine.UnsupportedVaultFormatException; import org.cryptomator.ui.controls.SecPasswordField; @@ -43,6 +51,8 @@ public class ChangePasswordController extends LocalizedFXMLViewController { private final Application app; final ObjectProperty vault = new SimpleObjectProperty<>(); private Optional listener = Optional.empty(); + private Zxcvbn zxcvbn = new Zxcvbn(); + private List sanitizedInputs = new ArrayList(); @Inject public ChangePasswordController(Application app, Localization localization) { @@ -68,12 +78,29 @@ public class ChangePasswordController extends LocalizedFXMLViewController { @FXML private Hyperlink downloadsPageLink; + @FXML + private Label passwordStrengthLabel; + + @FXML + private Rectangle passwordStrengthShape; + @Override public void initialize() { BooleanBinding oldPasswordIsEmpty = oldPasswordField.textProperty().isEmpty(); BooleanBinding newPasswordIsEmpty = newPasswordField.textProperty().isEmpty(); BooleanBinding passwordsDiffer = newPasswordField.textProperty().isNotEqualTo(retypePasswordField.textProperty()); changePasswordButton.disableProperty().bind(oldPasswordIsEmpty.or(newPasswordIsEmpty.or(passwordsDiffer))); + newPasswordField.textProperty().addListener((observable, oldValue, newValue) -> { + checkPasswordStrength(newValue); + }); + + // default password strength bar visual properties + passwordStrengthShape.setStroke(Color.GRAY); + changeProgressBarAspect(0f, 0f, Color.web("#FF0000")); + passwordStrengthLabel.setText(localization.getString("initialize.messageLabel.passwordStrength") + " : 0%"); + + // preparing inputs for the password strength checker + sanitizedInputs.add("cryptomator"); } @Override @@ -122,6 +149,51 @@ public class ChangePasswordController extends LocalizedFXMLViewController { } } + // **************************************** + // Password strength management + // **************************************** + + private void checkPasswordStrength(String password) { + int strengthPercentage = 0; + if (StringUtils.isEmpty(password)) { + changeProgressBarAspect(0f, 0f, Color.web("#FF0000")); + passwordStrengthLabel.setText(localization.getString("initialize.messageLabel.passwordStrength") + " : " + strengthPercentage + "%"); + } else { + Color color = Color.web("#FF0000"); + Strength strength = zxcvbn.measure(password, sanitizedInputs); + switch (strength.getScore()) { + case 0: + strengthPercentage = 20; + break; + case 1: + strengthPercentage = 40; + color = Color.web("#FF8000"); + break; + case 2: + strengthPercentage = 60; + color = Color.web("#FFBF00"); + break; + case 3: + strengthPercentage = 80; + color = Color.web("#FFFF00"); + break; + case 4: + strengthPercentage = 100; + color = Color.web("#BFFF00"); + break; + } + + passwordStrengthLabel.setText(localization.getString("initialize.messageLabel.passwordStrength") + " : " + strengthPercentage + "%"); + changeProgressBarAspect(0.5f, strengthPercentage * 2.23f, color); // 2.23f is the factor used to get the width to fit the window + } + } + + private void changeProgressBarAspect(float strokeWidth, float length, Color color) { + passwordStrengthShape.setFill(color); + passwordStrengthShape.setStrokeWidth(strokeWidth); + passwordStrengthShape.setWidth(length); + } + /* Getter/Setter */ public ChangePasswordListener getListener() { diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java index 02b1255df..bab9b948b 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/InitializeController.java @@ -79,12 +79,9 @@ public class InitializeController extends LocalizedFXMLViewController { checkPasswordStrength(newValue); }); - // progressbar graphic properties - passwordStrengthShape.setFill(Color.web("#ff1a1a")); - passwordStrengthShape.setStroke(Color.GRAY); - // default password strength bar visual properties - changeProgressBarAspect(0f, 0f, Color.web("#ff1a1a")); + passwordStrengthShape.setStroke(Color.GRAY); + changeProgressBarAspect(0f, 0f, Color.web("#FF0000")); passwordStrengthLabel.setText(localization.getString("initialize.messageLabel.passwordStrength") + " : 0%"); // preparing inputs for the password strength checker diff --git a/main/ui/src/main/resources/fxml/change_password.fxml b/main/ui/src/main/resources/fxml/change_password.fxml index 93b7f18b0..f415d0dc9 100644 --- a/main/ui/src/main/resources/fxml/change_password.fxml +++ b/main/ui/src/main/resources/fxml/change_password.fxml @@ -22,6 +22,7 @@ + @@ -44,12 +45,18 @@