Skip to content

Commit

Permalink
Merge pull request #3425 from setchy/feature/vulnerabilities-active-i…
Browse files Browse the repository at this point in the history
…nactive-toggle

feat(vulnerabilities): enhance API to support frontend changes for active/inactive affected projects
  • Loading branch information
nscuro committed Feb 3, 2024
2 parents e86a17c + 05e4b19 commit 59248a4
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 10 deletions.
20 changes: 20 additions & 0 deletions src/main/java/org/dependencytrack/model/Vulnerability.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ public static boolean isKnownSource(String source) {

private transient int affectedProjectCount;

private transient int affectedActiveProjectCount;

private transient int affectedInactiveProjectCount;

private transient FindingAttribution findingAttribution;

private transient List<AffectedComponent> affectedComponents;
Expand Down Expand Up @@ -646,6 +650,22 @@ public void setAffectedProjectCount(int affectedProjectCount) {
this.affectedProjectCount = affectedProjectCount;
}

public int getAffectedActiveProjectCount() {
return affectedActiveProjectCount;
}

public void setAffectedActiveProjectCount(int affectedActiveProjectCount) {
this.affectedActiveProjectCount = affectedActiveProjectCount;
}

public int getAffectedInactiveProjectCount() {
return affectedInactiveProjectCount;
}

public void setAffectedInactiveProjectCount(int affectedInactiveProjectCount) {
this.affectedInactiveProjectCount = affectedInactiveProjectCount;
}

public FindingAttribution getFindingAttribution() {
return findingAttribution;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,14 @@ public PaginatedResult getVulnerabilities() {
result = execute(query);
}
for (final Vulnerability vulnerability: result.getList(Vulnerability.class)) {
vulnerability.setAffectedProjectCount(this.getAffectedProjects(vulnerability).size());
List<AffectedProject> affectedProjects = this.getAffectedProjects(vulnerability);
int affectedProjectsCount = affectedProjects.size();
int affectedActiveProjectsCount = (int) affectedProjects.stream().filter(AffectedProject::getActive).count();
int affectedInactiveProjectsCount = affectedProjectsCount - affectedActiveProjectsCount;

vulnerability.setAffectedProjectCount(affectedProjectsCount);
vulnerability.setAffectedActiveProjectCount(affectedActiveProjectsCount);
vulnerability.setAffectedInactiveProjectCount(affectedInactiveProjectsCount);
vulnerability.setAliases(getVulnerabilityAliases(vulnerability));
}
return result;
Expand Down Expand Up @@ -494,6 +501,7 @@ public List<AffectedProject> getAffectedProjects(Vulnerability vulnerability) {
project.getDirectDependencies() != null,
project.getName(),
project.getVersion(),
project.isActive(),
null);
affectedProjectMap.put(project.getUuid(), affectedProject);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public Response getVulnerabilitiesByProject(@PathParam("uuid") String uuid,
})
@PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT)
public Response getVulnerabilityByUuid(@ApiParam(value = "The UUID of the vulnerability", required = true)
@PathParam("uuid") String uuid) {
@PathParam("uuid") String uuid) {
try (QueryManager qm = new QueryManager()) {
final Vulnerability vulnerability = qm.getObjectByUuid(Vulnerability.class, uuid);
if (vulnerability != null) {
Expand Down Expand Up @@ -180,7 +180,7 @@ public Response getVulnerabilityByVulnId(@PathParam("source") String source,
final Vulnerability vulnerability = qm.getVulnerabilityByVulnId(source, vuln);
if (vulnerability != null) {
final List<AffectedComponent> affectedComponents = new ArrayList<>();
for (final VulnerableSoftware vs: vulnerability.getVulnerableSoftware()) {
for (final VulnerableSoftware vs : vulnerability.getVulnerableSoftware()) {
AffectedComponent affectedComponent = new AffectedComponent(vs);
final List<AffectedVersionAttribution> attributions = qm.getAffectedVersionAttributions(vulnerability, vs);
affectedComponent.setAffectedVersionAttributions(attributions);
Expand Down Expand Up @@ -209,10 +209,17 @@ public Response getVulnerabilityByVulnId(@PathParam("source") String source,
})
@PermissionRequired(Permissions.Constants.VIEW_PORTFOLIO)
public Response getAffectedProject(@PathParam("source") String source,
@PathParam("vuln") String vuln) {
@PathParam("vuln") String vuln,
@ApiParam(value = "Optionally excludes inactive projects from being returned", required = false)
@QueryParam("excludeInactive") boolean excludeInactive) {
try (QueryManager qm = new QueryManager(getAlpineRequest())) {
final Vulnerability vulnerability = qm.getVulnerabilityByVulnId(source, vuln);
if (vulnerability != null) {
if (excludeInactive) {
final List<AffectedProject> filteredProjects = qm.getAffectedProjects(vulnerability).stream().filter(AffectedProject::getActive).toList();
final long filteredCount = filteredProjects.size();
return Response.ok(filteredProjects).header(TOTAL_COUNT_HEADER, filteredCount).build();
}
final List<AffectedProject> projects = qm.getAffectedProjects(vulnerability);
final long totalCount = projects.size();
return Response.ok(projects).header(TOTAL_COUNT_HEADER, totalCount).build();
Expand Down Expand Up @@ -280,7 +287,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) {
if (vulnerability == null) {
final List<Integer> cweIds = new ArrayList<>();
if (jsonVulnerability.getCwes() != null) {
for (int i=0; i<jsonVulnerability.getCwes().size(); i++) {
for (int i = 0; i < jsonVulnerability.getCwes().size(); i++) {
final Cwe cwe = CweResolver.getInstance().lookup(jsonVulnerability.getCwes().get(i));
if (cwe != null) {
cweIds.add(cwe.getCweId());
Expand All @@ -290,7 +297,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) {
}
final List<VulnerableSoftware> vsList = new ArrayList<>();
if (jsonVulnerability.getAffectedComponents() != null) {
for (final AffectedComponent ac: jsonVulnerability.getAffectedComponents()) {
for (final AffectedComponent ac : jsonVulnerability.getAffectedComponents()) {
final VulnerableSoftware vs = ac.toVulnerableSoftware();
if (vs != null) {
vsList.add(vs);
Expand All @@ -308,7 +315,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) {
} else {
return Response.status(Response.Status.CONFLICT).entity("A vulnerability with the specified vulnId already exists.").build();
}
} catch (MissingFactorException|IllegalArgumentException exception) {
} catch (MissingFactorException | IllegalArgumentException exception) {
return Response.status(Response.Status.BAD_REQUEST).entity(exception.getMessage()).build();
}
}
Expand Down Expand Up @@ -353,7 +360,7 @@ public Response updateVulnerability(Vulnerability jsonVuln) {

final List<Integer> cweIds = new ArrayList<>();
if (jsonVuln.getCwes() != null) {
for (int i=0; i<jsonVuln.getCwes().size(); i++) {
for (int i = 0; i < jsonVuln.getCwes().size(); i++) {
final Cwe cwe = CweResolver.getInstance().lookup(jsonVuln.getCwes().get(i));
if (cwe != null) {
cweIds.add(cwe.getCweId());
Expand All @@ -365,7 +372,7 @@ public Response updateVulnerability(Vulnerability jsonVuln) {
final List<VulnerableSoftware> vsListOld = qm.getVulnerableSoftwareByVulnId(vulnerability.getSource(), vulnerability.getVulnId());
List<VulnerableSoftware> vsList = new ArrayList<>();
if (jsonVuln.getAffectedComponents() != null) {
for (final AffectedComponent ac: jsonVuln.getAffectedComponents()) {
for (final AffectedComponent ac : jsonVuln.getAffectedComponents()) {
final VulnerableSoftware vs = ac.toVulnerableSoftware();
if (vs != null) {
vsList.add(vs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,16 @@ public class AffectedProject {

private final String version;

private final boolean active;

private final List<UUID> affectedComponentUuids;

public AffectedProject(UUID uuid, boolean dependencyGraphAvailable, String name, String version, List<UUID> affectedComponentUuids) {
public AffectedProject(UUID uuid, boolean dependencyGraphAvailable, String name, String version, boolean active, List<UUID> affectedComponentUuids) {
this.uuid = uuid;
this.dependencyGraphAvailable = dependencyGraphAvailable;
this.name = name;
this.version = version;
this.active = active;
this.affectedComponentUuids = affectedComponentUuids == null ? new ArrayList<>() : affectedComponentUuids;
}

Expand All @@ -63,6 +66,10 @@ public String getVersion() {
return version;
}

public boolean getActive() {
return active;
}

public List<UUID> getAffectedComponentUuids() {
return affectedComponentUuids;
}
Expand Down

0 comments on commit 59248a4

Please sign in to comment.