diff --git a/src/main/java/org/dependencytrack/model/Vulnerability.java b/src/main/java/org/dependencytrack/model/Vulnerability.java index 7d6fc4766..a284dd167 100644 --- a/src/main/java/org/dependencytrack/model/Vulnerability.java +++ b/src/main/java/org/dependencytrack/model/Vulnerability.java @@ -331,6 +331,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 affectedComponents; @@ -675,6 +679,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; } diff --git a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java index e4e70d943..4ab9d024d 100644 --- a/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/VulnerabilityQueryManager.java @@ -346,7 +346,14 @@ public PaginatedResult getVulnerabilities(Component component, boolean includeSu Map matchedEpssList = getEpssForCveIds( result.getList(Vulnerability.class).stream().map(vuln -> vuln.getVulnId()).distinct().toList()); for (final Vulnerability vulnerability: result.getList(Vulnerability.class)) { - vulnerability.setAffectedProjectCount(this.getAffectedProjects(vulnerability).size()); + List 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)); vulnerability.setEpss(matchedEpssList.get(vulnerability.getVulnId())); } @@ -542,6 +549,7 @@ public List getAffectedProjects(Vulnerability vulnerability) { project.getDirectDependencies() != null, project.getName(), project.getVersion(), + project.isActive(), null )) .collect(Collectors.toMap(affectedProject -> affectedProject.getUuid().toString(), Function.identity())); diff --git a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java index f1cbb510e..023011a0f 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java @@ -210,10 +210,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 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 projects = qm.getAffectedProjects(vulnerability); final long totalCount = projects.size(); return Response.ok(projects).header(TOTAL_COUNT_HEADER, totalCount).build(); @@ -281,7 +288,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) { if (vulnerability == null) { final List cweIds = new ArrayList<>(); if (jsonVulnerability.getCwes() != null) { - for (int i=0; i affectedComponentUuids; - public AffectedProject(UUID uuid, boolean dependencyGraphAvailable, String name, String version, List affectedComponentUuids) { + public AffectedProject(UUID uuid, boolean dependencyGraphAvailable, String name, String version, boolean active, List affectedComponentUuids) { this.uuid = uuid; this.dependencyGraphAvailable = dependencyGraphAvailable; this.name = name; this.version = version; + this.active = active; this.affectedComponentUuids = affectedComponentUuids == null ? new ArrayList<>() : affectedComponentUuids; } @@ -63,6 +66,10 @@ public String getVersion() { return version; } + public boolean getActive() { + return active; + } + public List getAffectedComponentUuids() { return affectedComponentUuids; }