#8: Setup Model, DAO & Fixtures
Signed-off-by: Dominik Säume <Dominik.Saeume@hmmh.de>
This commit is contained in:
parent
03ef4a235a
commit
fb6fc923ac
10 changed files with 404 additions and 7 deletions
Binary file not shown.
|
@ -34,8 +34,8 @@ public class Main extends Application {
|
|||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
this.primaryStage = primaryStage;
|
||||
executePassword();
|
||||
//executeMainApplication();
|
||||
//executePassword();
|
||||
executeMainApplication();
|
||||
}
|
||||
|
||||
private void executePassword() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package de.hitec.nhplus.datastorage;
|
||||
|
||||
import de.hitec.nhplus.login.database.UserDao;
|
||||
import de.hitec.nhplus.medication.database.MedicationDao;
|
||||
import de.hitec.nhplus.nurse.database.NurseDao;
|
||||
import de.hitec.nhplus.patient.database.PatientDao;
|
||||
|
@ -63,4 +64,12 @@ public class DaoFactory {
|
|||
public MedicationDao createMedicationDAO() {
|
||||
return new MedicationDao(ConnectionBuilder.getConnection());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A new {@link UserDao} instance with a database connection.
|
||||
* @see de.hitec.nhplus.login.User User
|
||||
*/
|
||||
public UserDao createUserDAO() {
|
||||
return new UserDao(ConnectionBuilder.getConnection());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ public class Fixtures {
|
|||
medicationFixture.setupTable(connection);
|
||||
medicationFixture.load();
|
||||
|
||||
UserFixture userFixture = new UserFixture();
|
||||
userFixture.dropTable(connection);
|
||||
userFixture.setupTable(connection);
|
||||
userFixture.load();
|
||||
|
||||
} catch (Exception exception) {
|
||||
System.out.println(exception.getMessage());
|
||||
}
|
||||
|
|
83
src/main/java/de/hitec/nhplus/fixtures/UserFixture.java
Normal file
83
src/main/java/de/hitec/nhplus/fixtures/UserFixture.java
Normal file
|
@ -0,0 +1,83 @@
|
|||
package de.hitec.nhplus.fixtures;
|
||||
|
||||
import de.hitec.nhplus.Main;
|
||||
import de.hitec.nhplus.datastorage.DaoFactory;
|
||||
import de.hitec.nhplus.login.User;
|
||||
import de.hitec.nhplus.login.database.UserDao;
|
||||
import de.hitec.nhplus.medication.Medication;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class UserFixture implements Fixture<User>{
|
||||
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 TO_NURSE_SCHEMA = "/de/hitec/nhplus/login/database/UserToNurse.sql";
|
||||
@Override
|
||||
public void dropTable(Connection connection) throws SQLException {
|
||||
connection.createStatement().execute("DROP TABLE IF EXISTS user");
|
||||
connection.createStatement().execute("DROP TABLE IF EXISTS user__permissions");
|
||||
connection.createStatement().execute("DROP TABLE IF EXISTS user__nurse");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupTable(Connection connection) throws SQLException {
|
||||
final InputStream schema = Main.class.getResourceAsStream(SCHEMA);
|
||||
final InputStream permissionSchema = Main.class.getResourceAsStream(PERMISSION_SCHEMA);
|
||||
final InputStream toNurseSchema = Main.class.getResourceAsStream(TO_NURSE_SCHEMA);
|
||||
|
||||
assert schema != null;
|
||||
assert permissionSchema != null;
|
||||
assert toNurseSchema != null;
|
||||
|
||||
String SQL = new Scanner(schema, StandardCharsets.UTF_8)
|
||||
.useDelimiter("\\A")
|
||||
.next();
|
||||
String permissionSQL = new Scanner(permissionSchema, StandardCharsets.UTF_8)
|
||||
.useDelimiter("\\A")
|
||||
.next();
|
||||
String toNurseSQL = new Scanner(toNurseSchema, StandardCharsets.UTF_8)
|
||||
.useDelimiter("\\A")
|
||||
.next();
|
||||
|
||||
connection.createStatement().execute(SQL);
|
||||
connection.createStatement().execute(permissionSQL);
|
||||
connection.createStatement().execute(toNurseSQL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, User> load() throws SQLException {
|
||||
List<User> users = new ArrayList<>();
|
||||
|
||||
User udo = new User(
|
||||
"udo",
|
||||
null,
|
||||
null,
|
||||
Integer.parseInt("00000001", 2),
|
||||
null
|
||||
);
|
||||
udo.setPassword("uD0_187!");
|
||||
users.add(udo);
|
||||
|
||||
User maria = new User(
|
||||
"maria",
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
null
|
||||
);
|
||||
maria.setPassword("H!mm3lf4hrt");
|
||||
users.add(maria);
|
||||
|
||||
UserDao dao = DaoFactory.getInstance().createUserDAO();
|
||||
Map<String, User> usersByUsername = new HashMap<>();
|
||||
for (User user : users){
|
||||
dao.create(user);
|
||||
usersByUsername.put(user.getUsername(), user);
|
||||
}
|
||||
return usersByUsername;
|
||||
}
|
||||
}
|
98
src/main/java/de/hitec/nhplus/login/User.java
Normal file
98
src/main/java/de/hitec/nhplus/login/User.java
Normal file
|
@ -0,0 +1,98 @@
|
|||
package de.hitec.nhplus.login;
|
||||
|
||||
import de.hitec.nhplus.nurse.Nurse;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class User {
|
||||
|
||||
private int id;
|
||||
private String username;
|
||||
private byte[] passwordSalt;
|
||||
private byte[] passwordHash;
|
||||
private int permissions = 0;
|
||||
private Nurse nurse;
|
||||
|
||||
public User(
|
||||
int id,
|
||||
String username,
|
||||
byte[] passwordSalt,
|
||||
byte[] passwordHash,
|
||||
int permissions,
|
||||
Nurse nurse
|
||||
) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.passwordSalt = passwordSalt;
|
||||
this.passwordHash = passwordHash;
|
||||
this.permissions = permissions;
|
||||
this.nurse = nurse;
|
||||
}
|
||||
|
||||
public User(
|
||||
String username,
|
||||
byte[] passwordSalt,
|
||||
byte[] passwordHash,
|
||||
int permissions,
|
||||
Nurse nurse
|
||||
) {
|
||||
this.username = username;
|
||||
this.passwordSalt = passwordSalt;
|
||||
this.passwordHash = passwordHash;
|
||||
this.permissions = permissions;
|
||||
this.nurse = nurse;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getPasswordSalt() {
|
||||
return passwordSalt;
|
||||
}
|
||||
|
||||
public byte[] getPasswordHash() {
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
try {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] salt = new byte[32];
|
||||
random.nextBytes(salt);
|
||||
this.passwordSalt = salt;
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
md.update(salt);
|
||||
this.passwordHash = md.digest(password.getBytes(StandardCharsets.UTF_8));
|
||||
}catch (NoSuchAlgorithmException exception){
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public int getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(int permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public Nurse getNurse() {
|
||||
return nurse;
|
||||
}
|
||||
|
||||
public void setNurse(Nurse nurse) {
|
||||
this.nurse = nurse;
|
||||
}
|
||||
}
|
202
src/main/java/de/hitec/nhplus/login/database/UserDao.java
Normal file
202
src/main/java/de/hitec/nhplus/login/database/UserDao.java
Normal file
|
@ -0,0 +1,202 @@
|
|||
package de.hitec.nhplus.login.database;
|
||||
|
||||
import de.hitec.nhplus.datastorage.Dao;
|
||||
import de.hitec.nhplus.datastorage.DaoFactory;
|
||||
import de.hitec.nhplus.login.User;
|
||||
import de.hitec.nhplus.nurse.Nurse;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UserDao implements Dao<User> {
|
||||
protected final Connection connection;
|
||||
|
||||
public UserDao(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public int readUserId(String username) throws SQLException {
|
||||
final String SQL = "SELECT id FROM user WHERE username = ?";
|
||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||
statement.setString(1, username);
|
||||
return statement.executeQuery().getInt(1);
|
||||
}
|
||||
|
||||
public byte[] readPasswordSalt(int id) throws SQLException {
|
||||
final String SQL = "SELECT passwordSalt FROM user WHERE id = ?";
|
||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||
statement.setInt(1, id);
|
||||
return statement.executeQuery().getBytes(1);
|
||||
}
|
||||
|
||||
public byte[] readPasswordHash(int id) throws SQLException {
|
||||
final String SQL = "SELECT passwordHash FROM user WHERE id = ?";
|
||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||
statement.setInt(1, id);
|
||||
return statement.executeQuery().getBytes(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User read(int id) throws SQLException {
|
||||
final String SQL = """
|
||||
SELECT user.username, user.passwordSalt, user.passwordHash, user__permissions.permissions, user__nurse.nurseId
|
||||
FROM user
|
||||
LEFT JOIN user__permissions ON user.id = user__permissions.userId
|
||||
LEFT JOIN user__nurse ON user.id = user__nurse.userId
|
||||
WHERE user.id = ?;
|
||||
""";
|
||||
PreparedStatement statement = this.connection.prepareStatement(SQL);
|
||||
statement.setInt(1, id);
|
||||
ResultSet result = statement.executeQuery();
|
||||
int nurseId = result.getInt(5);
|
||||
Nurse nurse = null;
|
||||
if (!result.wasNull()) {
|
||||
nurse = DaoFactory.getInstance().createNurseDAO().read(nurseId);
|
||||
}
|
||||
return new User(
|
||||
id,
|
||||
result.getString(1),
|
||||
result.getBytes(2),
|
||||
result.getBytes(3),
|
||||
result.getInt(4),
|
||||
nurse
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(User user) throws SQLException {
|
||||
connection.setAutoCommit(false); //Switch to Manual Commit, to do an SQL Transaction
|
||||
final String userSQL = """
|
||||
INSERT INTO user
|
||||
(username, passwordSalt, passwordHash)
|
||||
VALUES (?, ?, ?);
|
||||
""";
|
||||
PreparedStatement statement = this.connection.prepareStatement(userSQL);
|
||||
statement.setString(1, user.getUsername());
|
||||
statement.setBytes(2, user.getPasswordSalt());
|
||||
statement.setBytes(3, user.getPasswordHash());
|
||||
statement.execute();
|
||||
|
||||
ResultSet generatedKeys = connection.createStatement().executeQuery("SELECT id FROM user");
|
||||
connection.commit(); //Finish SQL Transaction
|
||||
connection.setAutoCommit(true); //Switch back Mode
|
||||
|
||||
if (!generatedKeys.next()) {
|
||||
return;
|
||||
}
|
||||
int newId = generatedKeys.getInt(1);
|
||||
|
||||
final String permissionSQL = """
|
||||
INSERT INTO user__permissions
|
||||
(userId, permissions)
|
||||
VALUES (?, ?);
|
||||
""";
|
||||
PreparedStatement permissionStatement = this.connection.prepareStatement(permissionSQL);
|
||||
permissionStatement.setInt(1, newId);
|
||||
permissionStatement.setInt(2, user.getPermissions());
|
||||
permissionStatement.execute();
|
||||
|
||||
if (user.getNurse() == null) {
|
||||
return;
|
||||
}
|
||||
final String nurseSQL = """
|
||||
INSERT INTO user__nurse
|
||||
(userId, nurseId)
|
||||
VALUES (?, ?);
|
||||
|
||||
|
||||
""";
|
||||
PreparedStatement nurseStatement = this.connection.prepareStatement(nurseSQL);
|
||||
permissionStatement.setInt(1, newId);
|
||||
permissionStatement.setInt(2, user.getNurse().getId());
|
||||
permissionStatement.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(User user) throws SQLException {
|
||||
final String userSQL = """
|
||||
UPDATE user SET
|
||||
username = ?,
|
||||
passwordSalt = ?,
|
||||
passwordHash = ?
|
||||
WHERE id = ?
|
||||
""";
|
||||
PreparedStatement statement = this.connection.prepareStatement(userSQL);
|
||||
statement.setString(1, user.getUsername());
|
||||
statement.setBytes(2, user.getPasswordSalt());
|
||||
statement.setBytes(3, user.getPasswordHash());
|
||||
statement.setInt(3, user.getId());
|
||||
statement.executeUpdate();
|
||||
|
||||
final String permissionSQL = """
|
||||
UPDATE user__permissions SET
|
||||
permissions = ?
|
||||
WHERE userId = ?
|
||||
""";
|
||||
PreparedStatement permissionStatement = this.connection.prepareStatement(permissionSQL);
|
||||
permissionStatement.setInt(1, user.getPermissions());
|
||||
permissionStatement.setInt(2, user.getId());
|
||||
permissionStatement.executeUpdate();
|
||||
|
||||
if (user.getNurse() == null) {
|
||||
final String nurseSQL = """
|
||||
DELETE FROM user__nurse WHERE userId = ?
|
||||
""";
|
||||
this.connection.prepareStatement(nurseSQL).executeUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
final String nurseSQL = """
|
||||
UPDATE user__nurse set
|
||||
nurseId = ?
|
||||
WHERE userId = ?
|
||||
""";
|
||||
PreparedStatement nurseStatement = this.connection.prepareStatement(nurseSQL);
|
||||
nurseStatement.setInt(1, user.getNurse().getId());
|
||||
nurseStatement.setInt(2, user.getId());
|
||||
permissionStatement.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(int id) throws SQLException {
|
||||
final String SQL = """
|
||||
DELETE FROM user WHERE user.id = ?;
|
||||
""";
|
||||
PreparedStatement preparedStatement = this.connection.prepareStatement(SQL);
|
||||
preparedStatement.setInt(1, id);
|
||||
preparedStatement.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<User> readAll() throws SQLException {
|
||||
final String SQL = """
|
||||
SELECT user.id, user.username, user.passwordSalt, user.passwordHash, user__permissions.permissions, user__nurse.nurseId
|
||||
FROM user
|
||||
LEFT JOIN user__permissions ON user.id = user__permissions.userId
|
||||
LEFT JOIN user__nurse ON user.id = user__nurse.userId
|
||||
""";
|
||||
ResultSet result = connection.prepareStatement(SQL).executeQuery();
|
||||
|
||||
List<User> users = new ArrayList<>();
|
||||
while (result.next()) {
|
||||
int nurseId = result.getInt(6);
|
||||
Nurse nurse = null;
|
||||
if (!result.wasNull()) {
|
||||
nurse = DaoFactory.getInstance().createNurseDAO().read(nurseId);
|
||||
}
|
||||
users.add(new User(
|
||||
result.getInt(1),
|
||||
result.getString(2),
|
||||
result.getBytes(3),
|
||||
result.getBytes(4),
|
||||
result.getInt(5),
|
||||
nurse
|
||||
));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
CREATE TABLE user
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
passwordSalt BLOB NOT NULL,
|
||||
passwordHash BLOB NOT NULL
|
||||
)
|
|
@ -1,6 +1,6 @@
|
|||
CREATE TABLE user__permissions
|
||||
(
|
||||
userId INTEGER NOT NULL,
|
||||
permissions INTEGER, -- Binary Bitmask for Permissions
|
||||
userId INTEGER NOT NULL UNIQUE,
|
||||
permissions INTEGER NOT NULL, -- Binary Bitmask for Permissions
|
||||
FOREIGN KEY (userId) REFERENCES user (id) ON DELETE CASCADE
|
||||
)
|
|
@ -1,7 +1,7 @@
|
|||
CREATE TABLE user__nurse
|
||||
(
|
||||
userId INTEGER NOT NULL,
|
||||
nurseId INTEGER NOT NULL,
|
||||
userId INTEGER NOT NULL UNIQUE,
|
||||
nurseId INTEGER NOT NULL UNIQUE,
|
||||
FOREIGN KEY (userId) REFERENCES user (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (nurseId) REFERENCES nurse (id) ON DELETE CASCADE
|
||||
)
|
Loading…
Reference in a new issue