diff --git a/user-service-api/gradle/wrapper/plugins/dependencies.gradle b/user-service-api/gradle/wrapper/plugins/dependencies.gradle index f821788..1dbf34e 100644 --- a/user-service-api/gradle/wrapper/plugins/dependencies.gradle +++ b/user-service-api/gradle/wrapper/plugins/dependencies.gradle @@ -14,6 +14,7 @@ dependencies { implementation 'br.com.rayan:hd-commons-lib:1.0.0' + // Spring Boot Starters initial project implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' @@ -22,12 +23,18 @@ dependencies { // Swagger / OpenAPI (compatível com Spring Boot 3.3.x) implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + // Lombok for code generation (at compile time) compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' + // MapStruct for object mapping (at compile time) implementation 'org.mapstruct:mapstruct:1.5.3.Final' annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' + // Spring Security dependencies for authentication and authorization + implementation 'org.springframework.security:spring-security-crypto:6.4.7' + + // Testing dependencies testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/config/BCryptConfig.java b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/config/BCryptConfig.java new file mode 100644 index 0000000..7ad3bd3 --- /dev/null +++ b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/config/BCryptConfig.java @@ -0,0 +1,14 @@ +package br.com.rayankonecny.userserviceapi.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +public class BCryptConfig { + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/controller/UserController.java b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/controller/UserController.java index d0ec4be..73228a1 100644 --- a/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/controller/UserController.java +++ b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/controller/UserController.java @@ -60,8 +60,10 @@ public interface UserController { @ApiResponse(responseCode = "200", description = "User updated successfully", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = UserResponse.class))), @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))), @ApiResponse(responseCode = "404", description = "User not found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))), - @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))), - }) + @ApiResponse(responseCode = "500", description = "Internal server error", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, schema = @Schema(implementation = StandardError.class))), }) @PutMapping("/{id}") - ResponseEntity update(@PathVariable(name = "id") final String id, @Valid @RequestBody final UpdateUserRequest updateUserRequest); + ResponseEntity update(@PathVariable(name = "id") + final String id, @Valid + @RequestBody + final UpdateUserRequest updateUserRequest); } diff --git a/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/service/UserService.java b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/service/UserService.java index 6552580..5b5149a 100644 --- a/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/service/UserService.java +++ b/user-service-api/src/main/java/br/com/rayankonecny/userserviceapi/service/UserService.java @@ -3,6 +3,7 @@ package br.com.rayankonecny.userserviceapi.service; import java.util.List; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import br.com.rayankonecny.userserviceapi.entity.User; @@ -19,36 +20,39 @@ import models.requests.UpdateUserRequest; @RequiredArgsConstructor public class UserService { - private final UserRepository userRepository; - private final UserMapper userMapper; + private final UserRepository repository; + private final UserMapper mapper; + private final BCryptPasswordEncoder encoder; public UserResponse findById(final String id) { - return userMapper.fromEntity(find(id)); + return mapper.fromEntity(find(id)); } - public void save(CreateUserRequest createUserRequest) { - verifyIfEmailAlreadyEexists(createUserRequest.email(), null); - userRepository.save(userMapper.fromRequest(createUserRequest)); + public void save(CreateUserRequest request) { + verifyIfEmailAlreadyEexists(request.email(), null); + repository.save(mapper.fromRequest(request).withPassword(encoder.encode(request.password()))); } private void verifyIfEmailAlreadyEexists(final String email, final String id) { - userRepository.findByEmail(email).filter(user -> !user.getId().equals(id)).ifPresent(user -> { + repository.findByEmail(email).filter(user -> !user.getId().equals(id)).ifPresent(user -> { throw new DataIntegrityViolationException("Email [" + email + "] already exists"); }); } public List findAll() { - return userRepository.findAll().stream().map(user -> userMapper.fromEntity(user)).toList(); + return repository.findAll().stream().map(user -> mapper.fromEntity(user)).toList(); } - public UserResponse update(final String id, @Valid final UpdateUserRequest updateUserRequest) { + public UserResponse update(final String id, @Valid + final UpdateUserRequest request) { User entity = find(id); - verifyIfEmailAlreadyEexists(updateUserRequest.email(), id); - return userMapper.fromEntity(userRepository.save(userMapper.update(updateUserRequest, entity))); + verifyIfEmailAlreadyEexists(request.email(), id); + return mapper.fromEntity(repository.save(mapper.update(request, entity) + .withPassword(request.password() != null ? encoder.encode(request.password()) : entity.getPassword()))); } private User find(final String id) { - return userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException( + return repository.findById(id).orElseThrow(() -> new ResourceNotFoundException( "Object not found! Id: " + id + ", Type: " + UserResponse.class.getSimpleName())); }