Post의 삭제와 수정 기능을 추가하였다.
해당 기능은 아래의 조건을 충족했을 때만 가능하다.
- JWT token을 갖고 있는 자 (로그인 한 유저)
- UserRole = ADMIN인 경우 모든 글에 대하여 삭제와 수정 가능
- UserRole = USER인 경우 자신의 글에 대하여 삭제와 수정 가능
1. Configuration
SecurityConfig
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
//WebSecurityConfigurerAdapter 는 이후 SpringBoot에서 잘 안쓰게 됨
public class SecurityConfig {
...
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.httpBasic().disable()
.csrf().disable()
.cors().and()
.exceptionHandling()
.authenticationEntryPoint(new CustomAuthenticationEntryPoint())
.and()
.authorizeRequests()
.antMatchers(PERMIT_URL_ARRAY).permitAll()
.antMatchers(HttpMethod.POST,"/api/**").authenticated() // post는 인가자만 허용
.antMatchers(HttpMethod.DELETE,"/api/**").authenticated() // delete는 인가자만 허용
.antMatchers(HttpMethod.PUT,"/api/**").authenticated() // put는 인가자만 허용 (글 수정)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // jwt사용하는 경우 씀
.and()
.addFilterBefore(new JwtTokenFilter(userService, secretKey), UsernamePasswordAuthenticationFilter.class) //UserNamePasswordAuthenticationFilter적용하기 전에 JWTTokenFilter를 적용
.build();
}
}
해당 SecurrityConfiguration에서 Delete와 Put method에도 접근 제한을 추가하였다.
2. Domain
PostModifyRequest(domain - dto directory)
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
public class PostModifyRequest {
private String title;
private String body;
}
글 수정시 클라이언트가 입력해야하는 글 제목과 글 내용을 담기 위한 dto를 추가하였다.
3. Service
PostService
@Service
@RequiredArgsConstructor
@Slf4j
public class PostService {
private final PostRepository postRepository;
private final UserRepository userRepository;
...
public void deletePost(String userName, Integer postId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new AppException(ErrorCode.POST_NOT_FOUND, ""));
User user = userRepository.findByUserName(userName)
.orElseThrow(() -> new AppException(ErrorCode.NOT_FOUNDED_USER_NAME, ""));
//userRole이 USER이고, 작성자와 삭제자 불일치시.
//ADMIN은 모두 제거 가능
if (user.getRole() == UserRole.USER && !Objects.equals(post.getUser().getUserName(), userName)) {
throw new AppException(ErrorCode.INVALID_PERMISSION, "");
}
postRepository.delete(post);
}
public PostDto modifyPost(Integer postId, String title, String body, String userName) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new AppException(ErrorCode.POST_NOT_FOUND, ""));
User user = userRepository.findByUserName(userName)
.orElseThrow(() -> new AppException(ErrorCode.NOT_FOUNDED_USER_NAME, ""));
//userRole이 USER이고, 작성자와 삭제자 불일치시.
//ADMIN은 모두 수정 가능.
if (user.getRole() == UserRole.USER && !Objects.equals(post.getUser().getUserName(), userName)) {
throw new AppException(ErrorCode.INVALID_PERMISSION, "");
}
post.setTitle(title);
post.setBody(body);
Post savedPost = postRepository.saveAndFlush(post);
return savedPost.toResponse();
}
}
글 수정과 삭제에 대한 비지니스 로직을 추가하였다.
- view에서 받은 postId를 통해 db에서 post를 검색하였을 시 나오지 않은 경우 exception 발생
- view에서 받은 userName을 통해 db에서 user를 검색하였을 시 나오지 않은 경우 exception 발생
- role = UserRole.USER일 경우, 작성자와 수정자, 삭제자가 일치하지 않은 경우 exception 발생
즉시 db에 수정사항이 반영되어야 하기 때문에, 글 수정의 경우 기존의 jpaRepository의 save()가 아닌 saveAndFlush()를 사용하였다.
<Reference>
https://velog.io/@codren/JPA-save-%EC%99%80-saveAndFlush-%EC%9D%98-%EC%B0%A8%EC%9D%B4
4. Controller
PostController
@RestController
@RequestMapping("/api/v1/posts")
@RequiredArgsConstructor
public class PostController {
private final PostService postService;
...
@DeleteMapping("/{postId}")
public Response<PostResponse> deletePost(@PathVariable Integer postId, Authentication authentication) {
postService.deletePost(authentication.getName(), postId);
return Response.success(new PostResponse("포스트 삭제 완료", postId));
}
@PutMapping("/{postId}")
public Response<PostResponse> modifyPost(@PathVariable Integer postId, @RequestBody PostModifyRequest req, Authentication authentication) {
PostDto postDto = postService.modifyPost(postId, req.getTitle(), req.getBody(), authentication.getName());
return Response.success(new PostResponse("포스트 수정 완료", postDto.getId()));
}
}
글 수정과 삭제에 대한 매핑을 추가하였다.
<전체 Reference>
https://velog.io/@codren/JPA-save-%EC%99%80-saveAndFlush-%EC%9D%98-%EC%B0%A8%EC%9D%B4
'프로젝트 > 멋사 개인 프로젝트 (mutsa-SNS)' 카테고리의 다른 글
[13] mutsa-SNS 6일차 - (2) Admin 권한 부여 기능 추가 (2) | 2022.12.27 |
---|---|
[12] mutsa-SNS 6일차 - (1) Post 삭제, 수정 Test Code 추가 (0) | 2022.12.27 |
[10] mutsa-SNS 5일차 - (1) Post 조회 기능 TestCode 추가 (0) | 2022.12.26 |
[09] mutsa-SNS 4일차 - Post 조회 기능 추가 (0) | 2022.12.24 |
[08] mutsa-SNS 3일차 - (3) JwtTokenFilter Exception 추가 (0) | 2022.12.23 |