Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b941d08
refactor(Volunteer): Find UseCase/Service를 Query UseCase/Service 로 통합
m-a-king Nov 28, 2024
9fa8b39
feat(BadRequestException): 메시지 타입을 ExceptionMessage도 가능하게 오버로딩
m-a-king Nov 28, 2024
72a0f3e
refactor: 클래스 명 변경
m-a-king Nov 28, 2024
05cb0ff
feat(VolunteerDetail): 레포지토리 인터페이스, 구현체 추가, 리픽토링
m-a-king Nov 28, 2024
df033e2
feat(Volunteer): Volunteer 쿼리 서비스 추가
m-a-king Nov 28, 2024
b3bfdbb
feat(Volunteer): 레포지토리 인터페이스, 구현체 추가, 리팩토링
m-a-king Nov 28, 2024
72b2cfa
feat(Volunteer): 존재하지 않는 봉사자 처리 메시지 추가
m-a-king Nov 28, 2024
7130dbc
feat(VolunteerDetail): baseEntity 상속
m-a-king Nov 28, 2024
9a0e2f6
feat: Volunteer 및 VolunteerDetail 엔티티를 위한 DTO 변환 기능 추가
m-a-king Nov 28, 2024
c737e85
refactor: 기존의 findService를 QueryService로 리팩토링
m-a-king Nov 28, 2024
793e279
feat(VolunteerQueryController): 프로필 조회 기능 추가
m-a-king Nov 28, 2024
2c89fe0
feat(VolunteerApply): 엔티티와 ApplyStatus ENUM 추가
m-a-king Nov 29, 2024
9510c4b
feat(VolunteerDetailRepository): 사용하지 않는 메서드 삭제
m-a-king Nov 29, 2024
8b9c593
test(VolunteerRepository): 봉사자 id, OAuth id로 봉사자 정보 조회 테스트 추가
m-a-king Nov 29, 2024
849b0d0
test(RecruitBoardFixture): completed 상태의 RecruitBoard 생성 추가
m-a-king Nov 29, 2024
499668d
test(RecruitBoardRepository): findNotCompletedIdsByCenterId 추가
m-a-king Nov 29, 2024
90dd88e
feat(VolunteerApplyRepository): 봉사 신청 repository 추가
m-a-king Nov 29, 2024
aa4694c
feat(RecruitBoardQueryService): 기관 아이디 기반으로 종료되지 않은 RecruitBoard 아이디 …
m-a-king Nov 29, 2024
4d66f16
feat(VolunteerApplyJpaRepository): JpaRepo 상속 추가
m-a-king Nov 29, 2024
5402867
feat(VolunteerQueryService): 닉네임 조회 값 null 처리
m-a-king Nov 29, 2024
2734cdc
feat(VolunteerApplyQueryService): 봉사 신청 Query Service/UseCase 추가
m-a-king Nov 29, 2024
542dc36
test: tearDown을 @Transactional로 변경
m-a-king Nov 29, 2024
5baca67
feat(VolunteerDetailAccessValidator): 봉사자 상세 정보 접근 검증 로직 구현
m-a-king Nov 29, 2024
84d7b87
test(RecruitBoardQueryService): 센터 아이디로 완료되지 않은 모집 게시글의 ID 조회 테스트 추가
m-a-king Nov 29, 2024
bde83d4
test(RecruitBoardQueryRepository): 센터 아이디로 완료되지 않은 모집 게시글의 ID 조회 테스트 추가
m-a-king Nov 29, 2024
2919f35
test(VolunteerApplyQueryService): 모집 아이디로 봉사자 아이디 리스트 조회 테스트 추가
m-a-king Nov 29, 2024
a3d5cec
test(VolunteerApplyRepository): 봉사 신청/조회, 모집 ID로 봉사자 ID 리스트/페이징 조회
m-a-king Nov 29, 2024
943ce64
test(VolunteerDetailRepository): 봉사자 ID로 봉사자 상세 정보 조회/저장
m-a-king Nov 29, 2024
25d0cd3
test(VolunteerQueryService): 기관의 봉사자 상세 정보 조회에 대한 권한 검증 추가
m-a-king Nov 29, 2024
5fac32a
test(VolunteerDetailAccessValidator): 봉사자 상세 정보를 기관이 조회하는 테스트 추가
m-a-king Nov 29, 2024
b1da776
test(VolunteerQueryService): 봉사자 기본/상세 정보 조회 테스트, 닉네임 조회 테스트 추가
m-a-king Nov 29, 2024
d2af443
feat(IntegrationTestSupport): @AutoConfigureMockMvc 추가
m-a-king Nov 29, 2024
a7c176c
test(VolunteerSignController): ControllerTestSupport 상속받도록 변경
m-a-king Nov 29, 2024
931a6fe
test(center): 공백 제거
m-a-king Nov 29, 2024
81c2373
test(VolunteerQueryController): 타인 프로필 조회 컨트롤러 테스트 추가
m-a-king Nov 29, 2024
37e7922
test(ControllerTestSupport): 필터 OFF
m-a-king Nov 30, 2024
8689d38
test(VolunteerController): 컨트롤러 테스트 삭제
m-a-king Nov 30, 2024
c1370be
feat(VolunteerQueryController): @Secured 적용, Mapping 리팩토링
m-a-king Nov 30, 2024
b653e38
feat(UserRole): GrantedAuthority 상속, authority 필드, 정적 메서드 from 추가
m-a-king Nov 30, 2024
cb637fa
feat(UserRole): UserRole.name() 사용에서 명시적인 Authority 필드 반환 메서드로 변경
m-a-king Nov 30, 2024
20b4fb3
feat(CookieService): 토큰 로그 추가
m-a-king Nov 30, 2024
fb54ab3
feat(DevAccountSetUpConfig): repository 변경, .name()을 .getAuthority로 변경
m-a-king Nov 30, 2024
339de3e
feat(HmacJwtGenerator): 일관성 있는 상수 처리
m-a-king Nov 30, 2024
e79d56b
refactor(JwtAuthFilter): 리팩토링, name() 사용 제거
m-a-king Nov 30, 2024
fd3c5ab
feat(SecurityConfig): @Slf4j, (securedEnabled = true) 추가로 @Secured 작동…
m-a-king Nov 30, 2024
d3f37a4
cicd(jacoco): controller 패키지를 테스트 커버리지에서 제외
m-a-king Nov 30, 2024
7036367
refactor(VolunteerDetailAccessValidator): elseThrow 반환이 없는 것을 anyMatc…
m-a-king Nov 30, 2024
daac8ef
feat(VolunteerQueryController): 성공 메시지 변경
m-a-king Nov 30, 2024
be87e25
refactor(sonar 반영): unused import, chaining join, 명시적인 엔티티 default fi…
m-a-king Nov 30, 2024
7009cf1
fix(VolunteerApplyQueryServiceTest): builder는 기본 값이 설정되지 않는 문제 해결
m-a-king Nov 30, 2024
29a621b
refactor(VolunteerQueryService): 인터페이스 의존으로 수정
m-a-king Nov 30, 2024
20ca50d
test(VolunteerResponseDto): 봉사자 응답 정보 스웨거 어노테이션 추가
m-a-king Nov 30, 2024
6f425ef
chore(package): 패키지이름 대문자 수정
m-a-king Nov 30, 2024
bef0ddb
style(개행): git 잠재적인 문제 예방
m-a-king Dec 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ def jacocoExcludePatterns = [
'**/domain/*',
'**/domains/*',
'**/fixture/*',
'**/controller/**',
'**/fixture/*',
'**/*Factory*'
]

Expand All @@ -132,6 +134,8 @@ def jacocoExcludePatternsForVerify = [
'*.domain.*',
'*.domains.*',
'*.fixture.*',
'*.controller.*',
'*.fixture.*',
'*.*Factory*'
]

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/somemore/auth/cookie/CookieService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ public class CookieService implements CookieUseCase {
public void setAccessToken(HttpServletResponse response, String value) {
ResponseCookie cookie = generateCookie(TokenType.ACCESS, value);
response.addHeader("Set-Cookie", cookie.toString());
log.info("SET_COOKIE_ACCESS_TOKEN = {}", value);
}

@Override
public void deleteAccessToken(HttpServletResponse response) {
ResponseCookie cookie = generateCookie(TokenType.SIGNOUT, TokenType.SIGNOUT.name());
response.addHeader("Set-Cookie", cookie.toString());
log.info("DELETE_COOKIE_ACCESS_TOKEN");
}

private static ResponseCookie generateCookie(TokenType tokenType, String value) {
Expand Down
31 changes: 27 additions & 4 deletions src/main/java/com/somemore/auth/jwt/domain/UserRole.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
package com.somemore.auth.jwt.domain;

public enum UserRole {
VOLUNTEER,
CENTER,
ADMIN
import com.somemore.auth.jwt.exception.JwtException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;

import static com.somemore.auth.jwt.exception.JwtErrorType.UNKNOWN_ERROR;

@RequiredArgsConstructor
public enum UserRole implements GrantedAuthority {
VOLUNTEER("ROLE_VOLUNTEER"),
CENTER("ROLE_CENTER"),
ADMIN("ROLE_ADMIN");

private final String authority;

@Override
public String getAuthority() {
return this.authority;
}

public static UserRole from(String role) {
for (UserRole userRole : values()) {
if (userRole.name().equals(role)) {
return userRole;
}
}
throw new JwtException(UNKNOWN_ERROR);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔하네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네, 컨트롤러 테스트 만들면서 겸사겸사 수정해봤습니다~

}
23 changes: 12 additions & 11 deletions src/main/java/com/somemore/auth/jwt/filter/JwtAuthFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
Expand All @@ -19,6 +17,9 @@
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@RequiredArgsConstructor
@Slf4j
@Component
Expand All @@ -34,7 +35,7 @@ protected boolean shouldNotFilter(HttpServletRequest request) {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
FilterChain filterChain) throws ServletException, IOException {
EncodedToken accessToken = getAccessToken(request);
jwtUseCase.processAccessToken(accessToken, response);

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

private EncodedToken getAccessToken(HttpServletRequest request) {
String accessToken = request.getHeader("Authorization");
if (!accessToken.startsWith("Bearer ")) {
throw new JwtException(JwtErrorType.MISSING_TOKEN);
}

accessToken = accessToken.substring(7);
String tokenPrefix = "Bearer ";
if (accessToken.startsWith(tokenPrefix)) {
return new EncodedToken(accessToken.substring(tokenPrefix.length()));
}

return new EncodedToken(accessToken);
throw new JwtException(JwtErrorType.MISSING_TOKEN);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

얼리 리턴 굳입니당

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다 ㅎㅎ


private JwtAuthenticationToken createAuthenticationToken(Claims claims,
EncodedToken accessToken) {
EncodedToken accessToken) {
String userId = claims.get("id", String.class);
UserRole role = UserRole.valueOf(claims.get("role", String.class));
String role = claims.get("role", String.class);

return new JwtAuthenticationToken(
userId,
accessToken,
List.of(new SimpleGrantedAuthority(role.name()))
List.of(new SimpleGrantedAuthority(role))
);
}
}
7 changes: 0 additions & 7 deletions src/main/java/com/somemore/auth/jwt/filter/UserRole.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ public EncodedToken generateToken(String userId, String role, TokenType tokenTyp
}

private static Claims buildClaims(String userId, String role) {
final String ID = "id";
final String ROLE = "role";

return Jwts.claims()
.add(ID, userId)
.add(ROLE, role)
.add("id", userId)
.add("role", role)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public EncodedToken saveRefreshTokenAndReturnAccessToken(UUID volunteerId) {
private EncodedToken generateToken(UUID volunteerId, TokenType tokenType) {
return jwtGenerator.generateToken(
volunteerId.toString(),
UserRole.VOLUNTEER.name(),
UserRole.VOLUNTEER.getAuthority(),
tokenType);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.somemore.auth.oauth.OAuthProvider;
import com.somemore.auth.oauth.naver.service.query.ProcessNaverOAuthUserService;
import com.somemore.auth.redirect.RedirectUseCase;
import com.somemore.volunteer.usecase.FindVolunteerIdUseCase;
import com.somemore.volunteer.usecase.VolunteerQueryUseCase;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -26,7 +26,7 @@
public class CustomOAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

private final ProcessNaverOAuthUserService processNaverOAuthService;
private final FindVolunteerIdUseCase findVolunteerIdUseCase;
private final VolunteerQueryUseCase volunteerQueryUseCase;
private final GenerateTokensOnLoginUseCase generateTokensOnLoginUseCase;
private final CookieUseCase cookieUseCase;
private final RedirectUseCase redirectUseCase;
Expand All @@ -45,7 +45,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
}
}

UUID volunteerId = findVolunteerIdUseCase.findVolunteerIdByOAuthId(oAuthId);
UUID volunteerId = volunteerQueryUseCase.getVolunteerIdByOAuthId(oAuthId);
EncodedToken accessToken = generateTokensOnLoginUseCase.saveRefreshTokenAndReturnAccessToken(volunteerId);

cookieUseCase.setAccessToken(response, accessToken.value());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.somemore.center.domain.Center;
import com.somemore.center.repository.CenterJpaRepository;
import com.somemore.volunteer.domain.Volunteer;
import com.somemore.volunteer.repository.VolunteerJpaRepository;
import com.somemore.volunteer.repository.VolunteerRepository;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.UUID;
Expand All @@ -25,7 +25,7 @@
@Component
public class DevAccountSetUpConfig {

private final VolunteerJpaRepository volunteerRepository;
private final VolunteerRepository volunteerRepository;
private final CenterJpaRepository centerRepository;
private final JwtGenerator jwtGenerator;
private final RefreshTokenManager refreshTokenManager;
Expand Down Expand Up @@ -88,7 +88,7 @@ private EncodedToken saveRefreshTokenAndReturnAccessToken(UUID id, UserRole role
}

private EncodedToken generateToken(UUID id, UserRole role, TokenType tokenType) {
return jwtGenerator.generateToken(id.toString(), role.name(), tokenType);
return jwtGenerator.generateToken(id.toString(), role.getAuthority(), tokenType);
}

private RefreshToken generateRefreshToken(UUID id, UserRole role, EncodedToken accessToken) {
Expand Down
25 changes: 0 additions & 25 deletions src/main/java/com/somemore/domains/VolunteerManagement.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.somemore.facade.validator;

import java.util.UUID;

public interface VolunteerDetailAccessValidator {

void validateByCenterId(UUID centerId, UUID targetVolunteerId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.somemore.facade.validator;

import com.somemore.global.exception.BadRequestException;
import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase;
import com.somemore.volunteerapply.usecase.VolunteerApplyQueryUseCase;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

대문자 수정은 왜 하게 되신건가용?
궁금해서 여쭤봅니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 소나가 짚어주기도 했고, 패키지는 소문자로 이뤄져야하는데 제가 실수 했습니다

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.UUID;

import static com.somemore.global.exception.ExceptionMessage.UNAUTHORIZED_VOLUNTEER_DETAIL;

@Component
@RequiredArgsConstructor
public class VolunteerDetailAccessValidatorImpl implements VolunteerDetailAccessValidator {

private final RecruitBoardQueryUseCase recruitBoardQueryUseCase;
private final VolunteerApplyQueryUseCase volunteerApplyQueryUseCase;

/**
* 기관 ID를 기반으로 완료되지 않은 모집글들의 ID를 조회하고,
* 해당 모집글들에 연관된 봉사자들의 ID 목록에 타겟 봉사자 ID가 포함되어 있는지 검증.
*/
public void validateByCenterId(UUID centerId, UUID targetVolunteerId) {
List<Long> notCompletedIdsByCenterIds = recruitBoardQueryUseCase.getNotCompletedIdsByCenterIds(centerId);

List<UUID> volunteerIdsByRecruitIds = volunteerApplyQueryUseCase.getVolunteerIdsByRecruitIds(notCompletedIdsByCenterIds);

if (volunteerIdsByRecruitIds.stream()
.anyMatch(volunteerId -> volunteerId.equals(targetVolunteerId))) {
return;
}

throw new BadRequestException(UNAUTHORIZED_VOLUNTEER_DETAIL);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조인없이 객체로 잘 풀어내신 것 같아요.
굳입니당~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다!

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.somemore.auth.oauth.handler.success.CustomOAuthSuccessHandler;
import com.somemore.auth.oauth.service.CustomOAuth2UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
Expand All @@ -20,8 +19,7 @@
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@Slf4j
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfig {

private final CustomOAuth2UserService customOAuth2UserService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public class BadRequestException extends RuntimeException{
public BadRequestException(final String message) {
super(message);
}

public BadRequestException(final ExceptionMessage message) {
super(message.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@
@Getter
public enum ExceptionMessage {

NOT_EXISTS_CENTER("존재하지 않는 기관 입니다."),
NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글 입니다."),
NOT_EXISTS_CENTER("존재하지 않는 기관입니다."),
NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글입니다."),
UNAUTHORIZED_COMMUNITY_BOARD("해당 게시글에 권한이 없습니다."),
NOT_EXISTS_COMMUNITY_COMMENT("존재하지 않는 댓글 입니다."),
UNAUTHORIZED_COMMUNITY_COMMENT("해당 댓글에 권한이 없습니다."),
NOT_EXISTS_LOCATION("존재하지 않는 위치 ID 입니다."),
NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글 ID 입니다."),
NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글입니다."),
UNAUTHORIZED_RECRUIT_BOARD("해당 봉사 모집글에 권한이 없습니다."),
UPLOAD_FAILED("파일 업로드에 실패했습니다."),
INVALID_FILE_TYPE("지원하지 않는 파일 형식입니다."),
FILE_SIZE_EXCEEDED("파일 크기가 허용된 한도를 초과했습니다."),
EMPTY_FILE("파일이 존재하지 않습니다."),
INSTANTIATION_NOT_ALLOWED("인스턴스화 할 수 없는 클래스 입니다."),
NOT_EXISTS_VOLUNTEER("존재하지 않는 봉사자입니다."),
UNAUTHORIZED_VOLUNTEER_DETAIL("해당 봉사자의 상세 정보 조회 권한이 없습니다."),
CANNOT_CANCEL_DELETED_INTEREST_CENTER("이미 삭제된 관심 기관은 취소할 수 없습니다."),
DUPLICATE_INTEREST_CENTER("이미 관심 표시한 기관입니다.")
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
import com.somemore.recruitboard.repository.mapper.RecruitBoardWithLocation;
import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition;
import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition;

import java.util.List;

import java.util.Optional;
import java.util.UUID;

import org.springframework.data.domain.Page;

public interface RecruitBoardRepository {
Expand All @@ -26,4 +29,6 @@ public interface RecruitBoardRepository {
Page<RecruitBoardDetail> findAllNearby(RecruitBoardNearByCondition condition);

Page<RecruitBoard> findAllByCenterId(UUID centerId, RecruitBoardSearchCondition condition);

List<Long> findNotCompletedIdsByCenterId(UUID centerId);
}
Loading