Skip to content

Commit 28badd4

Browse files
authored
feat(Volunteer): 봉사자 조회, 상세 조회, 검증 (#95)
* refactor(Volunteer): Find UseCase/Service를 Query UseCase/Service 로 통합 * feat(BadRequestException): 메시지 타입을 ExceptionMessage도 가능하게 오버로딩 * refactor: 클래스 명 변경 * feat(VolunteerDetail): 레포지토리 인터페이스, 구현체 추가, 리픽토링 * feat(Volunteer): Volunteer 쿼리 서비스 추가 * feat(Volunteer): 레포지토리 인터페이스, 구현체 추가, 리팩토링 * feat(Volunteer): 존재하지 않는 봉사자 처리 메시지 추가 * feat(VolunteerDetail): baseEntity 상속 * feat: Volunteer 및 VolunteerDetail 엔티티를 위한 DTO 변환 기능 추가 - Volunteer, VolunteerDetail 데이터 매핑. - VolunteerDetail 포함/미포함 두 가지 방식 지원. * refactor: 기존의 findService를 QueryService로 리팩토링 * feat(VolunteerQueryController): 프로필 조회 기능 추가 * feat(VolunteerApply): 엔티티와 ApplyStatus ENUM 추가 * feat(VolunteerDetailRepository): 사용하지 않는 메서드 삭제 * test(VolunteerRepository): 봉사자 id, OAuth id로 봉사자 정보 조회 테스트 추가 * test(RecruitBoardFixture): completed 상태의 RecruitBoard 생성 추가 - 리플렉션을 이용해서 status를 수정. * test(RecruitBoardRepository): findNotCompletedIdsByCenterId 추가 - 센터 아이디로 종료되지 않았고 삭제되지 않은 RecruitBoard의 아이디 리스트를 반환 - 자동 정렬 * feat(VolunteerApplyRepository): 봉사 신청 repository 추가 - save: 봉사 신청 데이터를 저장 - findById: 봉사 신청 ID로 조회 - findVolunteerIdsByRecruitIds: 모집글 ID 리스트로 봉사자 ID 리스트 조회 - findAllByRecruitId: 모집글 ID로 페이징된 봉사 신청 조회 - isNotDeleted: 논리 삭제된 데이터 제외 조건 추가 - toOrderSpecifiers: Sort 객체를 기반으로 정렬 조건 생성 - getCount: 페이징 처리를 위한 총 데이터 개수 조회 메서드 추가 * feat(RecruitBoardQueryService): 기관 아이디 기반으로 종료되지 않은 RecruitBoard 아이디 리스트 조회 추가 - getNotCompletedIdsByCenterIds * feat(VolunteerApplyJpaRepository): JpaRepo 상속 추가 * feat(VolunteerQueryService): 닉네임 조회 값 null 처리 * feat(VolunteerApplyQueryService): 봉사 신청 Query Service/UseCase 추가 - getVolunteerIdsByRecruitIds: 모집글 ID 리스트로 봉사자 ID 리스트 조회 * test: tearDown을 @transactional로 변경 * feat(VolunteerDetailAccessValidator): 봉사자 상세 정보 접근 검증 로직 구현 - 완료되지 않은 모집글 ID 조회 및 봉사자 ID와의 매칭 검증 - 타겟 봉사자 ID가 모집글과 연관되지 않은 경우 예외 처리 - RecruitBoardQueryUseCase와 VolunteerApplyQueryUseCase를 활용 * test(RecruitBoardQueryService): 센터 아이디로 완료되지 않은 모집 게시글의 ID 조회 테스트 추가 * test(RecruitBoardQueryRepository): 센터 아이디로 완료되지 않은 모집 게시글의 ID 조회 테스트 추가 * test(VolunteerApplyQueryService): 모집 아이디로 봉사자 아이디 리스트 조회 테스트 추가 * test(VolunteerApplyRepository): 봉사 신청/조회, 모집 ID로 봉사자 ID 리스트/페이징 조회 * test(VolunteerDetailRepository): 봉사자 ID로 봉사자 상세 정보 조회/저장 * test(VolunteerQueryService): 기관의 봉사자 상세 정보 조회에 대한 권한 검증 추가 * test(VolunteerDetailAccessValidator): 봉사자 상세 정보를 기관이 조회하는 테스트 추가 * test(VolunteerQueryService): 봉사자 기본/상세 정보 조회 테스트, 닉네임 조회 테스트 추가 - beforeEach 를 transactional로 변경 * feat(IntegrationTestSupport): @AutoConfigureMockMvc 추가 * test(VolunteerSignController): ControllerTestSupport 상속받도록 변경 * test(center): 공백 제거 * test(VolunteerQueryController): 타인 프로필 조회 컨트롤러 테스트 추가 * test(ControllerTestSupport): 필터 OFF * test(VolunteerController): 컨트롤러 테스트 삭제 * feat(VolunteerQueryController): @secured 적용, Mapping 리팩토링 * feat(UserRole): GrantedAuthority 상속, authority 필드, 정적 메서드 from 추가 * feat(UserRole): UserRole.name() 사용에서 명시적인 Authority 필드 반환 메서드로 변경 * feat(CookieService): 토큰 로그 추가 * feat(DevAccountSetUpConfig): repository 변경, .name()을 .getAuthority로 변경 * feat(HmacJwtGenerator): 일관성 있는 상수 처리 * refactor(JwtAuthFilter): 리팩토링, name() 사용 제거 * feat(SecurityConfig): @slf4j, (securedEnabled = true) 추가로 @secured 작동하도록 수정 * cicd(jacoco): controller 패키지를 테스트 커버리지에서 제외 - 나는 컨트롤러 테스트가 밉다. * refactor(VolunteerDetailAccessValidator): elseThrow 반환이 없는 것을 anyMatch로 수정 * feat(VolunteerQueryController): 성공 메시지 변경 * refactor(sonar 반영): unused import, chaining join, 명시적인 엔티티 default fields * fix(VolunteerApplyQueryServiceTest): builder는 기본 값이 설정되지 않는 문제 해결 * refactor(VolunteerQueryService): 인터페이스 의존으로 수정 * test(VolunteerResponseDto): 봉사자 응답 정보 스웨거 어노테이션 추가 * chore(package): 패키지이름 대문자 수정 * style(개행): git 잠재적인 문제 예방
1 parent 8ed8bd0 commit 28badd4

File tree

57 files changed

+1729
-620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1729
-620
lines changed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ def jacocoExcludePatterns = [
116116
'**/domain/*',
117117
'**/domains/*',
118118
'**/fixture/*',
119+
'**/controller/**',
120+
'**/fixture/*',
119121
'**/*Factory*'
120122
]
121123

@@ -132,6 +134,8 @@ def jacocoExcludePatternsForVerify = [
132134
'*.domain.*',
133135
'*.domains.*',
134136
'*.fixture.*',
137+
'*.controller.*',
138+
'*.fixture.*',
135139
'*.*Factory*'
136140
]
137141

src/main/java/com/somemore/auth/cookie/CookieService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ public class CookieService implements CookieUseCase {
1616
public void setAccessToken(HttpServletResponse response, String value) {
1717
ResponseCookie cookie = generateCookie(TokenType.ACCESS, value);
1818
response.addHeader("Set-Cookie", cookie.toString());
19+
log.info("SET_COOKIE_ACCESS_TOKEN = {}", value);
1920
}
2021

2122
@Override
2223
public void deleteAccessToken(HttpServletResponse response) {
2324
ResponseCookie cookie = generateCookie(TokenType.SIGNOUT, TokenType.SIGNOUT.name());
2425
response.addHeader("Set-Cookie", cookie.toString());
26+
log.info("DELETE_COOKIE_ACCESS_TOKEN");
2527
}
2628

2729
private static ResponseCookie generateCookie(TokenType tokenType, String value) {
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
11
package com.somemore.auth.jwt.domain;
22

3-
public enum UserRole {
4-
VOLUNTEER,
5-
CENTER,
6-
ADMIN
3+
import com.somemore.auth.jwt.exception.JwtException;
4+
import lombok.RequiredArgsConstructor;
5+
import org.springframework.security.core.GrantedAuthority;
6+
7+
import static com.somemore.auth.jwt.exception.JwtErrorType.UNKNOWN_ERROR;
8+
9+
@RequiredArgsConstructor
10+
public enum UserRole implements GrantedAuthority {
11+
VOLUNTEER("ROLE_VOLUNTEER"),
12+
CENTER("ROLE_CENTER"),
13+
ADMIN("ROLE_ADMIN");
14+
15+
private final String authority;
16+
17+
@Override
18+
public String getAuthority() {
19+
return this.authority;
20+
}
21+
22+
public static UserRole from(String role) {
23+
for (UserRole userRole : values()) {
24+
if (userRole.name().equals(role)) {
25+
return userRole;
26+
}
27+
}
28+
throw new JwtException(UNKNOWN_ERROR);
29+
}
730
}

src/main/java/com/somemore/auth/jwt/filter/JwtAuthFilter.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import jakarta.servlet.ServletException;
1010
import jakarta.servlet.http.HttpServletRequest;
1111
import jakarta.servlet.http.HttpServletResponse;
12-
import java.io.IOException;
13-
import java.util.List;
1412
import lombok.RequiredArgsConstructor;
1513
import lombok.extern.slf4j.Slf4j;
1614
import org.springframework.security.core.Authentication;
@@ -19,6 +17,9 @@
1917
import org.springframework.stereotype.Component;
2018
import org.springframework.web.filter.OncePerRequestFilter;
2119

20+
import java.io.IOException;
21+
import java.util.List;
22+
2223
@RequiredArgsConstructor
2324
@Slf4j
2425
@Component
@@ -34,7 +35,7 @@ protected boolean shouldNotFilter(HttpServletRequest request) {
3435

3536
@Override
3637
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
37-
FilterChain filterChain) throws ServletException, IOException {
38+
FilterChain filterChain) throws ServletException, IOException {
3839
EncodedToken accessToken = getAccessToken(request);
3940
jwtUseCase.processAccessToken(accessToken, response);
4041

@@ -47,24 +48,24 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
4748

4849
private EncodedToken getAccessToken(HttpServletRequest request) {
4950
String accessToken = request.getHeader("Authorization");
50-
if (!accessToken.startsWith("Bearer ")) {
51-
throw new JwtException(JwtErrorType.MISSING_TOKEN);
52-
}
5351

54-
accessToken = accessToken.substring(7);
52+
String tokenPrefix = "Bearer ";
53+
if (accessToken.startsWith(tokenPrefix)) {
54+
return new EncodedToken(accessToken.substring(tokenPrefix.length()));
55+
}
5556

56-
return new EncodedToken(accessToken);
57+
throw new JwtException(JwtErrorType.MISSING_TOKEN);
5758
}
5859

5960
private JwtAuthenticationToken createAuthenticationToken(Claims claims,
60-
EncodedToken accessToken) {
61+
EncodedToken accessToken) {
6162
String userId = claims.get("id", String.class);
62-
UserRole role = UserRole.valueOf(claims.get("role", String.class));
63+
String role = claims.get("role", String.class);
6364

6465
return new JwtAuthenticationToken(
6566
userId,
6667
accessToken,
67-
List.of(new SimpleGrantedAuthority(role.name()))
68+
List.of(new SimpleGrantedAuthority(role))
6869
);
6970
}
7071
}

src/main/java/com/somemore/auth/jwt/filter/UserRole.java

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/main/java/com/somemore/auth/jwt/generator/HmacJwtGenerator.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ public EncodedToken generateToken(String userId, String role, TokenType tokenTyp
3636
}
3737

3838
private static Claims buildClaims(String userId, String role) {
39-
final String ID = "id";
40-
final String ROLE = "role";
4139

4240
return Jwts.claims()
43-
.add(ID, userId)
44-
.add(ROLE, role)
41+
.add("id", userId)
42+
.add("role", role)
4543
.build();
4644
}
4745
}

src/main/java/com/somemore/auth/jwt/service/GenerateTokensOnLoginService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public EncodedToken saveRefreshTokenAndReturnAccessToken(UUID volunteerId) {
3535
private EncodedToken generateToken(UUID volunteerId, TokenType tokenType) {
3636
return jwtGenerator.generateToken(
3737
volunteerId.toString(),
38-
UserRole.VOLUNTEER.name(),
38+
UserRole.VOLUNTEER.getAuthority(),
3939
tokenType);
4040
}
4141

src/main/java/com/somemore/auth/oauth/handler/success/CustomOAuthSuccessHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import com.somemore.auth.oauth.OAuthProvider;
77
import com.somemore.auth.oauth.naver.service.query.ProcessNaverOAuthUserService;
88
import com.somemore.auth.redirect.RedirectUseCase;
9-
import com.somemore.volunteer.usecase.FindVolunteerIdUseCase;
9+
import com.somemore.volunteer.usecase.VolunteerQueryUseCase;
1010
import jakarta.servlet.http.HttpServletRequest;
1111
import jakarta.servlet.http.HttpServletResponse;
1212
import lombok.RequiredArgsConstructor;
@@ -26,7 +26,7 @@
2626
public class CustomOAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
2727

2828
private final ProcessNaverOAuthUserService processNaverOAuthService;
29-
private final FindVolunteerIdUseCase findVolunteerIdUseCase;
29+
private final VolunteerQueryUseCase volunteerQueryUseCase;
3030
private final GenerateTokensOnLoginUseCase generateTokensOnLoginUseCase;
3131
private final CookieUseCase cookieUseCase;
3232
private final RedirectUseCase redirectUseCase;
@@ -45,7 +45,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
4545
}
4646
}
4747

48-
UUID volunteerId = findVolunteerIdUseCase.findVolunteerIdByOAuthId(oAuthId);
48+
UUID volunteerId = volunteerQueryUseCase.getVolunteerIdByOAuthId(oAuthId);
4949
EncodedToken accessToken = generateTokensOnLoginUseCase.saveRefreshTokenAndReturnAccessToken(volunteerId);
5050

5151
cookieUseCase.setAccessToken(response, accessToken.value());

src/main/java/com/somemore/auth/util/DevAccountSetUpConfig.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import com.somemore.center.domain.Center;
1212
import com.somemore.center.repository.CenterJpaRepository;
1313
import com.somemore.volunteer.domain.Volunteer;
14-
import com.somemore.volunteer.repository.VolunteerJpaRepository;
14+
import com.somemore.volunteer.repository.VolunteerRepository;
1515
import jakarta.annotation.PostConstruct;
1616
import jakarta.annotation.PreDestroy;
1717
import java.util.UUID;
@@ -25,7 +25,7 @@
2525
@Component
2626
public class DevAccountSetUpConfig {
2727

28-
private final VolunteerJpaRepository volunteerRepository;
28+
private final VolunteerRepository volunteerRepository;
2929
private final CenterJpaRepository centerRepository;
3030
private final JwtGenerator jwtGenerator;
3131
private final RefreshTokenManager refreshTokenManager;
@@ -88,7 +88,7 @@ private EncodedToken saveRefreshTokenAndReturnAccessToken(UUID id, UserRole role
8888
}
8989

9090
private EncodedToken generateToken(UUID id, UserRole role, TokenType tokenType) {
91-
return jwtGenerator.generateToken(id.toString(), role.name(), tokenType);
91+
return jwtGenerator.generateToken(id.toString(), role.getAuthority(), tokenType);
9292
}
9393

9494
private RefreshToken generateRefreshToken(UUID id, UserRole role, EncodedToken accessToken) {

src/main/java/com/somemore/domains/VolunteerManagement.java

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)