Skip to content

Commit

Permalink
공유페이지 외부 공개 api 기능 구현 및 리팩토링 완료 (#205)
Browse files Browse the repository at this point in the history
* feat : ApiStatus에 forbidden 추가 (#204)

* feat : IsPublicUpdateRequest DTO 생성 (#204)

* refactor : shareURL로 공유페이지 접속하는 url 수정 (#204)

* feat : SpaceWall엔티티에 isPublic 컬럼 추가 (#204)

- 공유페이지 저장시엔 설정이 안되기 때문에 @ColumnDefault로 디폴트 값 false로 설정

* feat : updateIsPublic 컨트롤러 메서드 생성 및 findByshareURL url 수정 (#204)

* feat : shareURL로 공유페이지 접근 시 외부공개 여부 체크하여 예외처리 (#204)

* refactor : db에 중복된 shareURL이 있을 경우 예외처리 추가 (#204)

* refactor : SpaceWallResponse에 memberId제거 및 isPublic 추가 (#204)

* feat : updateIsPublic 서비스 메소드 생성 (#204)

* modify : request변수명 수정 (#204)

* modify : updateIsPublic컨트롤러 메서드 응답 수정 (#204)

* refactor : 파일첨부가 되지 않은 파일블록이 있을 경우 예외처리 (#204)
  • Loading branch information
miyounlee authored Oct 26, 2023
1 parent 17459ed commit 4540107
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 48 deletions.
3 changes: 2 additions & 1 deletion src/main/java/com/javajober/core/exception/ApiStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public enum ApiStatus {
INVALID_DATE(HttpStatus.BAD_REQUEST, "invalid date"),
NOT_FOUND(HttpStatus.NOT_FOUND, "data not found"),
PAYLOAD_TOO_LARGE(HttpStatus.PAYLOAD_TOO_LARGE, "Payload Too Large"),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "login token expire");
UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "login token expire"),
FORBIDDEN(HttpStatus.FORBIDDEN, "forbidden");;

private final HttpStatus httpStatus;
private final String message;
Expand Down
42 changes: 21 additions & 21 deletions src/main/java/com/javajober/core/security/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@ public class SecurityConfig {
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

public SecurityConfig(AuthenticationManagerConfig authenticationManagerConfig,
CustomAuthenticationEntryPoint customAuthenticationEntryPoint) {
CustomAuthenticationEntryPoint customAuthenticationEntryPoint) {
this.authenticationManagerConfig = authenticationManagerConfig;
this.customAuthenticationEntryPoint = customAuthenticationEntryPoint;
}

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //세션 사용 x 설정
.and()
.formLogin().disable()
.csrf().disable()
.cors()
.and()
.apply(authenticationManagerConfig)
.and()
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/api/members/login").permitAll()
.antMatchers("/api/members/signup").permitAll()
.antMatchers("/healthCheck").permitAll()
.antMatchers("/api/wall/shareURL/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.and()
.build();
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) //세션 사용 x 설정
.and()
.formLogin().disable()
.csrf().disable()
.cors()
.and()
.apply(authenticationManagerConfig)
.and()
.httpBasic().disable()
.authorizeRequests()
.antMatchers("/api/members/login").permitAll()
.antMatchers("/api/members/signup").permitAll()
.antMatchers("/healthCheck").permitAll()
.antMatchers("/api/wall/{shareURL}").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
.and()
.build();
}

public CorsConfigurationSource corsConfigurationSource() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.javajober.core.util.ApiUtils;
import com.javajober.core.exception.ApiStatus;
import com.javajober.spaceWall.domain.FlagType;
import com.javajober.spaceWall.dto.request.IsPublicUpdateRequest;
import com.javajober.spaceWall.dto.request.SpaceWallStringRequest;
import com.javajober.spaceWall.dto.request.SpaceWallStringUpdateRequest;
import com.javajober.spaceWall.dto.response.DuplicateURLResponse;
Expand Down Expand Up @@ -84,7 +85,7 @@ public ResponseEntity<ApiResponse.Response<SpaceWallResponse>> findPending(
return ApiResponse.response(ApiStatus.OK, "공유페이지 임시 저장 조회를 성공했습니다.", data);
}

@GetMapping("/wall/shareURL/{shareURL}")
@GetMapping("/wall/{shareURL}")
public ResponseEntity<ApiResponse.Response<SpaceWallResponse>> findByShareURL(@PathVariable final String shareURL) {

SpaceWallResponse data = spaceWallFindService.findByShareURL(shareURL);
Expand Down Expand Up @@ -118,4 +119,14 @@ public ResponseEntity<ApiResponse.MessageResponse> deleteTemporary(@PathVariable

return ApiResponse.messageResponse(ApiStatus.OK, "공유페이지 임시 저장 삭제를 성공했습니다.");
}

@PutMapping("/wall/public")
public ResponseEntity<ApiResponse.MessageResponse> updateIsPublic(@RequestBody IsPublicUpdateRequest isPublicUpdateRequest,
@RequestHeader("Authorization") String token) {

Long memberId = jwtTokenizer.getUserIdFromToken(token);
spaceWallService.updateIsPublic(isPublicUpdateRequest, memberId);

return ApiResponse.messageResponse(ApiStatus.OK, "외부 공개 여부가 업데이트 되었습니다.");
}
}
15 changes: 14 additions & 1 deletion src/main/java/com/javajober/spaceWall/domain/SpaceWall.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@

import lombok.Builder;
import lombok.Getter;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.time.LocalDateTime;

@DynamicInsert
@Getter
@Table(name = "space_wall")
@EntityListeners(AuditingEntityListener.class)
Expand Down Expand Up @@ -47,6 +50,10 @@ public class SpaceWall {
@Column(name = "flag", nullable = false)
private FlagType flag;

@ColumnDefault("false")
@Column(name = "is_public")
private Boolean isPublic;

@CreatedDate
@Column(name = "created_at")
private LocalDateTime createdAt;
Expand All @@ -64,23 +71,29 @@ protected SpaceWall() {

@Builder
public SpaceWall(final String blocks, final String shareURL, final AddSpace addSpace, final Member member,
final SpaceWallCategoryType spaceWallCategoryType, final FlagType flag) {
final SpaceWallCategoryType spaceWallCategoryType, final FlagType flag, final Boolean isPublic) {
this.blocks = blocks;
this.shareURL = shareURL;
this.addSpace = addSpace;
this.member = member;
this.spaceWallCategoryType = spaceWallCategoryType;
this.flag = flag;
this.isPublic = isPublic;
}

public void update(final DataStringUpdateRequest request, final FlagType flag, final String blockInfoArrayAsString){
this.blocks = blockInfoArrayAsString;
this.shareURL = request.getShareURL();
this.flag = flag;
}

public void fileUpdate(final DataUpdateRequest request, final FlagType flag, final String blockInfoArrayAsString){
this.blocks = blockInfoArrayAsString;
this.shareURL = request.getShareURL();
this.flag = flag;
}

public void updateIsPublic(final Boolean isPublic) {
this.isPublic = isPublic;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.javajober.spaceWall.dto.request;

import lombok.Getter;

@Getter
public class IsPublicUpdateRequest {

private Long spaceId;
private Long spaceWallId;
private Boolean isPublic;

public IsPublicUpdateRequest() {
}

public IsPublicUpdateRequest(final Long spaceId, final Long spaceWallId, final Boolean isPublic) {
this.spaceId = spaceId;
this.spaceWallId = spaceWallId;
this.isPublic = isPublic;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
public class SpaceWallResponse {

private String category;
private Long memberId;
private Long spaceId;
private Boolean isPublic;
private String shareURL;
private CommonResponse wallInfoBlock;
private List<BlockResponse<CommonResponse>> blocks;
Expand All @@ -20,12 +20,12 @@ public class SpaceWallResponse {
private SpaceWallResponse() {}

@Builder
public SpaceWallResponse(final String category, final Long memberId, final Long spaceId, final String shareURL, final CommonResponse wallInfoBlock,
public SpaceWallResponse(final String category, final Long spaceId, final Boolean isPublic, final String shareURL, final CommonResponse wallInfoBlock,
final List<BlockResponse<CommonResponse>> blocks, final CommonResponse styleSetting) {

this.category = category;
this.memberId = memberId;
this.spaceId = spaceId;
this.isPublic = isPublic;
this.shareURL = shareURL;
this.wallInfoBlock = wallInfoBlock;
this.blocks = blocks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.javajober.core.exception.ApplicationException;
import com.javajober.spaceWall.domain.FlagType;
import com.javajober.spaceWall.domain.SpaceWall;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
Expand Down Expand Up @@ -51,7 +52,11 @@ default SpaceWall findSpaceWall(Long id, Long addSpaceId, Long memberId, FlagTyp
}

default SpaceWall getByShareURL(final String shareURL) {
return findByShareURL(shareURL)
.orElseThrow(() -> new ApplicationException(ApiStatus.NOT_FOUND, "존재하지 않는 shareURL입니다."));
try {
return findByShareURL(shareURL)
.orElseThrow(() -> new ApplicationException(ApiStatus.NOT_FOUND, "존재하지 않는 shareURL입니다."));
} catch (IncorrectResultSizeDataAccessException e) {
throw new ApplicationException(ApiStatus.EXCEPTION, "중복된 shareURL이 존재합니다.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,23 +190,26 @@ private void processWallInfoBlock(final MultipartFile backgroundImgURL, final Mu

private void processBlocks(final List<BlockSaveRequest<?>> blocks, final ArrayNode blockInfoArray,
final AtomicLong blocksPositionCounter, final List<MultipartFile> files) {
try {
AtomicInteger fileIndexCounter = new AtomicInteger();

AtomicInteger fileIndexCounter = new AtomicInteger();
blocks.forEach(block -> {

blocks.forEach(block -> {
BlockType blockType = BlockType.findBlockTypeByString(block.getBlockType());
Long position = blocksPositionCounter.getAndIncrement();

BlockType blockType = BlockType.findBlockTypeByString(block.getBlockType());
Long position = blocksPositionCounter.getAndIncrement();

String strategyName = blockType.getStrategyName();
MoveBlockStrategy blockProcessingStrategy = blockStrategyFactory.findMoveBlockStrategy(strategyName);
String strategyName = blockType.getStrategyName();
MoveBlockStrategy blockProcessingStrategy = blockStrategyFactory.findMoveBlockStrategy(strategyName);

if (BlockStrategyName.FileBlockStrategy.name().equals(blockProcessingStrategy.getStrategyName())) {
blockProcessingStrategy.uploadFile(files.get(fileIndexCounter.getAndIncrement()));
}
if (BlockStrategyName.FileBlockStrategy.name().equals(blockProcessingStrategy.getStrategyName())) {
blockProcessingStrategy.uploadFile(files.get(fileIndexCounter.getAndIncrement()));
}

blockProcessingStrategy.saveBlocks(block, blockInfoArray, position);
});
blockProcessingStrategy.saveBlocks(block, blockInfoArray, position);
});
} catch (IndexOutOfBoundsException e) {
throw new ApplicationException(ApiStatus.INVALID_DATA, "파일이 첨부되지 않은 파일블록이 있습니다.");
}
}

private void processStyleSettingBlock(final MultipartFile styleImgURL, final DataSaveRequest data, final ArrayNode blockInfoArray,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public DuplicateURLResponse hasDuplicateShareURL(final String shareURL) {
public SpaceWallResponse findByShareURL(final String shareURL) {

SpaceWall spaceWall = spaceWallRepository.getByShareURL(shareURL);
if (!spaceWall.getIsPublic()) {
throw new ApplicationException(ApiStatus.FORBIDDEN, "공유페이지에 접근 권한이 없습니다.");
}
Long memberId = spaceWall.getMember().getId();
Long spaceId = spaceWall.getAddSpace().getId();
Long spaceWallId = spaceWall.getId();
Expand All @@ -67,15 +70,16 @@ public SpaceWallResponse find(final Long memberId, final Long spaceId, final Lon

String category = spaceWall.getSpaceWallCategoryType().getEngTitle();
String shareURL = spaceWall.getShareURL();
Boolean isPublic = spaceWall.getIsPublic();

return new SpaceWallResponse(category, memberId, spaceId, shareURL, wallInfoBlockResponse, blocks, styleSettingResponse);
return new SpaceWallResponse(category, spaceId, isPublic, shareURL, wallInfoBlockResponse, blocks, styleSettingResponse);
}

private CommonResponse createWallInfoBlock(Map<Long, List<JsonNode>> groupedBlockByPosition) {
List<JsonNode> wallInfoBlocks = groupedBlockByPosition.get(INITIAL_POSITION);

if (wallInfoBlocks == null || wallInfoBlocks.isEmpty()) {
throw new ApplicationException(ApiStatus.NOT_FOUND, "wallInfoBlock 조회를 실패했습니다.");
throw new ApplicationException(ApiStatus.FAIL, "wallInfoBlock 조회를 실패했습니다.");
}

FixBlockStrategy blockStrategy = blockStrategyFactory.findFixBlockStrategy(getBlockTypeStrategyName(wallInfoBlocks));
Expand All @@ -85,16 +89,17 @@ private CommonResponse createWallInfoBlock(Map<Long, List<JsonNode>> groupedBloc
private CommonResponse createStyleSettingBlock(Map<Long, List<JsonNode>> groupedBlockByPosition) {
Long endPosition = groupedBlockByPosition.keySet().stream()
.max(Long::compareTo)
.orElseThrow(() -> new ApplicationException(ApiStatus.NOT_FOUND, "endPosition이 없습니다."));
.orElseThrow(() -> new ApplicationException(ApiStatus.FAIL, "endPosition이 없습니다."));

List<JsonNode> styleSettingBlocks = groupedBlockByPosition.get(endPosition);
String blockTypeString = styleSettingBlocks.get(0).path(BLOCK_TYPE_KEY).asText();

if (blockTypeString.equals(BlockType.STYLE_SETTING.getEngTitle())) {
FixBlockStrategy blockStrategy = blockStrategyFactory.findFixBlockStrategy(getBlockTypeStrategyName(styleSettingBlocks));
return blockStrategy.createFixBlockDTO(styleSettingBlocks);
if (!blockTypeString.equals(BlockType.STYLE_SETTING.name())) {
throw new ApplicationException(ApiStatus.FAIL, "styleSetting 조회를 실패하였습니다.");
}
return null;

FixBlockStrategy blockStrategy = blockStrategyFactory.findFixBlockStrategy(getBlockTypeStrategyName(styleSettingBlocks));
return blockStrategy.createFixBlockDTO(styleSettingBlocks);
}

private List<BlockResponse<CommonResponse>> createBlockResponses(Map<Long, List<JsonNode>> groupedBlockByPosition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,17 @@ private Long saveSpaceWall(final SpaceWallCategoryType spaceWallCategoryType, fi
return spaceWallRepository.save(spaceWall).getId();
}

@Transactional
public void updateIsPublic(IsPublicUpdateRequest publicUpdateRequest, Long memberId) {
Long spaceId = publicUpdateRequest.getSpaceId();
Long spaceWallId = publicUpdateRequest.getSpaceWallId();
SpaceWall spaceWall = spaceWallRepository.findSpaceWall(spaceWallId, spaceId, memberId, FlagType.SAVED);

Boolean isPublic = publicUpdateRequest.getIsPublic();
spaceWall.updateIsPublic(isPublic);
spaceWallRepository.save(spaceWall);
}

@Transactional
public SpaceWallSaveResponse update(final Long memberId, final SpaceWallStringUpdateRequest spaceWallUpdateRequest, final FlagType flagType) {

Expand Down

0 comments on commit 4540107

Please sign in to comment.