From 2bc2a3d6e3b03f0d82d1c6f674cfe5aff48a24b1 Mon Sep 17 00:00:00 2001 From: Rinjae Date: Wed, 26 Aug 2026 09:43:00 +0900 Subject: [PATCH] =?UTF-8?q?"=EC=8B=A0=EA=B7=9C=20=EC=8B=A0=EC=B2=AD=20?= =?UTF-8?q?=EC=BF=A8=EB=8B=A4=EC=9A=B4=20=EB=A1=9C=EC=A7=81=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20-=20Repository/Service/Controller=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EB=A6=AC=20-=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20HTML=20=EC=8A=A4=ED=81=AC=EB=A6=BD?= =?UTF-8?q?=ED=8A=B8=20=EC=A0=9C=EA=B1=B0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/app/controller/MyAppController.java | 19 ---------- .../security/WriteRateLimitService.java | 37 ------------------- .../views/apps/mypage/apiKeyList.html | 6 --- 3 files changed, 62 deletions(-) diff --git a/src/main/java/com/eactive/apim/portal/apps/app/controller/MyAppController.java b/src/main/java/com/eactive/apim/portal/apps/app/controller/MyAppController.java index 33ab770..81aebe4 100644 --- a/src/main/java/com/eactive/apim/portal/apps/app/controller/MyAppController.java +++ b/src/main/java/com/eactive/apim/portal/apps/app/controller/MyAppController.java @@ -16,7 +16,6 @@ import com.eactive.apim.portal.apps.auth.twofactor.StepUpProtectedPaths; import com.eactive.apim.portal.apps.auth.twofactor.TwoFactorProperties; import com.eactive.apim.portal.apps.auth.twofactor.TwoFactorService; import com.eactive.apim.portal.common.exception.UserErrorMessageResolver; -import com.eactive.apim.portal.common.security.WriteRateLimitService; import com.eactive.apim.portal.common.user.PortalAuthenticatedUser; import com.eactive.apim.portal.common.util.ApiServiceHelper; import com.eactive.apim.portal.common.util.SecurityUtil; @@ -89,7 +88,6 @@ public class MyAppController { private final FileTypeDetector fileTypeDetector; private final TwoFactorService twoFactorService; private final TwoFactorProperties twoFactorProperties; - private final WriteRateLimitService writeRateLimitService; private static final long MAX_APP_ICON_BYTES = 2L * 1024 * 1024; // 2MB @@ -532,18 +530,9 @@ public class MyAppController { @RequestParam(value = "clear", required = false, defaultValue = "false") boolean clear, @ModelAttribute("apiKeyRegistration") ApiKeyRegistrationDTO registration, SessionStatus sessionStatus, - RedirectAttributes redirectAttributes, Model model) { PortalAuthenticatedUser user = SecurityUtil.getPortalAuthenticatedUser(); - // 재신청 쿨다운이면 입력을 다 하고 막히지 않도록 진입 시점에 되돌린다(최종 차단은 step2 가 한다). - long cooldownMinutes = writeRateLimitService.newAppRequestCooldownRemainingMinutes(); - if (cooldownMinutes > 0) { - sessionStatus.setComplete(); - redirectAttributes.addFlashAttribute("error", writeRateLimitService.cooldownMessage(cooldownMinutes)); - return new ModelAndView("redirect:/clients"); - } - // 명시적으로 요청된 경우에만 세션 초기화 (새 등록 시작) // 페이지 새로고침이나 뒤로가기 시에는 세션 데이터를 보존 if (clear) { @@ -728,14 +717,6 @@ public class MyAppController { return new ModelAndView("redirect:/clients/register/step1"); } - // 무제한 신청 차단 — 신규 신청은 1시간에 1건으로 고정한다(PortalProperty 무관). - long cooldownMinutes = writeRateLimitService.newAppRequestCooldownRemainingMinutes(); - if (cooldownMinutes > 0) { - sessionStatus.setComplete(); - redirectAttributes.addFlashAttribute("error", writeRateLimitService.cooldownMessage(cooldownMinutes)); - return new ModelAndView("redirect:/clients"); - } - PortalAuthenticatedUser user = SecurityUtil.getPortalAuthenticatedUser(); try { diff --git a/src/main/java/com/eactive/apim/portal/common/security/WriteRateLimitService.java b/src/main/java/com/eactive/apim/portal/common/security/WriteRateLimitService.java index 5f29d69..277cb60 100644 --- a/src/main/java/com/eactive/apim/portal/common/security/WriteRateLimitService.java +++ b/src/main/java/com/eactive/apim/portal/common/security/WriteRateLimitService.java @@ -1,8 +1,5 @@ package com.eactive.apim.portal.common.security; -import com.eactive.apim.portal.apprequest.entity.AppRequest; -import com.eactive.apim.portal.apprequest.entity.AppRequestType; -import com.eactive.apim.portal.apprequest.repository.AppRequestRepository; import com.eactive.apim.portal.apps.community.partnership.repository.PartnershipApplicationRepository; import com.eactive.apim.portal.apps.community.qna.repository.InquiryRepository; import com.eactive.apim.portal.common.entity.Auditable; @@ -20,7 +17,6 @@ import java.time.Duration; import java.time.LocalDateTime; import java.util.Collections; import java.util.List; -import java.util.Optional; /** * 작성 요청 빈도 제한(무제한 요청 차단). @@ -40,9 +36,6 @@ public class WriteRateLimitService { /** 빈도 판정 기준 구간 */ private static final Duration WINDOW = Duration.ofMinutes(1); - /** 클라이언트/API 신규 이용신청 재신청 금지 시간. PortalProperty 와 무관한 고정값. */ - public static final Duration NEW_APP_REQUEST_COOLDOWN = Duration.ofHours(1); - /** 빈도 제한 대상. 대상별로 카운터가 독립이다. */ public enum WriteTarget { INQUIRY("Q&A 문의"), @@ -64,7 +57,6 @@ public class WriteRateLimitService { private final InquiryRepository inquiryRepository; private final InquiryCommentRepository inquiryCommentRepository; private final PartnershipApplicationRepository partnershipApplicationRepository; - private final AppRequestRepository appRequestRepository; /** 현재 로그인 사용자 기준으로 허용 빈도를 넘었는지 */ public boolean isExceeded(WriteTarget target) { @@ -105,35 +97,6 @@ public class WriteRateLimitService { + "건까지 가능합니다. 잠시 후 다시 시도해 주세요."; } - /** - * 클라이언트/API 신규 이용신청 재신청까지 남은 시간(분). 쿨다운이 아니면 0. - * 1분 미만 남았어도 안내 문구를 위해 최소 1을 돌려준다. - */ - @Transactional(readOnly = true) - public long newAppRequestCooldownRemainingMinutes() { - String userId = currentUserId(); - if (userId == null || userId.isEmpty()) { - return 0; - } - Optional latest = appRequestRepository - .findFirstByApproval_Requester_IdAndTypeOrderByCreatedDateDesc(userId, AppRequestType.NEW); - if (!latest.isPresent() || latest.get().getCreatedDate() == null) { - return 0; - } - - LocalDateTime available = latest.get().getCreatedDate().plus(NEW_APP_REQUEST_COOLDOWN); - LocalDateTime now = LocalDateTime.now(); - if (!available.isAfter(now)) { - return 0; - } - return Math.max(1, Duration.between(now, available).toMinutes()); - } - - /** 쿨다운 안내 문구 */ - public String cooldownMessage(long remainingMinutes) { - return "클라이언트/API 이용신청은 1시간에 1건까지 가능합니다. 약 " + remainingMinutes + "분 후 다시 시도해 주세요."; - } - /** 감사 필드 createdBy 와 동일한 식별자(PortalUser.id). 비인증이면 null. */ private static String currentUserId() { PortalAuthenticatedUser user = SecurityUtil.getPortalAuthenticatedUser(); diff --git a/src/main/resources/templates/views/apps/mypage/apiKeyList.html b/src/main/resources/templates/views/apps/mypage/apiKeyList.html index 72432e0..a37d7c2 100644 --- a/src/main/resources/templates/views/apps/mypage/apiKeyList.html +++ b/src/main/resources/templates/views/apps/mypage/apiKeyList.html @@ -146,12 +146,6 @@ - -