diff --git a/helpmehelpapplication/helpmehelpapplication.iml b/helpmehelpapplication/helpmehelpapplication.iml
new file mode 100644
index 0000000..9e3449c
--- /dev/null
+++ b/helpmehelpapplication/helpmehelpapplication.iml
@@ -0,0 +1,6 @@
+
+
The generated hash contains both a random salt and the hashed password, + * encoded as Base64 string. + *
+ * + * @author Robin Strand Prestmo + */ +public final class PasswordHasher { + private static final SecureRandom RNG = new SecureRandom(); + + /** + * Hashes a password using PBKDF2 and a random salt. + * + * @param password the password to hash. + * @return a Base64 string containing the salt and the hashed password. + * @throws IllegalArgumentException if the password is null or blank. + */ + public String getHashPassword(String password) { + if (password == null || password.isBlank()) { + throw new IllegalArgumentException("Password cannot be null or blank."); + } + + String hashPass = ""; + + try { + // 1. Create salt + byte[] salt = new byte[16]; + RNG.nextBytes(salt); + + // 2. Create PBKDF2 Hash value + PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 100000, 32 * 8); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + byte[] hash = factory.generateSecret(spec).getEncoded(); + + // 3. Combine salt and password bytes + byte[] hashBytes = new byte[48]; + System.arraycopy(salt, 0, hashBytes, 0, 16); + System.arraycopy(hash, 0, hashBytes, 16, 32); + + // 4. Turn the combined salt+hash into a string. + hashPass = Base64.getEncoder().encodeToString(hashBytes); + } catch (Exception e) { + throw new RuntimeException("Error while hashing password.", e); + } + return hashPass; + } + + /** + * Checks if the password matches a perviously stored hash. + * + * @param password The password the user types. + * @param hashPass Is the stored hashed password + * @return True if password is valid, otherwise false. + */ + public boolean isValidPassword(String password, String hashPass) { + if (password == null || password.isBlank()) { + return false; + } + + try { + // Extract the bytes + byte[] hashBytes = Base64.getDecoder().decode(hashPass); + + // Get salt + byte[] salt = new byte[16]; + System.arraycopy(hashBytes, 0, salt, 0, 16); + + // Compute the hash on the password the user entered + PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 100000, 32 * 8); + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + byte[] hash = factory.generateSecret(spec).getEncoded(); + + // Compare results + byte[] storedHash = new byte[32]; + System.arraycopy(hashBytes, 16, storedHash, 0, 32); + + return MessageDigest.isEqual(storedHash, hash); + + } catch (Exception e) { + throw new RuntimeException("Error while validating password.", e); + } + } +} diff --git a/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/models/user/UserTest.java b/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/models/user/UserTest.java new file mode 100644 index 0000000..5fa92c8 --- /dev/null +++ b/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/models/user/UserTest.java @@ -0,0 +1,218 @@ +package ntnu.sytemutvikling.team6.models.user; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class UserTest { + + @Nested + class constructorTests { + private final UUID validID = UUID.randomUUID(); + private final String validName = "Name"; + private final String validEmail = "Email@gmail.com"; + private final String validPassword = "Password"; + private final Role validRole = Role.NORMAL_USER; + private final Settings validSettings = new Settings(); + private final Inbox validInbox = new Inbox(); + + @Test + void shouldThrowIfIdIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + null, + validName, + validEmail, + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfNameIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + null, + validEmail, + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfNameIsBlank() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + " ", + validEmail, + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Nested + class emailTests { + + @Test + void shouldThrowIfEmailIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + null, + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfEmailIsBlank() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + " ", + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfEmailDoesNotContainAt() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + "test.gmail.com", + validPassword, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfEmailDoesNotContainPeriod() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + "test@gmailcom", + validPassword, + validRole, + validSettings, + validInbox + )); + } + } + + @Test + void shouldThrowIfPasswordIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + validEmail, + null, + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfRoleIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + validEmail, + validPassword, + null, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfPasswordIsBlank() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + validEmail, + " ", + validRole, + validSettings, + validInbox + )); + } + + @Test + void shouldThrowIfSettingsIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + validEmail, + validPassword, + validRole, + null, + validInbox + )); + } + + @Test + void shouldThrowIfInboxIsNull() { + assertThrows(IllegalArgumentException.class, () -> + new User( + validID, + validName, + validEmail, + validPassword, + validRole, + validSettings, + null + )); + } + + @Test + void shouldCreateUser() { + User user = new User( + validID, + validName, + validEmail, + validPassword, + validRole, + validSettings, + validInbox + ); + + assertAll( + () -> assertEquals(validID, user.getId()), + () -> assertEquals(validName, user.getName()), + () -> assertEquals(validEmail, user.getEmail()), + () -> assertEquals(validRole, user.getRole()), + () -> assertEquals(validSettings, user.getSettings()), + () -> assertEquals(validInbox, user.getInbox()) + ); + } + + } +} \ No newline at end of file diff --git a/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/security/PasswordHasherTest.java b/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/security/PasswordHasherTest.java new file mode 100644 index 0000000..68a9409 --- /dev/null +++ b/helpmehelpapplication/src/test/java/ntnu/sytemutvikling/team6/security/PasswordHasherTest.java @@ -0,0 +1,70 @@ +package ntnu.sytemutvikling.team6.security; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PasswordHasherTest { + private final PasswordHasher hasher = new PasswordHasher(); + + @Nested + class getHashPasswordTest { + + @Test + void shouldThrowIfPasswordIsNull() { + assertThrows(IllegalArgumentException.class, () -> hasher.getHashPassword(null)); + } + + @Test + void shouldThrowIfPasswordIsBlank() { + assertThrows(IllegalArgumentException.class, () -> hasher.getHashPassword(" ")); + } + + @Test + void shouldReturnDifferentHashesForSamePasswordBecauseSaltIsRandom() { + String test1 = hasher.getHashPassword("Password"); + String test2 = hasher.getHashPassword("Password"); + + assertNotEquals(test1, test2); + } + } + + @Nested + class isValidPasswordTest { + + @Test + void shouldReturnTrueForCorrectPassword() { + String test = hasher.getHashPassword("Password"); + assertTrue(hasher.isValidPassword("Password", test)); + } + + @Test + void shouldReturnFalseForWrongPassword() { + String test = hasher.getHashPassword("Password"); + assertFalse(hasher.isValidPassword("password", test)); + } + + @Test + void shouldReturnFalseIfPasswordIsBlank() { + String test = hasher.getHashPassword("Test"); + assertFalse(hasher.isValidPassword(" ", test)); + } + + @Test + void shouldReturnFalseIfPasswordIsNull() { + String test = hasher.getHashPassword("Test"); + assertFalse(hasher.isValidPassword(null, test)); + } + + @Test + void shouldThrowIfStoredHashIsNull() { + assertThrows(RuntimeException.class, () -> hasher.isValidPassword("Password", null)); + } + + @Test + void shouldThrowIfStoredHashIsBlank() { + assertThrows(RuntimeException.class, () -> hasher.isValidPassword("Password", " ")); + } + } +} \ No newline at end of file diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/Main.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/Main.class new file mode 100644 index 0000000..110f8b9 Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/Main.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class index 7803742..ef0710b 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Charity.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class index 61b8503..c923756 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/CharityRegistry.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class index 78d4151..eeddec5 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Donation.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class index 1b81460..4f9d393 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/DonationRegistry.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class index 28853ec..e4b6592 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Feedback.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class deleted file mode 100644 index 72613e7..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Inbox.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class deleted file mode 100644 index de22840..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Language.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class deleted file mode 100644 index 12c1cec..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Message.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class deleted file mode 100644 index f19f0d3..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Role.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class deleted file mode 100644 index 9420861..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/Settings.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class deleted file mode 100644 index c0cc6c8..0000000 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/User.class and /dev/null differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class index 970aced..ce901b4 100644 Binary files a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/UserRegistry.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Inbox.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Inbox.class new file mode 100644 index 0000000..4e08a72 Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Inbox.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Language.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Language.class new file mode 100644 index 0000000..5520821 Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Language.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Message.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Message.class new file mode 100644 index 0000000..e556e51 Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Message.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Role.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Role.class new file mode 100644 index 0000000..8d6c32e Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Role.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Settings.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Settings.class new file mode 100644 index 0000000..26851ad Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/Settings.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/User.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/User.class new file mode 100644 index 0000000..e981ecb Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/models/user/User.class differ diff --git a/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/security/PasswordHasher.class b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/security/PasswordHasher.class new file mode 100644 index 0000000..e454773 Binary files /dev/null and b/helpmehelpapplication/target/classes/ntnu/sytemutvikling/team6/security/PasswordHasher.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests$emailTests.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests$emailTests.class new file mode 100644 index 0000000..51a8c3c Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests$emailTests.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests.class new file mode 100644 index 0000000..e7def3c Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest$constructorTests.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest.class new file mode 100644 index 0000000..810d4b9 Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/models/user/UserTest.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$getHashPasswordTest.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$getHashPasswordTest.class new file mode 100644 index 0000000..4047693 Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$getHashPasswordTest.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$isValidPasswordTest.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$isValidPasswordTest.class new file mode 100644 index 0000000..7d04343 Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest$isValidPasswordTest.class differ diff --git a/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest.class b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest.class new file mode 100644 index 0000000..93e185d Binary files /dev/null and b/helpmehelpapplication/target/test-classes/ntnu/sytemutvikling/team6/security/PasswordHasherTest.class differ