From 9b9e9db5171fcf3c9a3bdd9db514273ab44e5f0f Mon Sep 17 00:00:00 2001 From: Fredrik Marjoni Date: Tue, 10 Mar 2026 15:27:41 +0100 Subject: [PATCH] feat(user): switch password handling to char[] and enforce BCrypt 72-char limit --- .../java/edu/group5/app/model/user/User.java | 10 +++++++--- .../edu/group5/app/model/user/UserService.java | 4 ++-- .../group5/app/model/user/CustomerTest.java | 18 +++++++++++++++--- .../group5/app/model/user/UserServiceTest.java | 12 ++++++------ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/group5/app/model/user/User.java b/src/main/java/edu/group5/app/model/user/User.java index bdb4700..411538d 100644 --- a/src/main/java/edu/group5/app/model/user/User.java +++ b/src/main/java/edu/group5/app/model/user/User.java @@ -102,12 +102,16 @@ public String getPasswordHash() { * This method uses BCrypt to compare the plaintext password with the hashed password. * @param password the plaintext password to verify * @return true if the password is correct, false otherwise + * @throws IllegalArgumentException if the password is null, empty, or longer than 72 characters (BCrypt limit) */ - public boolean verifyPassword(String password) { - if (password == null || password.isEmpty()) { + public boolean verifyPassword(char[] password) { + if (password == null || password.length == 0) { return false; } + if (password.length > 72) { // BCrypt has a maximum password length of 72 bytes + throw new IllegalArgumentException("Password cannot be longer than 72 characters"); + } BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); - return encoder.matches(password, this.passwordHash); + return encoder.matches(new String(password), this.passwordHash); } } diff --git a/src/main/java/edu/group5/app/model/user/UserService.java b/src/main/java/edu/group5/app/model/user/UserService.java index 0b754c8..5df32ee 100644 --- a/src/main/java/edu/group5/app/model/user/UserService.java +++ b/src/main/java/edu/group5/app/model/user/UserService.java @@ -69,8 +69,8 @@ public boolean registerUser(String role, String firstName, String lastName, * (i.e., the user exists and the password is correct), false otherwise * @throws IllegalArgumentException if email is null or empty, or if password is null or empty */ - public boolean login(String email, String password) { - if (email == null || email.trim().isEmpty() || password == null || password.trim().isEmpty()) { + public boolean login(String email, char[] password) { + if (email == null || email.trim().isEmpty() || password == null || password.length == 0) { return false; } User user = this.userRepository.findUserByEmail(email); diff --git a/src/test/java/edu/group5/app/model/user/CustomerTest.java b/src/test/java/edu/group5/app/model/user/CustomerTest.java index bd607f5..7c96438 100644 --- a/src/test/java/edu/group5/app/model/user/CustomerTest.java +++ b/src/test/java/edu/group5/app/model/user/CustomerTest.java @@ -116,7 +116,7 @@ void verifyPasswordReturnsTrueForCorrectPassword() { User user = new Customer(testUserId, testFirstName, testLastName, testEmail, testPasswordHash); - assertTrue(user.verifyPassword(testPassword)); + assertTrue(user.verifyPassword(testPassword.toCharArray())); } @Test @@ -124,7 +124,7 @@ void verifyPasswordReturnsFalseForIncorrectPassword() { User user = new Customer(testUserId, testFirstName, testLastName, testEmail, testPasswordHash); - assertFalse(user.verifyPassword("wrongPassword")); + assertFalse(user.verifyPassword("wrongPassword".toCharArray())); } @Test @@ -140,7 +140,19 @@ void verifyPasswordReturnsFalseForEmptyPassword() { User user = new Customer(testUserId, testFirstName, testLastName, testEmail, testPasswordHash); - assertFalse(user.verifyPassword("")); + assertFalse(user.verifyPassword("".toCharArray())); + } + + @Test + void verifyPasswordThrowsExceptionForTooLongPassword() { + User user = new Customer(testUserId, testFirstName, + testLastName, testEmail, testPasswordHash); + char[] longPassword = new char[73]; // 73 characters, exceeding BCrypt limit + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, + () -> user.verifyPassword(longPassword) + ); + assertEquals("Password cannot be longer than 72 characters", exception.getMessage()); } @Test diff --git a/src/test/java/edu/group5/app/model/user/UserServiceTest.java b/src/test/java/edu/group5/app/model/user/UserServiceTest.java index 7f45dc7..cb0b7b6 100644 --- a/src/test/java/edu/group5/app/model/user/UserServiceTest.java +++ b/src/test/java/edu/group5/app/model/user/UserServiceTest.java @@ -95,7 +95,7 @@ void loginValidPassword() { User testUser = new Customer(10, "Test", "User", "test@example.com", hashedPassword); repo.addContent(testUser); - boolean result = service.login("test@example.com", plainPassword); + boolean result = service.login("test@example.com", plainPassword.toCharArray()); assertTrue(result); } @@ -107,9 +107,9 @@ void loginInvalidPassword() { User testUser = new Customer(10, "Test", "User", "test@example.com", hashedPassword); repo.addContent(testUser); - boolean result = service.login("test@example.com", "wrongpass"); + boolean result = service.login("test@example.com", "wrongpass".toCharArray()); boolean result2 = service.login("test@example.com", null); - boolean result3 = service.login("test@example.com", " "); + boolean result3 = service.login("test@example.com", " ".toCharArray()); assertFalse(result); assertFalse(result2); assertFalse(result3); @@ -117,9 +117,9 @@ void loginInvalidPassword() { @Test void loginInvalidEmail() { - boolean result = service.login("nonexist@example.com", "password"); - boolean result2 = service.login(null, "password"); - boolean result3 = service.login(" ", "password"); + boolean result = service.login("nonexist@example.com", "password".toCharArray()); + boolean result2 = service.login(null, "password".toCharArray()); + boolean result3 = service.login(" ", "password".toCharArray()); assertFalse(result); assertFalse(result2); assertFalse(result3);