diff --git a/run_preferences_test.sh b/run_preferences_test.sh new file mode 100755 index 0000000..fa63241 --- /dev/null +++ b/run_preferences_test.sh @@ -0,0 +1,14 @@ +#!/bin/bash +mkdir -p build/test/stubs +mkdir -p build/test/classes + +# Compile AlertMaker stub +javac -d build/test/stubs test/stubs/library/assistant/alert/AlertMaker.java + +# Compile Preferences and Test +javac -sourcepath "src" -cp "libs/*:libs/test/*:build/test/stubs" -d build/test/classes \ +src/library/assistant/ui/settings/Preferences.java \ +test/library/assistant/ui/settings/PreferencesTest.java + +# Run Test +java -cp "build/test/classes:build/test/stubs:libs/*:libs/test/*" org.junit.runner.JUnitCore library.assistant.ui.settings.PreferencesTest diff --git a/src/library/assistant/ui/login/LoginController.java b/src/library/assistant/ui/login/LoginController.java index cdf0cfd..10c4a32 100644 --- a/src/library/assistant/ui/login/LoginController.java +++ b/src/library/assistant/ui/login/LoginController.java @@ -1,5 +1,6 @@ package library.assistant.ui.login; +import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXPasswordField; import com.jfoenix.controls.JFXTextField; import java.io.IOException; @@ -11,6 +12,7 @@ import javafx.fxml.Initializable; import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.control.Label; import javafx.stage.Stage; import javafx.stage.StageStyle; import library.assistant.ui.settings.Preferences; @@ -29,12 +31,20 @@ public class LoginController implements Initializable { private JFXTextField username; @FXML private JFXPasswordField password; + @FXML + private JFXButton loginButton; + @FXML + private Label titleLabel; Preferences preference; @Override public void initialize(URL url, ResourceBundle rb) { preference = Preferences.getPreferences(); + if (preference.getUsername() == null || preference.getUsername().isEmpty()) { + titleLabel.setText("First Run: Create Admin Account"); + loginButton.setText("Save"); + } } @FXML @@ -42,14 +52,26 @@ private void handleLoginButtonAction(ActionEvent event) { String uname = StringUtils.trimToEmpty(username.getText()); String pword = DigestUtils.shaHex(password.getText()); - if (uname.equals(preference.getUsername()) && pword.equals(preference.getPassword())) { + if (preference.getUsername() == null || preference.getUsername().isEmpty()) { + if (uname.isEmpty() || password.getText().isEmpty()) { + titleLabel.setText("Please enter username and password"); + return; + } + preference.setUsername(uname); + preference.setPassword(pword); + Preferences.writePreferenceToFile(preference); closeStage(); loadMain(); - LOGGER.log(Level.INFO, "User successfully logged in {}", uname); - } - else { - username.getStyleClass().add("wrong-credentials"); - password.getStyleClass().add("wrong-credentials"); + LOGGER.log(Level.INFO, "Admin account created and logged in: {}", uname); + } else { + if (uname.equals(preference.getUsername()) && pword.equals(preference.getPassword())) { + closeStage(); + loadMain(); + LOGGER.log(Level.INFO, "User successfully logged in {}", uname); + } else { + username.getStyleClass().add("wrong-credentials"); + password.getStyleClass().add("wrong-credentials"); + } } } diff --git a/src/library/assistant/ui/login/login.fxml b/src/library/assistant/ui/login/login.fxml index 0b72af5..75466d1 100644 --- a/src/library/assistant/ui/login/login.fxml +++ b/src/library/assistant/ui/login/login.fxml @@ -4,11 +4,17 @@ + + @@ -19,7 +25,7 @@ - + diff --git a/src/library/assistant/ui/settings/Preferences.java b/src/library/assistant/ui/settings/Preferences.java index 4767633..dc8a17f 100644 --- a/src/library/assistant/ui/settings/Preferences.java +++ b/src/library/assistant/ui/settings/Preferences.java @@ -23,8 +23,6 @@ public class Preferences { public Preferences() { nDaysWithoutFine = 14; finePerDay = 2; - username = "admin"; - setPassword("admin"); } public int getnDaysWithoutFine() { diff --git a/test/library/assistant/ui/settings/PreferencesTest.java b/test/library/assistant/ui/settings/PreferencesTest.java new file mode 100644 index 0000000..62d82ba --- /dev/null +++ b/test/library/assistant/ui/settings/PreferencesTest.java @@ -0,0 +1,35 @@ +package library.assistant.ui.settings; + +import org.junit.Test; +import static org.junit.Assert.*; +import org.apache.commons.codec.digest.DigestUtils; + +public class PreferencesTest { + + @Test + public void testDefaultConstructorNoCredentials() { + Preferences prefs = new Preferences(); + assertNull("Username should be null by default", prefs.getUsername()); + assertNull("Password should be null by default", prefs.getPassword()); + } + + @Test + public void testSetPasswordHashing() { + Preferences prefs = new Preferences(); + String password = "short"; + prefs.setPassword(password); + + String expectedHash = DigestUtils.shaHex(password); + assertEquals("Short password should be hashed", expectedHash, prefs.getPassword()); + } + + @Test + public void testSetPasswordNoHashing() { + Preferences prefs = new Preferences(); + // A string that is already a hash (>= 16 chars) + String longPassword = "thisisalongpasswordthatshouldnotbehashed"; + prefs.setPassword(longPassword); + + assertEquals("Long password should not be hashed again", longPassword, prefs.getPassword()); + } +} diff --git a/test/stubs/library/assistant/alert/AlertMaker.java b/test/stubs/library/assistant/alert/AlertMaker.java new file mode 100644 index 0000000..222dc0c --- /dev/null +++ b/test/stubs/library/assistant/alert/AlertMaker.java @@ -0,0 +1,21 @@ +package library.assistant.alert; + +import java.util.List; + +public class AlertMaker { + + public static void showSimpleAlert(String title, String content) { + } + + public static void showErrorMessage(String title, String content) { + } + + public static void showErrorMessage(Exception ex) { + } + + public static void showErrorMessage(Exception ex, String title, String content) { + } + + public static void showTrayMessage(String title, String message) { + } +}