diff --git a/src/main/java/com/sellbycar/marketplace/ad/AdvertisementServiceImpl.java b/src/main/java/com/sellbycar/marketplace/ad/AdvertisementServiceImpl.java index d96cbf0..aa9c72a 100644 --- a/src/main/java/com/sellbycar/marketplace/ad/AdvertisementServiceImpl.java +++ b/src/main/java/com/sellbycar/marketplace/ad/AdvertisementServiceImpl.java @@ -54,7 +54,7 @@ public AdvertisementDAO getAdvertisement(Long id) { } @Transactional - public AdvertisementDAO createAdvertisement(AdvertisementDTO advertisementDTO, List files) throws IOException { + public AdvertisementDAO createAdvertisement(AdvertisementDTO advertisementDTO, List files) { UserDAO user = userService.getUserFromSecurityContextHolder(); AdvertisementDAO advertisement = advertisementMapper.toDAO(advertisementDTO); advertisement.setUser(user); diff --git a/src/main/java/com/sellbycar/marketplace/config/SecurityConfig.java b/src/main/java/com/sellbycar/marketplace/config/SecurityConfig.java index bb8016b..a4e4fc0 100644 --- a/src/main/java/com/sellbycar/marketplace/config/SecurityConfig.java +++ b/src/main/java/com/sellbycar/marketplace/config/SecurityConfig.java @@ -77,7 +77,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { HttpMethod.PUT, "/advertisement/{id}", "/user/me", - "/user/password" + "/user/password", + "/user/me/photo" ) .authenticated() .requestMatchers( diff --git a/src/main/java/com/sellbycar/marketplace/image/ImageController.java b/src/main/java/com/sellbycar/marketplace/image/ImageController.java index c62a1bd..9ac17c5 100644 --- a/src/main/java/com/sellbycar/marketplace/image/ImageController.java +++ b/src/main/java/com/sellbycar/marketplace/image/ImageController.java @@ -56,7 +56,7 @@ public ResponseEntity downloadImage(@PathVariable Long id) { @ApiResponse(responseCode = "201", description = "Created"), @ApiResponse(responseCode = "400", description = "Bad request") }) - public ResponseEntity uploadImage(@RequestPart MultipartFile image) throws IOException { + public ResponseEntity uploadImage(@RequestPart MultipartFile image) { if (image.isEmpty()) { return ResponseUtil.error("Image should not be empty.", HttpStatus.BAD_REQUEST); } diff --git a/src/main/java/com/sellbycar/marketplace/image/ImageService.java b/src/main/java/com/sellbycar/marketplace/image/ImageService.java index 112f3e1..804d95e 100644 --- a/src/main/java/com/sellbycar/marketplace/image/ImageService.java +++ b/src/main/java/com/sellbycar/marketplace/image/ImageService.java @@ -12,9 +12,8 @@ public interface ImageService { * * @param multipartFile The MultipartFile representing the image file. * @return The created Image entity. - * @throws IOException If an I/O error occurs while reading the file. */ - ImageDAO createImage(MultipartFile multipartFile) throws IOException; + ImageDAO createImage(MultipartFile multipartFile); /** * Retrieves an Image entity by its unique identifier. diff --git a/src/main/java/com/sellbycar/marketplace/image/ImageServiceImpl.java b/src/main/java/com/sellbycar/marketplace/image/ImageServiceImpl.java index bb02245..58877c8 100644 --- a/src/main/java/com/sellbycar/marketplace/image/ImageServiceImpl.java +++ b/src/main/java/com/sellbycar/marketplace/image/ImageServiceImpl.java @@ -1,5 +1,6 @@ package com.sellbycar.marketplace.image; +import com.sellbycar.marketplace.util.exception.RequestException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -17,12 +18,16 @@ public class ImageServiceImpl implements ImageService { private final ImageRepository imageRepository; @Override - public ImageDAO createImage(MultipartFile multipartFile) throws IOException { + public ImageDAO createImage(MultipartFile multipartFile) { ImageDAO image = new ImageDAO(); image.setName(multipartFile.getName()); image.setContentType(multipartFile.getContentType()); image.setSize(multipartFile.getSize()); - image.setContent(multipartFile.getBytes()); + try { + image.setContent(multipartFile.getBytes()); + } catch (IOException e) { + throw RequestException.bad("Could not read image file."); + } image.setCreatedTimestamp(Instant.now()); return imageRepository.save(image); } diff --git a/src/main/java/com/sellbycar/marketplace/user/UserController.java b/src/main/java/com/sellbycar/marketplace/user/UserController.java index 7904a1d..98e89b1 100644 --- a/src/main/java/com/sellbycar/marketplace/user/UserController.java +++ b/src/main/java/com/sellbycar/marketplace/user/UserController.java @@ -2,6 +2,7 @@ import com.sellbycar.marketplace.auth.JwtUtils; import com.sellbycar.marketplace.auth.LoginRequest; +import com.sellbycar.marketplace.web.ResponseBody; import com.sellbycar.marketplace.web.ResponseUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; import java.util.Objects; @@ -33,6 +35,40 @@ public class UserController { private final UserService userService; private final JwtUtils jwtUtils; + @PutMapping("/me") + @SecurityRequirement(name = "Bearer Authentication") + @Operation(summary = "Update current user") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK"), + @ApiResponse(responseCode = "401", description = "UNAUTHORIZED"), + @ApiResponse(responseCode = "403", description = "FORBIDDEN"), + @ApiResponse(responseCode = "404", description = "User not found") + }) + public ResponseEntity updateUser(@RequestBody UserDTO updatedUser) { + String token = getTokenFromRequest(); + String emailOfUser = jwtUtils.getEmailFromJwtToken(token); + + UserDAO user = userService.updateUser(updatedUser, emailOfUser); + UserDTO userDTO = userMapper.toDTO(user); + + return ResponseEntity.ok(userDTO); + } + + @PutMapping(value = "/me/photo", consumes = {"multipart/form-data"}) + @SecurityRequirement(name = "Bearer Authentication") + @Operation(summary = "Update current user's photo", tags = {"User Library"}) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "User's photo updated successfully"), + @ApiResponse(responseCode = "400", description = "Bad Request") + }) + public ResponseEntity> putUserPhoto(@RequestPart("image") MultipartFile image) { + String userToken = getTokenFromRequest(); + String userEmail = jwtUtils.getEmailFromJwtToken(userToken); + UserDAO userDAO = userService.findUserByEmailOrThrow(userEmail); + UserDAO updatedUser = userService.updatePhoto(userDAO, image); + return ResponseUtil.ok(userMapper.toDTO(updatedUser)); + } + @GetMapping("/me") @SecurityRequirement(name = "Bearer Authentication") @Operation(summary = "Get current user", tags = {"User Library"}) @@ -56,25 +92,6 @@ public ResponseEntity getUser() { } } - @PutMapping("/me") - @SecurityRequirement(name = "Bearer Authentication") - @Operation(summary = "Update current user") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "OK"), - @ApiResponse(responseCode = "401", description = "UNAUTHORIZED"), - @ApiResponse(responseCode = "403", description = "FORBIDDEN"), - @ApiResponse(responseCode = "404", description = "User not found") - }) - public ResponseEntity updateUser(@RequestBody UserDTO updatedUser) { - String token = getTokenFromRequest(); - String emailOfUser = jwtUtils.getEmailFromJwtToken(token); - - UserDAO user = userService.updateUser(updatedUser, emailOfUser); - UserDTO userDTO = userMapper.toDTO(user); - - return ResponseEntity.ok(userDTO); - } - @DeleteMapping("/me") @SecurityRequirement(name = "Bearer Authentication") @Operation(summary = "Delete current user.", tags = {"User Library"}) diff --git a/src/main/java/com/sellbycar/marketplace/user/UserService.java b/src/main/java/com/sellbycar/marketplace/user/UserService.java index c1c35a2..b19d13f 100644 --- a/src/main/java/com/sellbycar/marketplace/user/UserService.java +++ b/src/main/java/com/sellbycar/marketplace/user/UserService.java @@ -4,17 +4,18 @@ import com.sellbycar.marketplace.auth.SignupRequest; import jakarta.mail.MessagingException; import org.springframework.security.core.Authentication; +import org.springframework.web.multipart.MultipartFile; public interface UserService { + UserDAO updatePhoto(UserDAO user, MultipartFile newPhoto); + /** * Registers a new user in the system. * * @param signUpRequest DTO containing all required data for user registration. - * @return true if the registration is successful, false otherwise. * @throws UserDataException if there is an issue during the registration process. */ - void createNewUser(SignupRequest signUpRequest) throws MessagingException; /** diff --git a/src/main/java/com/sellbycar/marketplace/user/UserServiceImpl.java b/src/main/java/com/sellbycar/marketplace/user/UserServiceImpl.java index 67c6212..b234f7f 100644 --- a/src/main/java/com/sellbycar/marketplace/user/UserServiceImpl.java +++ b/src/main/java/com/sellbycar/marketplace/user/UserServiceImpl.java @@ -2,6 +2,8 @@ import com.sellbycar.marketplace.auth.LoginRequest; import com.sellbycar.marketplace.auth.SignupRequest; +import com.sellbycar.marketplace.image.ImageDAO; +import com.sellbycar.marketplace.image.ImageService; import com.sellbycar.marketplace.mail.MailService; import com.sellbycar.marketplace.util.exception.RequestException; import jakarta.mail.MessagingException; @@ -13,6 +15,7 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import java.time.Instant; import java.util.*; @@ -28,6 +31,14 @@ public class UserServiceImpl implements UserService { private final MailService mailService; private final UserRequestValidator userRequestValidator; private final UserMapper userMapper; + private final ImageService imageService; + + @Override + public UserDAO updatePhoto(UserDAO userDAO, MultipartFile newPhoto) { + ImageDAO imageDAO = imageService.createImage(newPhoto); + userDAO.setPhoto(imageDAO); + return userRepository.save(userDAO); + } public void createNewUser(SignupRequest signUpRequest) throws MessagingException { userRequestValidator.throwIfSignupRequestNotValid(signUpRequest);