add: common에 audit, constants 추가
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.ktds.hi.common.audit;
|
||||
|
||||
/**
|
||||
* 감사 액션 열거형
|
||||
*/
|
||||
public enum AuditAction {
|
||||
CREATE,
|
||||
UPDATE,
|
||||
DELETE,
|
||||
ACCESS,
|
||||
LOGIN,
|
||||
LOGOUT
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.ktds.hi.common.audit;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 감사 로그 엔티티
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AuditLog {
|
||||
|
||||
private Long id;
|
||||
private String entityType;
|
||||
private String entityId;
|
||||
private AuditAction action;
|
||||
private String oldValues;
|
||||
private String newValues;
|
||||
private String userId;
|
||||
private String userAgent;
|
||||
private String ipAddress;
|
||||
private LocalDateTime timestamp;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ktds.hi.common.audit;
|
||||
|
||||
/**
|
||||
* 감사 로그 리포지토리 인터페이스
|
||||
*/
|
||||
public interface AuditLogRepository {
|
||||
|
||||
void save(AuditLog auditLog);
|
||||
|
||||
AuditLog findById(Long id);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.ktds.hi.common.audit;
|
||||
|
||||
import com.ktds.hi.common.repository.AuditLogRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 감사 로거
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class AuditLogger {
|
||||
|
||||
private final AuditLogRepository auditLogRepository;
|
||||
|
||||
public void logCreate(Object entity) {
|
||||
AuditLog auditLog = AuditLog.builder()
|
||||
.entityType(entity.getClass().getSimpleName())
|
||||
.entityId(extractEntityId(entity))
|
||||
.action(AuditAction.CREATE)
|
||||
.newValues(extractEntityInfo(entity))
|
||||
.userId(getCurrentUserInfo())
|
||||
.ipAddress(getClientInfo())
|
||||
.timestamp(LocalDateTime.now())
|
||||
.build();
|
||||
|
||||
auditLogRepository.save(auditLog);
|
||||
log.info("감사 로그 기록 - CREATE: {}", auditLog);
|
||||
}
|
||||
|
||||
public void logUpdate(Object entity, Map<String, Object> oldValues, Map<String, Object> newValues) {
|
||||
AuditLog auditLog = AuditLog.builder()
|
||||
.entityType(entity.getClass().getSimpleName())
|
||||
.entityId(extractEntityId(entity))
|
||||
.action(AuditAction.UPDATE)
|
||||
.oldValues(oldValues.toString())
|
||||
.newValues(newValues.toString())
|
||||
.userId(getCurrentUserInfo())
|
||||
.ipAddress(getClientInfo())
|
||||
.timestamp(LocalDateTime.now())
|
||||
.build();
|
||||
|
||||
auditLogRepository.save(auditLog);
|
||||
log.info("감사 로그 기록 - UPDATE: {}", auditLog);
|
||||
}
|
||||
|
||||
public void logDelete(Object entity) {
|
||||
AuditLog auditLog = AuditLog.builder()
|
||||
.entityType(entity.getClass().getSimpleName())
|
||||
.entityId(extractEntityId(entity))
|
||||
.action(AuditAction.DELETE)
|
||||
.oldValues(extractEntityInfo(entity))
|
||||
.userId(getCurrentUserInfo())
|
||||
.ipAddress(getClientInfo())
|
||||
.timestamp(LocalDateTime.now())
|
||||
.build();
|
||||
|
||||
auditLogRepository.save(auditLog);
|
||||
log.info("감사 로그 기록 - DELETE: {}", auditLog);
|
||||
}
|
||||
|
||||
public void logAccess(String entityType, String entityId) {
|
||||
AuditLog auditLog = AuditLog.builder()
|
||||
.entityType(entityType)
|
||||
.entityId(entityId)
|
||||
.action(AuditAction.ACCESS)
|
||||
.userId(getCurrentUserInfo())
|
||||
.ipAddress(getClientInfo())
|
||||
.timestamp(LocalDateTime.now())
|
||||
.build();
|
||||
|
||||
auditLogRepository.save(auditLog);
|
||||
log.debug("감사 로그 기록 - ACCESS: {}", auditLog);
|
||||
}
|
||||
|
||||
private String extractEntityId(Object entity) {
|
||||
// 리플렉션을 사용하여 ID 필드 추출
|
||||
try {
|
||||
return entity.getClass().getMethod("getId").invoke(entity).toString();
|
||||
} catch (Exception e) {
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private String extractEntityInfo(Object entity) {
|
||||
// 엔티티 정보를 JSON 형태로 변환
|
||||
return entity.toString();
|
||||
}
|
||||
|
||||
private String getCurrentUserInfo() {
|
||||
// 현재 사용자 정보 반환
|
||||
return "system"; // 실제 구현에서는 SecurityContext에서 가져옴
|
||||
}
|
||||
|
||||
private String getClientInfo() {
|
||||
// 클라이언트 IP 정보 반환
|
||||
return "127.0.0.1"; // 실제 구현에서는 HttpServletRequest에서 가져옴
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ktds.hi.common.audit;
|
||||
|
||||
import org.springframework.data.domain.AuditorAware;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* JPA Auditing을 위한 사용자 정보 제공자
|
||||
*/
|
||||
@Component
|
||||
public class CustomAuditorAware implements AuditorAware<String> {
|
||||
|
||||
@Override
|
||||
public Optional<String> getCurrentAuditor() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
if (authentication == null || !authentication.isAuthenticated()) {
|
||||
return Optional.of("system");
|
||||
}
|
||||
|
||||
return Optional.of(authentication.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.ktds.hi.common.constants;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* 캐시 관련 상수
|
||||
*/
|
||||
public class CacheConstants {
|
||||
|
||||
public static final Duration DEFAULT_TTL = Duration.ofHours(1);
|
||||
public static final Duration SHORT_TTL = Duration.ofMinutes(15);
|
||||
public static final Duration LONG_TTL = Duration.ofHours(24);
|
||||
|
||||
public static final String USER_CACHE_PREFIX = "user:";
|
||||
public static final String STORE_CACHE_PREFIX = "store:";
|
||||
public static final String REVIEW_CACHE_PREFIX = "review:";
|
||||
public static final String RECOMMENDATION_CACHE_PREFIX = "recommend:";
|
||||
|
||||
private CacheConstants() {
|
||||
// 유틸리티 클래스
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ktds.hi.common.constants;
|
||||
|
||||
/**
|
||||
* 에러 코드 상수
|
||||
*/
|
||||
public class ErrorCode {
|
||||
|
||||
public static final String INVALID_REQUEST = "INVALID_REQUEST";
|
||||
public static final String UNAUTHORIZED = "UNAUTHORIZED";
|
||||
public static final String FORBIDDEN = "FORBIDDEN";
|
||||
public static final String NOT_FOUND = "NOT_FOUND";
|
||||
public static final String DUPLICATE_RESOURCE = "DUPLICATE_RESOURCE";
|
||||
public static final String BUSINESS_RULE_VIOLATION = "BUSINESS_RULE_VIOLATION";
|
||||
public static final String EXTERNAL_SERVICE_ERROR = "EXTERNAL_SERVICE_ERROR";
|
||||
public static final String INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR";
|
||||
|
||||
private ErrorCode() {
|
||||
// 유틸리티 클래스
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ktds.hi.common.constants;
|
||||
|
||||
/**
|
||||
* 메시지 코드 상수
|
||||
*/
|
||||
public class MessageCode {
|
||||
|
||||
public static final String SUCCESS_CREATE = "성공적으로 생성되었습니다";
|
||||
public static final String SUCCESS_UPDATE = "성공적으로 수정되었습니다";
|
||||
public static final String SUCCESS_DELETE = "성공적으로 삭제되었습니다";
|
||||
public static final String INVALID_INPUT = "입력값이 올바르지 않습니다";
|
||||
public static final String DUPLICATE_USERNAME = "이미 사용중인 아이디입니다";
|
||||
public static final String DUPLICATE_NICKNAME = "이미 사용중인 닉네임입니다";
|
||||
public static final String INVALID_CREDENTIALS = "아이디 또는 비밀번호가 일치하지 않습니다";
|
||||
public static final String ACCESS_DENIED = "접근 권한이 없습니다";
|
||||
|
||||
private MessageCode() {
|
||||
// 유틸리티 클래스
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ktds.hi.common.constants;
|
||||
|
||||
/**
|
||||
* 보안 관련 상수
|
||||
*/
|
||||
public class SecurityConstants {
|
||||
|
||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
public static final String BEARER_PREFIX = "Bearer ";
|
||||
public static final String TOKEN_TYPE_ACCESS = "access";
|
||||
public static final String TOKEN_TYPE_REFRESH = "refresh";
|
||||
|
||||
public static final long ACCESS_TOKEN_EXPIRE_TIME = 30 * 60 * 1000L; // 30분
|
||||
public static final long REFRESH_TOKEN_EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000L; // 7일
|
||||
|
||||
private SecurityConstants() {
|
||||
// 유틸리티 클래스
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user