Skip to content

Commit

Permalink
Merge pull request #592 from SWM-Morandi/feat/#577
Browse files Browse the repository at this point in the history
♻️ Refactor. MemberID Extraction
  • Loading branch information
miiiinju1 authored Dec 8, 2023
2 parents b27c179 + f559bf2 commit 8ca615f
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 111 deletions.
Binary file modified .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.env
codes/*
docker-compose.yml
src/main/resources/application.yml
src/main/java/swm_nm/morandi/auth/constants/SecurityConstants.java
Expand Down
4 changes: 1 addition & 3 deletions src/main/java/swm_nm/morandi/aop/logging/LoggingAspect.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable

@Around("bean(*Controller)")
public Object controllerAroundLogging(ProceedingJoinPoint pjp) throws Throwable {
// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
HttpServletRequest originalRequest = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
CachedBodyHttpServletWrapper request = new CachedBodyHttpServletWrapper(originalRequest);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
//Sentry 사용자 식별을 위한 User 인스턴스 생성
User user = new User();
//로그인 이전의 Controller에서도 이 함수에 들어오기 때문에 Security Context에 있는 MemberId를 가져올 수 없다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public boolean isFinished() {
return cachedBodyInputStream.available() == 0;
}

//TODO
/*
*
* 비동기 처리 사용 시에는 아래 isReady , setReadListener 메서드를 구현해야함
*
*/
@Override
public boolean isReady() {
return true;
Expand Down
121 changes: 35 additions & 86 deletions src/main/java/swm_nm/morandi/config/swagger/SwaggerConfig.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package swm_nm.morandi.config.swagger;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
Expand All @@ -12,128 +9,80 @@
import springfox.documentation.service.Server;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import swm_nm.morandi.global.annotations.CurrentMember;

import java.util.Collections;

@Configuration
public class SwaggerConfig {
Server serverLocal = new Server("local", "http://localhost:8080", "for local usages", Collections.emptyList(), Collections.emptyList());
Server testServer = new Server("test", "https://api.morandi.co.kr", "for testing", Collections.emptyList(), Collections.emptyList());
@Bean
public Docket memberApi() {

private Docket createDocket(String groupName, String basePackage) {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("member-api")
.groupName(groupName)
.useDefaultResponseMessages(false)
.ignoredParameterTypes(CurrentMember.class)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.member.controller"))
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}

// 공통으로 사용할 ApiInfo 정의
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Practice Swagger")
.description("practice swagger config")
.version("1.0")
.build();
}

@Bean
public Docket memberApi() {
return createDocket("member-api", "swm_nm.morandi.domain.member.controller");
}

@Bean
public Docket testDuringApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-during-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testDuring.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("test-during-api", "swm_nm.morandi.domain.testDuring.controller");
}

@Bean
public Docket testExitApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-exit-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testExit.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("test-exit-api", "swm_nm.morandi.domain.testExit.controller");
}

@Bean
public Docket testInfoApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-info-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testInfo.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("test-info-api", "swm_nm.morandi.domain.testInfo.controller");
}

@Bean
public Docket testRecordApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-record-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testRecord.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("test-record-api", "swm_nm.morandi.domain.testRecord.controller");
}

@Bean
public Docket testStartApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-start-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testStart.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("test-start-api", "swm_nm.morandi.domain.testStart.controller");
}

@Bean
public Docket codeSubmitApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("code-submit-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.codeSubmit.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("code-submit-api", "swm_nm.morandi.domain.codeSubmit.controller");
}

@Bean
public Docket practiceProblemApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("practice-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.practice.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
return createDocket("practice-api", "swm_nm.morandi.domain.practice.controller");
}

@Bean
public Docket testRetryApi() {
return new Docket(DocumentationType.OAS_30)
.servers(serverLocal, testServer)
.groupName("test-retry-api")
.useDefaultResponseMessages(false)
.select()
.apis(RequestHandlerSelectors.basePackage("swm_nm.morandi.domain.testRetry.controller"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Practice Swagger")
.description("practice swagger config")
.version("1.0")
.build();
return createDocket("test-retry-api", "swm_nm.morandi.domain.testRetry.controller");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,10 @@ public ResponseEntity<String> oauthLogin(@PathVariable String type, @RequestPara

Cookie jwtCookie = new Cookie("accessToken", accessToken);
jwtCookie.setHttpOnly(true);

jwtCookie.setDomain(domain);; // 최상위 도메인 설정
jwtCookie.setPath("/"); // 이거 사용해

jwtCookie.setPath("/");
jwtCookie.setMaxAge(24 * 60 * 60); //쿠키 24시간
//jwtCookie.setSecure(true); // secure flag (HTTPS)

// jwtCookie.setSecure(true); // secure flag (HTTPS)
response.addCookie(jwtCookie);

return ResponseEntity.status(HttpStatus.FOUND).location(URI.create(redirectUri)).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@ public Page<Tests> findAllTestHistoryByCondition(String testTypename, Long bojPr

JPQLQuery<Tests> query = queryFactory
.selectFrom(tests)
.join(tests.member, member)
.join(tests.attemptProblems, attemptProblem)
.join(attemptProblem.problem, problem)
.where(bojIdEq(bojId),
testTypenameEq(testTypename),
bojProblemIdEq(bojProblemId),
tests.testStatus.eq(TestStatus.COMPLETED));

applyConditionalJoins(query, bojId, testTypename, bojProblemId);

JPQLQuery<Tests> paginatedQuery = query
.offset(pageable.getOffset())
.limit(pageable.getPageSize());
Expand All @@ -49,6 +48,16 @@ public Page<Tests> findAllTestHistoryByCondition(String testTypename, Long bojPr
return new PageImpl<>(testList, pageable, query.fetchCount());
}

private void applyConditionalJoins(JPQLQuery<Tests> query, String bojId, String testTypename, Long bojProblemId) {
if (StringUtils.hasText(bojId) || StringUtils.hasText(testTypename)) {
query.join(tests.member, member);
}
if (bojProblemId != null) {
query.join(tests.attemptProblems, attemptProblem)
.join(attemptProblem.problem, problem);
}
}

private BooleanExpression bojIdEq(String bojId) {
return StringUtils.hasText(bojId) ? tests.member.bojId.eq(bojId) : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import swm_nm.morandi.domain.testStart.dto.TestStartRequestDto;
import swm_nm.morandi.domain.testStart.dto.TestStartResponseDto;
import swm_nm.morandi.domain.testStart.service.TestStartUseCase;
import swm_nm.morandi.global.annotations.CurrentMember;

@RestController
@RequestMapping("/tests")
Expand All @@ -23,8 +24,9 @@ public class TestStartController {
@PostMapping
@Operation(summary = "테스트 입장", description = "사용자가 테스트에 입장할 때 테스트 문제 세트를 구성합니다.")
public ResponseEntity<TestStartResponseDto> testStart
(@RequestBody TestStartRequestDto testStartRequestDto) {
(@CurrentMember Long memberId,
@RequestBody TestStartRequestDto testStartRequestDto) {
Long testTypeId = testStartRequestDto.getTestTypeId();
return new ResponseEntity<>(testStartUseCase.getTestStartsData(testTypeId), HttpStatus.OK);
return new ResponseEntity<>(testStartUseCase.getTestStartsData(memberId, testTypeId), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ public class TestStartUseCase {
//이미 테스트 중인지 확인
@MemberLock
@Transactional
public TestStartResponseDto getTestStartsData(Long testTypeId) {
Long memberId = SecurityUtils.getCurrentMemberId();
public TestStartResponseDto getTestStartsData(Long memberId, Long testTypeId) {
Member member = memberRepository.findById(memberId).orElseThrow(
() -> new MorandiException(MemberErrorCode.MEMBER_NOT_FOUND));

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/swm_nm/morandi/global/annotations/CurrentMember.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package swm_nm.morandi.global.annotations;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentMember {
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package swm_nm.morandi.interceptor.config;
package swm_nm.morandi.global.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import swm_nm.morandi.global.resolver.CurrentMemberArgumentResolver;
import swm_nm.morandi.interceptor.BaekjoonLoginInterceptor;

import java.util.List;
Expand All @@ -20,5 +22,11 @@ public void addInterceptors(InterceptorRegistry registry) {
.excludePathPatterns(List.of("/submit/cookie","/swagger-ui/**","/v3/api-docs","/swagger-resources/**","/oauths/**"));
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new CurrentMemberArgumentResolver());
}


}

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
@Getter
public enum AuthErrorCode implements ErrorCode {
MEMBER_DUPLICATED(HttpStatus.CONFLICT, "이미 가입된 사용자입니다."),
SECURITY_CONTEXT_NOT_FOUND(HttpStatus.UNAUTHORIZED,"SecurityContext를 찾을 수 없습니다."),
SECURITY_CONTEXT_FAIL_PARSE(HttpStatus.UNAUTHORIZED,"SecurityContext의 memberId를 파싱할 수 없습니다."),
MEMBER_NOT_FOUND(HttpStatus.UNAUTHORIZED,"사용자를 찾을 수 없습니다"),
INVALID_PASSWORD(HttpStatus.UNAUTHORIZED,"유효하지 않은 인증 정보입니다."),
EXPIRED_TOKEN(HttpStatus.UNAUTHORIZED,"인증 시간이 만료된 토큰입니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package swm_nm.morandi.global.resolver;

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import swm_nm.morandi.global.annotations.CurrentMember;
import swm_nm.morandi.global.utils.SecurityUtils;


public class CurrentMemberArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation(CurrentMember.class) != null
&& parameter.getParameterType().equals(Long.class);

}

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return SecurityUtils.getCurrentMemberId();
}

}
Loading

0 comments on commit 8ca615f

Please sign in to comment.