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

Feat/check permission #95

Merged
merged 3 commits into from
Jan 13, 2024
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
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -107,8 +108,10 @@ public Long createClubPost(Long userId, ClubPostReq clubPostReq, List<MultipartF

// 글 수정
@Transactional
public void updateClubPost(Long clubPostId, UpdateClubPostReq updateClubPostReq, List<MultipartFile> images) throws IOException {

public void updateClubPost(Long clubPostId, Long userId, UpdateClubPostReq updateClubPostReq, List<MultipartFile> images) throws IOException {
if (!isAdminOrWriter(clubPostId, userId)) {
throw new AccessDeniedException("해당 게시글에 대한 권한이 없습니다.");
}
ClubPost clubPost = clubPostRepository.findById(clubPostId)
.orElseThrow(() -> new DefaultException(ErrorCode.CONTENTS_NOT_FOUND));

Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<MultipartFile> 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: 권한있음
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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());
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "아이디어의 글을 삭제한다.")
Expand All @@ -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: 권한있음
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,12 @@ public ProjectDetailRes getProjectDetail(Long projectId) {

@Transactional
public void updateProject(Long userId, Long projectId, PostProjectReq updateProjectReq, List<MultipartFile> 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());
Expand All @@ -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);
Expand Down Expand Up @@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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: 권한있음
}
}