Skip to content

Commit 64cafcc

Browse files
authored
Add support for exclude pattern in cli driver (#179)
1 parent 64ab4cc commit 64cafcc

File tree

3 files changed

+151
-15
lines changed

3 files changed

+151
-15
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.jfrog.ide.common.configuration;
2+
3+
import lombok.Getter;
4+
5+
import java.util.List;
6+
import java.util.Map;
7+
8+
@Getter
9+
public class AuditConfig {
10+
// Getters
11+
private final List<String> scannedDirectories;
12+
private final String serverId;
13+
private final List<String> excludedPattern;
14+
private final Map<String, String> envVars;
15+
16+
private AuditConfig(Builder builder) {
17+
this.scannedDirectories = builder.scannedDirectories;
18+
this.serverId = builder.serverId;
19+
this.excludedPattern = builder.excludedPattern;
20+
this.envVars = builder.envVars;
21+
}
22+
23+
public static class Builder {
24+
private List<String> scannedDirectories;
25+
private String serverId;
26+
private List<String> excludedPattern;
27+
private Map<String, String> envVars;
28+
29+
public Builder serverId(String serverId) {
30+
this.serverId = serverId;
31+
return this;
32+
}
33+
34+
public Builder scannedDirectories(List<String> scannedDirectories) {
35+
this.scannedDirectories = scannedDirectories;
36+
return this;
37+
}
38+
39+
public Builder excludedPattern(List<String> excludedPattern) {
40+
this.excludedPattern = excludedPattern;
41+
return this;
42+
}
43+
44+
public Builder envVars(Map<String, String> envVars) {
45+
this.envVars = envVars;
46+
return this;
47+
}
48+
49+
public AuditConfig build() {
50+
return new AuditConfig(this);
51+
}
52+
}
53+
54+
}

src/main/java/com/jfrog/ide/common/configuration/JfrogCliDriver.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,36 @@ public CommandResults addCliServerConfig(String xrayUrl, String artifactoryUrl,
182182
}
183183
}
184184

185-
public CommandResults runCliAudit(File workingDirectory, List<String> scannedDirectories, String serverId, List<String> extraArgs, Map<String, String> envVars) throws Exception {
185+
public CommandResults runCliAudit(File workingDirectory, List<String> scannedDirectories, String serverId, Map<String, String> envVars) throws Exception {
186+
AuditConfig config = new AuditConfig.Builder()
187+
.scannedDirectories(scannedDirectories)
188+
.serverId(serverId)
189+
.envVars(envVars)
190+
.build();
191+
return runCliAudit(workingDirectory, config);
192+
}
193+
194+
public CommandResults runCliAudit(File workingDirectory, AuditConfig config) throws Exception {
186195
List<String> args = new ArrayList<>();
187196
args.add("audit");
188-
if (scannedDirectories != null && !scannedDirectories.isEmpty()) {
189-
String workingDirsString = scannedDirectories.size() > 1 ? String.join(", ", scannedDirectories) : scannedDirectories.get(0);
190-
args.add("--working-dirs=" + workingDirsString);
197+
198+
if (config.getScannedDirectories() != null && !config.getScannedDirectories().isEmpty()) {
199+
String workingDirsString = config.getScannedDirectories().size() > 1 ?
200+
String.join(", ", config.getScannedDirectories()) :
201+
config.getScannedDirectories().get(0);
202+
args.add("--working-dirs=" + quoteArgumentForUnix(workingDirsString));
191203
}
192-
args.add("--server-id=" + serverId);
204+
205+
args.add("--server-id=" + config.getServerId());
193206
args.add("--format=sarif");
207+
208+
if (config.getExcludedPattern() != null && !config.getExcludedPattern().isEmpty()) {
209+
String excludedPatterns = String.join(",", config.getExcludedPattern());
210+
args.add("--exclusions=" + quoteArgumentForUnix(excludedPatterns));
211+
}
212+
194213
try {
195-
return runCommand(workingDirectory, envVars, args.toArray(new String[0]), extraArgs != null ? extraArgs : Collections.emptyList(), null, log);
214+
return runCommand(workingDirectory, config.getEnvVars(), args.toArray(new String[0]), Collections.emptyList(), null, log);
196215
} catch (IOException | InterruptedException e) {
197216
throw new Exception("Failed to run JF audit. Reason: " + e.getMessage(), e);
198217
}
@@ -218,4 +237,9 @@ private void addDefaultEnvVars(Map<String, String> env) {
218237
env.put("JFROG_CLI_AVOID_NEW_VERSION_WARNING", "true");
219238
}
220239
}
240+
241+
private String quoteArgumentForUnix(String commaSeparatedValues) {
242+
// macOS/Linux: add quotes around the comma-separated values
243+
return SystemUtils.IS_OS_WINDOWS ? commaSeparatedValues : "\"" + commaSeparatedValues + "\"";
244+
}
221245
}

src/test/java/com/jfrog/ide/common/configuration/JfrogCliDriverTest.java

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
package com.jfrog.ide.common.configuration;
22

3+
import com.jfrog.ide.common.nodes.FileIssueNode;
4+
import com.jfrog.ide.common.nodes.FileTreeNode;
5+
import com.jfrog.ide.common.nodes.subentities.Severity;
6+
import com.jfrog.ide.common.nodes.subentities.SourceCodeScanType;
7+
import com.jfrog.ide.common.parse.SarifParser;
38
import org.apache.commons.lang3.SystemUtils;
49
import org.jfrog.build.api.util.NullLog;
510
import org.jfrog.build.extractor.executor.CommandResults;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
613
import org.testng.annotations.AfterMethod;
714
import org.testng.annotations.BeforeMethod;
815
import org.testng.annotations.Test;
@@ -19,7 +26,6 @@
1926
import java.text.SimpleDateFormat;
2027
import java.util.*;
2128

22-
import static java.util.Collections.singletonList;
2329
import static org.testng.Assert.*;
2430

2531
/**
@@ -40,6 +46,8 @@ public class JfrogCliDriverTest {
4046
private final String XRAY_URL = SERVER_URL + "xray/";
4147
private String testServerId;
4248
private File tempDir;
49+
private final SarifParser parser = new SarifParser(new NullLog());
50+
private final Logger logger = LoggerFactory.getLogger(JfrogCliDriverTest.class);
4351

4452
@SuppressWarnings("unused")
4553
@Test()
@@ -82,6 +90,8 @@ private void configJfrogCli(Boolean skipDownload) {
8290
fail(e.getMessage(), e);
8391
}
8492
testEnv.put("JFROG_CLI_HOME_DIR", tempDir.getAbsolutePath());
93+
testEnv.put("JFROG_CLI_LOG_LEVEL", "DEBUG");
94+
testEnv.put("CI", "true");
8595
jfrogCliDriver = new JfrogCliDriver(testEnv, tempDir.getAbsolutePath() + File.separator, new NullLog());
8696
}
8797

@@ -152,7 +162,6 @@ public void testAddCliServerConfig_withUsernameAndPassword() {
152162
CommandResults response = jfrogCliDriver.addCliServerConfig(XRAY_URL, ARTIFACTORY_URL, testServerId, USER_NAME, PASSWORD, null, tempDir, testEnv);
153163
JfrogCliServerConfig serverConfig = jfrogCliDriver.getServerConfig(tempDir, Collections.emptyList(), testEnv);
154164
assertTrue(response.isOk());
155-
assertTrue(response.getErr().isBlank());
156165
assertNotNull(serverConfig);
157166
assertEquals(serverConfig.getUsername(), USER_NAME);
158167
assertEquals(serverConfig.getPassword(), PASSWORD);
@@ -169,7 +178,6 @@ public void testAddCliServerConfig_withAccessToken() {
169178
CommandResults response = jfrogCliDriver.addCliServerConfig(XRAY_URL, ARTIFACTORY_URL, testServerId, null, null, ACCESS_TOKEN, tempDir, testEnv);
170179
JfrogCliServerConfig serverConfig = jfrogCliDriver.getServerConfig(tempDir, Collections.emptyList(), testEnv);
171180
assertTrue(response.isOk());
172-
assertTrue(response.getErr().isBlank());
173181
assertNotNull(serverConfig);
174182
assertEquals(serverConfig.getAccessToken(), ACCESS_TOKEN);
175183
assertEquals(serverConfig.getArtifactoryUrl(), ARTIFACTORY_URL);
@@ -195,13 +203,23 @@ public void testAddServerConfig_withBadCredentials() {
195203

196204
@Test
197205
public void testRunAudit_NpmProject() {
198-
String projectToCheck = "npm";
199206
try {
200207
Path exampleProjectsFolder = Path.of("src/test/resources/example-projects/npm");
201208
CommandResults response = jfrogCliDriver.runCliAudit(exampleProjectsFolder.toFile(),
202-
singletonList(projectToCheck), testServerId, null, testEnv);
203-
//TODO: check real values after the sarif parser is added
209+
null, testServerId, testEnv);
204210
assertEquals(response.getExitValue(),0);
211+
logger.info("Audit debug logs: \n" + response.getErr());
212+
logger.info("Audit response: \n" + response.getRes());
213+
List<FileTreeNode> findings = parser.parse(response.getRes());
214+
assertNotNull(findings);
215+
assertFalse(findings.isEmpty(), "Expected findings in SARIF output for npm project");
216+
// Verify the findings
217+
assertEquals(findings.size(), 1, "Expected exactly one file with findings");
218+
FileTreeNode node = findings.get(0);
219+
assertEquals(node.getChildren().size(), 1, "Expected exactly one vulnerabilities");
220+
FileIssueNode issue = (FileIssueNode) node.getChildren().get(0);
221+
assertEquals(issue.getSeverity(), Severity.High, "Expected severity to be HIGH");
222+
assertEquals(issue.getReporterType(), SourceCodeScanType.SCA, "Expected reporter type to be SCA");
205223
} catch (Exception e) {
206224
fail(e.getMessage(), e);
207225
}
@@ -213,9 +231,20 @@ public void testRunAudit_MultiMavenProject() {
213231
try {
214232
Path exampleProjectsFolder = Path.of("src/test/resources/example-projects/maven-example");
215233
CommandResults response = jfrogCliDriver.runCliAudit(exampleProjectsFolder.toFile(),
216-
projectsToCheck, testServerId, null, testEnv);
217-
//TODO: check real values after the sarif parser is added
234+
projectsToCheck, testServerId, testEnv);
218235
assertEquals(response.getExitValue(), 0);
236+
logger.info("Audit debug logs: \n" + response.getErr());
237+
logger.info("Audit response: \n" + response.getRes());
238+
List<FileTreeNode> findings = parser.parse(response.getRes());
239+
assertNotNull(findings);
240+
assertFalse(findings.isEmpty(), "Expected findings in SARIF output for multi-maven project");
241+
// Verify the findings
242+
assertEquals(findings.size(), 1, "Expected exactly one file with findings");
243+
FileTreeNode node = findings.get(0);
244+
assertEquals(node.getChildren().size(), 3, "Expected exactly three vulnerabilities");
245+
assertEquals(node.getSeverity(), Severity.High, "Expected severity to be HIGH");
246+
FileIssueNode issue = (FileIssueNode) node.getChildren().get(0);
247+
assertEquals(issue.getReporterType(), SourceCodeScanType.SCA, "Expected reporter type to be SCA");
219248
} catch (Exception e) {
220249
fail(e.getMessage(), e);
221250
}
@@ -225,6 +254,35 @@ private String createServerId() {
225254
return "ide-plugins-common-test-server-" + timeStampFormat.format(System.currentTimeMillis());
226255
}
227256

257+
@Test
258+
public void testRunAudit_WithExcludedPattern() {
259+
try {
260+
Path exampleProjectsFolder = Path.of("src/test/resources/example-projects/maven-example");
261+
AuditConfig config = new AuditConfig.Builder()
262+
.serverId(testServerId)
263+
.excludedPattern(new ArrayList<>(List.of("*multi3*")))
264+
.serverId(testServerId)
265+
.envVars(testEnv)
266+
.build();
267+
CommandResults response = jfrogCliDriver.runCliAudit(exampleProjectsFolder.toFile(), config);
268+
assertEquals(response.getExitValue(), 0);
269+
logger.info("Audit debug logs: \n" + response.getErr());
270+
logger.info("Audit response: \n" + response.getRes());
271+
List<FileTreeNode> findings = parser.parse(response.getRes());
272+
assertNotNull(findings);
273+
assertFalse(findings.isEmpty(), "Expected findings in SARIF output for multi-maven project");
274+
// Verify the findings
275+
assertEquals(findings.size(), 1, "Expected exactly one file with findings");
276+
FileTreeNode node = findings.get(0);
277+
assertEquals(node.getChildren().size(), 3, "Expected exactly three vulnerabilities");
278+
assertEquals(node.getSeverity(), Severity.High, "Expected severity to be HIGH");
279+
FileIssueNode issue = (FileIssueNode) node.getChildren().get(0);
280+
assertEquals(issue.getReporterType(), SourceCodeScanType.SCA, "Expected reporter type to be SCA");
281+
} catch (Exception e) {
282+
fail(e.getMessage(), e);
283+
}
284+
}
285+
228286
@AfterMethod
229287
public void cleanUp(Method method) {
230288
try {
@@ -236,4 +294,4 @@ public void cleanUp(Method method) {
236294
fail(e.getMessage(), e);
237295
}
238296
}
239-
}
297+
}

0 commit comments

Comments
 (0)