From a550dc0216b762507c32666c79301dc135a09b1a Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Tue, 19 Apr 2022 10:10:36 +0200 Subject: [PATCH] cleaning, adding comments to User class --- pom.xml | 2 +- .../de/srsoftware/widerhall/data/User.java | 121 +++++++++++++++--- 2 files changed, 103 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index 4e3326c..f949725 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.example Widerhall - 0.0.7 + 0.0.8 diff --git a/src/main/java/de/srsoftware/widerhall/data/User.java b/src/main/java/de/srsoftware/widerhall/data/User.java index 0fdb597..1513738 100644 --- a/src/main/java/de/srsoftware/widerhall/data/User.java +++ b/src/main/java/de/srsoftware/widerhall/data/User.java @@ -1,8 +1,6 @@ package de.srsoftware.widerhall.data; import de.srsoftware.widerhall.Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.security.InvalidKeyException; import java.sql.ResultSet; @@ -10,21 +8,31 @@ import java.sql.SQLException; import java.time.LocalDate; import java.util.*; -import static de.srsoftware.widerhall.data.Database.*; import static de.srsoftware.widerhall.Constants.*; +/** + * @author Stephan Richter + * This class represents User objects of the widerhall db. + */ public class User { public static final String TABLE_NAME = "Users"; - private static final Logger LOG = LoggerFactory.getLogger(User.class); - private static final HashMap users = new HashMap<>(); public static final int PERMISSION_ADMIN = 1; public static final int PERMISSION_CREATE_LISTS = 2; - public static final String SALT = "salt"; public static final String HASHED_PASS = "hashedPassword"; + public static final String SALT = "salt"; + private static final HashMap users = new HashMap<>(); private String email, salt, hashedPass, name; private int permissions; + /** + * create a new user object + * @param email + * @param name + * @param salt + * @param hashedPass + * @param permissions + */ public User(String email, String name, String salt, String hashedPass, int permissions) { this.email = email; this.name = name; @@ -56,6 +64,12 @@ public class User { /************** end of field accessors ****************/ + /** + * Add a new permission to the current user object. + * Also updates the corresponding db entry + * @param newPermission + * @throws SQLException + */ public void addPermission(int newPermission) throws SQLException { permissions |= newPermission; Database.open() @@ -67,6 +81,15 @@ public class User { } + /** + * Create a new user object by hashing it's password and storing user data, salt and hashed password to the db. + * Initially, the user is created without any permissions. + * @param email + * @param name + * @param password + * @return + * @throws SQLException + */ public static User create(String email, String name, String password) throws SQLException { String salt = null; String hashedPass = null; @@ -77,6 +100,10 @@ public class User { return new User(email,name,salt,hashedPass,0).save(); } + /** + * create user table + * @throws SQLException + */ public static void createTable() throws SQLException { var sql = new StringBuilder() .append("CREATE TABLE ").append(TABLE_NAME) @@ -91,29 +118,61 @@ public class User { Database.open().query(sql).compile().run(); } + /** + * Withdraw a specific permission from the user object. + * Updated permission flag will be written to db. + * @param newPermission + * @throws SQLException + */ public void dropPermission(int newPermission) throws SQLException { permissions ^= (permissions & newPermission); Database.open().update(TABLE_NAME).set(PERMISSIONS,permissions).compile().run(); } + /** + * check, if User object has requested permission(s). + * @param permission + * @return + */ public boolean hashPermission(int permission){ return (permissions & permission) > 0; } + /** + * Load the list of all users. Internally calls loadAll(null) + * @return + * @throws SQLException + */ public static List loadAll() throws SQLException { return loadAll(null); } + /** + * Load the list of all users identified by the provided email list. + * If emails is null, all users are loaded. + * If emails is empty, an empty list well be returned. + * @param emails + * @return + * @throws SQLException + */ public static List loadAll(Collection emails) throws SQLException { + if (emails != null && emails.isEmpty()) return List.of(); var userList = new ArrayList(); var query = Database.open().select(TABLE_NAME); - if (emails != null && !emails.isEmpty()) query.where(EMAIL,emails); + if (emails != null) query.where(EMAIL,emails); var rs = query.compile().exec(); while (rs.next()) userList.add(User.from(rs)); return userList; } + /** + * Create a new User object from a ResultSet. + * This method is cached: If a User object with an identifying email has been loaded before, the already-loaded object will be returned. + * @param rs + * @return + * @throws SQLException + */ private static User from(ResultSet rs) throws SQLException { var email = rs.getString(EMAIL); var user = users.get(email); @@ -127,6 +186,14 @@ public class User { } + /** + * Loads the user identified by it's email, but only if the provided password matches. + * @param email + * @param password + * @return + * @throws InvalidKeyException + * @throws SQLException + */ public static User loadUser(String email, String password) throws InvalidKeyException, SQLException { ResultSet rs = Database.open() .select(TABLE_NAME) @@ -146,24 +213,36 @@ public class User { } + /** + * checks, if the provided password matches the User obejcts's original password by comparing hashes. + * @param password + * @return + */ private boolean matching(String password) { if (hashedPass == null) return password == null; return hashedPass.equals(Util.sha256(password+salt)); } + /** + * Checks, whether the user table is empty + * @return + * @throws SQLException + */ public static boolean noUsers() throws SQLException { var rs = Database.open().select(TABLE_NAME,"count(*)").compile().exec(); try { - if (rs.next()) { - return rs.getInt(1) < 1; - } + if (rs.next()) return rs.getInt(1) < 1; } finally { rs.close(); } return false; } + /** + * creates a readable permission list from the permission flag. + * @return + */ public String permissionList(){ var list = new ArrayList(); if (hashPermission(PERMISSION_ADMIN)) list.add("admin"); @@ -171,20 +250,24 @@ public class User { return String.join(", ",list); } + /** + * creates a map containing all of the Users data but the password. + * @return + */ public Map safeMap(){ return Map.of(NAME,name,EMAIL,email,PERMISSIONS,permissionList(),PASSWORD,hashedPassword() == null ? "no" : "yes"); } + /** + * sae the current User object to the database + * @return + * @throws SQLException + */ private User save() throws SQLException { - var values = new HashMap(); - values.put(EMAIL,email); - values.put(NAME,name); - if (salt != null) values.put(SALT,salt); - if (hashedPass != null) values.put(HASHED_PASS,hashedPass); - Database.open().insertInto(TABLE_NAME) - .values(values) - .compile() - .run(); + var req = Database.open().insertInto(TABLE_NAME).set(EMAIL,email).set(NAME,name); + if (salt != null) req.set(SALT,salt); + if (hashedPass != null) req.set(HASHED_PASS,hashedPass); + req.compile().run(); return this; } }