From ab236c742b4e367df9b287fc6d349fc520e987c9 Mon Sep 17 00:00:00 2001 From: jisu <98259433+jisu-jeong0@users.noreply.github.com> Date: Sat, 13 Jan 2024 23:51:37 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Fix:=20JavaMailSender=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 - .../main/ideac/global/config/MailConfig.java | 59 ++++++++++++++----- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index c50eca9..5aad665 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,6 @@ subprojects { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-mail' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/ideac-core/src/main/java/depth/main/ideac/global/config/MailConfig.java b/ideac-core/src/main/java/depth/main/ideac/global/config/MailConfig.java index 7f1d23a..754e711 100644 --- a/ideac-core/src/main/java/depth/main/ideac/global/config/MailConfig.java +++ b/ideac-core/src/main/java/depth/main/ideac/global/config/MailConfig.java @@ -1,15 +1,44 @@ -//package depth.main.ideac.global.config; -// -//import org.springframework.context.annotation.Bean; -//import org.springframework.context.annotation.Configuration; -//import org.springframework.mail.javamail.JavaMailSender; -//import org.springframework.mail.javamail.JavaMailSenderImpl; -// -//@Configuration -//public class MailConfig { -// -// @Bean -// public JavaMailSender javaMailSender() { -// return new JavaMailSenderImpl(); -// } -//} \ No newline at end of file +package depth.main.ideac.global.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import java.util.Properties; + +@Configuration +public class MailConfig { + + @Value("${spring.mail.host}") + private String host; + + @Value("${spring.mail.username}") + private String username; + + @Value("${spring.mail.password}") + private String password; + + @Value("${spring.mail.port}") + private int port; + @Bean + public JavaMailSender javaMailService() { + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); + + javaMailSender.setHost(host); + javaMailSender.setUsername(username); + javaMailSender.setPassword(password); + javaMailSender.setPort(port); + + javaMailSender.setJavaMailProperties(getMailProperties()); + + return javaMailSender; + } + + private Properties getMailProperties() { + Properties properties = new Properties(); + properties.setProperty("mail.smtp.auth", "true"); + properties.setProperty("mail.smtp.starttls.enable", "true"); + return properties; + } +} \ No newline at end of file From f4d01eef4f65839df8332330cfee5cf15fca0fa4 Mon Sep 17 00:00:00 2001 From: jisu <98259433+jisu-jeong0@users.noreply.github.com> Date: Sun, 14 Jan 2024 00:37:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Feat:=20=EA=B6=8C=ED=95=9C=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/ClubPostService.java | 12 +++++-- .../presentation/ClubPostController.java | 32 ++++++------------- .../application/IdeaPostService.java | 13 ++++++-- .../presentation/IdeaPostController.java | 15 ++++----- .../application/ProjectPostService.java | 21 +++++++----- .../presentation/ProjectPostController.java | 7 ++++ 6 files changed, 55 insertions(+), 45 deletions(-) diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/club_post/application/ClubPostService.java b/ideac-user/src/main/java/depth/main/ideac/domain/club_post/application/ClubPostService.java index 7e0ec18..bf0245d 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/club_post/application/ClubPostService.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/club_post/application/ClubPostService.java @@ -18,6 +18,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -107,8 +108,10 @@ public Long createClubPost(Long userId, ClubPostReq clubPostReq, List images) throws IOException { - + public void updateClubPost(Long clubPostId, Long userId, UpdateClubPostReq updateClubPostReq, List images) throws IOException { + if (!isAdminOrWriter(clubPostId, userId)) { + throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); + } ClubPost clubPost = clubPostRepository.findById(clubPostId) .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND)); @@ -123,7 +126,10 @@ public void updateClubPost(Long clubPostId, UpdateClubPostReq updateClubPostReq, // 글 삭제 @Transactional - public void deleteClubPost(Long clubPostId) { + public void deleteClubPost(Long clubPostId, Long userId) { + if (!isAdminOrWriter(clubPostId, userId)) { + throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); + } ClubPost clubPost = clubPostRepository.findById(clubPostId) .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND)); this.deleteFile(clubPostId); diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/club_post/presentation/ClubPostController.java b/ideac-user/src/main/java/depth/main/ideac/domain/club_post/presentation/ClubPostController.java index 7efa967..ee7decb 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/club_post/presentation/ClubPostController.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/club_post/presentation/ClubPostController.java @@ -68,7 +68,6 @@ public ResponseEntity getDetailClubPosts(@PathVariable Long id) { // 글 등록하기 @Operation(summary = "글 등록", description = "동아리/학회 글을 등록하는 API입니다.") - // @PreAuthorize("hasAnyRole('USER', 'ADMIN', 'OWNER')") @PostMapping public ResponseEntity createClubPost(@CurrentUser UserPrincipal userPrincipal, @Valid @RequestPart ClubPostReq clubPostReq, @@ -87,36 +86,23 @@ public ResponseEntity createClubPost(@CurrentUser UserPrincipal userPrincipal public ResponseEntity updateClubPost(@CurrentUser UserPrincipal userPrincipal, @PathVariable Long id, @Valid @RequestPart UpdateClubPostReq updateClubPostReq, @RequestPart("images") List images) throws IOException { - - checkPermission(id, userPrincipal.getId()); - - clubPostService.updateClubPost(id, updateClubPostReq, images); - ApiResponse apiResponse = ApiResponse.builder() - .check(true) - .information("글이 수정되었습니다.") - .build(); - return ResponseEntity.ok(apiResponse); + clubPostService.updateClubPost(id, userPrincipal.getId(), updateClubPostReq, images); + return ResponseEntity.ok().build(); } // 글 삭제하기 @Operation(summary = "글 삭제", description = "동아리/학회 글을 삭제하는 API입니다.") @DeleteMapping("/{id}") public ResponseEntity deleteClubPost(@CurrentUser UserPrincipal userPrincipal, @PathVariable Long id) { - - checkPermission(id, userPrincipal.getId()); - - clubPostService.deleteClubPost(id); - ApiResponse apiResponse = ApiResponse.builder() - .check(true) - .information("글이 삭제되었습니다.") - .build(); - return ResponseEntity.ok(apiResponse); + clubPostService.deleteClubPost(id, userPrincipal.getId()); + return ResponseEntity.ok().build(); } - private void checkPermission(Long clubPostId, Long userId) { - if (!clubPostService.isAdminOrWriter(clubPostId, userId)) { - throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); - } + @Operation(summary = "권한 확인", description = "동아리/학회 수정/삭제 권한을 확인하는 API입니다. true: 가능, false: 불가능") + @GetMapping("/check/{id}") + private boolean checkPermission(@CurrentUser UserPrincipal userPrincipal, + @PathVariable Long id) { + return clubPostService.isAdminOrWriter(id, userPrincipal.getId()); // true: 권한있음 } } diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/application/IdeaPostService.java b/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/application/IdeaPostService.java index 3eda3ed..68942f8 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/application/IdeaPostService.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/application/IdeaPostService.java @@ -22,6 +22,7 @@ import org.springframework.data.redis.core.ValueOperations; import org.springframework.http.ResponseEntity; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -58,7 +59,7 @@ public Long registerIdea(UserPrincipal userPrincipal, RegisterIdeaReq registerId return ideapost.getId(); } - //상세아디이어 조회 + //상세 조회 @Transactional public ResponseEntity getDetailIdea(Long id) { IdeaPost ideaPost = ideaPostRepository.findById(id).get(); @@ -88,7 +89,10 @@ public ResponseEntity getDetailIdea(Long id) { //아이디어 수정 @Transactional - public ResponseEntity updateIdea(Long id, UpdateIdeaReq updateIdeaReq) { + public ResponseEntity updateIdea(Long id, Long userId, UpdateIdeaReq updateIdeaReq) { + if (!isAdminOrWriter(id, userId)) { + throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); + } IdeaPost ideaPost = ideaPostRepository.findById(id).get(); ideaPost.setTitle(updateIdeaReq.getTitle()); @@ -107,7 +111,10 @@ public ResponseEntity updateIdea(Long id, UpdateIdeaReq updateIdeaReq) { } //아이디어 삭제 @Transactional - public ResponseEntity deleteIdea(Long id) { + public ResponseEntity deleteIdea(Long id, Long userId) { + if (!isAdminOrWriter(id, userId)) { + throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); + } IdeaPost ideaPost = ideaPostRepository.findById(id).get(); ideaPostRepository.delete(ideaPost); ApiResponse apiResponse = ApiResponse.builder() diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/presentation/IdeaPostController.java b/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/presentation/IdeaPostController.java index e48f72c..258bc0d 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/presentation/IdeaPostController.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/idea_post/presentation/IdeaPostController.java @@ -80,8 +80,7 @@ public ResponseEntity getDetailIdea(@PathVariable Long id) { public ResponseEntity updateIdea(@CurrentUser UserPrincipal userPrincipal, @PathVariable Long id, @Valid @RequestBody UpdateIdeaReq updateIdeaReq) { - checkPermission(id, userPrincipal.getId()); - return ideaPostService.updateIdea(id, updateIdeaReq); + return ideaPostService.updateIdea(id, userPrincipal.getId(), updateIdeaReq); } @Operation(summary = "글 삭제", description = "아이디어의 글을 삭제한다.") @@ -92,13 +91,13 @@ public ResponseEntity updateIdea(@CurrentUser UserPrincipal userPrincipal, @DeleteMapping("/{id}") public ResponseEntity deleteIdea(@CurrentUser UserPrincipal userPrincipal, @PathVariable Long id) { - checkPermission(id, userPrincipal.getId()); - return ideaPostService.deleteIdea(id); + return ideaPostService.deleteIdea(id, userPrincipal.getId()); } - private void checkPermission(Long clubPostId, Long userId) { - if (!ideaPostService.isAdminOrWriter(clubPostId, userId)) { - throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다."); - } + @Operation(summary = "권한 확인", description = "아이디어 수정/삭제 권한을 확인하는 API입니다. true: 가능, false: 불가능") + @GetMapping("/check/{id}") + private boolean checkPermission(@CurrentUser UserPrincipal userPrincipal, + @PathVariable Long id) { + return ideaPostService.isAdminOrWriter(id, userPrincipal.getId()); // true: 권한있음 } } diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/project_post/application/ProjectPostService.java b/ideac-user/src/main/java/depth/main/ideac/domain/project_post/application/ProjectPostService.java index 11852cc..4a86383 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/project_post/application/ProjectPostService.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/project_post/application/ProjectPostService.java @@ -172,12 +172,12 @@ public ProjectDetailRes getProjectDetail(Long projectId) { @Transactional public void updateProject(Long userId, Long projectId, PostProjectReq updateProjectReq, List images) throws IOException { - User user = userRepository.findById(userId).orElseThrow(() -> new DefaultException(ErrorCode.USER_NOT_FOUND)); - ProjectPost projectPost = projectPostRepository.findById(projectId) - .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND, "프로젝트를 찾을 수 없습니다.")); - if (user.getRole() != Role.OWNER && user.getRole() != Role.ADMIN && !userId.equals(projectPost.getUser().getId())) { + if (!isAdminOrWriter(projectId, userId)) { throw new DefaultException(ErrorCode.UNAUTHORIZED, "수정 권한이 없습니다."); } + ProjectPost projectPost = projectPostRepository.findById(projectId) + .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND, "프로젝트를 찾을 수 없습니다.")); + projectPost.setTitle(updateProjectReq.getTitle()); projectPost.setSimpleDescription(updateProjectReq.getSimpleDescription()); projectPost.setDetailedDescription(updateProjectReq.getDetailedDescription()); @@ -194,10 +194,7 @@ public void updateProject(Long userId, Long projectId, PostProjectReq updateProj @Transactional public void deleteProject(Long userId, Long projectId) { - User user = userRepository.findById(userId).orElseThrow(() -> new DefaultException(ErrorCode.USER_NOT_FOUND)); - ProjectPost projectPost = projectPostRepository.findById(projectId) - .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND, "프로젝트를 찾을 수 없습니다.")); - if (user.getRole() != Role.OWNER && user.getRole() != Role.ADMIN && !userId.equals(projectPost.getUser().getId())) { + if (!isAdminOrWriter(projectId, userId)) { throw new DefaultException(ErrorCode.UNAUTHORIZED, "삭제 권한이 없습니다."); } this.deleteFile(projectId); @@ -263,4 +260,12 @@ public void deleteHitFromRedis() { System.out.println("projectPost hits update complete"); } + + public boolean isAdminOrWriter(Long projectId, Long userId) { + User user = userRepository.findById(userId).orElseThrow(() -> new DefaultException(ErrorCode.USER_NOT_FOUND)); + ProjectPost projectPost = projectPostRepository.findById(projectId) + .orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND, "프로젝트를 찾을 수 없습니다.")); + + return user.getRole() == Role.OWNER || user.getRole() == Role.ADMIN || userId.equals(projectPost.getUser().getId()); + } } diff --git a/ideac-user/src/main/java/depth/main/ideac/domain/project_post/presentation/ProjectPostController.java b/ideac-user/src/main/java/depth/main/ideac/domain/project_post/presentation/ProjectPostController.java index 796f6a5..cbbd0c1 100644 --- a/ideac-user/src/main/java/depth/main/ideac/domain/project_post/presentation/ProjectPostController.java +++ b/ideac-user/src/main/java/depth/main/ideac/domain/project_post/presentation/ProjectPostController.java @@ -114,4 +114,11 @@ public ResponseEntity deleteProject(@CurrentUser UserPrincipal userPrincipal, projectPostService.deleteProject(userPrincipal.getId(), projectId); return ResponseEntity.ok().build(); } + + @Operation(summary = "권한 확인", description = "프로젝트 수정/삭제 권한을 확인하는 API입니다. true: 가능, false: 불가능") + @GetMapping("/check/{id}") + private boolean checkPermission(@CurrentUser UserPrincipal userPrincipal, + @PathVariable Long id) { + return projectPostService.isAdminOrWriter(id, userPrincipal.getId()); // true: 권한있음 + } }