Skip to content

Commit

Permalink
fix(auth): fix an error related authenticate and getting team detail (#…
Browse files Browse the repository at this point in the history
…133)

* refactor(meeting): add filtering logic when check meeting request duplicated

* refactor(meeting): modify the logic of inquiring about likes and meeting request data

* fix(meeting): fix an error when querying a list of successful meetings & refresh api (#129)

* fix(meeting): add result that meeting list from my request to find accepted meeting list query

* refactor(auth): change RefreshToken key name

* test(auth): fix refresh test and add API specification

* test(auth): fix refresh test and add API specification

* test(auth): fix refresh test and add API specification

* fix(meeting): fix test fail in workflow CI

---------

Co-authored-by: KAispread <[email protected]>

* refactor(auth): modify refresh api
  • Loading branch information
KAispread authored Sep 12, 2023
1 parent f56132d commit 228a1a2
Show file tree
Hide file tree
Showing 28 changed files with 280 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.e2i.wemeet.exception.token.NotEqualRoleToTokenException;
import com.e2i.wemeet.exception.unauthorized.UnAuthorizedException;
import jakarta.validation.ValidationException;
import java.lang.reflect.UndeclaredThrowableException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.JDBCException;
Expand Down Expand Up @@ -148,7 +149,7 @@ public ResponseEntity<ErrorResponse> handleNotEqualRoleException(
}

// SQL 관련 예외 핸들링 + sql & sql 예외 원인 Logging
@ExceptionHandler(DataAccessException.class)
@ExceptionHandler({DataAccessException.class, UndeclaredThrowableException.class})
public ResponseEntity<ErrorResponse> handleDatabaseAccessException(
final DataAccessException e) {
final int code = DATA_ACCESS.getCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ public class MeetingController {

@PostMapping
public ResponseDto<Void> sendMeetingRequest(@MemberId Long memberId, @RequestBody @Valid SendMeetingRequestDto requestDto) {
meetingHandleService.sendRequest(requestDto, memberId);
LocalDateTime meetingRequestTime = LocalDateTime.now();
meetingHandleService.sendRequest(requestDto, memberId, meetingRequestTime);

return ResponseDto.success("Send meeting request success");
}

@PostMapping("/message")
public ResponseDto<Void> sendMeetingRequestWithMessage(@MemberId Long memberId,
@RequestBody @Valid SendMeetingWithMessageRequestDto requestDto) {
meetingHandleService.sendRequestWithMessage(requestDto, memberId);
LocalDateTime meetingRequestTime = LocalDateTime.now();
meetingHandleService.sendRequestWithMessage(requestDto, memberId, meetingRequestTime);

return ResponseDto.success("Send meeting request with message success");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.e2i.wemeet.security.manager.IsManager;
import com.e2i.wemeet.service.team.TeamService;
import jakarta.validation.Valid;
import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand Down Expand Up @@ -58,7 +59,8 @@ public ResponseDto<MyTeamResponseDto> readTeam(@MemberId Long memberId) {

@GetMapping("/{teamId}")
public ResponseDto<TeamDetailResponseDto> readTeamById(@MemberId Long memberId, @PathVariable Long teamId) {
TeamDetailResponseDto result = teamService.readByTeamId(memberId, teamId);
final LocalDateTime readTime = LocalDateTime.now();
TeamDetailResponseDto result = teamService.readByTeamId(memberId, teamId, readTime);

return ResponseDto.success("Get Team Detail Success", result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.e2i.wemeet.domain.meeting.data.AcceptStatus;
import com.e2i.wemeet.domain.team.Team;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
Expand All @@ -24,11 +25,11 @@ public interface MeetingRequestRepository extends JpaRepository<MeetingRequest,

// 미팅 신청 이력 조회 ('대기중' 인 요청만)
@Query("""
select mr.meetingRequestId from MeetingRequest mr
where mr.team.teamId = :teamId and mr.partnerTeam.teamId = :partnerTeamId
select mr.createdAt from MeetingRequest mr
where mr.team.teamId = :teamId and mr.partnerTeam.teamId = :partnerTeamId
and mr.acceptStatus = 0
""")
Optional<Long> findIdByTeamIdAndPartnerTeamId(@Param("teamId") Long teamId, @Param("partnerTeamId") Long partnerTeamId);
Optional<LocalDateTime> findIdByTeamIdAndPartnerTeamId(@Param("teamId") Long teamId, @Param("partnerTeamId") Long partnerTeamId);

// 팀의 이전 미팅 신청 이력 조회 (신청 상태 조건)
@Query("""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Integer> findCreditByMemberId(@Param("memberId") Long memberId);

@Query("select m.role from Member m where m.memberId = :memberId")
Role findRoleByMemberId(Long memberId);
Optional<Role> findRoleByMemberId(@Param("memberId") Long memberId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.e2i.wemeet.domain.team.data.TeamImageData;
import com.e2i.wemeet.dto.dsl.TeamInformationDto;
import com.e2i.wemeet.dto.response.LeaderResponseDto;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

Expand All @@ -21,6 +22,6 @@ public interface TeamCustomRepository {
/*
* 팀 정보 조회
* */
Optional<TeamInformationDto> findTeamInformationByTeamId(Long memberLeaderId, Long teamId);
Optional<TeamInformationDto> findTeamInformationByTeamId(Long memberLeaderId, Long teamId, LocalDateTime readTime);

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
import static com.e2i.wemeet.domain.team.QTeam.team;
import static com.e2i.wemeet.domain.team_image.QTeamImage.teamImage;
import static com.e2i.wemeet.domain.team_member.QTeamMember.teamMember;
import static com.e2i.wemeet.service.heart.HeartServiceImpl.HEART_EXPIRE_DAY;
import static com.e2i.wemeet.service.meeting.MeetingHandleServiceImpl.MEETING_REQUEST_EXPIRE_DAY;

import com.e2i.wemeet.domain.team.data.TeamImageData;
import com.e2i.wemeet.dto.dsl.TeamInformationDto;
import com.e2i.wemeet.dto.dsl.TeamMemberInformationDto;
import com.e2i.wemeet.dto.response.LeaderResponseDto;
import com.e2i.wemeet.exception.notfound.TeamNotFoundException;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -60,7 +64,7 @@ public Optional<LeaderResponseDto> findLeaderByTeamId(final Long teamId) {
}

@Override
public Optional<TeamInformationDto> findTeamInformationByTeamId(final Long memberLeaderId, final Long teamId) {
public Optional<TeamInformationDto> findTeamInformationByTeamId(final Long memberLeaderId, final Long teamId, final LocalDateTime readTime) {
com.e2i.wemeet.domain.team.QTeam myTeam = new com.e2i.wemeet.domain.team.QTeam("myTeam");
TeamInformationDto teamInformationDto = Optional.ofNullable(queryFactory
.select(Projections.constructor(TeamInformationDto.class,
Expand All @@ -73,20 +77,29 @@ public Optional<TeamInformationDto> findTeamInformationByTeamId(final Long membe
team.additionalActivity,
team.introduction,
team.deletedAt,
meetingRequest.acceptStatus,
heart.heartId,
// 미팅 요청 조회
JPAExpressions
.select(meetingRequest.acceptStatus)
.from(meetingRequest)
.where(meetingRequest.team.eq(myTeam),
meetingRequest.partnerTeam.eq(team),
meetingRequest.createdAt.goe(readTime.minusDays(MEETING_REQUEST_EXPIRE_DAY))
)
.orderBy(meetingRequest.createdAt.desc())
.limit(1),
// 좋아요 표시 여부 조회
JPAExpressions
.select(heart.heartId)
.from(heart)
.where(heart.team.eq(myTeam),
heart.partnerTeam.eq(team),
heart.createdAt.goe(readTime.minusDays(HEART_EXPIRE_DAY))
)
.limit(1),
myTeam.teamId
))
.from(team)
.leftJoin(myTeam).on(myTeam.teamLeader.memberId.eq(memberLeaderId))
.leftJoin(heart).on(
heart.team.eq(myTeam),
heart.partnerTeam.teamId.eq(teamId)
)
.leftJoin(meetingRequest).on(
meetingRequest.team.eq(myTeam),
meetingRequest.partnerTeam.teamId.eq(teamId)
)
.where(team.teamId.eq(teamId))
.fetchOne())
.orElseThrow(TeamNotFoundException::new);
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/e2i/wemeet/dto/dsl/TeamInformationDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,20 @@ public TeamInformationDto(Long teamId, String chatLink, Integer memberNum, Regio
this.memberHasTeam = requestMemberTeamId != null;
}

public static TeamInformationDto of(Team team) {
public static TeamInformationDto of(Team team, Long heartId, Long requestMemberTeamId, AcceptStatus status) {
TeamInformationDto dto = TeamInformationDto.builder()
.teamId(team.getTeamId())
.chatLink(team.getChatLink())
.heartId(1L)
.heartId(heartId)
.memberNum(team.getMemberNum())
.region(team.getRegion())
.drinkRate(team.getDrinkRate())
.drinkWithGame(team.getDrinkWithGame())
.additionalActivity(team.getAdditionalActivity())
.introduction(team.getIntroduction())
.deletedAt(team.getDeletedAt())
.meetingRequestStatus(AcceptStatus.PENDING)
.requestMemberTeamId(1L)
.meetingRequestStatus(status)
.requestMemberTeamId(requestMemberTeamId)
.build();

dto.setTeamMember(team.getTeamMembers());
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/e2i/wemeet/exception/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public enum ErrorCode {
ACCESS_TOKEN_NOT_FOUND(40207, "access.token.not.found"),
MEETING_REQUEST_NOT_FOUND(40208, "meeting.request.not.found"),
MEETING_NOT_FOUND(40209, "meeting.not.found"),
REFRESH_TOKEN_NOT_EXIST(40210, "refresh.token.not.exist"),

UNAUTHORIZED(40300, "unauthorized"),
UNAUTHORIZED_ROLE(40301, "unauthorized.role"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.e2i.wemeet.exception.token;

import com.e2i.wemeet.exception.ErrorCode;

public class RefreshTokenNotExistException extends TokenException {

public RefreshTokenNotExistException() {
super(ErrorCode.REFRESH_TOKEN_NOT_EXIST);
}

public RefreshTokenNotExistException(ErrorCode errorCode) {
super(errorCode);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import com.e2i.wemeet.security.token.TokenInjector;
import com.e2i.wemeet.security.token.handler.AccessTokenHandler;
import com.e2i.wemeet.security.token.handler.RefreshTokenHandler;
import com.e2i.wemeet.service.admin.TokenAuthorizationService;
import com.e2i.wemeet.service.credential.sms.SmsCredentialService;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
Expand Down Expand Up @@ -71,9 +70,9 @@ public RefreshTokenProcessingFilter refreshTokenProcessingFilter(
RedisTemplate<String, String> redisTemplate, RefreshTokenHandler refreshTokenHandler,
TokenInjector tokenInjector, ObjectMapper objectMapper,
AccessTokenHandler accessTokenHandler,
TokenAuthorizationService tokenAuthorizationService) {
MemberRepository memberRepository) {
return new RefreshTokenProcessingFilter(redisTemplate, refreshTokenHandler, tokenInjector,
objectMapper, accessTokenHandler, tokenAuthorizationService);
objectMapper, accessTokenHandler, memberRepository);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

import static org.springframework.http.HttpMethod.POST;

import com.e2i.wemeet.domain.member.MemberRepository;
import com.e2i.wemeet.domain.member.data.Role;
import com.e2i.wemeet.dto.response.ResponseDto;
import com.e2i.wemeet.exception.notfound.MemberNotFoundException;
import com.e2i.wemeet.exception.token.RefreshTokenMismatchException;
import com.e2i.wemeet.exception.token.RefreshTokenNotExistException;
import com.e2i.wemeet.security.token.JwtEnv;
import com.e2i.wemeet.security.token.Payload;
import com.e2i.wemeet.security.token.TokenInjector;
import com.e2i.wemeet.security.token.handler.AccessTokenHandler;
import com.e2i.wemeet.security.token.handler.RefreshTokenHandler;
import com.e2i.wemeet.service.admin.TokenAuthorizationService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand All @@ -22,6 +24,7 @@
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

/*
Expand All @@ -40,21 +43,20 @@ public class RefreshTokenProcessingFilter extends OncePerRequestFilter {
private final TokenInjector tokenInjector;
private final ObjectMapper objectMapper;
private final AccessTokenHandler accessTokenHandler;

private final TokenAuthorizationService tokenAuthorizationService;
private final MemberRepository memberRepository;

public RefreshTokenProcessingFilter(RedisTemplate<String, String> redisTemplate,
RefreshTokenHandler refreshTokenHandler,
TokenInjector tokenInjector, ObjectMapper objectMapper,
AccessTokenHandler accessTokenHandler,
TokenAuthorizationService tokenAuthorizationService) {
MemberRepository memberRepository) {
this.filterRequestMatcher = new AntPathRequestMatcher(REFRESH_REQUEST_URL, POST.name());
this.redisTemplate = redisTemplate;
this.refreshTokenHandler = refreshTokenHandler;
this.tokenInjector = tokenInjector;
this.objectMapper = objectMapper;
this.accessTokenHandler = accessTokenHandler;
this.tokenAuthorizationService = tokenAuthorizationService;
this.memberRepository = memberRepository;
}

@Override
Expand All @@ -75,13 +77,14 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
private void reIssueToken(HttpServletRequest request, HttpServletResponse response)
throws IOException {
Payload payload = getPayload(request);
validateRefreshToken(request, payload);
Role role = memberRepository.findRoleByMemberId(payload.getMemberId())
.orElseThrow(MemberNotFoundException::new);

Role role = tokenAuthorizationService.getMemberRoleByMemberId(payload.getMemberId());
payload = new Payload(payload.getMemberId(), role.name());
validateRefreshToken(request, payload);
Payload newPayloadForToken = new Payload(payload.getMemberId(), role.name());

tokenInjector.injectToken(response, payload);
writeResponse(response, payload);
tokenInjector.injectToken(response, newPayloadForToken);
writeResponse(response, newPayloadForToken);
}

private Payload getPayload(HttpServletRequest request) {
Expand Down Expand Up @@ -109,6 +112,10 @@ private boolean matchesRefreshTokenInRedis(Payload payload, String refreshToken)
String redisKey = JwtEnv.getRedisKeyForRefresh(payload);
String savedRefresh = operations.get(redisKey);

if (!StringUtils.hasText(savedRefresh)) {
throw new RefreshTokenNotExistException();
}

boolean tokenEquals = refreshToken.equals(savedRefresh);
if (tokenEquals) {
// Redis 에서 RefreshToken 삭제
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
@Service
public class HeartServiceImpl implements HeartService {

public static final int HEART_EXPIRE_DAY = 1;
private static final LocalTime boundaryTime = LocalTime.of(23, 11);
private final HeartRepository heartRepository;
private final MemberRepository memberRepository;
Expand Down Expand Up @@ -87,7 +88,7 @@ public List<ReceivedHeartResponseDto> getReceivedHeart(Long memberId,
private void checkTodayHeart(Long teamId, LocalDateTime requestTime) {
LocalDateTime boundaryDateTime = requestTime.with(boundaryTime);
if (requestTime.isBefore(boundaryDateTime)) {
boundaryDateTime = boundaryDateTime.minusDays(1);
boundaryDateTime = boundaryDateTime.minusDays(HEART_EXPIRE_DAY);
}

heartRepository.findTodayHeart(teamId, boundaryDateTime, requestTime)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ public interface MeetingHandleService {
/*
* 미팅 신청
* */
void sendRequest(SendMeetingRequestDto requestDto, Long memberId);
Long sendRequest(SendMeetingRequestDto requestDto, Long memberId, LocalDateTime meetingRequestTime);

/*
* 쪽지와 함께 미팅 신청
* */
void sendRequestWithMessage(SendMeetingWithMessageRequestDto requestDto, Long memberId);
Long sendRequestWithMessage(SendMeetingWithMessageRequestDto requestDto, Long memberId, LocalDateTime meetingRequestTime);

/*
* 미팅 신청 수락
Expand Down
Loading

0 comments on commit 228a1a2

Please sign in to comment.