diff --git a/src/main/java/in/koreatech/koin/admin/history/aop/AdminActivityHistoryAspect.java b/src/main/java/in/koreatech/koin/admin/history/aop/AdminActivityHistoryAspect.java index 3f385ffa2..720ae012c 100644 --- a/src/main/java/in/koreatech/koin/admin/history/aop/AdminActivityHistoryAspect.java +++ b/src/main/java/in/koreatech/koin/admin/history/aop/AdminActivityHistoryAspect.java @@ -1,20 +1,21 @@ package in.koreatech.koin.admin.history.aop; -import java.lang.reflect.Method; - +import org.apache.commons.lang3.EnumUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.reflect.MethodSignature; +import org.aspectj.lang.annotation.Pointcut; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.util.ContentCachingRequestWrapper; +import in.koreatech.koin.admin.history.enums.DomainType; import in.koreatech.koin.admin.history.enums.HttpMethodType; import in.koreatech.koin.admin.history.model.AdminActivityHistory; import in.koreatech.koin.admin.history.repository.AdminActivityHistoryRepository; +import in.koreatech.koin.admin.user.model.Admin; import in.koreatech.koin.admin.user.repository.AdminRepository; import in.koreatech.koin.global.auth.AuthContext; import jakarta.servlet.http.HttpServletRequest; @@ -25,50 +26,114 @@ @Profile("!test") @RequiredArgsConstructor public class AdminActivityHistoryAspect { - - private static final String SEPARATOR = "/"; private static final String REGEX_NUMERIC = "^[0-9]*$"; + private static final String SEGMENT_SHOPS = "SHOPS"; + private static final String SEGMENT_BENEFIT = "benefit"; + private static final String SEGMENT_CATEGORIES = "CATEGORIES"; + private static final String SEGMENT_CLOSE = "close"; + private static final String SEGMENT_ABTEST = "abtest"; private final AuthContext authContext; private final AdminRepository adminRepository; private final AdminActivityHistoryRepository adminActivityHistoryRepository; - @Around("@annotation(AdminLogging) && (args(..))") + @Pointcut("execution(* in.koreatech.koin.admin..controller.*.*(..))") + private void allAdminControllers() { + } + + @Pointcut("!@annotation(org.springframework.web.bind.annotation.GetMapping)") + private void excludeGetMapping() { + } + + @Pointcut("!execution(* in.koreatech.koin.admin.user.controller.AdminUserController.adminLogin(..)) && " + + "!execution(* in.koreatech.koin.admin.user.controller.AdminUserController.logout(..)) && " + + "!execution(* in.koreatech.koin.admin.user.controller.AdminUserController.refresh(..)) && " + + "!execution(* in.koreatech.koin.admin.user.controller.AdminUserController.createAdmin(..)) && " + + "!execution(* in.koreatech.koin.admin.user.controller.AdminUserController.adminPasswordChange(..)) && " + + "!execution(* in.koreatech.koin.admin.abtest.controller.AbtestController.assignOrGetAbtestVariable(..)) &&" + + "!execution(* in.koreatech.koin.admin.abtest.controller.AbtestController.issueAccessHistoryId(..))") + private void excludeSpecificMethods() { + } + + @Around("allAdminControllers() && excludeGetMapping() && excludeSpecificMethods()") public Object logAdminActivity(ProceedingJoinPoint joinPoint) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest(); + String requestURI = request.getRequestURI(); + HttpMethodType requestMethod = HttpMethodType.valueOf(request.getMethod()); + ContentCachingRequestWrapper cachingRequest = (ContentCachingRequestWrapper)request; + String requestMessage = new String(cachingRequest.getContentAsByteArray()); Object result = joinPoint.proceed(); - AdminLogging annotation = getAnnotation(joinPoint); + + Admin admin = adminRepository.getById(authContext.getUserId()); + DomainInfo domainInfo = getDomainInfo(requestURI); adminActivityHistoryRepository.save(AdminActivityHistory.builder() - .domainId(getDomainId(annotation, request.getRequestId())) - .admin(adminRepository.getById(authContext.getUserId())) - .requestMethod(HttpMethodType.valueOf(request.getMethod())) - .domainName(annotation.domainType()) - .requestMessage(new String(cachingRequest.getContentAsByteArray())) + .domainId(domainInfo.domainId()) + .admin(admin) + .requestMethod(requestMethod) + .domainName(DomainType.valueOf(domainInfo.domainName())) + .requestMessage(requestMessage) .build() ); return result; } - private AdminLogging getAnnotation(ProceedingJoinPoint joinPoint) { - MethodSignature signature = (MethodSignature)joinPoint.getSignature(); - Method method = signature.getMethod(); - return method.getAnnotation(AdminLogging.class); - } + private DomainInfo getDomainInfo(String requestURI) { + String[] segments = requestURI.split("/"); + Integer domainId = null; + String domainName = null; - private Integer getDomainId(AdminLogging annotation, String requestURI) { - if (annotation.hasId()) { - String[] segments = requestURI.split(SEPARATOR); + for (int i = segments.length - 1; i >= 0; i--) { + String segment = segments[i]; - for (int index = segments.length - 1; index >= 0; index--) { - if (segments[index].matches(REGEX_NUMERIC)) { - return Integer.parseInt(segments[index]); - } + if (isDomainType(segment)) { + domainName = getDomainName(segment, segments, i); + domainId = getDomainId(segments, i); + break; } + + if (isCloseAbtest(segment, segments, i)) { + domainName = segments[i - 1].toUpperCase(); + domainId = Integer.valueOf(segments[i + 1]); + break; + } + } + + return new DomainInfo(domainId, domainName); + } + + private boolean isDomainType(String segment) { + return EnumUtils.isValidEnumIgnoreCase(DomainType.class, segment); + } + + private String getDomainName(String segment, String[] segments, int index) { + String domainName = segment.toUpperCase(); + + if (SEGMENT_SHOPS.equals(domainName) && SEGMENT_BENEFIT.equals(segments[index - 2])) { + return segments[index - 2].toUpperCase(); + } + + if (SEGMENT_CATEGORIES.equals(domainName)) { + return (segments[index - 1] + domainName).toUpperCase(); + } + + return domainName; + } + + private Integer getDomainId(String[] segments, int index) { + if (index != segments.length - 1 && segments[index + 1].matches(REGEX_NUMERIC)) { + return Integer.valueOf(segments[index + 1]); } return null; } + + private boolean isCloseAbtest(String segment, String[] segments, int index) { + return SEGMENT_CLOSE.equals(segment) && SEGMENT_ABTEST.equals(segments[index - 1]); + } + + private record DomainInfo(Integer domainId, String domainName) { + } } diff --git a/src/main/java/in/koreatech/koin/admin/history/aop/AdminLogging.java b/src/main/java/in/koreatech/koin/admin/history/aop/AdminLogging.java deleted file mode 100644 index c8b77b6f0..000000000 --- a/src/main/java/in/koreatech/koin/admin/history/aop/AdminLogging.java +++ /dev/null @@ -1,20 +0,0 @@ -package in.koreatech.koin.admin.history.aop; - -import static java.lang.annotation.ElementType.METHOD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Profile; - -import in.koreatech.koin.admin.history.enums.DomainType; - -@Retention(RUNTIME) -@Target(METHOD) -@Profile("!test") -public @interface AdminLogging { - DomainType domainType(); - - boolean hasId() default false; -}