Skip to content

Commit

Permalink
Merge branch 'dev/refactor/media-file'
Browse files Browse the repository at this point in the history
  • Loading branch information
juwon-code committed Oct 8, 2024
2 parents 0f2b451 + 3630233 commit 3d68e6d
Show file tree
Hide file tree
Showing 59 changed files with 1,031 additions and 838 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import com.prgrms2.java.bitta.apply.exception.ApplyException;
import com.prgrms2.java.bitta.apply.repository.ApplyRepository;
import com.prgrms2.java.bitta.jobpost.util.JobPostProvider;
import com.prgrms2.java.bitta.member.dto.MemberProvider;
import com.prgrms2.java.bitta.member.entity.Member;
import com.prgrms2.java.bitta.member.service.MemberProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.prgrms2.java.bitta.feed.dto.FeedDTO;
import com.prgrms2.java.bitta.feed.service.FeedService;
import com.prgrms2.java.bitta.global.exception.AuthenticationException;
import com.prgrms2.java.bitta.global.util.AuthenticationProvider;
import com.prgrms2.java.bitta.media.dto.MediaDto;
import com.prgrms2.java.bitta.member.entity.Role;
import com.prgrms2.java.bitta.member.service.MemberProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
Expand Down Expand Up @@ -230,6 +234,10 @@ public ResponseEntity<?> createFeed(@RequestPart(value = "feed") @Valid FeedDTO
@PutMapping(value = "/{id}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> modifyFeed(@PathVariable("id") @Min(1) Long id, @RequestPart("feed") @Valid FeedDTO feedDTO
, @RequestPart("filesToUpload") List<MultipartFile> filesToUpload, @RequestPart("filesToDelete") List<MediaDto> filesToDelete) {
if (!checkPermission(id)) {
throw AuthenticationException.CANNOT_ACCESS.get();
}

feedDTO.setId(id);

feedService.update(feedDTO, filesToUpload, filesToDelete);
Expand Down Expand Up @@ -276,9 +284,21 @@ public ResponseEntity<?> modifyFeed(@PathVariable("id") @Min(1) Long id, @Reques
)
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteFeed(@PathVariable("id") @Min(1) Long id) {
if (!checkPermission(id)) {
throw AuthenticationException.CANNOT_ACCESS.get();
}

feedService.delete(id);

return ResponseEntity.ok().body(Map.of("message", "피드가 삭제되었습니다."));
}

private boolean checkPermission(Long id) {
if (AuthenticationProvider.getRoles() == Role.ADMIN) {
return true;
}

return feedService.checkAuthority(id, AuthenticationProvider.getUsername());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ public interface FeedRepository extends JpaRepository<Feed, Long> {
//////////////////////////
@Query(value = "SELECT * FROM feed ORDER BY RAND() LIMIT :limit", nativeQuery = true)
List<Feed> findRandomFeeds(@Param("limit") int limit);

boolean existsByIdAndMember_Username(Long feedId, String username);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface FeedService {

void delete(Long id);


List<FeedDTO> readRandomFeeds(int limit);

boolean checkAuthority(Long feedId, String memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.prgrms2.java.bitta.feed.repository.FeedRepository;
import com.prgrms2.java.bitta.media.dto.MediaDto;
import com.prgrms2.java.bitta.media.service.MediaService;
import com.prgrms2.java.bitta.member.dto.MemberProvider;
import com.prgrms2.java.bitta.member.service.MemberProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand Down Expand Up @@ -67,7 +67,7 @@ public void insert(FeedDTO feedDTO, List<MultipartFile> files) {

Feed feed = dtoToEntity(feedDTO);

mediaService.upload(files, feedDTO.getId());
mediaService.uploads(files, feed.getId());

feedRepository.save(feed);
}
Expand All @@ -85,7 +85,7 @@ public void update(FeedDTO feedDTO, List<MultipartFile> filesToUpload, List<Medi

feed.clearMedias();

mediaService.upload(filesToUpload, feedDTO.getId());
mediaService.uploads(filesToUpload, feedDTO.getId());

feedRepository.save(feed);
}
Expand All @@ -100,7 +100,6 @@ public void delete(Long id) {
}
}

///////////////////////////////////////
@Override
@Transactional(readOnly = true)
public List<FeedDTO> readRandomFeeds(int limit) {
Expand All @@ -110,7 +109,10 @@ public List<FeedDTO> readRandomFeeds(int limit) {
.collect(Collectors.toList());
}

///////////////////////////////////////
@Override
public boolean checkAuthority(Long feedId, String username) {
return feedRepository.existsByIdAndMember_Username(feedId, username);
}

private Feed dtoToEntity(FeedDTO feedDto) {
return Feed.builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prgrms2.java.bitta.global.advice;

import com.prgrms2.java.bitta.global.exception.AuthenticationTaskException;
import jakarta.validation.ConstraintViolationException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -38,4 +39,9 @@ public ResponseEntity<?> handleFileSizeLimitExceeded(MaxUploadSizeExceededExcept
.body(Map.of("error", "Payload Too Large", "reason", "파일의 크기가 허용된 한도를 초과했습니다."));
}

@ExceptionHandler(AuthenticationTaskException.class)
public ResponseEntity<?> handleArgsException(AuthenticationTaskException e) {
return ResponseEntity.status(e.getCode())
.body(Map.of("error", e.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.prgrms2.java.bitta.security;
package com.prgrms2.java.bitta.global.config;

import com.prgrms2.java.bitta.token.filter.TokenAuthenticationFilter;
import com.prgrms2.java.bitta.token.util.TokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -20,11 +22,10 @@
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

private final JwtTokenProvider jwtTokenProvider;
private final TokenProvider tokenProvider;

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.httpBasic(basic -> basic.disable())
.csrf(csrf -> csrf.disable())
Expand All @@ -44,7 +45,7 @@ public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Excepti
.requestMatchers("/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**", "/webjars/**").permitAll()
// .requestMatchers("/images/**").permitAll() / S3 연결 필요
.anyRequest().authenticated())
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new TokenAuthenticationFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class)
.build();
}

Expand Down Expand Up @@ -76,7 +77,6 @@ public CorsConfigurationSource corsConfigurationSource() {

@Bean
public PasswordEncoder passwordEncoder() {
// BCrypt Encoder 사용
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.prgrms2.java.bitta.global.exception;

public enum AuthenticationException {
CANNOT_ACCESS(403, "해당 API에 대한 액세스 권한이 없습니다.");

private AuthenticationTaskException authenticationTaskException;

AuthenticationException(int code, String message) {
authenticationTaskException = new AuthenticationTaskException(code, message);
}

public AuthenticationTaskException get() {
return authenticationTaskException;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.prgrms2.java.bitta.global.exception;

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public class AuthenticationTaskException extends RuntimeException {
private int code;
private String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.prgrms2.java.bitta.global.util;

import com.prgrms2.java.bitta.member.entity.Role;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;


public class AuthenticationProvider {
public static String getUsername() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication == null || authentication.getName() == null) {
throw new RuntimeException("No authentication information.");
}

return authentication.getName();
}

public static Role getRoles() {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication == null || authentication.getAuthorities().isEmpty()) {
throw new RuntimeException("");
}

String role = authentication.getAuthorities().iterator().next().getAuthority();

return Role.valueOf(role);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.prgrms2.java.bitta.jobpost.entity;

import com.prgrms2.java.bitta.apply.entity.Apply;
import com.prgrms2.java.bitta.media.entity.Media;
import com.prgrms2.java.bitta.member.entity.Member;
import jakarta.persistence.*;
import lombok.*;
Expand Down Expand Up @@ -62,6 +63,9 @@ public boolean isClosed() {
return LocalDate.now().isAfter(this.endDate);
}

@OneToOne(mappedBy = "jobPost", cascade = CascadeType.ALL, orphanRemoval = true)
private Media media;

// 해당 게시글에 대한 신청 목록 가져야함
@OneToMany(mappedBy = "jobPost", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Apply> apply = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.prgrms2.java.bitta.jobpost.entity.JobPost;
import com.prgrms2.java.bitta.jobpost.exception.JobPostException;
import com.prgrms2.java.bitta.jobpost.repository.JobPostRepository;
import com.prgrms2.java.bitta.member.dto.MemberProvider;
import com.prgrms2.java.bitta.member.service.MemberProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/prgrms2/java/bitta/media/dto/MediaDto.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.prgrms2.java.bitta.media.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.prgrms2.java.bitta.media.entity.MediaCategory;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
Expand All @@ -17,6 +18,7 @@
@AllArgsConstructor
@NoArgsConstructor
@Schema(title = "미디어 DTO", description = "미디어 파일의 요청 및 응답에 사용하는 DTO입니다.")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MediaDto {
@Schema(title = "미디어 ID (PK)", description = "미디어 파일의 고유 ID 입니다.")
@Min(value = 1, message = "ID는 0 또는 음수가 될 수 없습니다.")
Expand All @@ -43,6 +45,14 @@ public class MediaDto {
@Min(value = 1, message = "ID는 0 또는 음수가 될 수 없습니다.")
private Long feedId;

@Schema(title = "회원 ID (FK)", description = "회원의 ID입니다.")
@Min(value = 1, message = "ID는 0 또는 음수가 될 수 없습니다.")
private Long memberId;

@Schema(title = "일거리 ID (FK)", description = "일거리의 ID입니다.")
@Min(value = 1, message = "ID는 0 또는 음수가 될 수 없습니다.")
private Long jobPostId;

@Schema(title = "파일 저장일시", description = "파일이 저장된 날짜 및 시간입니다.", example = "2023-09-24T14:45:00")
private LocalDateTime createdAt;

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/prgrms2/java/bitta/media/entity/Media.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.prgrms2.java.bitta.media.entity;

import com.prgrms2.java.bitta.feed.entity.Feed;
import com.prgrms2.java.bitta.jobpost.entity.JobPost;
import com.prgrms2.java.bitta.member.entity.Member;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
Expand Down Expand Up @@ -40,6 +42,14 @@ public class Media {
@JoinColumn(name = "feed_id")
private Feed feed;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "jobpost_id")
private JobPost jobPost;

@CreatedDate
@Column(updatable = false, nullable = false)
private LocalDateTime createdAt;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.prgrms2.java.bitta.media.entity;

public enum MediaCategory {
IMAGE, VIDEO, PROFILE
IMAGE, VIDEO
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.prgrms2.java.bitta.media.exception;

public enum MediaException {
BAD_REQUEST(400, "올바르지 않은 접근 경로입니다."),
NOT_FOUND(404, "해당 파일은 존재하지 않습니다."),
INTERNAL_ERROR(500, "파일 처리에 실패했습니다."),
INVALID_FORMAT(500, "올바르지 않은 파일 포맷입니다.");

private MediaTaskException mediaTaskException;

MediaException(int code, String message) {
mediaTaskException = new MediaTaskException(code, message);
}

public MediaTaskException get() {
return mediaTaskException;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class MediaFileTaskException extends RuntimeException {
@AllArgsConstructor
public class MediaTaskException extends RuntimeException {
private int code;
private String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface MediaRepository extends JpaRepository<Media, Long> {
@Query("SELECT m FROM Media m WHERE m.feed.id = :feedId")
List<Media> findAllByFeedId(@Param("feedId") Long feedId);

Optional<Media> findByFilename(@Param("filename") String filename);
}
Loading

0 comments on commit 3d68e6d

Please sign in to comment.