1
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
package com.yunhai.bschclassmanage.utils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* GZIP 压缩/解压,用于审计日志响应体(MEDIUMBLOB)存储。
|
||||
*/
|
||||
public class GzipUtil {
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
public static byte[] compress(String data) {
|
||||
if (data == null) return null;
|
||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(out)) {
|
||||
gzip.write(data.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.finish();
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("GZIP 压缩失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String decompress(byte[] data) {
|
||||
if (data == null || data.length == 0) return null;
|
||||
try (ByteArrayInputStream in = new ByteArrayInputStream(data);
|
||||
GZIPInputStream gzip = new GZIPInputStream(in);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
byte[] buf = new byte[BUFFER_SIZE];
|
||||
int n;
|
||||
while ((n = gzip.read(buf)) > 0) out.write(buf, 0, n);
|
||||
return out.toString(StandardCharsets.UTF_8.name());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("GZIP 解压失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.yunhai.bschclassmanage.utils;
|
||||
|
||||
import com.yunhai.bschclassmanage.enums.LogLevel;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* 审计日志级别/类型解析:根据 HTTP 方法 + URI + 方法名推断。
|
||||
* 对齐本项目命名(save/import/upload 视为新增,delete/del/remove 视为删除)。
|
||||
*/
|
||||
public class OperationLogResolver {
|
||||
private static final String[] DELETE_KEYWORDS = {"delete", "del", "remove"};
|
||||
private static final String[] CREATE_KEYWORDS = {"add", "create", "insert", "save", "import", "upload"};
|
||||
|
||||
public static LogLevel resolveLevel(String httpMethod, String uri, String methodName) {
|
||||
if (StringUtils.isBlank(httpMethod)) return LogLevel.SECONDARY;
|
||||
String m = httpMethod.toUpperCase();
|
||||
if ("GET".equals(m)) return LogLevel.GENERAL;
|
||||
if ("DELETE".equals(m)) return LogLevel.IMPORTANT;
|
||||
if (containsAny(uri, methodName, DELETE_KEYWORDS)) return LogLevel.IMPORTANT;
|
||||
return LogLevel.SECONDARY;
|
||||
}
|
||||
|
||||
public static String resolveOperationType(String httpMethod, String uri, String methodName) {
|
||||
if (StringUtils.isBlank(httpMethod)) return "UPDATE";
|
||||
String m = httpMethod.toUpperCase();
|
||||
if ("GET".equals(m)) return "QUERY";
|
||||
if ("DELETE".equals(m)) return "DELETE";
|
||||
if (containsAny(uri, methodName, DELETE_KEYWORDS)) return "DELETE";
|
||||
if (containsAny(uri, methodName, CREATE_KEYWORDS)) return "CREATE";
|
||||
return "UPDATE";
|
||||
}
|
||||
|
||||
private static boolean containsAny(String uri, String methodName, String[] keywords) {
|
||||
String text = StringUtils.lowerCase(uri) + " " + StringUtils.lowerCase(methodName);
|
||||
for (String kw : keywords) if (StringUtils.contains(text, kw)) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.yunhai.bschclassmanage.utils;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 日志脱敏:对 request_params / response_data 中的敏感字段值掩码为 ***
|
||||
* 默认敏感字段:password,pwd,secret,token,appSecret,accessKey,idCard,phone,mobile,credential
|
||||
* 脱敏失败返回原文,绝不阻断主流程。
|
||||
*/
|
||||
public class SensitiveDataUtil {
|
||||
|
||||
private static volatile Set<String> SENSITIVE_KEYS = new HashSet<>(Arrays.asList(
|
||||
"password", "pwd", "pass", "secret", "token", "appsecret", "accesskey",
|
||||
"idcard", "phone", "mobile", "credential"
|
||||
));
|
||||
|
||||
private static volatile Pattern FIELD_PATTERN = buildPattern();
|
||||
|
||||
private static Pattern buildPattern() {
|
||||
return Pattern.compile(
|
||||
"(\"(?i:(" + String.join("|", SENSITIVE_KEYS) + "))\"\\s*:\\s*)\"?[^,}\\s\"]+\"?",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
public static void setSensitiveKeys(Set<String> keys) {
|
||||
if (keys != null && !keys.isEmpty()) {
|
||||
SENSITIVE_KEYS = new HashSet<>(keys);
|
||||
FIELD_PATTERN = buildPattern();
|
||||
}
|
||||
}
|
||||
|
||||
public static String mask(String json) {
|
||||
if (StringUtils.isBlank(json)) return json;
|
||||
try {
|
||||
Matcher m = FIELD_PATTERN.matcher(json);
|
||||
return m.replaceAll("$1\"***\"");
|
||||
} catch (Exception e) {
|
||||
return json;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user