Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…verTown-MasilGasil-BE into refactor-authorization
  • Loading branch information
IjjS committed Mar 14, 2024
2 parents 600b26e + 202ccc2 commit 6bf63f8
Show file tree
Hide file tree
Showing 56 changed files with 1,673 additions and 212 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package team.silvertown.masil.common.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
Expand Down Expand Up @@ -91,4 +92,17 @@ public ResponseEntity<ErrorResponse> handleHttpMessageNotReadableException(
return handleUnknownException((Exception) rootCause);
}

@ExceptionHandler(BeanInstantiationException.class)
public ResponseEntity<ErrorResponse> handleBeanInstantiationException(
BeanInstantiationException e
) {
Throwable rootCause = e.getRootCause();

if (rootCause instanceof BadRequestException) {
return handleBadRequestException((BadRequestException) rootCause);
}

return handleUnknownException(e);
}

}
27 changes: 27 additions & 0 deletions src/main/java/team/silvertown/masil/common/scroll/OrderType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package team.silvertown.masil.common.scroll;

import io.micrometer.common.util.StringUtils;
import java.util.Arrays;
import java.util.Objects;
import team.silvertown.masil.common.exception.BadRequestException;
import team.silvertown.masil.common.scroll.dto.ScrollErrorCode;

public enum OrderType {
LATEST,
MOST_POPULAR;

public static OrderType get(String order) {
if (StringUtils.isBlank(order)) {
return LATEST;
}

return Arrays.stream(OrderType.values())
.filter(orderType -> order.equals(orderType.name()))
.findFirst()
.orElseThrow(() -> new BadRequestException(ScrollErrorCode.INVALID_ORDER_TYPE));
}

public static boolean isMostPopular(OrderType orderType) {
return Objects.isNull(orderType) || orderType == MOST_POPULAR;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package team.silvertown.masil.common.scroll.dto;

import java.util.Objects;
import lombok.Builder;
import lombok.Getter;

@Getter
public final class NormalListRequest {

private final String depth1;
private final String depth2;
private final String depth3;
private final ScrollRequest scrollRequest;

@Builder
private NormalListRequest(
String depth1,
String depth2,
String depth3,
String order,
String cursor,
int size
) {
this.depth1 = depth1;
this.depth2 = depth2;
this.depth3 = depth3;
this.scrollRequest = new ScrollRequest(order, cursor, size);
}

public int getSize() {
return this.scrollRequest.getSize();
}

public boolean isBasedOnAddress() {
return Objects.nonNull(depth1) && Objects.nonNull(depth2) && Objects.nonNull(depth3);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package team.silvertown.masil.common.scroll.dto;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import team.silvertown.masil.common.exception.ErrorCode;

@RequiredArgsConstructor
@Getter
public enum ScrollErrorCode implements ErrorCode {
INVALID_ORDER_TYPE(20311000, "올바르지 않은 정렬 기준입니다"),
INVALID_CURSOR_FORMAT(20311001, "정렬 기준에 맞지 않은 커서 형식입니다");

private final int code;
private final String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package team.silvertown.masil.common.scroll.dto;

import lombok.Getter;
import team.silvertown.masil.common.scroll.OrderType;
import team.silvertown.masil.common.validator.ScrollValidator;

@Getter
public final class ScrollRequest {

private final OrderType order;
private final String cursor;
private final int size;

public ScrollRequest(
String order,
String cursor,
int size
) {
OrderType orderType = OrderType.get(order);

ScrollValidator.validateCursorFormat(cursor, orderType);

this.order = orderType;
this.cursor = cursor;
this.size = size;
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package team.silvertown.masil.common.response;
package team.silvertown.masil.common.scroll.dto;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package team.silvertown.masil.common.validator;

import io.micrometer.common.util.StringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import team.silvertown.masil.common.exception.BadRequestException;
import team.silvertown.masil.common.scroll.OrderType;
import team.silvertown.masil.common.scroll.dto.ScrollErrorCode;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ScrollValidator extends Validator {

private static final int ID_CURSOR_LENGTH = 16;
private static final String INITIAL_CURSUR = "0";

public static void validateCursorFormat(String cursor, OrderType order) {
if (StringUtils.isBlank(cursor) || cursor.equals(INITIAL_CURSUR)) {
return;
}

if (OrderType.isMostPopular(order)) {
throwIf(cursor.length() != ID_CURSOR_LENGTH,
() -> new BadRequestException(ScrollErrorCode.INVALID_CURSOR_FORMAT));
return;
}

notOver(cursor.length(), ID_CURSOR_LENGTH, ScrollErrorCode.INVALID_CURSOR_FORMAT);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@ public class HttpRequestsConfigurer
"/swagger-resources/**"
};
private static final String AUTH_RESOURCE = "/api/v1/users/login";
private static final String[] POST_GET_RESOURCES = {
"/api/v1/posts"
private static final String[] GET_PERMIT_ALL_RESOURCES = {
// users
"api/v1/users/**",

// posts
"/api/v1/posts",
"/api/v1/posts/**",

// mates
"/api/v1/mates/**"
};
private static final String USER_ME_RESOURCE = "/api/v1/users/me";
private static final String ADMIN_PANEL = "/{0}/**";

private final SnapAdminProperties snapAdminProperties;
Expand All @@ -40,10 +49,12 @@ public void customize(
.permitAll()
.requestMatchers(AUTH_RESOURCE)
.permitAll()
.requestMatchers(HttpMethod.GET, POST_GET_RESOURCES)
.requestMatchers(HttpMethod.GET, GET_PERMIT_ALL_RESOURCES)
.permitAll()
.requestMatchers(MessageFormat.format(ADMIN_PANEL, snapAdminProperties.getBaseUrl()))
.permitAll()
.requestMatchers(HttpMethod.GET, USER_ME_RESOURCE)
.authenticated()
.anyRequest()
.authenticated();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
@Getter
@AllArgsConstructor
public enum ImageErrorCode implements ErrorCode {
NOT_SUPPORTED_CONTENT(500_16000, "지원하지 않는 파일 형식 입니다");
NOT_SUPPORTED_CONTENT(500_16000, "지원하지 않는 파일 형식 입니다"),
FILE_IS_EMPTY(500_16001, "비어있는 파일입니다");

private final int code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package team.silvertown.masil.image.validator;

import org.springframework.web.multipart.MultipartFile;
import team.silvertown.masil.common.exception.BadRequestException;
import team.silvertown.masil.common.validator.Validator;
import team.silvertown.masil.image.exception.ImageErrorCode;

public class ImageFileServiceValidator extends Validator {

public static void validateImgFile(MultipartFile file) {
throwIf(file.isEmpty(), () -> new BadRequestException(ImageErrorCode.FILE_IS_EMPTY));
String contentType = file.getContentType();
throwIf(!ImageFileType.isImage(contentType),
() -> new BadRequestException(ImageErrorCode.NOT_SUPPORTED_CONTENT));
}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package team.silvertown.masil.masil.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.net.URI;
import java.time.LocalDate;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import team.silvertown.masil.masil.dto.request.CreateMasilRequest;
import team.silvertown.masil.masil.dto.request.PeriodRequest;
Expand All @@ -30,7 +35,6 @@ public class MasilController {

public final MasilService masilService;


@PostMapping("/api/v1/masils")
@Operation(summary = "마실 생성")
@ApiResponse(
Expand Down Expand Up @@ -69,6 +73,7 @@ public ResponseEntity<CreateMasilResponse> create(
public ResponseEntity<RecentMasilResponse> getRecent(
@AuthenticationPrincipal
Long userId,
@RequestParam(required = false, defaultValue = "10")
Integer size
) {
RecentMasilResponse response = masilService.getRecent(userId, size);
Expand All @@ -85,9 +90,28 @@ public ResponseEntity<RecentMasilResponse> getRecent(
schema = @Schema(implementation = PeriodResponse.class)
)
)
@Parameters(
{
@Parameter(
name = "startDate",
in = ParameterIn.QUERY,
schema = @Schema(implementation = LocalDate.class),
example = "2024-03-12",
description = "없을 시 오늘이 포함된 월 초하루"
),
@Parameter(
name = "endDate",
in = ParameterIn.QUERY,
schema = @Schema(implementation = LocalDate.class),
example = "2024-03-12",
description = "없을 시 시작 날짜가 포함된 월 말일"
)
}
)
public ResponseEntity<PeriodResponse> getInGivenPeriod(
@AuthenticationPrincipal
Long userId,
@Parameter(hidden = true)
PeriodRequest request
) {
PeriodResponse response = masilService.getInGivenPeriod(userId, request);
Expand Down
11 changes: 0 additions & 11 deletions src/main/java/team/silvertown/masil/masil/domain/Masil.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,40 +38,29 @@ public class Masil extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;

@Column(name = "post_id")
private Long postId;

@Embedded
@Getter(AccessLevel.NONE)
private Address address;

@Column(name = "path", nullable = false)
private LineString path;

@Column(name = "content", columnDefinition = "TEXT")
private String content;

@Column(name = "thumbnail_url", length = 1024)
private String thumbnailUrl;

@Column(name = "distance", nullable = false)
private Integer distance;

@Column(name = "total_time", nullable = false)
private Integer totalTime;

@Column(name = "calories", nullable = false)
private Integer calories;

@Column(name = "started_at", nullable = false, columnDefinition = "TIMESTAMP(6)")
@TimeZoneStorage(TimeZoneStorageType.NORMALIZE)
private OffsetDateTime startedAt;

@OneToMany(mappedBy = "masil")
private final List<MasilPin> masilPins = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ public class MasilQueryRepositoryImpl implements MasilQueryRepository {
private static final int DEFAULT_RECENT_SIZE = 10;

private final JPAQueryFactory jpaQueryFactory;
private final QMasil masil = QMasil.masil;

public List<Masil> findRecent(User user, Integer size) {
QMasil masil = QMasil.masil;
int limit = DEFAULT_RECENT_SIZE;

if (Objects.nonNull(size) && size != 0) {
Expand All @@ -49,7 +49,6 @@ public List<MasilDailyDto> findInGivenPeriod(
OffsetDateTime startDateTime,
OffsetDateTime endDateTime
) {
QMasil masil = QMasil.masil;
BooleanBuilder condition = new BooleanBuilder();
StringTemplate startDate = convertToLocalDate(masil.startedAt);

Expand All @@ -62,7 +61,7 @@ public List<MasilDailyDto> findInGivenPeriod(
.orderBy(masil.startedAt.asc())
.transform(
GroupBy.groupBy(startDate)
.as(projectDailyDetail(masil))
.as(projectDailyDetail())
)
.entrySet()
.stream()
Expand All @@ -77,9 +76,7 @@ private StringTemplate convertToLocalDate(DateTimePath<OffsetDateTime> dateTime)
);
}

private GroupExpression<MasilDailyDetailDto, List<MasilDailyDetailDto>> projectDailyDetail(
QMasil masil
) {
private GroupExpression<MasilDailyDetailDto, List<MasilDailyDetailDto>> projectDailyDetail() {
return GroupBy.list(
Projections.constructor(
MasilDailyDetailDto.class,
Expand Down
Loading

0 comments on commit 6bf63f8

Please sign in to comment.