Skip to content

Commit

Permalink
MATE-113 : [FEAT] 메이트 관련 기능 url에서 memberId 제거 (#105)
Browse files Browse the repository at this point in the history
* MATE-113 : [FEAT] 메이트 게시글 작성 url 수정

* MATE-113 : [FEAT] 메이트 게시글 상태변경, 삭제 url 수정

* MATE-113 : [FEAT] 메이트 게시글 직관완료, 후기등록 url 수정

* MATE-113 : [CHORE] import문 정리
  • Loading branch information
MisaSohee authored Dec 7, 2024
1 parent 53af026 commit 8830ca6
Show file tree
Hide file tree
Showing 40 changed files with 327 additions and 755 deletions.
6 changes: 1 addition & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
FROM eclipse-temurin:17-jdk-alpine

# Redis 설치
RUN apk add --no-cache redis

COPY ./build/libs/*SNAPSHOT.jar project.jar
ENTRYPOINT redis-server & java -jar project.jar
ENTRYPOINT ["java", "-jar", "project.jar"]
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// Lombok
compileOnly 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.mate.common.config;

//import com.example.mate.common.security.filter.JwtCheckFilter;

import com.example.mate.common.security.filter.JwtCheckFilter;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class SwaggerConfig {
@Bean
Expand All @@ -19,6 +22,7 @@ public OpenAPI openAPI() {

return new OpenAPI()
.info(info)
.servers(List.of(new Server().url("http://localhost:8080")))
.addSecurityItem(new SecurityRequirement().addList("Bearer Authentication"))
.components(new Components().addSecuritySchemes("Bearer Authentication", createAPIKeyScheme()));
}
Expand Down
23 changes: 0 additions & 23 deletions src/main/java/com/example/mate/common/config/WebMvcConfig.java

This file was deleted.

1 change: 0 additions & 1 deletion src/main/java/com/example/mate/common/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public enum ErrorCode {
AUTH_UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "A002", "인증에 실패했습니다. 유효한 토큰을 제공해주세요."),
AUTH_FORBIDDEN(HttpStatus.FORBIDDEN, "A003", "접근 권한이 없습니다. 권한을 확인해주세요."),
UNAUTHORIZED_USER(HttpStatus.UNAUTHORIZED, "A004", "인증되지 않은 사용자입니다"),
INVALID_AUTH_TOKEN(HttpStatus.BAD_REQUEST, "A005", "잘못된 토큰 형식입니다."),

// Team
TEAM_NOT_FOUND(HttpStatus.NOT_FOUND, "T001", "팀을 찾을 수 없습니다"),
Expand Down
26 changes: 10 additions & 16 deletions src/main/java/com/example/mate/common/response/PageResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

@Getter
@Builder
Expand Down Expand Up @@ -39,21 +41,13 @@ public static <R, T> PageResponse<T> from(Page<R> page, List<T> content) {
.build();
}

/**
* Page 객체를 기반으로 PageResponse 를 생성하는 팩토리 메서드
*
* @param page Spring Data JPA 의 Page 객체
* @param <T> 변환된 데이터 타입
* @return PageResponse
*/
public static <T> PageResponse<T> from(Page<T> page) {
return PageResponse.<T>builder()
.content(page.getContent())
.totalPages(page.getTotalPages())
.totalElements(page.getTotalElements())
.hasNext(page.hasNext())
.pageNumber(page.getNumber())
.pageSize(page.getSize())
.build();
// Pageable 검증 메서드
public static Pageable validatePageable(Pageable pageable) {
// pageNumber 검증: 0보다 작은 값은 0으로 처리
int pageNumber = Math.max(pageable.getPageNumber(), 0);

// pageSize 검증: 0 이하이면 기본값 10으로 설정
int pageSize = pageable.getPageSize() <= 0 ? 10 : pageable.getPageSize();
return PageRequest.of(pageNumber, pageSize, pageable.getSort());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@

import com.example.mate.common.security.auth.AuthMember;
import com.example.mate.common.security.util.JwtUtil;
import com.example.mate.domain.member.service.LogoutRedisService;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@RequiredArgsConstructor
public class JwtCheckFilter extends OncePerRequestFilter {

private final JwtUtil jwtUtil;
private final LogoutRedisService logoutRedisService;

// 필터링 적용하지 않을 URI 체크
@Override
Expand All @@ -47,15 +44,8 @@ protected void doFilterInternal(HttpServletRequest request,
return;
}

// 토큰 유효성 검증 후 SecurityContext 설정
String accessToken = headerAuth.substring(7); // "Bearer " 제외한 토큰 저장

// 액세스 토큰이 블랙리스트에 있는지 확인
if (logoutRedisService.isTokenBlacklisted(accessToken)) {
handleException(response, new Exception("ACCESS TOKEN IS BLACKLISTED"));
return;
}

// 액세스 토큰의 모든 유효성 검증 후 SecurityContext 설정
try {
Map<String, Object> claims = jwtUtil.validateToken(accessToken);
setAuthentication(claims); // 인증 정보 설정
Expand All @@ -72,7 +62,6 @@ private boolean isExcludedPath(String requestURI) {
requestURI.startsWith("/api/auth") ||
requestURI.startsWith("/api/members/join") ||
requestURI.startsWith("/swagger-ui") ||
requestURI.startsWith("/v3/api-docs") ||
requestURI.startsWith("/api/members/login");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.mate.common.validator;
package com.example.mate.common.utils.validator;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.mate.common.validator;
package com.example.mate.common.utils.validator;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
Expand Down
27 changes: 0 additions & 27 deletions src/main/java/com/example/mate/common/validator/ValidPageable.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.example.mate.common.response.ApiResponse;
import com.example.mate.common.response.PageResponse;
import com.example.mate.common.security.auth.AuthMember;
import com.example.mate.common.validator.ValidPageable;
import com.example.mate.domain.goods.dto.request.GoodsPostRequest;
import com.example.mate.domain.goods.dto.request.GoodsReviewRequest;
import com.example.mate.domain.goods.dto.response.GoodsPostResponse;
Expand All @@ -15,6 +14,7 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
Expand Down Expand Up @@ -84,7 +84,7 @@ public ResponseEntity<ApiResponse<List<GoodsPostSummaryResponse>>> getGoodsPosts
public ResponseEntity<ApiResponse<PageResponse<GoodsPostSummaryResponse>>> getGoodsPosts(
@Parameter(description = "팀 ID") @RequestParam(required = false) Long teamId,
@Parameter(description = "카테고리") @RequestParam(required = false) String category,
@Parameter(description = "페이징 정보", required = true) @ValidPageable Pageable pageable
@Parameter(description = "페이징 정보", required = true) @PageableDefault Pageable pageable
) {
PageResponse<GoodsPostSummaryResponse> pageGoodsPosts = goodsService.getPageGoodsPosts(teamId, category, pageable);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.mate.domain.goods.dto.request;

import com.example.mate.common.validator.ValidEnum;
import com.example.mate.common.utils.validator.ValidEnum;
import com.example.mate.domain.goods.dto.LocationInfo;
import com.example.mate.domain.goods.entity.Category;
import com.example.mate.domain.goods.entity.GoodsPost;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.mate.domain.goods.dto.request;

import com.example.mate.common.validator.ValidEnum;
import com.example.mate.common.utils.validator.ValidEnum;
import com.example.mate.domain.constant.Rating;
import com.example.mate.domain.goods.entity.GoodsPost;
import com.example.mate.domain.goods.entity.GoodsReview;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@
import com.example.mate.common.response.ApiResponse;
import com.example.mate.common.response.PageResponse;
import com.example.mate.common.security.auth.AuthMember;
import com.example.mate.common.validator.ValidPageable;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatMessageResponse;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatRoomResponse;
import com.example.mate.domain.goodsChat.dto.response.GoodsChatRoomSummaryResponse;
import com.example.mate.domain.goodsChat.service.GoodsChatService;
import com.example.mate.domain.member.dto.response.MemberSummaryResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -28,68 +25,51 @@
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/goods/chat")
@Tag(name = "GoodsChatRoomController", description = "굿즈거래 채팅방 관련 API")
public class GoodsChatRoomController {

private final GoodsChatService goodsChatService;

@PostMapping
@Operation(summary = "굿즈거래 채팅방 입장 및 생성", description = "굿즈 거래 게시글에 대한 채팅방을 생성하거나 기존 채팅방 정보를 조회합니다.")
public ResponseEntity<ApiResponse<GoodsChatRoomResponse>> createGoodsChatRoom(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "판매글 ID", required = true) @RequestParam Long goodsPostId
) {
public ResponseEntity<ApiResponse<GoodsChatRoomResponse>> createGoodsChatRoom(@AuthenticationPrincipal AuthMember member,
@RequestParam Long goodsPostId) {
GoodsChatRoomResponse response = goodsChatService.getOrCreateGoodsChatRoom(member.getMemberId(), goodsPostId);
return ResponseEntity.ok(ApiResponse.success(response));
}

@GetMapping("/{chatRoomId}/message")
@Operation(summary = "굿즈거래 채팅방 메시지 조회", description = "지정된 채팅방의 메시지를 페이징 처리하여 조회합니다.")
public ResponseEntity<ApiResponse<PageResponse<GoodsChatMessageResponse>>> getGoodsChatRoomMessages(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "채팅방 ID", required = true) @PathVariable Long chatRoomId,
@Parameter(description = "페이징 정보") @ValidPageable Pageable pageable
@PathVariable Long chatRoomId,
@PageableDefault(page = 1, size = 20) Pageable pageable
) {
PageResponse<GoodsChatMessageResponse> response = goodsChatService.getMessagesForChatRoom(chatRoomId, member.getMemberId(), pageable);
return ResponseEntity.ok(ApiResponse.success(response));
}

@GetMapping
@Operation(summary = "사용자의 굿즈거래 채팅방 목록 조회", description = "사용자가 참여 중인 굿즈거래 채팅방 목록을 조회합니다.")
public ResponseEntity<ApiResponse<PageResponse<GoodsChatRoomSummaryResponse>>> getGoodsChatRooms(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "페이징 정보") @ValidPageable Pageable pageable
) {
public ResponseEntity<ApiResponse<PageResponse<GoodsChatRoomSummaryResponse>>> getGoodsChatRooms(@AuthenticationPrincipal AuthMember member,
@PageableDefault Pageable pageable) {
PageResponse<GoodsChatRoomSummaryResponse> response = goodsChatService.getGoodsChatRooms(member.getMemberId(), pageable);
return ResponseEntity.ok(ApiResponse.success(response));
}

@DeleteMapping("/{chatRoomId}")
@Operation(summary = "굿즈거래 채팅방 나가기", description = "사용자가 지정된 굿즈거래 채팅방을 나갑니다. 만약 모든 사용자가 나가면 채팅방이 삭제됩니다.")
public ResponseEntity<Void> leaveGoodsChatRoom(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "채팅방 ID", required = true) @PathVariable Long chatRoomId
) {
public ResponseEntity<Void> leaveGoodsChatRoom(@AuthenticationPrincipal AuthMember member, @PathVariable Long chatRoomId) {
goodsChatService.deactivateGoodsChatPart(member.getMemberId(), chatRoomId);

return ResponseEntity.noContent().build();
}

@GetMapping("/{chatRoomId}")
@Operation(summary = "굿즈거래 채팅방 입장", description = "굿즈 거래 채팅방의 정보를 조회합니다.")
public ResponseEntity<ApiResponse<GoodsChatRoomResponse>> getGoodsChatRoomInfo(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "채팅방 ID", required = true) @PathVariable Long chatRoomId
) {
public ResponseEntity<ApiResponse<GoodsChatRoomResponse>> getGoodsChatRoomInfo(@AuthenticationPrincipal AuthMember member,
@PathVariable Long chatRoomId) {
GoodsChatRoomResponse response = goodsChatService.getGoodsChatRoomInfo(member.getMemberId(), chatRoomId);
return ResponseEntity.ok(ApiResponse.success(response));
}

@GetMapping("/{chatRoomId}/members")
@Operation(summary = "굿즈거래 채팅방 인원 조회", description = "지정된 채팅방에 참여 중인 사용자 목록을 조회합니다.")
public ResponseEntity<ApiResponse<List<MemberSummaryResponse>>> getGoodsChatRoomMembers(
@AuthenticationPrincipal AuthMember member,
@Parameter(description = "채팅방 ID", required = true) @PathVariable Long chatRoomId
) {
public ResponseEntity<ApiResponse<List<MemberSummaryResponse>>> getGoodsChatRoomMembers(@AuthenticationPrincipal AuthMember member,
@PathVariable Long chatRoomId) {
List<MemberSummaryResponse> responses = goodsChatService.getChatRoomMembers(member.getMemberId(), chatRoomId);
return ResponseEntity.ok(ApiResponse.success(responses));
}
Expand Down
Loading

0 comments on commit 8830ca6

Please sign in to comment.