Skip to content

Commit

Permalink
Merge pull request #18 from snyk/fix/handle-license-annotations-with-…
Browse files Browse the repository at this point in the history
…critical

Ignore existing annotations with `critical` license severities
  • Loading branch information
maxjeffos authored Nov 3, 2021
2 parents 3f1f675 + 2c45954 commit 9cc793c
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 32 deletions.
97 changes: 65 additions & 32 deletions plugin/src/main/java/io/snyk/plugins/nexus/util/Formatter.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
package io.snyk.plugins.nexus.util;

import javax.annotation.Nonnull;

import java.util.List;

import io.snyk.plugins.nexus.model.ScanResult;
import io.snyk.sdk.model.Issue;
import io.snyk.sdk.model.Severity;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static io.snyk.sdk.util.Predicates.distinctByKey;

public final class Formatter {

private static final Pattern ISSUES_WITH_CRITICAL_REGEX = Pattern.compile("(\\d+) critical, (\\d+) high, (\\d+) medium, (\\d+) low");
private static final Pattern ISSUES_WITHOUT_CRITICAL_REGEX = Pattern.compile("(\\d+) high, (\\d+) medium, (\\d+) low");

private Formatter() {
}

public static long getIssuesCountBySeverity(@Nonnull List<? extends Issue> issues, @Nonnull Severity severity) {
return issues.stream()
.filter(issue -> issue.severity == severity)
.filter(distinctByKey(issue -> issue.id))
.count();
.filter(issue -> issue.severity == severity)
.filter(distinctByKey(issue -> issue.id))
.count();
}

public static String getVulnerabilityIssuesAsFormattedString(@Nonnull ScanResult scanResult) {
Expand All @@ -38,24 +44,12 @@ public static void enrichScanResultWithVulnerabilityIssues(@Nonnull ScanResult s
return;
}

String[] parts = formattedIssues.split(", ");

int i = 0;
if (parts.length == 4) {
String critical = parts[i].replace(" critical", "");
scanResult.criticalVulnerabilityIssueCount = Long.parseLong(critical);
i++;
}
String high = parts[i].replace(" high", "");
scanResult.highVulnerabilityIssueCount = Long.parseLong(high);
i++;

String medium = parts[i].replace(" medium", "");
scanResult.mediumVulnerabilityIssueCount = Long.parseLong(medium);
i++;

String low = parts[i].replace(" low", "");
scanResult.lowVulnerabilityIssueCount = Long.parseLong(low);
IssueCounts issueCounts = getIssueCountsFromFormattedString(formattedIssues)
.orElseThrow(() -> new RuntimeException(String.format("Invalid format for vulnerability issues: %s", formattedIssues)));
scanResult.criticalVulnerabilityIssueCount = issueCounts.critical.orElse(Long.valueOf(0));
scanResult.highVulnerabilityIssueCount = issueCounts.high;
scanResult.mediumVulnerabilityIssueCount = issueCounts.medium;
scanResult.lowVulnerabilityIssueCount = issueCounts.low;
}

public static void enrichScanResultWithLicenseIssues(@Nonnull ScanResult scanResult, String formattedIssues) {
Expand All @@ -66,15 +60,54 @@ public static void enrichScanResultWithLicenseIssues(@Nonnull ScanResult scanRes
return;
}

String[] parts = formattedIssues.split(", ");
IssueCounts issueCounts = getIssueCountsFromFormattedString(formattedIssues)
.orElseThrow(() -> new RuntimeException(String.format("Invalid format for license issues: %s", formattedIssues)));
// regardless of if critical is present or not, we ignore it
scanResult.highLicenseIssueCount = issueCounts.high;
scanResult.mediumLicenseIssueCount = issueCounts.medium;
scanResult.lowLicenseIssueCount = issueCounts.low;
}

public static Optional<IssueCounts> getIssueCountsFromFormattedString(String formattedIssues) {
Matcher issuesWithCriticalMatch = ISSUES_WITH_CRITICAL_REGEX.matcher(formattedIssues);
if (issuesWithCriticalMatch.matches()) {
return Optional.of(new IssueCounts(
issuesWithCriticalMatch.group(1),
issuesWithCriticalMatch.group(2),
issuesWithCriticalMatch.group(3),
issuesWithCriticalMatch.group(4)
));
}

Matcher issuesWithoutCriticalMatch = ISSUES_WITHOUT_CRITICAL_REGEX.matcher(formattedIssues);
if (issuesWithoutCriticalMatch.matches()) {
return Optional.of(new IssueCounts(
issuesWithoutCriticalMatch.group(1),
issuesWithoutCriticalMatch.group(2),
issuesWithoutCriticalMatch.group(3)
));
}

String high = parts[0].replace(" high", "");
scanResult.highLicenseIssueCount = Long.parseLong(high);
return Optional.empty();
}
}

String medium = parts[1].replace(" medium", "");
scanResult.mediumLicenseIssueCount = Long.parseLong(medium);
class IssueCounts {
Optional<Long> critical = Optional.empty();
long high = 0;
long medium = 0;
long low = 0;

IssueCounts(String critical, String high, String medium, String low) {
this.critical = Optional.of(Long.parseLong(critical));
this.high = Long.parseLong(high);
this.medium = Long.parseLong(medium);
this.low = Long.parseLong(low);
}

String low = parts[2].replace(" low", "");
scanResult.lowLicenseIssueCount = Long.parseLong(low);
IssueCounts(String high, String medium, String low) {
this.high = Long.parseLong(high);
this.medium = Long.parseLong(medium);
this.low = Long.parseLong(low);
}
}
46 changes: 46 additions & 0 deletions plugin/src/test/java/io/snyk/plugins/nexus/util/FormatterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import io.snyk.plugins.nexus.model.ScanResult;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class FormatterTest {

Expand Down Expand Up @@ -78,6 +80,20 @@ void enrichScanResultWithVulnerabilityIssues() {
});
}

@Test
void enrichScanResultWithVulnerabilityIssuesThrowsIfInvalidFormat() {
ScanResult scanResult = new ScanResult();
RuntimeException e = assertThrows(RuntimeException.class, () -> Formatter.enrichScanResultWithVulnerabilityIssues(scanResult, "10 super, 15 elite, 20 fantastic"));
assertEquals(e.getMessage(), "Invalid format for vulnerability issues: 10 super, 15 elite, 20 fantastic");
}

@Test
void enrichScanResultWithVulnerabilityIssuesThrowsIfInvalidValues() {
ScanResult scanResult = new ScanResult();
RuntimeException e = assertThrows(RuntimeException.class, () -> Formatter.enrichScanResultWithVulnerabilityIssues(scanResult, "a critical, b high, c medium, d low"));
assertEquals(e.getMessage(), "Invalid format for vulnerability issues: a critical, b high, c medium, d low");
}

@Test
void enrichScanResultWithLicenseIssues_null() {
// given
Expand Down Expand Up @@ -128,4 +144,34 @@ void enrichScanResultWithLicenseIssues() {
});
}

@Test
void enrichScanResultWithLicenseIssuesWhenFormattedIssuesContainsCritical() {
ScanResult scanResult = new ScanResult();

// when
Formatter.enrichScanResultWithLicenseIssues(scanResult, "6 critical, 10 high, 0 medium, 25 low");

// then
Assertions.assertAll(
() -> {
Assertions.assertEquals(10, scanResult.highLicenseIssueCount);
Assertions.assertEquals(0, scanResult.mediumLicenseIssueCount);
Assertions.assertEquals(25, scanResult.lowLicenseIssueCount);
});
}

@Test
void enrichScanResultWithLicenseIssuesThrowsIfInvalidFormat() {
ScanResult scanResult = new ScanResult();
RuntimeException e = assertThrows(RuntimeException.class, () -> Formatter.enrichScanResultWithLicenseIssues(scanResult, "10 super, 15 elite, 20 fantastic"));
assertEquals(e.getMessage(), "Invalid format for license issues: 10 super, 15 elite, 20 fantastic");
}

@Test
void enrichScanResultWithLicenseIssuesThrowsIfInvalidValues() {
ScanResult scanResult = new ScanResult();
RuntimeException e = assertThrows(RuntimeException.class, () -> Formatter.enrichScanResultWithLicenseIssues(scanResult, "x critical, y high, 0 medium, z low"));
assertEquals(e.getMessage(), "Invalid format for license issues: x critical, y high, 0 medium, z low");
}

}

0 comments on commit 9cc793c

Please sign in to comment.