Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

유저 프로필 사진 설정 API 추가 #333

Merged
merged 3 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions perfume-api/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ include::{snippets}/update-user-profile/http-response.adoc[]
=== 실패 응답
include::{snippets}/update-user-profile-failed/http-response.adoc[]

== 프로필 사진 수정
=== 요청
include::{snippets}/update-user-profile-pic/http-request.adoc[]

=== 응답
include::{snippets}/update-user-profile-pic/http-response.adoc[]

== 로그인 중인 회원 탈퇴
=== 요청
include::{snippets}/leave-user/http-request.adoc[]
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
package io.perfume.api.user.adapter.in.http;

import io.perfume.api.file.application.port.in.FindFileUseCase;
import io.perfume.api.user.adapter.in.http.dto.LeaveUserDto;
import io.perfume.api.user.adapter.in.http.dto.UpdateEmailRequestDto;
import io.perfume.api.user.adapter.in.http.dto.UpdatePasswordRequestDto;
import io.perfume.api.user.adapter.in.http.dto.UpdateProfileRequestDto;
import io.perfume.api.user.adapter.in.http.dto.UserProfileDto;
import io.perfume.api.user.adapter.in.http.dto.*;
import io.perfume.api.user.adapter.in.http.exception.UserNotAuthenticatedException;
import io.perfume.api.user.application.port.in.FindEncryptedUsernameUseCase;
import io.perfume.api.user.application.port.in.FindUserUseCase;
import io.perfume.api.user.application.port.in.LeaveUserUseCase;
import io.perfume.api.user.application.port.in.SendResetPasswordMailUseCase;
import io.perfume.api.user.application.port.in.UpdateAccountUseCase;
import io.perfume.api.user.application.port.in.*;
import io.perfume.api.user.application.port.in.dto.UpdateEmailCommand;
import io.perfume.api.user.application.port.in.dto.UpdatePasswordCommand;
import io.perfume.api.user.application.port.in.dto.UpdateProfileCommand;
import io.perfume.api.user.application.port.in.dto.UserProfileResult;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import java.io.IOException;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
Expand All @@ -42,6 +31,7 @@ public class UserSupportController {
private final FindFileUseCase findFileUseCase;
private final SendResetPasswordMailUseCase resetPasswordUserCase;
private final UpdateAccountUseCase updateAccountUseCase;
private final UpdateProfilePicUseCase updateProfilePicUseCase;

private final LeaveUserUseCase leaveUserUseCase;

Expand Down Expand Up @@ -116,6 +106,27 @@ public void updateProfileByUser(
updateAccountUseCase.updateUserProfile(updateProfileCommand);
}

@PatchMapping("/user/profile-pic")
@PreAuthorize("isAuthenticated()")
public void updateProfilePic(@AuthenticationPrincipal User user, final MultipartFile file) {
var now = LocalDateTime.now();
checkAuthenticatedUser(user);
long userId = parseUserId(user);
updateProfilePicUseCase.update(userId, getFileContent(file), now);
}

private long parseUserId(User user) {
return Long.parseLong(user.getUsername());
}

private byte[] getFileContent(MultipartFile file) {
try {
return file.getBytes();
} catch (IOException e) {
return null;
}
}

private void checkAuthenticatedUser(User user) {
if (user == null || user.getUsername() == null) {
throw new UserNotAuthenticatedException();
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.perfume.api.user.application.port.in;

import io.perfume.api.user.application.port.in.dto.UpdateProfilePicResult;
import java.time.LocalDateTime;

public interface UpdateProfilePicUseCase {

UpdateProfilePicResult update(Long userId, byte[] imageFileContent, LocalDateTime now);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.perfume.api.user.application.port.in.dto;

import io.perfume.api.file.application.port.in.dto.FileResult;

public record UpdateProfilePicResult(Long userId, Long fileId, String url) {

public static UpdateProfilePicResult from(Long userId, FileResult fileResult) {
return new UpdateProfilePicResult(userId, fileResult.id(), fileResult.url());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import encryptor.OneWayEncryptor;
import io.perfume.api.user.application.exception.FailedToLeaveException;
import io.perfume.api.user.application.exception.NotFoundUserException;
import io.perfume.api.user.application.exception.UserNotFoundException;
import io.perfume.api.user.application.port.in.FindEncryptedUsernameUseCase;
import io.perfume.api.user.application.port.in.LeaveUserUseCase;
import io.perfume.api.user.application.port.in.SendResetPasswordMailUseCase;
Expand Down Expand Up @@ -59,24 +60,16 @@ public String findEncryptedUsername(String email) {

@Override
public void leave(Long userId) {

try {

User user = userQueryRepository.loadUser(userId).orElseThrow(NotFoundUserException::new);

User user =
userQueryRepository.loadUser(userId).orElseThrow(() -> new UserNotFoundException(userId));
LocalDateTime now = LocalDateTime.now();

user.softDelete(now);

userRepository.save(user);

} catch (NotFoundUserException e) {

FailedToLeaveException failedLeaveException =
new FailedToLeaveException("회원탈퇴 실패", "user id : " + userId + ", 회원탈퇴 실패");

failedLeaveException.initCause(e);

throw failedLeaveException;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.perfume.api.user.application.service;

import io.perfume.api.file.application.port.in.dto.FileResult;
import io.perfume.api.file.application.service.FileService;
import io.perfume.api.user.application.exception.UserNotFoundException;
import io.perfume.api.user.application.port.in.UpdateProfilePicUseCase;
import io.perfume.api.user.application.port.in.dto.UpdateProfilePicResult;
import io.perfume.api.user.application.port.out.UserQueryRepository;
import io.perfume.api.user.application.port.out.UserRepository;
import io.perfume.api.user.domain.User;
import java.time.LocalDateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UpdateProfilePicService implements UpdateProfilePicUseCase {

private final UserQueryRepository userQueryRepository;
private final UserRepository userRepository;
private final FileService fileUploadService;

public UpdateProfilePicService(
UserQueryRepository userQueryRepository,
UserRepository userRepository,
FileService fileUploadService) {
this.userQueryRepository = userQueryRepository;
this.userRepository = userRepository;
this.fileUploadService = fileUploadService;
}

@Override
@Transactional
public UpdateProfilePicResult update(Long userId, byte[] imageFileContent, LocalDateTime now) {
FileResult fileResult = fileUploadService.uploadFile(imageFileContent, userId, now);
User user =
userQueryRepository
.findUserById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
user.updateThumbnailId(fileResult.id());
userRepository.save(user);
return UpdateProfilePicResult.from(userId, fileResult);
}
}
Loading