#8 story/pfleger-module-login-pfleger #50
10 changed files with 126 additions and 19 deletions
|
@ -37,10 +37,18 @@ public class Main extends Application {
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) {
|
public void start(Stage primaryStage) {
|
||||||
this.primaryStage = primaryStage;
|
this.primaryStage = primaryStage;
|
||||||
executePassword();
|
User user = executeLogin();
|
||||||
|
if(user != null){
|
||||||
|
executeMainApplication(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executePassword() {
|
/**
|
||||||
|
* Executes the login.
|
||||||
|
* @return User The {@link User} object for the logged-in {@link User}.
|
||||||
|
* Is {@code null}, if the login was not successful,
|
||||||
|
*/
|
||||||
|
private User executeLogin() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/login/LoginView.fxml"));
|
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/de/hitec/nhplus/login/LoginView.fxml"));
|
||||||
|
@ -55,12 +63,10 @@ public class Main extends Application {
|
||||||
controller.initialize(loginStage);
|
controller.initialize(loginStage);
|
||||||
|
|
||||||
loginStage.showAndWait();
|
loginStage.showAndWait();
|
||||||
|
return controller.user;
|
||||||
if(controller.user != null){
|
|
||||||
executeMainApplication(controller.user);
|
|
||||||
}
|
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,11 @@ import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link Fixture} for {@link User}.
|
||||||
|
*
|
||||||
|
* @author Dominik Säume
|
||||||
|
*/
|
||||||
public class UserFixture implements Fixture<User> {
|
public class UserFixture implements Fixture<User> {
|
||||||
private static final String SCHEMA = "/de/hitec/nhplus/login/database/User.sql";
|
private static final String SCHEMA = "/de/hitec/nhplus/login/database/User.sql";
|
||||||
private static final String PERMISSION_SCHEMA = "/de/hitec/nhplus/login/database/UserPermission.sql";
|
private static final String PERMISSION_SCHEMA = "/de/hitec/nhplus/login/database/UserPermission.sql";
|
||||||
|
|
|
@ -17,6 +17,11 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for handling the login of {@link User}s.
|
||||||
|
*
|
||||||
|
* @author Dominik Säume
|
||||||
|
*/
|
||||||
public class LoginController {
|
public class LoginController {
|
||||||
|
|
||||||
public User user;
|
public User user;
|
||||||
|
@ -29,11 +34,18 @@ public class LoginController {
|
||||||
private Stage stage;
|
private Stage stage;
|
||||||
private int loginTries = 0;
|
private int loginTries = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JavaFX Initialization method that is called after the binding of all the fields.
|
||||||
|
*
|
||||||
|
* @param stage The {@link Stage}, so the modal can close itself, when finished.
|
||||||
|
*/
|
||||||
public void initialize(Stage stage) {
|
public void initialize(Stage stage) {
|
||||||
this.stage = stage;
|
this.stage = stage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to handle actions on wrong logins, like a shake, timout and total tries.
|
||||||
|
*/
|
||||||
private void handleWrongPasswordOrUsername() {
|
private void handleWrongPasswordOrUsername() {
|
||||||
loginTries++;
|
loginTries++;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
package de.hitec.nhplus.login;
|
package de.hitec.nhplus.login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple class holding the bitmasks for all permissions.
|
||||||
|
* This is a class instead of an enum, for ease of use.
|
||||||
|
*
|
||||||
|
* @author Dominiok Säume
|
||||||
|
*/
|
||||||
public class Permissions {
|
public class Permissions {
|
||||||
public final static int EVERYBODY = 0b0;
|
public final static int EVERYBODY = 0b0;
|
||||||
public final static int NURSE = 0b1;
|
public final static int NURSE = 0b1;
|
||||||
|
|
|
@ -7,8 +7,13 @@ import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class User {
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model for a {@link User}.
|
||||||
|
*
|
||||||
|
* @author Dominik Säume
|
||||||
|
*/
|
||||||
|
public class User {
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
private String username;
|
private String username;
|
||||||
|
@ -17,6 +22,10 @@ public class User {
|
||||||
private int permissions = 0;
|
private int permissions = 0;
|
||||||
private Nurse nurse;
|
private Nurse nurse;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor allows instantiating a {@link User} object with all existing fields.
|
||||||
|
*/
|
||||||
public User(
|
public User(
|
||||||
int id,
|
int id,
|
||||||
String username,
|
String username,
|
||||||
|
@ -33,6 +42,9 @@ public class User {
|
||||||
this.nurse = nurse;
|
this.nurse = nurse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor allows instantiating a {@link User} object.
|
||||||
|
*/
|
||||||
public User(
|
public User(
|
||||||
String username,
|
String username,
|
||||||
int permissions,
|
int permissions,
|
||||||
|
@ -42,6 +54,12 @@ public class User {
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
this.nurse = nurse;
|
this.nurse = nurse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link User} password. The {@link User} will need to be manually stored with the
|
||||||
|
* {@link de.hitec.nhplus.login.database.UserDao UserDao}, for changes to persists.
|
||||||
|
* @param password The new Password
|
||||||
|
*/
|
||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
try {
|
try {
|
||||||
SecureRandom random = new SecureRandom();
|
SecureRandom random = new SecureRandom();
|
||||||
|
@ -59,6 +77,7 @@ public class User {
|
||||||
public boolean hasNursePermissions(){
|
public boolean hasNursePermissions(){
|
||||||
return (permissions & Permissions.NURSE) != 0;
|
return (permissions & Permissions.NURSE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAdminPermissions(){
|
public boolean hasAdminPermissions(){
|
||||||
return (permissions & Permissions.MANAGEMENT) != 0;
|
return (permissions & Permissions.MANAGEMENT) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,12 @@ import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link UserDao} is an implementation of the{@link de.hitec.nhplus.datastorage.Dao Dao}
|
||||||
|
* for the {@link User} model.
|
||||||
|
*
|
||||||
|
* @author Dominik Säume
|
||||||
|
*/
|
||||||
public class UserDao implements Dao<User> {
|
public class UserDao implements Dao<User> {
|
||||||
protected final Connection connection;
|
protected final Connection connection;
|
||||||
|
|
||||||
|
@ -19,6 +25,11 @@ public class UserDao implements Dao<User> {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try reading a {@link User#id} by its {@link User#username}.
|
||||||
|
* @param username The {@link User#username username} to try reading the {@link User#id id} of.
|
||||||
|
* @return The {@link User#id}. {@code 0} if the {@link User} doesn't exist.
|
||||||
|
*/
|
||||||
public int readUserId(String username) throws SQLException {
|
public int readUserId(String username) throws SQLException {
|
||||||
final String SQL = "SELECT id FROM user WHERE username = ?";
|
final String SQL = "SELECT id FROM user WHERE username = ?";
|
||||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||||
|
@ -26,6 +37,11 @@ public class UserDao implements Dao<User> {
|
||||||
return statement.executeQuery().getInt(1);
|
return statement.executeQuery().getInt(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a {@link User}s {@link User#passwordSalt password salt}.
|
||||||
|
* @param id The {@link User#id} of which the {@link User#passwordSalt password salt} should be read.
|
||||||
|
* @return The {@link User#passwordSalt password salt} as a{@code byte[]}.
|
||||||
|
*/
|
||||||
public byte[] readPasswordSalt(int id) throws SQLException {
|
public byte[] readPasswordSalt(int id) throws SQLException {
|
||||||
final String SQL = "SELECT passwordSalt FROM user WHERE id = ?";
|
final String SQL = "SELECT passwordSalt FROM user WHERE id = ?";
|
||||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||||
|
@ -33,6 +49,11 @@ public class UserDao implements Dao<User> {
|
||||||
return statement.executeQuery().getBytes(1);
|
return statement.executeQuery().getBytes(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a {@link User}s {@link User#passwordHash password hash} for authentication purposes.
|
||||||
|
* @param id The {@link User#id} of which the {@link User#passwordHash password hash} should be read.
|
||||||
|
* @return The {@link User#passwordHash password hash} as a{@code byte[]}.
|
||||||
|
*/
|
||||||
public byte[] readPasswordHash(int id) throws SQLException {
|
public byte[] readPasswordHash(int id) throws SQLException {
|
||||||
final String SQL = "SELECT passwordHash FROM user WHERE id = ?";
|
final String SQL = "SELECT passwordHash FROM user WHERE id = ?";
|
||||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||||
|
|
|
@ -14,10 +14,7 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Controller for the main window of the application, which holds all tabs.
|
* Controller for the main window of the application, which holds all tabs.
|
||||||
*
|
*
|
||||||
* @author Bernd Heidemann
|
|
||||||
* @author Dominik Säume
|
* @author Dominik Säume
|
||||||
* @author Armin Ribic
|
|
||||||
* @author Dorian Nemec
|
|
||||||
*/
|
*/
|
||||||
public class MainWindowController {
|
public class MainWindowController {
|
||||||
private static MainWindowController instace;
|
private static MainWindowController instace;
|
||||||
|
@ -30,14 +27,13 @@ public class MainWindowController {
|
||||||
instace = this;
|
instace = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method copying the idea of a singleton, to allow getting the current {@link User}.
|
||||||
|
*/
|
||||||
public static MainWindowController getInstance() {
|
public static MainWindowController getInstance() {
|
||||||
return instace;
|
return instace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JavaFX Initialization method that is called after the binding of all the fields.
|
* JavaFX Initialization method that is called after the binding of all the fields.
|
||||||
*
|
*
|
||||||
|
@ -95,4 +91,8 @@ public class MainWindowController {
|
||||||
mainTabPane.getSelectionModel().select(defaultTab);
|
mainTabPane.getSelectionModel().select(defaultTab);
|
||||||
defaultTab.getOnSelectionChanged().handle(new Event(Event.ANY));
|
defaultTab.getOnSelectionChanged().handle(new Event(Event.ANY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class Nurse extends Person {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor allows instantiating a {@link Nurse} object with
|
* This constructor allows instantiating a {@link Nurse} object with
|
||||||
* specifying if the nurse is locked or not.
|
* specifying whether the {@link Nurse} is locked or not.
|
||||||
*/
|
*/
|
||||||
public Nurse(
|
public Nurse(
|
||||||
String firstName,
|
String firstName,
|
||||||
|
|
|
@ -15,6 +15,12 @@ import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class to construct {@link Tab}s from views. This also supports sub {@link Tab}s.
|
||||||
|
*
|
||||||
|
* @author Dominiok Säume
|
||||||
|
* @see TabManager
|
||||||
|
*/
|
||||||
public class TabManager {
|
public class TabManager {
|
||||||
private final User user;
|
private final User user;
|
||||||
|
|
||||||
|
@ -22,11 +28,21 @@ public class TabManager {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method to check permissions
|
||||||
|
* @param requiredPermissions The permissions the {@link User} requires.
|
||||||
|
* @param permissions The permissions the {@link User} has.
|
||||||
|
*/
|
||||||
private boolean hasPermissions(int requiredPermissions, int permissions) {
|
private boolean hasPermissions(int requiredPermissions, int permissions) {
|
||||||
return requiredPermissions == Permissions.EVERYBODY
|
return requiredPermissions == Permissions.EVERYBODY
|
||||||
|| (permissions & requiredPermissions) != 0;
|
|| (permissions & requiredPermissions) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set up a single tab and register it to its {@link TabPane}.
|
||||||
|
* @param tabPane The {@link TabPane} to register to.
|
||||||
|
* @param tabStruct The data needed to construct the new tab.
|
||||||
|
*/
|
||||||
public void setupTab(TabPane tabPane, TabStruct tabStruct) {
|
public void setupTab(TabPane tabPane, TabStruct tabStruct) {
|
||||||
if (!hasPermissions(tabStruct.requiredPermissions, user.getPermissions())) {
|
if (!hasPermissions(tabStruct.requiredPermissions, user.getPermissions())) {
|
||||||
return;
|
return;
|
||||||
|
@ -39,6 +55,11 @@ public class TabManager {
|
||||||
tabPane.getTabs().add(tab);
|
tabPane.getTabs().add(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EventHandler} to handle the loading of a {@link Tab}.
|
||||||
|
* @param tabStruct The {@link TabStruct} holding the path of the view.
|
||||||
|
* @param pane The main pane of the {@link Tab}.
|
||||||
|
*/
|
||||||
private EventHandler<Event> loadTabEventHandler(TabStruct tabStruct, AnchorPane pane) {
|
private EventHandler<Event> loadTabEventHandler(TabStruct tabStruct, AnchorPane pane) {
|
||||||
return event -> {
|
return event -> {
|
||||||
try {
|
try {
|
||||||
|
@ -56,6 +77,13 @@ public class TabManager {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set up a sub tab and register it to its parent {@link TabPane}.
|
||||||
|
* @param parentTabPane The {@link TabPane} to register to.
|
||||||
|
* @param title The title of the {@link Tab}.
|
||||||
|
* @param requiredPermissions The permissions required to see the sub {@link Tab}.
|
||||||
|
* @param subTabs A {@link List} of {@link TabStruct}s to create in the sub {@link Tab}.
|
||||||
|
*/
|
||||||
public void setupSubTabPane(TabPane parentTabPane, String title, int requiredPermissions, List<TabStruct> subTabs) {
|
public void setupSubTabPane(TabPane parentTabPane, String title, int requiredPermissions, List<TabStruct> subTabs) {
|
||||||
if (!hasPermissions(requiredPermissions, user.getPermissions())) {
|
if (!hasPermissions(requiredPermissions, user.getPermissions())) {
|
||||||
return;
|
return;
|
||||||
|
@ -73,6 +101,10 @@ public class TabManager {
|
||||||
parentTabPane.getTabs().add(tab);
|
parentTabPane.getTabs().add(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EventHandler} to handle the loading of a sub {@link TabPane}.
|
||||||
|
* @param tabPane The {@link TabPane} of the sub {@link Tab} to handle loading.
|
||||||
|
*/
|
||||||
private EventHandler<Event> loadSubTabPaneEventHandler(TabPane tabPane) {
|
private EventHandler<Event> loadSubTabPaneEventHandler(TabPane tabPane) {
|
||||||
return event -> {
|
return event -> {
|
||||||
Tab tab = tabPane.getSelectionModel().getSelectedItem();
|
Tab tab = tabPane.getSelectionModel().getSelectedItem();
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
package de.hitec.nhplus.utils.tab;
|
package de.hitec.nhplus.utils.tab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple class holding the data needed for constructing a {@link javafx.scene.control.Tab Tab}.
|
||||||
|
*
|
||||||
|
* @author Dominiok Säume
|
||||||
|
* @see TabManager
|
||||||
|
*/
|
||||||
public class TabStruct {
|
public class TabStruct {
|
||||||
public String title;
|
public String title;
|
||||||
public String view;
|
public String view;
|
||||||
|
|
Loading…
Reference in a new issue