diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java index cab4519ae7..01270bf671 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java @@ -28,6 +28,7 @@ import jakarta.json.JsonArray; import jakarta.json.JsonValue; import org.apache.commons.lang3.tuple.Pair; +import org.dependencytrack.model.Tag; import org.dependencytrack.model.Component; import org.dependencytrack.model.ComponentIdentity; import org.dependencytrack.model.ComponentOccurrence; @@ -325,11 +326,12 @@ public PaginatedResult getComponentByHash(String hash) { * @return a list of components */ public PaginatedResult getComponents( - ComponentIdentity identity, - Project project, - boolean includeMetrics, - boolean excludeInactiveProjects, - boolean onlyLatestProjectVersions) { + ComponentIdentity identity, + Project project, + boolean includeMetrics, + boolean excludeInactiveProjects, + boolean onlyLatestProjectVersions, + String projectTag) { if (identity == null) { return null; } @@ -347,6 +349,14 @@ public PaginatedResult getComponents( if (onlyLatestProjectVersions) { queryFilterElements.add(" project.isLatest == true "); } + if (projectTag != null && !projectTag.isBlank()) { + final Tag tag = getTagByName(projectTag.trim()); + + if (tag != null) { + queryFilterElements.add(" project.tags.contains(:tag) "); + queryParams.put("tag", tag); + } +} final PaginatedResult result; if (identity.getGroup() != null || identity.getName() != null || identity.getVersion() != null) { diff --git a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java index 24929566d9..d5ad1114a1 100644 --- a/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/apiserver/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -486,16 +486,18 @@ public PaginatedResult getComponentByHash(String hash) { public PaginatedResult getComponents( ComponentIdentity identity, - Project project, - boolean includeMetrics, - boolean excludeInactiveProjects, - boolean onlyLatestProjectVersions) { + Project project, + boolean includeMetrics, + boolean excludeInactiveProjects, + boolean onlyLatestProjectVersions, + String projectTag) { return getComponentQueryManager().getComponents( - identity, - project, - includeMetrics, - excludeInactiveProjects, - onlyLatestProjectVersions); + identity, + project, + includeMetrics, + excludeInactiveProjects, + onlyLatestProjectVersions, + projectTag); } public Component createComponent(Component component, boolean commitIndex) { diff --git a/apiserver/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java b/apiserver/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java index 422909bbc1..19e3814818 100644 --- a/apiserver/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java +++ b/apiserver/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java @@ -228,7 +228,10 @@ public Response getComponentByIdentity(@Parameter(description = "The group of th @Parameter(description = "When true, only return components from active projects") @QueryParam("excludeInactiveProjects") boolean excludeInactiveProjects, @Parameter(description = "When true, only return components from projects flagged as the latest version") - @QueryParam("onlyLatestProjectVersions") boolean onlyLatestProjectVersions) { + @QueryParam("onlyLatestProjectVersions") boolean onlyLatestProjectVersions, +@Parameter(description = "Only return components belonging to projects with the specified tag") +@QueryParam("projectTag") +String projectTag) { try (QueryManager qm = new QueryManager(getAlpineRequest())) { Project project = null; if (projectUuid != null) { @@ -254,11 +257,12 @@ public Response getComponentByIdentity(@Parameter(description = "The group of th return Response.ok().header(TOTAL_COUNT_HEADER, 0).build(); } else { final PaginatedResult result = qm.getComponents( - identity, - project, - /* includeMetrics */ true, - excludeInactiveProjects, - onlyLatestProjectVersions); + identity, + project, + /* includeMetrics */ true, + excludeInactiveProjects, + onlyLatestProjectVersions, + projectTag); return Response.ok(result.getObjects()).header(TOTAL_COUNT_HEADER, result.getTotal()).build(); } }