diff --git a/src/main/java/com/tiketeer/Tiketeer/domain/purchase/annotation/CheckWaitingQueueAndTokenAop.java b/src/main/java/com/tiketeer/Tiketeer/domain/purchase/annotation/CheckWaitingQueueAndTokenAop.java index 20525acf..52f0eddc 100644 --- a/src/main/java/com/tiketeer/Tiketeer/domain/purchase/annotation/CheckWaitingQueueAndTokenAop.java +++ b/src/main/java/com/tiketeer/Tiketeer/domain/purchase/annotation/CheckWaitingQueueAndTokenAop.java @@ -28,7 +28,7 @@ public class CheckWaitingQueueAndTokenAop { private final SecurityContextHelper securityContextHelper; private final RedisService redisService; - private final String tokenPattern = "^[\\w\\.-]+@[\\w\\.-]+:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}+:\\d+$"; + private final String tokenPattern = "^[\\w\\.-]+@[\\w\\.-]+:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}+$"; @Around("@annotation(com.tiketeer.Tiketeer.domain.purchase.annotation.CheckWaitingQueueAndToken)") public Object check(final ProceedingJoinPoint joinPoint) throws Throwable { @@ -47,17 +47,16 @@ public Object check(final ProceedingJoinPoint joinPoint) throws Throwable { String[] args = purchaseToken.split(":"); var email = args[0]; var ticketingId = args[1]; - var entryTime = Long.parseLong(args[2]); validateUser(email); - validateTokenWithRedis(ticketingId, email, entryTime); + validateTokenWithRedis(ticketingId, email); try { return joinPoint.proceed(); } catch (Throwable e) { throw e; } finally { - redisService.removeZset(ticketingId, email); + redisService.removeZset("queue::" + ticketingId, email); } } @@ -77,22 +76,13 @@ private void validateUser(String email) { } } - private void validateTokenWithRedis(String ticketingId, String email, Long entryTime) { - var results = redisService.getZSetRankAndScore(ticketingId, email).orElseThrow(() -> { - log.error("User does not enter queue (email: " + email + ", ticketing_id: " + ticketingId + ")"); + private void validateTokenWithRedis(String ticketingId, String email) { + var results = redisService.getZSetRankAndScore("queue::" + ticketingId, email).orElseThrow(() -> { + log.error("User does not enter queue (email: {}, ticketing_id: {})", email, ticketingId); return new UserNotExistInQueueException(); }); var rank = results.getFirst(); - var entryTimeInRedis = results.getSecond(); - if (entryTime != entryTimeInRedis.longValue()) { - log.error( - "Entry time(" + entryTime + ") in token does not match with entry time(" - + entryTimeInRedis.longValue() - + ") in redis (email: " + email - + ", ticketing_id: " + ticketingId + ")"); - throw new PurchaseTokenNotValidException(); - } if (rank >= 10) { log.error( "User is not in purchasing order. (email: \" + email + \", ticketing_id: \" + ticketingId + \")\""); diff --git a/src/test/java/com/tiketeer/Tiketeer/domain/purchase/controller/PurchaseControllerTest.java b/src/test/java/com/tiketeer/Tiketeer/domain/purchase/controller/PurchaseControllerTest.java index 64425d8b..759d0adc 100644 --- a/src/test/java/com/tiketeer/Tiketeer/domain/purchase/controller/PurchaseControllerTest.java +++ b/src/test/java/com/tiketeer/Tiketeer/domain/purchase/controller/PurchaseControllerTest.java @@ -110,8 +110,8 @@ void postPurchaseSuccess() throws Exception { String content = objectMapper.writeValueAsString(req); var unixTime = System.currentTimeMillis(); - redisService.addZSet(ticketing.getId().toString(), buyerEmail, (double)unixTime); - List tokenValues = Arrays.asList(buyerEmail, ticketing.getId().toString(), String.valueOf(unixTime)); + redisService.addZSet("queue::" + ticketing.getId().toString(), buyerEmail, (double)unixTime); + List tokenValues = Arrays.asList(buyerEmail, ticketing.getId().toString()); var purchaseToken = Encoders.BASE64.encode(String.join(":", tokenValues).getBytes()); // when @@ -128,7 +128,7 @@ void postPurchaseSuccess() throws Exception { .andExpect(status().isCreated()) .andExpect(jsonPath("$.data.purchaseId").value(purchaseRepository.findAll().getFirst().getId().toString() )); - var rankOpt = redisService.getZSetRank(ticketing.getId().toString(), buyerEmail); + var rankOpt = redisService.getZSetRank("queue::" + ticketing.getId().toString(), buyerEmail); Assertions.assertThat(rankOpt).isNotPresent(); } @@ -187,7 +187,7 @@ void postPurchaseFailPurchaseTokenNotValid() throws Exception { .build(); String content = objectMapper.writeValueAsString(req); - List tokenValues = Arrays.asList(buyerEmail, ticketingId.toString()); + List tokenValues = Arrays.asList(buyerEmail, ""); var purchaseToken = Encoders.BASE64.encode(String.join(":", tokenValues).getBytes()); // when @@ -224,8 +224,7 @@ void postPurchaseFailPurchaseTokenOfOtherUser() throws Exception { .build(); String content = objectMapper.writeValueAsString(req); - var unixTime = System.currentTimeMillis(); - List tokenValues = Arrays.asList(otherEmail, ticketingId.toString(), String.valueOf(unixTime)); + List tokenValues = Arrays.asList(otherEmail, ticketingId.toString()); var purchaseToken = Encoders.BASE64.encode(String.join(":", tokenValues).getBytes()); // when @@ -279,45 +278,6 @@ void postPurchaseFailUserNotExistInQueue() throws Exception { .andExpect(status().isUnauthorized()); } - @Test - @DisplayName("일치하지 않는 entry time > 구매 생성 요청 > 실패") - @Transactional - void postPurchaseFailEntryTimeNotValid() throws Exception { - // given - var ticketingId = UUID.randomUUID(); - var buyerEmail = "buyer@test.com"; - String token = testHelper.registerAndLoginAndReturnAccessToken(buyerEmail, RoleEnum.BUYER); - var buyer = memberRepository.findByEmail(buyerEmail).orElseThrow(); - buyer.setPoint(10000); - Cookie cookie = new Cookie(JwtMetadata.ACCESS_TOKEN, token); - - var count = 2; - PostPurchaseRequestDto req = PostPurchaseRequestDto.builder() - .ticketingId(ticketingId) - .count(count) - .build(); - String content = objectMapper.writeValueAsString(req); - - var unixTime = System.currentTimeMillis(); - var otherUnixTime = unixTime + 100; - redisService.addZSet(ticketingId.toString(), buyerEmail, (double)unixTime); - List tokenValues = Arrays.asList(buyerEmail, ticketingId.toString(), String.valueOf(otherUnixTime)); - var purchaseToken = Encoders.BASE64.encode(String.join(":", tokenValues).getBytes()); - - // when - mockMvc - .perform(post("/api/purchases") - .contextPath("/api") - .contentType(MediaType.APPLICATION_JSON) - .characterEncoding("utf-8") - .content(content) - .cookie(cookie) - .header("Purchase-Token", purchaseToken) - ) - //then - .andExpect(status().isUnauthorized()); - } - @Test @DisplayName("구매 가능한 대기열 순위에 들지 않음 > 구매 생성 요청 > 실패") @Transactional @@ -338,11 +298,11 @@ void postPurchaseFailNotInOrder() throws Exception { String content = objectMapper.writeValueAsString(req); var unixTime = System.currentTimeMillis(); - redisService.addZSet(ticketingId.toString(), buyerEmail, (double)unixTime); + redisService.addZSet("queue::" + ticketingId, buyerEmail, (double)unixTime); for (int i = 1; i < 11; i++) { - redisService.addZSet(ticketingId.toString(), i + "@test.com", (double)(unixTime - 100 * i)); + redisService.addZSet("queue::" + ticketingId, i + "@test.com", (double)(unixTime - 100 * i)); } - List tokenValues = Arrays.asList(buyerEmail, ticketingId.toString(), String.valueOf(unixTime)); + List tokenValues = Arrays.asList(buyerEmail, ticketingId.toString()); var purchaseToken = Encoders.BASE64.encode(String.join(":", tokenValues).getBytes()); // when