refactored a lot
This commit is contained in:
parent
36363716c1
commit
a6add75201
|
@ -16,6 +16,15 @@ Content-Type: application/json
|
||||||
"passwordConfirmation": "1234"
|
"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 user with id 4
|
||||||
GET http://localhost:8080/api/users/4
|
GET http://localhost:8080/api/users/4
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package ch.bbw.pr.tresorbackend.controller;
|
package ch.bbw.pr.tresorbackend.controller;
|
||||||
|
|
||||||
import ch.bbw.pr.tresorbackend.model.ConfigProperties;
|
import ch.bbw.pr.tresorbackend.model.*;
|
||||||
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.service.PasswordEncryptionService;
|
import ch.bbw.pr.tresorbackend.service.PasswordEncryptionService;
|
||||||
import ch.bbw.pr.tresorbackend.service.UserService;
|
import ch.bbw.pr.tresorbackend.service.UserService;
|
||||||
|
|
||||||
|
@ -81,15 +78,13 @@ public class UserController {
|
||||||
System.out.println("UserController.createUser, password validation passed");
|
System.out.println("UserController.createUser, password validation passed");
|
||||||
|
|
||||||
//transform registerUser to user
|
//transform registerUser to user
|
||||||
String salt = PasswordEncryptionService.generateSalt();
|
|
||||||
|
|
||||||
User user = new User(
|
User user = new User(
|
||||||
null,
|
null,
|
||||||
registerUser.getFirstName(),
|
registerUser.getFirstName(),
|
||||||
registerUser.getLastName(),
|
registerUser.getLastName(),
|
||||||
registerUser.getEmail(),
|
registerUser.getEmail(),
|
||||||
passwordService.hashPassword(registerUser.getPassword(), salt),
|
passwordService.hashPassword(registerUser.getPassword())
|
||||||
salt
|
|
||||||
);
|
);
|
||||||
|
|
||||||
User savedUser = userService.createUser(user);
|
User savedUser = userService.createUser(user);
|
||||||
|
@ -110,6 +105,34 @@ public class UserController {
|
||||||
return new ResponseEntity<>(user, HttpStatus.OK);
|
return new ResponseEntity<>(user, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
||||||
|
@PostMapping("/login")
|
||||||
|
public ResponseEntity<String> login(@Valid @RequestBody LoginRequest loginRequest, BindingResult bindingResult) {
|
||||||
|
//input validation
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
List<String> 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
|
// Build Get All Users REST API
|
||||||
// http://localhost:8080/api/users
|
// http://localhost:8080/api/users
|
||||||
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -32,7 +32,4 @@ public class User {
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Column(nullable = false)
|
|
||||||
private String salt;
|
|
||||||
}
|
}
|
|
@ -1,11 +1,14 @@
|
||||||
package ch.bbw.pr.tresorbackend.service;
|
package ch.bbw.pr.tresorbackend.service;
|
||||||
|
|
||||||
|
import ch.bbw.pr.tresorbackend.model.User;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import org.bouncycastle.util.encoders.Hex;
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PasswordEncryptionService
|
* PasswordEncryptionService
|
||||||
|
@ -15,23 +18,38 @@ import java.security.SecureRandom;
|
||||||
@Service
|
@Service
|
||||||
public class PasswordEncryptionService {
|
public class PasswordEncryptionService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PepperService pepperService;
|
||||||
|
|
||||||
|
private final BCryptPasswordEncoder encoder;
|
||||||
|
|
||||||
public PasswordEncryptionService() {
|
public PasswordEncryptionService() {
|
||||||
//todo anpassen!
|
this.encoder = new BCryptPasswordEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateSalt() {
|
public String hashPassword(String password) {
|
||||||
byte[] salt = new byte[5];
|
String pepper = pepperService.getPepper();
|
||||||
new SecureRandom().nextBytes(salt);
|
|
||||||
return Hex.toHexString(salt);
|
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) {
|
public boolean verifyPassword(User user, String password) {
|
||||||
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
|
String pepper = pepperService.getPepper();
|
||||||
String pepper = new 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) {
|
|
||||||
}
|
|
|
@ -33,7 +33,7 @@ public class UserServiceImpl implements UserService {
|
||||||
@Override
|
@Override
|
||||||
public User findByEmail(String email) {
|
public User findByEmail(String email) {
|
||||||
Optional<User> optionalUser = userRepository.findByEmail(email);
|
Optional<User> optionalUser = userRepository.findByEmail(email);
|
||||||
return optionalUser.get();
|
return optionalUser.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue