feat: auto scan plugins
This commit is contained in:
119
src/main/java/com/novitechie/scan/CanaryAutoScanner.java
Normal file
119
src/main/java/com/novitechie/scan/CanaryAutoScanner.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package com.novitechie.scan;
|
||||
|
||||
import com.janetfilter.core.commons.DebugInfo;
|
||||
import com.janetfilter.core.enums.RuleType;
|
||||
import com.janetfilter.core.models.FilterRule;
|
||||
import com.janetfilter.core.plugin.PluginConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class CanaryAutoScanner {
|
||||
private static final List<FilterRule> DEFAULT_SCAN_PLUGINS = Collections.unmodifiableList(Arrays.asList(new FilterRule(RuleType.EQUAL, "izhangzhihao.rainbow.brackets")));
|
||||
private static final List<FilterRule> DEFAULT_SCAN_PACKAGES = Collections.unmodifiableList(Arrays.asList(new FilterRule(RuleType.PREFIX, "com.janetfilter."), new FilterRule(RuleType.PREFIX, "com.novitechie.")));
|
||||
|
||||
private CanaryAutoScanner() {
|
||||
}
|
||||
|
||||
public static final class AutoScanResult {
|
||||
private final List<FilterRule> classRules;
|
||||
private final boolean markerResourceExists;
|
||||
|
||||
private AutoScanResult(List<FilterRule> classRules, boolean markerResourceExists) {
|
||||
this.classRules = classRules == null ? Collections.emptyList() : classRules;
|
||||
this.markerResourceExists = markerResourceExists;
|
||||
}
|
||||
|
||||
public static AutoScanResult empty() {
|
||||
return new AutoScanResult(Collections.emptyList(), false);
|
||||
}
|
||||
|
||||
public List<FilterRule> getClassRules() {
|
||||
return new ArrayList(this.classRules);
|
||||
}
|
||||
|
||||
public boolean isMarkerResourceExists() {
|
||||
return this.markerResourceExists;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<FilterRule> scan(PluginConfig config) {
|
||||
return scanWithResult(config).getClassRules();
|
||||
}
|
||||
|
||||
public static AutoScanResult scanWithResult(PluginConfig config) {
|
||||
List<FilterRule> pluginRules = rules(config, "Auto_Scan_Plugin", DEFAULT_SCAN_PLUGINS);
|
||||
List<FilterRule> packageRules = rules(config, "Auto_Scan_Package", DEFAULT_SCAN_PACKAGES);
|
||||
List<FilterRule> excludeRules = emptyIfNull(config.getBySection("Auto_Scan_Exclude"));
|
||||
if (pluginRules.isEmpty() || packageRules.isEmpty()) {
|
||||
DebugInfo.warn("[PRIVACY-SCAN] Auto scan disabled: plugin or package rules are empty");
|
||||
return AutoScanResult.empty();
|
||||
}
|
||||
List<File> scanTargets = JbDirectoryScanner.getPluginDir(config);
|
||||
if (scanTargets.isEmpty()) {
|
||||
DebugInfo.warn("[PRIVACY-SCAN] No plugin scan targets found");
|
||||
return AutoScanResult.empty();
|
||||
}
|
||||
DebugInfo.output("[PRIVACY-SCAN] Plugin targets: " + fileSummary(scanTargets));
|
||||
DebugInfo.output("[PRIVACY-SCAN] Scan_Plugin: " + ruleSummary(pluginRules));
|
||||
DebugInfo.output("[PRIVACY-SCAN] Scan_Package: " + ruleSummary(packageRules));
|
||||
DebugInfo.output("[PRIVACY-SCAN] Exclude_Package: " + ruleSummary(excludeRules));
|
||||
CanaryScanner.ScanResult result = CanaryScanner.scan(scanTargets, pluginRules, packageRules, excludeRules);
|
||||
List<String> classNames = result.getClassNames();
|
||||
List<FilterRule> classRules = new ArrayList<>(classNames.size());
|
||||
DebugInfo.output("[PRIVACY-SCAN] Found " + classNames.size() + " canary classes");
|
||||
for (String className : classNames) {
|
||||
classRules.add(FilterRule.of("EQUAL", className));
|
||||
DebugInfo.output("[PRIVACY-SCAN] - " + className);
|
||||
}
|
||||
DebugInfo.output("[PRIVACY-SCAN] Marker resource exists: " + result.isMarkerResourceExists());
|
||||
return new AutoScanResult(classRules, result.isMarkerResourceExists());
|
||||
}
|
||||
|
||||
private static List<FilterRule> rules(PluginConfig config, String section, List<FilterRule> defaultValue) {
|
||||
List<FilterRule> configRules = config.getBySection(section);
|
||||
if (hasSection(config, section)) {
|
||||
return emptyIfNull(configRules);
|
||||
}
|
||||
if (defaultValue == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static boolean hasSection(PluginConfig config, String section) {
|
||||
return config.getData() != null && config.getData().containsKey(section);
|
||||
}
|
||||
|
||||
private static List<FilterRule> emptyIfNull(List<FilterRule> rules) {
|
||||
return rules == null ? Collections.emptyList() : rules;
|
||||
}
|
||||
|
||||
private static String fileSummary(List<File> files) {
|
||||
StringBuilder summary = new StringBuilder();
|
||||
for (File file : files) {
|
||||
if (summary.length() > 0) {
|
||||
summary.append(", ");
|
||||
}
|
||||
summary.append(file.getAbsolutePath());
|
||||
}
|
||||
return summary.toString();
|
||||
}
|
||||
|
||||
private static String ruleSummary(List<FilterRule> rules) {
|
||||
if (rules == null || rules.isEmpty()) {
|
||||
return "(none)";
|
||||
}
|
||||
StringBuilder summary = new StringBuilder();
|
||||
for (FilterRule rule : rules) {
|
||||
if (summary.length() > 0) {
|
||||
summary.append(", ");
|
||||
}
|
||||
summary.append(rule);
|
||||
}
|
||||
return summary.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user