瀏覽代碼

#927 adding logic to stub

Armin Schrenk 5 年之前
父節點
當前提交
4bfb543419

+ 90 - 1
main/ui/src/main/java/org/cryptomator/ui/changepassword/ChangePasswordController.java

@@ -1,24 +1,113 @@
 package org.cryptomator.ui.changepassword;
 
+import javafx.beans.binding.Bindings;
+import javafx.beans.binding.BooleanBinding;
+import javafx.beans.property.IntegerProperty;
+import javafx.beans.property.SimpleIntegerProperty;
+import javafx.fxml.FXML;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Region;
+import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
 import org.cryptomator.common.vaults.Vault;
+import org.cryptomator.cryptolib.api.InvalidPassphraseException;
 import org.cryptomator.ui.common.FxController;
+import org.cryptomator.ui.controls.SecPasswordField;
+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.util.ResourceBundle;
 
 @ChangePasswordScoped
 public class ChangePasswordController implements FxController {
 
+	private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);
+
 	private final Stage window;
 	private final Vault vault;
 	private final ResourceBundle resourceBundle;
+	private final PasswordStrengthUtil strengthRater;
+	private final IntegerProperty passwordStrength;
+
+	public SecPasswordField oldPasswordField;
+	public SecPasswordField newPasswordField;
+	public SecPasswordField reenterPasswordField;
+	public Region passwordStrengthLevel0;
+	public Region passwordStrengthLevel1;
+	public Region passwordStrengthLevel2;
+	public Region passwordStrengthLevel3;
+	public Region passwordStrengthLevel4;
+	public Label passwordStrengthLabel;
+	public HBox passwordMatchBox;
+	public Rectangle checkmark;
+	public Rectangle cross;
+	public Label passwordMatchLabel;
+	public Button finishButton;
 
 	@Inject
-	public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, ResourceBundle resourceBundle) {
+	public ChangePasswordController(@ChangePasswordWindow Stage window, @ChangePasswordWindow Vault vault, ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater) {
 		this.window = window;
 		this.vault = vault;
 		this.resourceBundle = resourceBundle;
+		this.strengthRater = strengthRater;
+		this.passwordStrength = new SimpleIntegerProperty(-1);
+	}
+
+	@FXML
+	public void initialize() {
+		//binds the actual strength value to the rating of the password util
+		passwordStrength.bind(Bindings.createIntegerBinding(() -> strengthRater.computeRate(newPasswordField.getCharacters().toString()), newPasswordField.textProperty()));
+		//binding indicating if the passwords not match
+		BooleanBinding passwordsMatch = Bindings.createBooleanBinding(() -> CharSequence.compare(newPasswordField.getCharacters(), reenterPasswordField.getCharacters()) == 0, newPasswordField.textProperty(), reenterPasswordField.textProperty());
+		BooleanBinding reenterFieldNotEmpty = reenterPasswordField.textProperty().isNotEmpty();
+		//disable the finish button when passwords do not match or one is empty
+		finishButton.disableProperty().bind(reenterFieldNotEmpty.not().or(passwordsMatch.not()));
+		//make match indicator invisible when passwords do not match or one is empty
+		passwordMatchBox.visibleProperty().bind(reenterFieldNotEmpty);
+		checkmark.visibleProperty().bind(passwordsMatch.and(reenterFieldNotEmpty));
+		cross.visibleProperty().bind(passwordsMatch.not().and(reenterFieldNotEmpty));
+		passwordMatchLabel.textProperty().bind(Bindings.when(passwordsMatch.and(reenterFieldNotEmpty)).then(resourceBundle.getString("addvaultwizard.new.passwordsMatch")).otherwise(resourceBundle.getString("addvaultwizard.new.passwordsDoNotMatch")));
+
+		//bindsings for the password strength indicator
+		passwordStrengthLevel0.backgroundProperty().bind(EasyBind.combine(passwordStrength, new SimpleIntegerProperty(0), strengthRater::getBackgroundWithStrengthColor));
+		passwordStrengthLevel1.backgroundProperty().bind(EasyBind.combine(passwordStrength, new SimpleIntegerProperty(1), strengthRater::getBackgroundWithStrengthColor));
+		passwordStrengthLevel2.backgroundProperty().bind(EasyBind.combine(passwordStrength, new SimpleIntegerProperty(2), strengthRater::getBackgroundWithStrengthColor));
+		passwordStrengthLevel3.backgroundProperty().bind(EasyBind.combine(passwordStrength, new SimpleIntegerProperty(3), strengthRater::getBackgroundWithStrengthColor));
+		passwordStrengthLevel4.backgroundProperty().bind(EasyBind.combine(passwordStrength, new SimpleIntegerProperty(4), strengthRater::getBackgroundWithStrengthColor));
+		passwordStrengthLabel.textProperty().bind(EasyBind.map(passwordStrength, strengthRater::getStrengthDescription));
+
+	}
+
+	@FXML
+	public void cancel() {
+		window.close();
+	}
+
+	@FXML
+	public void finish() {
+		try {
+			vault.changePassphrase(oldPasswordField.getCharacters(), newPasswordField.getCharacters());
+			LOG.info("Successful changed password for {}", vault.getDisplayableName());
+			window.close();
+		} catch (IOException e) {
+			//TODO
+			LOG.error("IO error occured during password change. Unable to perform operation.", e);
+			e.printStackTrace();
+		} catch (InvalidPassphraseException e) {
+			//TODO
+			LOG.info("Wrong old password.");
+		}
+	}
+	/* Getter/Setter */
+
+	public Vault getVault() {
+		return vault;
 	}
 
 }

+ 54 - 2
main/ui/src/main/resources/fxml/changepassword.fxml

@@ -1,17 +1,69 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ButtonBar?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Region?>
 <?import javafx.scene.layout.VBox?>
-
+<?import javafx.scene.shape.Rectangle?>
+<?import javafx.scene.text.Text?>
+<?import javafx.scene.text.TextFlow?>
+<?import org.cryptomator.ui.controls.SecPasswordField?>
 <VBox xmlns="http://javafx.com/javafx"
 	  xmlns:fx="http://javafx.com/fxml"
 	  fx:controller="org.cryptomator.ui.changepassword.ChangePasswordController"
 	  minWidth="300"
-	  maxWidth="300"
+	  maxWidth="600"
 	  spacing="6">
 	<padding>
 		<Insets bottom="6.0" left="6.0" right="6.0" top="6.0"/>
 	</padding>
 	<children>
+		<TextFlow styleClass="text-flow">
+			<Label labelFor="$oldPasswordField" text="%changepassword.enterOldPassword"/>
+			<Text text=" &quot;"/>
+			<Text text="${controller.vault.displayableName}"/>
+			<Text text="&quot;:"/>
+		</TextFlow>
+		<SecPasswordField fx:id="oldPasswordField"/>
+
+		<Region VBox.vgrow="ALWAYS" minHeight="48"/>
+
+		<Label labelFor="$newPasswordField" text="%changepassword.enterNewPassword"/>
+		<SecPasswordField fx:id="newPasswordField"/>
+		<HBox spacing="6.0" prefHeight="6.0" cacheShape="true" cache="true">
+			<Region HBox.hgrow="ALWAYS" fx:id="passwordStrengthLevel0" cacheShape="true" cache="true"/>
+			<Region HBox.hgrow="ALWAYS" fx:id="passwordStrengthLevel1" cacheShape="true" cache="true"/>
+			<Region HBox.hgrow="ALWAYS" fx:id="passwordStrengthLevel2" cacheShape="true" cache="true"/>
+			<Region HBox.hgrow="ALWAYS" fx:id="passwordStrengthLevel3" cacheShape="true" cache="true"/>
+			<Region HBox.hgrow="ALWAYS" fx:id="passwordStrengthLevel4" cacheShape="true" cache="true"/>
+		</HBox>
+		<HBox alignment="BASELINE_RIGHT">
+			<Label fx:id="passwordStrengthLabel"/>
+		</HBox>
+
+		<Region VBox.vgrow="ALWAYS" minHeight="12"/>
+
+		<Label labelFor="$reenterPasswordField" text="%changepassword.reenterNewPassword"/>
+		<SecPasswordField fx:id="reenterPasswordField"/>
+		<HBox fx:id="passwordMatchBox" spacing="12.0" alignment="BASELINE_RIGHT">
+			<!-- TODO
+			<ImageView fx:id="checkmark" image="/path/to/checkmark" fitWidth="10" fitHeight="10" />
+			<ImageView fx:id="cross" image="/path/to/cross" fitWidth="10" fitHeight="10" />
+			-->
+			<Rectangle fx:id="checkmark" width="10" height="10" fill="green"/>
+			<Rectangle fx:id="cross" width="10" height="10" fill="red"/>
+			<Label fx:id="passwordMatchLabel"/>
+		</HBox>
+
+		<Region VBox.vgrow="ALWAYS"/>
+		<ButtonBar buttonMinWidth="120" buttonOrder="C+I">
+			<buttons>
+				<Button text="%generic.button.cancel" ButtonBar.buttonData="CANCEL_CLOSE" onAction="#cancel"/>
+				<Button fx:id="finishButton" text="%generic.button.change" ButtonBar.buttonData="FINISH" onAction="#finish" defaultButton="true"/>
+			</buttons>
+		</ButtonBar>
 	</children>
 </VBox>

+ 4 - 0
main/ui/src/main/resources/i18n/strings.properties

@@ -2,6 +2,7 @@
 ##Button
 generic.button.back=Back
 generic.button.cancel=Cancel
+generic.button.change=Change
 generic.button.create=Create
 generic.button.next=Next
 generic.button.open=Open
@@ -30,6 +31,9 @@ addvaultwizard.new.passwordsDoNotMatch=Passwords do not match.
 
 #ChangePassword
 changepassword.title=Change Password
+changepassword.enterOldPassword=To change the password, please enter the current password for
+changepassword.enterNewPassword=Please enter a new password:
+changepassword.reenterNewPassword=Please reenter the new password:
 
 #Unlock
 unlock.title=Unlock Vault