diff --git a/api-request/auth-service/changeEmail.http b/api-request/auth-service/changeEmail.http new file mode 100644 index 0000000..52b0320 --- /dev/null +++ b/api-request/auth-service/changeEmail.http @@ -0,0 +1,10 @@ +### Post mapping to update an email. + +### Requires a UserRequestDto: email (This is the new email.) +POST http://localhost:4004/api/auth/change-email +Authorization: Bearer {{token}} +Content-Type: application/json + +{ + "email": "conflicted_test_user@gmail.com" +} \ No newline at end of file diff --git a/api-request/auth-service/changePassword.http b/api-request/auth-service/changePassword.http new file mode 100644 index 0000000..bd5ebad --- /dev/null +++ b/api-request/auth-service/changePassword.http @@ -0,0 +1,11 @@ +### Post request to change password. + +### Requires a token. +### Requires a UserRequestDto: email, password (This is the new password.) +POST http://localhost:4004/api/auth/change-password +Authorization: Bearer {{token}} +Content-Type: application/json + +{ + "password": "java_4_life" +} diff --git a/api-request/auth-service/login.http b/api-request/auth-service/login.http index df9f310..082ff99 100644 --- a/api-request/auth-service/login.http +++ b/api-request/auth-service/login.http @@ -3,8 +3,8 @@ POST http://localhost:4004/api/auth/login Content-Type: application/json { - "email": "testuser@test.com", - "password": "password123" + "email": "test_email@gmail.com", + "password": "c++_4_life!" } > {% client.global.set("token", response.body.token) %} diff --git a/api-request/auth-service/register.http b/api-request/auth-service/register.http new file mode 100644 index 0000000..daed131 --- /dev/null +++ b/api-request/auth-service/register.http @@ -0,0 +1,7 @@ +POST http://localhost:4004/api/auth/register +Content-Type: application/json + +{ + "email": "test_email@gmail.com", + "password": "c++_4_life!" +} diff --git a/api-request/client-service/create-user.http b/api-request/client-service/create-user.http index e18ade1..3e54968 100644 --- a/api-request/client-service/create-user.http +++ b/api-request/client-service/create-user.http @@ -1,6 +1,7 @@ ### Post request to create a user. POST http://localhost:4004/api/clients Authorization: Bearer {{token}} +X-AUTH-ID: a7920032-59cf-461f-a293-6944954d3747 Content-Type: application/json { diff --git a/auth-service/src/main/java/com/cm/authservice/controller/AuthController.java b/auth-service/src/main/java/com/cm/authservice/controller/AuthController.java index 8c80c1e..647c42c 100644 --- a/auth-service/src/main/java/com/cm/authservice/controller/AuthController.java +++ b/auth-service/src/main/java/com/cm/authservice/controller/AuthController.java @@ -1,5 +1,4 @@ package com.cm.authservice.controller; - import com.cm.authservice.dto.LoginResponseDTO; import com.cm.authservice.dto.UserRequestDto; import com.cm.authservice.dto.UserResponseDto; @@ -17,16 +16,17 @@ public class AuthController { private final AuthService authService; - public AuthController(AuthService authService){ + + public AuthController(AuthService authService) { this.authService = authService; } @PostMapping("/login") @Operation(summary = "Generate token on user login") - public ResponseEntity login(@RequestBody UserRequestDto loginRequestDTO){ - Optional tokenOptional = authService.authenticate(loginRequestDTO); + public ResponseEntity login(@RequestBody UserRequestDto userRequestDto) { + Optional tokenOptional = authService.authenticate(userRequestDto); - if(tokenOptional.isEmpty()){ + if (tokenOptional.isEmpty()) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } @@ -36,34 +36,32 @@ public ResponseEntity login(@RequestBody UserRequestDto loginR @GetMapping("/validate") @Operation(summary = "Validate token") - public ResponseEntity validateToken(@RequestHeader("Authorization") String authHeader){ - if(authHeader == null || !authHeader.startsWith("Bearer ")) + public ResponseEntity validateToken(@RequestHeader("Authorization") String authHeader) { + if (authHeader == null || !authHeader.startsWith("Bearer ")) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); - if(authService.validateToken(authHeader.substring(7))){ + if (authService.validateToken(authHeader.substring(7))) { User user = authService.getUser(authHeader.substring(7)); - return ResponseEntity.ok() - .header("X-AUTH-ID", user.getId() - .toString()).build(); + return ResponseEntity.ok().header("X-AUTH-ID", user.getId().toString()).build(); } - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } @PostMapping("/register") @Operation(summary = "Register a new user") - public ResponseEntity register(@RequestBody UserRequestDto userRequestDto){ + public ResponseEntity register(@RequestBody UserRequestDto userRequestDto) { UserResponseDto response = authService.register(userRequestDto); return ResponseEntity.ok().body(response); } - @PutMapping("/update-email") - @Operation(summary = "Update user account email.") - public ResponseEntity updateEmail(@RequestHeader("Authorization") String authHeader, - @RequestBody UserRequestDto userRequestDto){ + @PostMapping("/change-email") + @Operation(summary = "Change user account email.") + public ResponseEntity changeEmail(@RequestHeader("Authorization") String authHeader, + @RequestBody UserRequestDto userRequestDto) { - if(authHeader == null || !authHeader.startsWith("Bearer ")) + if (authHeader == null || !authHeader.startsWith("Bearer ")) return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); // Now check if the token came from the person who claimed to want to change their email. @@ -73,5 +71,20 @@ public ResponseEntity updateEmail(@RequestHeader("Authorization return ResponseEntity.ok().body(userResponseDto); } + @PostMapping("/change-password") + @Operation(summary = "Change a users password with valid token") + public ResponseEntity changePassword(@RequestHeader("Authorization") String authHeader, + @RequestBody UserRequestDto userRequestDto) { + if (authHeader == null + || !authHeader.startsWith("Bearer ") + || !authService.validateToken(authHeader.substring(7))) { + + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + + UserResponseDto response = + authService.changePassword(userRequestDto, authHeader.substring(7)); + return ResponseEntity.ok().body(response); + } } diff --git a/auth-service/src/main/java/com/cm/authservice/service/AuthService.java b/auth-service/src/main/java/com/cm/authservice/service/AuthService.java index 5b35cb6..436e00d 100644 --- a/auth-service/src/main/java/com/cm/authservice/service/AuthService.java +++ b/auth-service/src/main/java/com/cm/authservice/service/AuthService.java @@ -1,6 +1,7 @@ package com.cm.authservice.service; import com.cm.authservice.dto.*; +import com.cm.authservice.exception.TokenEmailDoesNotMatchException; import com.cm.authservice.exception.UserNotFoundException; import com.cm.authservice.model.User; import com.cm.authservice.util.JwtUtil; @@ -69,13 +70,23 @@ public User getUser(String token) { .orElseThrow(() -> new UserNotFoundException("User not found.")); } - public UserResponseDto register(UserRequestDto registrationRequestDto) { + public UserResponseDto register(UserRequestDto userRequestDto) { String passwordHash = - BCrypt.hashpw(registrationRequestDto.getPassword(), BCrypt.gensalt()); + BCrypt.hashpw(userRequestDto.getPassword(), BCrypt.gensalt()); return - userService.registerUser(registrationRequestDto.getEmail(), passwordHash); + userService.registerUser(userRequestDto.getEmail(), passwordHash); } + + public UserResponseDto changePassword(UserRequestDto userRequestDto, String token) { + // Hash the new password. + String passwordHash = + BCrypt.hashpw(userRequestDto.getPassword(), BCrypt.gensalt()); + + UUID id = jwtUtil.getIdFromToken(token); + + return userService.changePassword(id, passwordHash); + } } diff --git a/auth-service/src/main/java/com/cm/authservice/service/UserService.java b/auth-service/src/main/java/com/cm/authservice/service/UserService.java index aa7a177..5936c86 100644 --- a/auth-service/src/main/java/com/cm/authservice/service/UserService.java +++ b/auth-service/src/main/java/com/cm/authservice/service/UserService.java @@ -2,6 +2,7 @@ import com.cm.authservice.dto.UserRequestDto; import com.cm.authservice.dto.UserResponseDto; import com.cm.authservice.exception.EmailAlreadyExistsException; +import com.cm.authservice.exception.UserNotFoundException; import com.cm.authservice.mapper.UserMapper; import com.cm.authservice.model.User; import com.cm.authservice.repository.UserRepository; @@ -13,17 +14,17 @@ public class UserService { private final UserRepository userRepository; - public UserService(UserRepository userRepository){ + public UserService(UserRepository userRepository) { this.userRepository = userRepository; } - public Optional findByEmail(String email){ + public Optional findByEmail(String email) { return userRepository.findByEmail(email); } - public UserResponseDto updateEmail(User user, UserRequestDto userRequestDto){ + public UserResponseDto updateEmail(User user, UserRequestDto userRequestDto) { - if(userRepository.existsByEmail(userRequestDto.getEmail())){ + if (userRepository.existsByEmail(userRequestDto.getEmail())) { throw new EmailAlreadyExistsException("User already exists with email: " + userRequestDto.getEmail()); } @@ -38,7 +39,7 @@ public Optional findById(UUID id) { } public UserResponseDto registerUser(String email, String passwordHash) { - if(userRepository.existsByEmail(email)){ + if (userRepository.existsByEmail(email)) { throw new EmailAlreadyExistsException("This email is already taken: " + email); } @@ -46,8 +47,24 @@ public UserResponseDto registerUser(String email, String passwordHash) { user.setPassword(passwordHash); user.setEmail(email); + // Magic role name, fix later when actually using roles. + user.setRole("BASE_USER"); + User newUser = userRepository.save(user); return UserMapper.toDto(newUser); } + + public UserResponseDto changePassword(UUID id, String passwordHash) { + + User user = userRepository.findById(id).orElseThrow( + () -> new UserNotFoundException("User was not found with id: " + id) + ); + + user.setPassword(passwordHash); + + User updatedUser = userRepository.save(user); + + return UserMapper.toDto(updatedUser); + } } diff --git a/client-service/src/main/java/com/cm/clientservice/controller/UserController.java b/client-service/src/main/java/com/cm/clientservice/controller/UserController.java index 8aeed1a..60fb3d2 100644 --- a/client-service/src/main/java/com/cm/clientservice/controller/UserController.java +++ b/client-service/src/main/java/com/cm/clientservice/controller/UserController.java @@ -3,6 +3,8 @@ import com.cm.clientservice.dto.validators.CreateUserValidationGroup; import com.cm.clientservice.service.UserService; import jakarta.validation.groups.Default; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -18,6 +20,7 @@ @RequestMapping("/clients") @Tag(name="Clients", description = "API for managing Clients") public class UserController { + private final Logger log = LoggerFactory.getLogger(UserController.class); private final UserService userService; @@ -26,12 +29,14 @@ public UserController(UserService userService){ } @PostMapping - @Operation(summary = "Create a user") + @Operation(summary = "Create a user.") public ResponseEntity createUser( @Validated({Default.class, CreateUserValidationGroup.class}) - @RequestBody UserRequestDTO userRequestDTO){ - - UserResponseDTO userResponseDTO = userService.createUser(userRequestDTO); + @RequestBody UserRequestDTO userRequestDTO, + @RequestHeader("X-AUTH-ID") String auth_id + ){ + log.debug("AUTH ID IS {}", auth_id); + UserResponseDTO userResponseDTO = userService.createUser(userRequestDTO, auth_id); return ResponseEntity.ok().body(userResponseDTO); } diff --git a/client-service/src/main/java/com/cm/clientservice/service/UserService.java b/client-service/src/main/java/com/cm/clientservice/service/UserService.java index a5b1de4..d9ee028 100644 --- a/client-service/src/main/java/com/cm/clientservice/service/UserService.java +++ b/client-service/src/main/java/com/cm/clientservice/service/UserService.java @@ -32,15 +32,16 @@ public UserService(UserRepository userRepository, } - public UserResponseDTO createUser(UserRequestDTO userRequestDTO){ + public UserResponseDTO createUser(UserRequestDTO userRequestDTO, String auth_id){ // Make a call to the repository to create a user. if(userRepository.existsByEmail(userRequestDTO.getEmail())){ throw new EmailAlreadyExistsException("A user with this email already exists" + userRequestDTO.getEmail()); } - User newUser = userRepository.save( - UserMapper.toModel(userRequestDTO)); + User newUser = UserMapper.toModel(userRequestDTO); + newUser.setAuthId(UUID.fromString(auth_id)); + newUser = userRepository.save(newUser); return UserMapper.toDTO(newUser); }