mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-06-23 16:05:09 +00:00
remove props, set ranges
This commit is contained in:
parent
561003f9af
commit
bb04361c77
@ -37,12 +37,13 @@ public class AuditAspect {
|
|||||||
Method method = signature.getMethod();
|
Method method = signature.getMethod();
|
||||||
Audited auditedAnnotation = method.getAnnotation(Audited.class);
|
Audited auditedAnnotation = method.getAnnotation(Audited.class);
|
||||||
|
|
||||||
// Use unified check to determine if we should audit
|
// Fast path: use unified check to determine if we should audit
|
||||||
|
// This avoids all data collection if auditing is disabled
|
||||||
if (!AuditUtils.shouldAudit(method, auditConfig)) {
|
if (!AuditUtils.shouldAudit(method, auditConfig)) {
|
||||||
return joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use AuditUtils to create the base audit data
|
// Only create the map once we know we'll use it
|
||||||
Map<String, Object> auditData = AuditUtils.createBaseAuditData(joinPoint, auditedAnnotation.level());
|
Map<String, Object> auditData = AuditUtils.createBaseAuditData(joinPoint, auditedAnnotation.level());
|
||||||
|
|
||||||
// Add HTTP information if we're in a web context
|
// Add HTTP information if we're in a web context
|
||||||
@ -80,7 +81,8 @@ public class AuditAspect {
|
|||||||
auditConfig.getAuditLevel() == AuditLevel.VERBOSE);
|
auditConfig.getAuditLevel() == AuditLevel.VERBOSE);
|
||||||
|
|
||||||
if (includeResult && result != null) {
|
if (includeResult && result != null) {
|
||||||
auditData.put("result", result.toString());
|
// Use safe string conversion with size limiting
|
||||||
|
auditData.put("result", AuditUtils.safeToString(result, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -65,12 +65,16 @@ public enum AuditLevel {
|
|||||||
* @return The corresponding AuditLevel
|
* @return The corresponding AuditLevel
|
||||||
*/
|
*/
|
||||||
public static AuditLevel fromInt(int level) {
|
public static AuditLevel fromInt(int level) {
|
||||||
|
// Ensure level is within valid bounds
|
||||||
|
int boundedLevel = Math.min(Math.max(level, 0), 3);
|
||||||
|
|
||||||
for (AuditLevel auditLevel : values()) {
|
for (AuditLevel auditLevel : values()) {
|
||||||
if (auditLevel.level == level) {
|
if (auditLevel.level == boundedLevel) {
|
||||||
return auditLevel;
|
return auditLevel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Default to STANDARD if invalid level
|
|
||||||
|
// Default to STANDARD if somehow we didn't match
|
||||||
return STANDARD;
|
return STANDARD;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,6 +23,8 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared utilities for audit aspects to ensure consistent behavior
|
* Shared utilities for audit aspects to ensure consistent behavior
|
||||||
* across different audit mechanisms.
|
* across different audit mechanisms.
|
||||||
@ -69,18 +71,25 @@ public class AuditUtils {
|
|||||||
* @param auditLevel The current audit level
|
* @param auditLevel The current audit level
|
||||||
*/
|
*/
|
||||||
public static void addHttpData(Map<String, Object> data, String httpMethod, String path, AuditLevel auditLevel) {
|
public static void addHttpData(Map<String, Object> data, String httpMethod, String path, AuditLevel auditLevel) {
|
||||||
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
if (httpMethod == null || path == null) {
|
||||||
if (attrs == null) {
|
return; // Skip if we don't have basic HTTP info
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpServletRequest req = attrs.getRequest();
|
|
||||||
HttpServletResponse resp = attrs.getResponse();
|
|
||||||
|
|
||||||
// BASIC level HTTP data
|
// BASIC level HTTP data
|
||||||
data.put("httpMethod", httpMethod);
|
data.put("httpMethod", httpMethod);
|
||||||
data.put("path", path);
|
data.put("path", path);
|
||||||
|
|
||||||
|
// Get request attributes safely
|
||||||
|
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
if (attrs == null) {
|
||||||
|
return; // No request context available
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServletRequest req = attrs.getRequest();
|
||||||
|
if (req == null) {
|
||||||
|
return; // No request available
|
||||||
|
}
|
||||||
|
|
||||||
// STANDARD level HTTP data
|
// STANDARD level HTTP data
|
||||||
if (auditLevel.includes(AuditLevel.STANDARD)) {
|
if (auditLevel.includes(AuditLevel.STANDARD)) {
|
||||||
data.put("clientIp", req.getRemoteAddr());
|
data.put("clientIp", req.getRemoteAddr());
|
||||||
@ -150,8 +159,53 @@ public class AuditUtils {
|
|||||||
Object[] vals = joinPoint.getArgs();
|
Object[] vals = joinPoint.getArgs();
|
||||||
if (names != null && vals != null) {
|
if (names != null && vals != null) {
|
||||||
IntStream.range(0, names.length)
|
IntStream.range(0, names.length)
|
||||||
.forEach(i -> data.put("arg_" + names[i], vals[i]));
|
.forEach(i -> {
|
||||||
|
if (vals[i] != null) {
|
||||||
|
// Convert objects to safe string representation
|
||||||
|
data.put("arg_" + names[i], safeToString(vals[i], 500));
|
||||||
|
} else {
|
||||||
|
data.put("arg_" + names[i], null);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely convert an object to string with size limiting
|
||||||
|
*
|
||||||
|
* @param obj The object to convert
|
||||||
|
* @param maxLength Maximum length of the resulting string
|
||||||
|
* @return A safe string representation, truncated if needed
|
||||||
|
*/
|
||||||
|
public static String safeToString(Object obj, int maxLength) {
|
||||||
|
if (obj == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
String result;
|
||||||
|
try {
|
||||||
|
// Handle common types directly to avoid toString() overhead
|
||||||
|
if (obj instanceof String) {
|
||||||
|
result = (String) obj;
|
||||||
|
} else if (obj instanceof Number || obj instanceof Boolean) {
|
||||||
|
result = obj.toString();
|
||||||
|
} else if (obj instanceof byte[]) {
|
||||||
|
result = "[binary data length=" + ((byte[]) obj).length + "]";
|
||||||
|
} else {
|
||||||
|
// For complex objects, use toString but handle exceptions
|
||||||
|
result = obj.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate if necessary
|
||||||
|
if (result != null && result.length() > maxLength) {
|
||||||
|
return StringUtils.truncate(result, maxLength - 3) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If toString() fails, return the class name
|
||||||
|
return "[" + obj.getClass().getName() + " - toString() failed]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,20 +217,19 @@ public class AuditUtils {
|
|||||||
* @return true if the method should be audited
|
* @return true if the method should be audited
|
||||||
*/
|
*/
|
||||||
public static boolean shouldAudit(Method method, AuditConfigurationProperties auditConfig) {
|
public static boolean shouldAudit(Method method, AuditConfigurationProperties auditConfig) {
|
||||||
// First check if audit is globally enabled
|
// First check if audit is globally enabled - fast path
|
||||||
if (!auditConfig.isEnabled()) {
|
if (!auditConfig.isEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for annotation override
|
// Check for annotation override
|
||||||
Audited auditedAnnotation = method.getAnnotation(Audited.class);
|
Audited auditedAnnotation = method.getAnnotation(Audited.class);
|
||||||
if (auditedAnnotation != null) {
|
AuditLevel requiredLevel = (auditedAnnotation != null)
|
||||||
// Method has @Audited - check if the specific level is enabled
|
? auditedAnnotation.level()
|
||||||
return auditConfig.isLevelEnabled(auditedAnnotation.level());
|
: AuditLevel.BASIC;
|
||||||
}
|
|
||||||
|
|
||||||
// No annotation - use global level for controllers
|
// Check if the required level is enabled
|
||||||
return auditConfig.isLevelEnabled(AuditLevel.BASIC);
|
return auditConfig.getAuditLevel().includes(requiredLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,7 +251,11 @@ public class AuditUtils {
|
|||||||
|
|
||||||
// Add HTTP status code if available
|
// Add HTTP status code if available
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
|
try {
|
||||||
data.put("statusCode", response.getStatus());
|
data.put("statusCode", response.getStatus());
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore - response might be in an inconsistent state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +277,7 @@ public class AuditUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For HTTP methods, infer based on controller and path
|
// For HTTP methods, infer based on controller and path
|
||||||
if (httpMethod != null) {
|
if (httpMethod != null && path != null) {
|
||||||
String cls = controller.getSimpleName().toLowerCase();
|
String cls = controller.getSimpleName().toLowerCase();
|
||||||
String pkg = controller.getPackage().getName().toLowerCase();
|
String pkg = controller.getPackage().getName().toLowerCase();
|
||||||
|
|
||||||
|
@ -89,7 +89,8 @@ public class ControllerAuditAspect {
|
|||||||
MethodSignature sig = (MethodSignature) joinPoint.getSignature();
|
MethodSignature sig = (MethodSignature) joinPoint.getSignature();
|
||||||
Method method = sig.getMethod();
|
Method method = sig.getMethod();
|
||||||
|
|
||||||
// Use unified check to determine if we should audit
|
// Fast path: check if auditing is enabled before doing any work
|
||||||
|
// This avoids all data collection if auditing is disabled
|
||||||
if (!AuditUtils.shouldAudit(method, auditConfig)) {
|
if (!AuditUtils.shouldAudit(method, auditConfig)) {
|
||||||
return joinPoint.proceed();
|
return joinPoint.proceed();
|
||||||
}
|
}
|
||||||
@ -155,7 +156,8 @@ public class ControllerAuditAspect {
|
|||||||
|
|
||||||
// Add result for VERBOSE level
|
// Add result for VERBOSE level
|
||||||
if (level.includes(AuditLevel.VERBOSE) && result != null) {
|
if (level.includes(AuditLevel.VERBOSE) && result != null) {
|
||||||
data.put("result", result.toString());
|
// Use safe string conversion with size limiting
|
||||||
|
data.put("result", AuditUtils.safeToString(result, 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the event type using the unified method
|
// Resolve the event type using the unified method
|
||||||
|
@ -28,10 +28,15 @@ public class AuditConfigurationProperties {
|
|||||||
applicationProperties.getPremium().getProFeatures().getAudit();
|
applicationProperties.getPremium().getProFeatures().getAudit();
|
||||||
// Read values directly from configuration
|
// Read values directly from configuration
|
||||||
this.enabled = auditConfig.isEnabled();
|
this.enabled = auditConfig.isEnabled();
|
||||||
this.level = auditConfig.getLevel();
|
|
||||||
|
// Ensure level is within valid bounds (0-3)
|
||||||
|
int configLevel = auditConfig.getLevel();
|
||||||
|
this.level = Math.min(Math.max(configLevel, 0), 3);
|
||||||
|
|
||||||
|
// Retention days (0 means infinite)
|
||||||
this.retentionDays = auditConfig.getRetentionDays();
|
this.retentionDays = auditConfig.getRetentionDays();
|
||||||
|
|
||||||
log.debug("Initialized audit configuration: enabled={}, level={}, retentionDays={}",
|
log.debug("Initialized audit configuration: enabled={}, level={}, retentionDays={} (0=infinite)",
|
||||||
this.enabled, this.level, this.retentionDays);
|
this.enabled, this.level, this.retentionDays);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,4 +56,13 @@ public class AuditConfigurationProperties {
|
|||||||
public boolean isLevelEnabled(AuditLevel requiredLevel) {
|
public boolean isLevelEnabled(AuditLevel requiredLevel) {
|
||||||
return enabled && getAuditLevel().includes(requiredLevel);
|
return enabled && getAuditLevel().includes(requiredLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the effective retention period in days
|
||||||
|
* @return The number of days to retain audit records, or -1 for infinite retention
|
||||||
|
*/
|
||||||
|
public int getEffectiveRetentionDays() {
|
||||||
|
// 0 means infinite retention
|
||||||
|
return retentionDays <= 0 ? -1 : retentionDays;
|
||||||
|
}
|
||||||
}
|
}
|
@ -34,8 +34,8 @@ public class AuditService {
|
|||||||
* @param level The minimum audit level required for this event to be logged
|
* @param level The minimum audit level required for this event to be logged
|
||||||
*/
|
*/
|
||||||
public void audit(AuditEventType type, Map<String, Object> data, AuditLevel level) {
|
public void audit(AuditEventType type, Map<String, Object> data, AuditLevel level) {
|
||||||
// Skip auditing if this level is not enabled
|
// Skip auditing if this level is not enabled - check first to avoid further processing
|
||||||
if (!auditConfig.isLevelEnabled(level)) {
|
if (!auditConfig.isEnabled() || !auditConfig.getAuditLevel().includes(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# ── Actuator surface-area hardening ───────────────────────
|
|
||||||
# Enable Prometheus metrics endpoint
|
|
||||||
management.endpoints.web.exposure.include=health,info,metrics,prometheus
|
|
||||||
# Exclude auditevents from exposure
|
|
||||||
management.endpoints.web.exposure.exclude=auditevents
|
|
||||||
# Disable the audit events endpoint completely
|
|
||||||
management.endpoint.auditevents.enabled=false
|
|
||||||
# Configure endpoints
|
|
||||||
management.endpoints.web.base-path=/actuator
|
|
||||||
management.info.env.enabled=true
|
|
||||||
management.endpoint.health.show-details=when_authorized
|
|
||||||
management.endpoint.health.roles=ADMIN
|
|
Loading…
x
Reference in New Issue
Block a user