From a6add75201fb0174cb8ecd93ade10b2cb86ed9fe Mon Sep 17 00:00:00 2001 From: lorenzhohermuth Date: Thu, 15 May 2025 22:28:17 +0200 Subject: [PATCH] refactored a lot --- .../httprequest/UserRequests.http | 9 ++++ .../controller/UserController.java | 37 ++++++++++++---- .../pr/tresorbackend/model/LoginRequest.java | 21 ++++++++++ .../ch/bbw/pr/tresorbackend/model/User.java | 3 -- .../service/PasswordEncryptionService.java | 42 +++++++++++++------ .../service/impl/UserServiceImpl.java | 2 +- 6 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/LoginRequest.java diff --git a/183_12_1_tresorbackend_rupe-master/httprequest/UserRequests.http b/183_12_1_tresorbackend_rupe-master/httprequest/UserRequests.http index bf8d5d8..1ee2d11 100644 --- a/183_12_1_tresorbackend_rupe-master/httprequest/UserRequests.http +++ b/183_12_1_tresorbackend_rupe-master/httprequest/UserRequests.http @@ -16,6 +16,15 @@ Content-Type: application/json "passwordConfirmation": "1234" } +### +POST http://localhost:8080/api/users/login +Content-Type: application/json + +{ +"email": "violett.weber@bbw.ch", +"password": "1234" +} + ### #Get user with id 4 GET http://localhost:8080/api/users/4 diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java index 4d5e7bc..463a241 100644 --- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java +++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/controller/UserController.java @@ -1,9 +1,6 @@ package ch.bbw.pr.tresorbackend.controller; -import ch.bbw.pr.tresorbackend.model.ConfigProperties; -import ch.bbw.pr.tresorbackend.model.EmailAdress; -import ch.bbw.pr.tresorbackend.model.RegisterUser; -import ch.bbw.pr.tresorbackend.model.User; +import ch.bbw.pr.tresorbackend.model.*; import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService; import ch.bbw.pr.tresorbackend.service.UserService; @@ -81,15 +78,13 @@ public class UserController { System.out.println("UserController.createUser, password validation passed"); //transform registerUser to user - String salt = PasswordEncryptionService.generateSalt(); User user = new User( null, registerUser.getFirstName(), registerUser.getLastName(), registerUser.getEmail(), - passwordService.hashPassword(registerUser.getPassword(), salt), - salt + passwordService.hashPassword(registerUser.getPassword()) ); User savedUser = userService.createUser(user); @@ -110,6 +105,34 @@ public class UserController { return new ResponseEntity<>(user, HttpStatus.OK); } + @CrossOrigin(origins = "${CROSS_ORIGIN}") + @PostMapping("/login") + public ResponseEntity login(@Valid @RequestBody LoginRequest loginRequest, BindingResult bindingResult) { + //input validation + if (bindingResult.hasErrors()) { + List errors = bindingResult.getFieldErrors().stream() + .map(fieldError -> fieldError.getField() + ": " + fieldError.getDefaultMessage()) + .collect(Collectors.toList()); + System.out.println("UserController.createUser " + errors); + + JsonArray arr = new JsonArray(); + errors.forEach(arr::add); + JsonObject obj = new JsonObject(); + obj.add("message", arr); + String json = new Gson().toJson(obj); + + System.out.println("UserController.createUser, validation fails: " + json); + return ResponseEntity.badRequest().body(json); + } + + User user = userService.findByEmail(loginRequest.getEmail()); + + if (user != null && passwordService.verifyPassword(user, loginRequest.getPassword())) { + return ResponseEntity.status(200).body("User logged in"); + } + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + // Build Get All Users REST API // http://localhost:8080/api/users @CrossOrigin(origins = "${CROSS_ORIGIN}") diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/LoginRequest.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/LoginRequest.java new file mode 100644 index 0000000..c22d067 --- /dev/null +++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/LoginRequest.java @@ -0,0 +1,21 @@ +package ch.bbw.pr.tresorbackend.model; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class LoginRequest { + @NotEmpty(message = "Email cannot be empty") + @Email(message = "Invalid email format") + private String email; + + @NotEmpty(message = "Password cannot be empty") + private String password; +} \ No newline at end of file diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java index cccf563..01d4f6c 100644 --- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java +++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/model/User.java @@ -32,7 +32,4 @@ public class User { @Column(nullable = false) private String password; - - @Column(nullable = false) - private String salt; } \ No newline at end of file diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/PasswordEncryptionService.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/PasswordEncryptionService.java index 2f78da7..a88ddcc 100644 --- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/PasswordEncryptionService.java +++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/PasswordEncryptionService.java @@ -1,11 +1,14 @@ package ch.bbw.pr.tresorbackend.service; +import ch.bbw.pr.tresorbackend.model.User; import lombok.Value; import org.bouncycastle.util.encoders.Hex; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import java.security.SecureRandom; +import java.util.Objects; /** * PasswordEncryptionService @@ -15,23 +18,38 @@ import java.security.SecureRandom; @Service public class PasswordEncryptionService { + @Autowired + private PepperService pepperService; + + private final BCryptPasswordEncoder encoder; + public PasswordEncryptionService() { - //todo anpassen! + this.encoder = new BCryptPasswordEncoder(); } - public static String generateSalt() { - byte[] salt = new byte[5]; - new SecureRandom().nextBytes(salt); - return Hex.toHexString(salt); + public String hashPassword(String password) { + String pepper = pepperService.getPepper(); + + if (pepper == null || pepper.isEmpty()) { + throw new IllegalStateException("Pepper is missing or empty"); + } + + // Combine pepper and password, let BCrypt handle salting internally + String connectedPassword = pepper + password; + return encoder.encode(connectedPassword); } - public String hashPassword(String password, String salt) { - BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); - String pepper = new PepperService().getPepper(); + public boolean verifyPassword(User user, String password) { + String pepper = pepperService.getPepper(); - return encoder.encode(pepper + password ); + if (pepper == null || pepper.isEmpty()) { + throw new IllegalStateException("Pepper is missing or empty"); + } + + // Reconstruct the original password with pepper + String connectedPassword = pepper + password; + + // Directly compare the stored hash with the user input + return encoder.matches(connectedPassword, user.getPassword()); } } - -record PasswordBean(String hashedPassword, String Salt) { -} \ No newline at end of file diff --git a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/impl/UserServiceImpl.java b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/impl/UserServiceImpl.java index efe85ef..f1ea1df 100644 --- a/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/impl/UserServiceImpl.java +++ b/183_12_1_tresorbackend_rupe-master/src/main/java/ch/bbw/pr/tresorbackend/service/impl/UserServiceImpl.java @@ -33,7 +33,7 @@ public class UserServiceImpl implements UserService { @Override public User findByEmail(String email) { Optional optionalUser = userRepository.findByEmail(email); - return optionalUser.get(); + return optionalUser.orElse(null); } @Override