feat: add AI-based security suggestion engine and CLI integration
Introduce new package org.egothor.methodatlas.ai providing AI-assisted classification of JUnit tests for security relevance. Key changes: - add AI suggestion engine, provider abstraction, and provider clients (OpenAI-compatible, Ollama, Anthropic) - implement strict JSON prompt/response contract and taxonomy handling - integrate AI enrichment into MethodAtlas CLI output (CSV and plain modes) - add configuration via AiOptions and CLI flags - add comprehensive JUnit + Mockito test coverage for AI components and CLI integration scenarios - add realistic test fixtures for security-related test classes - update Gradle configuration for Mockito agent support on JDK 21+ - provide complete Javadoc for the AI module The AI layer is optional and degrades gracefully when providers are unavailable or responses fail.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package com.acme.storage;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PathTraversalValidationTest {
|
||||
|
||||
@Test
|
||||
@Tag("security")
|
||||
@Tag("validation")
|
||||
void shouldRejectRelativePathTraversalSequence() {
|
||||
String userInput = "../secrets.txt";
|
||||
|
||||
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
|
||||
if (userInput.contains("..")) {
|
||||
throw new IllegalArgumentException("Path traversal attempt detected");
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals("Path traversal attempt detected", ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Tag("security")
|
||||
@Tag("validation")
|
||||
void shouldRejectNestedTraversalAfterNormalization() {
|
||||
String userInput = "reports/../../admin/keys.txt";
|
||||
Path normalized = Path.of("/srv/app/uploads").resolve(userInput).normalize();
|
||||
|
||||
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
|
||||
if (!normalized.startsWith(Path.of("/srv/app/uploads"))) {
|
||||
throw new IllegalArgumentException("Escaped upload root");
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals("Escaped upload root", ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Tag("security")
|
||||
@Tag("validation")
|
||||
void shouldAllowSafePathInsideUploadRoot() {
|
||||
String userInput = "reports/2026/statement.pdf";
|
||||
Path normalized = Path.of("/srv/app/uploads").resolve(userInput).normalize();
|
||||
|
||||
boolean allowed = normalized.startsWith(Path.of("/srv/app/uploads"));
|
||||
|
||||
assertEquals(true, allowed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBuildDownloadFileName() {
|
||||
String accountId = "ACC-42";
|
||||
String fileName = accountId + "-statement.pdf";
|
||||
|
||||
assertEquals("ACC-42-statement.pdf", fileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user