2023-01-05 05:06:19 +01:00
|
|
|
package com.bib.essensbestellungsverwaltung;
|
2023-01-06 00:02:06 +01:00
|
|
|
|
|
|
|
import javax.crypto.SecretKeyFactory;
|
|
|
|
import javax.crypto.spec.PBEKeySpec;
|
|
|
|
import java.security.NoSuchAlgorithmException;
|
2023-01-16 17:23:25 +01:00
|
|
|
import java.security.SecureRandom;
|
2023-01-06 00:02:06 +01:00
|
|
|
import java.security.spec.InvalidKeySpecException;
|
|
|
|
import java.security.spec.KeySpec;
|
2023-01-07 23:14:41 +01:00
|
|
|
import java.util.ArrayList;
|
2023-01-06 00:02:06 +01:00
|
|
|
import java.util.Base64;
|
2023-01-07 23:14:41 +01:00
|
|
|
import java.util.List;
|
2023-01-06 00:02:06 +01:00
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* A collection of functions loosely related to account management
|
|
|
|
* Acts as an abstraction layer to the database
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-05 05:06:19 +01:00
|
|
|
public class AccountMgr {
|
2023-02-01 22:52:04 +01:00
|
|
|
|
2023-01-05 05:06:19 +01:00
|
|
|
/**
|
|
|
|
* creates a user with createUser(...) and adds its id to the 'worker' table
|
2023-02-01 22:52:04 +01:00
|
|
|
* @param worker the worker to be created
|
2023-01-05 05:06:19 +01:00
|
|
|
* @return userid or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-05 05:06:19 +01:00
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static long createWorker(Worker worker){
|
|
|
|
long id = createUser(worker);
|
2023-01-05 05:06:19 +01:00
|
|
|
String sId = String.valueOf(id);
|
|
|
|
Database.insert("worker", new String[]{"userid"}, new String[]{sId});
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* creates a user with createUser(...) and adds its id to the 'parent' table
|
2023-02-01 22:52:04 +01:00
|
|
|
* @param parent the parent to be created
|
2023-01-05 05:06:19 +01:00
|
|
|
* @return userid or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-05 05:06:19 +01:00
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static long createParent(Parent parent){
|
|
|
|
long id = createUser(parent);
|
2023-01-05 05:06:19 +01:00
|
|
|
String sId = String.valueOf(id);
|
|
|
|
Database.insert("parent", new String[]{"userid"}, new String[]{sId});
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* adds a user to the database
|
2023-02-01 22:52:04 +01:00
|
|
|
* @param user the user to be created
|
2023-01-05 05:06:19 +01:00
|
|
|
* @return userid or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-05 05:06:19 +01:00
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static long createUser(User user) {
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] userH = {"name", "firstname", "addressid", "password", "email"};
|
2023-01-30 04:26:30 +01:00
|
|
|
String name = user.getName();
|
|
|
|
String firstname = user.getFirstname();
|
|
|
|
String pw = hashAndSalt(user.getPassword(), getSalt());
|
|
|
|
String email = user.getEmail();
|
|
|
|
long addressId = user.getAddress().getId();
|
|
|
|
if(addressId < 1){
|
|
|
|
addressId = createAddress(user.getAddress());
|
|
|
|
}
|
|
|
|
String[] userD = {name, firstname, String.valueOf(addressId), pw, email};
|
|
|
|
return Database.insert("user", userH, userD);
|
|
|
|
}
|
2023-01-05 05:06:19 +01:00
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* adds an address to the database
|
|
|
|
* @param address the address to be created
|
|
|
|
* @return id or -1
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static long createAddress(Address address){
|
|
|
|
String[] addressH = {"street", "number", "plz", "city"};
|
|
|
|
String[] addressD = {address.getStreet(),address.getNumber(),address.getPlz(),address.getCity()};
|
|
|
|
return Database.insert("address",addressH,addressD);
|
2023-01-05 05:06:19 +01:00
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* adds a child and allergies to the database
|
2023-02-01 22:52:04 +01:00
|
|
|
* @param child the child to be created
|
2023-01-16 16:35:45 +01:00
|
|
|
* @return id of child or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static long createChild(Child child){
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] childH = {"name","firstname","addressid"};
|
2023-01-30 04:26:30 +01:00
|
|
|
String[] childD = {child.getName(), child.getFirstname(), String.valueOf(child.getAddress().getId())};
|
|
|
|
long id = Database.insert("child", childH, childD);
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] child_allergyH = {"childid","allergyid","severityid"};
|
2023-01-30 04:26:30 +01:00
|
|
|
for (AllergySeverity allergy: child.getAllergies()) {
|
|
|
|
String sId = String.valueOf(id);
|
|
|
|
String sAllergyId = String.valueOf(allergy.getAllergy().getId());
|
|
|
|
String sSeverityId = String.valueOf(allergy.getSeverityId());
|
|
|
|
String[] child_allergyD = {sId,sAllergyId,sSeverityId};
|
|
|
|
Database.insert("child_allergy",child_allergyH,child_allergyD);
|
2023-01-05 05:06:19 +01:00
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* returns a User(Worker | Parent) for a given id or null if no unique id was found
|
|
|
|
* @param id id of the User
|
|
|
|
* @return User(Worker | Parent) or null
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-27 15:14:36 +01:00
|
|
|
protected static User getUserById(long id){
|
|
|
|
List<String> entry = Database.getEntryById("user",id);
|
2023-02-01 22:52:04 +01:00
|
|
|
if(entry.size() != 1){
|
|
|
|
return null;
|
|
|
|
}
|
2023-01-27 15:14:36 +01:00
|
|
|
String[] parts = entry.get(0).split(":");
|
|
|
|
Address address = getAddressById(id);
|
2023-01-30 04:26:30 +01:00
|
|
|
if(isWorker(String.valueOf(id))){
|
|
|
|
return new Worker(id,parts[1],parts[2],parts[4],parts[5],address);
|
|
|
|
}else{
|
|
|
|
String[] parent_childH = {"parentuserid"};
|
|
|
|
String[] parent_childD = {String.valueOf(id)};
|
|
|
|
List<Child> children = new ArrayList<>();
|
|
|
|
List<String> parent_childEntries = Database.select("parent_child",parent_childH,parent_childD);
|
|
|
|
for (String parent_childEntry: parent_childEntries) {
|
|
|
|
String[] parent_childParts = parent_childEntry.split(":");
|
|
|
|
children.add(getChildById(Long.parseLong(parent_childParts[2])));
|
|
|
|
}
|
|
|
|
return new Parent(id,parts[1],parts[2],parts[4],parts[5],address,children);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* returns a Child for a given id or null if no unique id was found
|
|
|
|
* @param id id of child
|
|
|
|
* @return Child or null
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
protected static Child getChildById(long id){
|
|
|
|
List<String> entry = Database.getEntryById("child",id);
|
2023-02-01 22:52:04 +01:00
|
|
|
if(entry.size() != 1){
|
|
|
|
return null;
|
|
|
|
}
|
2023-01-30 04:26:30 +01:00
|
|
|
String[] parts = entry.get(0).split(":");
|
|
|
|
String[] child_allergyH = {"childid"};
|
|
|
|
String[] child_allergyD = {String.valueOf(id)};
|
|
|
|
List<String> entriesAllergy = Database.select("child_allergy",child_allergyH,child_allergyD);
|
|
|
|
List<AllergySeverity> allergySeverities = new ArrayList<>();
|
|
|
|
for (String entryAllergy : entriesAllergy) {
|
|
|
|
String[] allergyParts = entryAllergy.split(":");
|
|
|
|
List<String> severity = Database.getEntryById("severity", Long.parseLong(allergyParts[3]));
|
|
|
|
String sSeverity = severity.get(0).split(":")[1];
|
|
|
|
long lSeverity = Long.parseLong(severity.get(0).split(":")[0]);
|
|
|
|
allergySeverities.add(new AllergySeverity(FoodMgr.getAllergyById(Long.parseLong(allergyParts[2])),lSeverity,sSeverity));
|
|
|
|
}
|
|
|
|
return new Child(id,parts[1],parts[2],getAddressById(Long.parseLong(parts[3])),allergySeverities);
|
2023-01-27 15:14:36 +01:00
|
|
|
}
|
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* returns an Address for a given id or null if no unique id was found
|
|
|
|
* @param id id of the address
|
|
|
|
* @return Address or null
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-27 15:14:36 +01:00
|
|
|
protected static Address getAddressById(long id){
|
|
|
|
List<String> entry = Database.getEntryById("address",id);
|
2023-02-01 22:52:04 +01:00
|
|
|
if(entry.size() != 1){
|
|
|
|
return null;
|
|
|
|
}
|
2023-01-27 15:14:36 +01:00
|
|
|
String[] parts = entry.get(0).split(":");
|
|
|
|
return new Address(Long.parseLong(parts[0]),parts[1],parts[2],parts[3],parts[4]);
|
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* creates entries in the database to match parent to child
|
|
|
|
* @param parentId id of parent
|
|
|
|
* @param childId id of child
|
|
|
|
* @return id of parent_child or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
|
|
|
protected static long matchParentChild(String parentId, String childId){
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] parent_childH = {"parentuserid","childid"};
|
|
|
|
String[] parent_childD = {parentId,childId};
|
|
|
|
return Database.insert("parent_child", parent_childH,parent_childD);
|
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* a simple login to check if a given email matches a password
|
|
|
|
* @param email email
|
|
|
|
* @param pw password
|
|
|
|
* @return id or -1
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
|
|
|
protected static long login(String email, String pw){
|
2023-01-16 17:23:25 +01:00
|
|
|
String[] pwH = {"email"};
|
|
|
|
String[] pwD = {email};
|
|
|
|
List<String> foundEmail = Database.select("user",pwH,pwD);
|
2023-01-17 13:47:24 +01:00
|
|
|
String salt;
|
|
|
|
if(foundEmail.size() == 1){
|
|
|
|
String[] userParts = foundEmail.get(0).split(":");
|
|
|
|
String[] pwParts = userParts[4].split("\\.");
|
|
|
|
salt = pwParts[1];
|
|
|
|
}else{
|
|
|
|
//no unique user found; still calculating a hash for security reasons
|
|
|
|
salt = getSalt();
|
|
|
|
}
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] userH = {"email","password"};
|
2023-01-16 17:23:25 +01:00
|
|
|
String[] userD = {email,hashAndSalt(pw,salt)};
|
2023-01-05 05:06:19 +01:00
|
|
|
return Database.getSingleId("user",userH,userD);
|
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* checks if id is in worker table
|
|
|
|
* @param id userid
|
|
|
|
* @return true if id is in worker table
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
|
|
|
protected static boolean isWorker(String id){
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] workerH = {"userid"};
|
|
|
|
String[] workerD = {id};
|
|
|
|
long workerId = Database.getSingleId("worker",workerH,workerD);
|
|
|
|
return workerId > 0;
|
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* checks if id is in parent table
|
|
|
|
* @param id userid
|
|
|
|
* @return true if id is in parent table
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
|
|
|
protected static boolean isParent(String id){
|
2023-01-05 05:06:19 +01:00
|
|
|
String[] parentH = {"userid"};
|
|
|
|
String[] parentD = {id};
|
|
|
|
long parentId = Database.getSingleId("parent",parentH,parentD);
|
|
|
|
return parentId > 0;
|
|
|
|
}
|
2023-01-06 00:02:06 +01:00
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* returns a hashed and salted password
|
|
|
|
* @param pw the password to hash
|
|
|
|
* @return hashed and salted password
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
2023-01-30 04:26:30 +01:00
|
|
|
private static String hashAndSalt(String pw, String salt){
|
2023-01-16 17:23:25 +01:00
|
|
|
Base64.Decoder dec = Base64.getDecoder();
|
|
|
|
byte[] bySalt = dec.decode(salt);
|
|
|
|
KeySpec spec = new PBEKeySpec(pw.toCharArray(), bySalt,310001,256);
|
2023-01-06 01:51:42 +01:00
|
|
|
String hashedPw;
|
2023-01-06 00:02:06 +01:00
|
|
|
try {
|
|
|
|
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
|
|
|
|
byte[] hash = factory.generateSecret(spec).getEncoded();
|
|
|
|
Base64.Encoder enc = Base64.getEncoder();
|
|
|
|
hashedPw = enc.encodeToString(hash);
|
|
|
|
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
2023-01-16 17:23:25 +01:00
|
|
|
hashedPw += "." + salt;
|
2023-01-06 00:02:06 +01:00
|
|
|
return hashedPw;
|
|
|
|
}
|
2023-01-07 23:14:41 +01:00
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* generates a secure random salt, Base64 encoded
|
|
|
|
* @return String Base64 encoded
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
2023-01-16 17:23:25 +01:00
|
|
|
private static String getSalt(){
|
|
|
|
SecureRandom sec = new SecureRandom();
|
|
|
|
byte[] salt = new byte[16];
|
|
|
|
sec.nextBytes(salt);
|
|
|
|
Base64.Encoder enc = Base64.getEncoder();
|
|
|
|
return enc.encodeToString(salt);
|
|
|
|
}
|
|
|
|
|
2023-01-16 16:35:45 +01:00
|
|
|
/**
|
|
|
|
* gives the invoice for one month and one child
|
|
|
|
* @param date YYYY-MM the month
|
|
|
|
* @param childId id of child
|
|
|
|
* @return the invoice as a List
|
2023-02-01 22:52:04 +01:00
|
|
|
* @author Malte Schulze Hobeling
|
2023-01-16 16:35:45 +01:00
|
|
|
*/
|
|
|
|
protected static List<String> getInvoice(String date, String childId){
|
2023-01-07 23:14:41 +01:00
|
|
|
List<String> invoice = new ArrayList<>();
|
|
|
|
List<String> child = Database.getEntryById("child", Long.parseLong(childId));
|
2023-02-01 22:52:04 +01:00
|
|
|
if(child.size() != 1){
|
|
|
|
return invoice;
|
|
|
|
}
|
|
|
|
invoice.add("Monatsabrechnung " + date);
|
2023-01-07 23:14:41 +01:00
|
|
|
String[] childParts = child.get(0).split(":");
|
|
|
|
invoice.add(childParts[1] + ", " + childParts[2]);
|
|
|
|
String[] food_planH = {"date"};
|
|
|
|
String[] food_planD = {date+"%"};
|
|
|
|
List<String> food_plan = Database.select("food_plan",food_planH,food_planD);
|
|
|
|
for (String day : food_plan) {
|
|
|
|
String[] food_planParts = day.split(":");
|
|
|
|
String[] food_selectionH = {"childid","food_planid"};
|
|
|
|
String[] food_selectionD = {childId,food_planParts[0]};
|
|
|
|
List<String> food_selection = Database.select("food_selection",food_selectionH,food_selectionD);
|
|
|
|
for (String food_select : food_selection) {
|
|
|
|
String[] food_selectParts = food_select.split(":");
|
|
|
|
List<String> food = Database.getEntryById("food",Long.parseLong(food_selectParts[3]));
|
|
|
|
String[] foodParts = food.get(0).split(":");
|
|
|
|
String line = food_planParts[1] + ": " + foodParts[1];
|
|
|
|
invoice.add(line);
|
|
|
|
}
|
|
|
|
}
|
2023-02-01 22:52:04 +01:00
|
|
|
double price = getPrice();
|
2023-01-07 23:14:41 +01:00
|
|
|
invoice.add("Total: " + (invoice.size()-2) + " X " + price + "€ = " + ((invoice.size()-2)*price) + "€");
|
|
|
|
return invoice;
|
|
|
|
}
|
2023-01-30 04:26:30 +01:00
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* gets the price per meal from the database and converts it to double
|
|
|
|
* @return double price
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
|
|
|
protected static double getPrice(){
|
2023-01-30 04:26:30 +01:00
|
|
|
List<String> priceEntry = Database.getEntryById("price",1);
|
2023-02-01 22:52:04 +01:00
|
|
|
return Double.parseDouble(priceEntry.get(0).split(":")[1])/100.0;
|
2023-01-30 04:26:30 +01:00
|
|
|
}
|
|
|
|
|
2023-02-01 22:52:04 +01:00
|
|
|
/**
|
|
|
|
* converts the price per meal to integer and updates it in the database
|
|
|
|
* @param price double
|
|
|
|
* @author Malte Schulze Hobeling
|
|
|
|
*/
|
|
|
|
protected static void setPrice(double price){
|
2023-01-30 04:26:30 +01:00
|
|
|
String[] priceH = {"id","price"};
|
2023-02-01 22:52:04 +01:00
|
|
|
String[] priceD = {"1", String.valueOf((int)(price*100))};
|
2023-01-30 04:26:30 +01:00
|
|
|
Database.update("price",priceH,priceD);
|
|
|
|
}
|
2023-01-05 05:06:19 +01:00
|
|
|
}
|