diff options
author | Havoc Pennington <hp@pobox.com> | 2025-03-07 10:43:52 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2025-03-08 20:03:09 +0000 |
commit | 0e77c2d0ebcf094399d67bc725387e2ab0a40a08 (patch) | |
tree | 8785dea5aeeb21d0e8ba5015f0585d9f4f0895a4 /server/sonar-db-dao | |
parent | 09bd736d1b5017bf3ad2b76fffc608c937bdaa16 (diff) | |
download | sonarqube-0e77c2d0ebcf094399d67bc725387e2ab0a40a08.tar.gz sonarqube-0e77c2d0ebcf094399d67bc725387e2ab0a40a08.zip |
SQRP-308 add the newInPullRequest filter to releases and risks endpoints
Also, default it to true on pull requests.
Diffstat (limited to 'server/sonar-db-dao')
12 files changed, 94 insertions, 43 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java index 42eba53cfb8..cd5ebb31ee7 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDaoIT.java @@ -57,8 +57,8 @@ class ScaIssuesReleasesDetailsDaoIT { void selectByBranchUuid_shouldReturnIssues() { var projectData = db.components().insertPrivateProject(); var componentDto = projectData.getMainBranchComponent(); - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid(), projectData.projectUuid()); - var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid(), projectData.projectUuid()); + var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid()); + var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid()); var foundPage = scaIssuesReleasesDetailsDao.selectByBranchUuid(db.getSession(), componentDto.branchUuid(), Pagination.forPage(1).andSize(1)); @@ -68,6 +68,7 @@ class ScaIssuesReleasesDetailsDaoIT { issue1.scaIssueUuid(), issue1.scaReleaseUuid(), ScaIssueType.VULNERABILITY, + false, "fakePackageUrl1", "fakeVulnerabilityId1", ScaIssueDto.NULL_VALUE, @@ -80,6 +81,7 @@ class ScaIssuesReleasesDetailsDaoIT { issue2.scaIssueUuid(), issue2.scaReleaseUuid(), ScaIssueType.PROHIBITED_LICENSE, + false, ScaIssueDto.NULL_VALUE, ScaIssueDto.NULL_VALUE, "0BSD", @@ -279,6 +281,28 @@ class ScaIssuesReleasesDetailsDaoIT { } @Test + void withQueryFilteredByNewInPullRequest_shouldReturnExpectedItems() { + QueryTestData testData = createQueryTestData(); + + var expectedNew = testData.expectedIssuesSortedByIdentityAsc().stream() + .filter(issue -> issue.newInPullRequest()) + .toList(); + var expectedNotNew = testData.expectedIssuesSortedByIdentityAsc().stream() + .filter(issue -> !issue.newInPullRequest()) + .toList(); + + executeQueryTest(testData, + queryBuilder -> queryBuilder.setNewInPullRequest(true), + expectedNew, + "Only the releases marked newInPullRequest should be returned"); + + executeQueryTest(testData, + queryBuilder -> queryBuilder.setNewInPullRequest(false), + expectedNotNew, + "Only the releases marked not newInPullRequest should be returned"); + } + + @Test void withQueryFilteredBySeverity_shouldReturnExpectedItems() { QueryTestData testData = createQueryTestData(); var expectedSeverityInfo = testData.expectedIssuesSortedByIdentityAsc().stream() @@ -414,35 +438,35 @@ class ScaIssuesReleasesDetailsDaoIT { var projectData = db.components().insertPrivateProject(); var componentDto = projectData.getMainBranchComponent(); // the first two are set to NPM, the others default to MAVEN - var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid(), projectData.projectUuid(), + var issue1 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "1", componentDto.uuid(), scaIssueDto -> scaIssueDto, scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto, scaReleaseDto -> scaReleaseDto.toBuilder().setPackageManager(PackageManager.NPM).build(), scaIssueReleaseDto -> scaIssueReleaseDto); - var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid(), projectData.projectUuid(), + var issue2 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "2", componentDto.uuid(), scaIssueDto -> scaIssueDto, scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto, scaReleaseDto -> scaReleaseDto.toBuilder().setPackageManager(PackageManager.NPM).build(), scaIssueReleaseDto -> scaIssueReleaseDto); - var issue3 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "3", componentDto.uuid(), projectData.projectUuid()); - var issue4 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "4", componentDto.uuid(), projectData.projectUuid()); + var issue3 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "3", componentDto.uuid()); + var issue4 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.PROHIBITED_LICENSE, "4", componentDto.uuid()); // low cvss but high severity - var issue5 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "5", componentDto.uuid(), projectData.projectUuid(), + var issue5 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "5", componentDto.uuid(), scaIssueDto -> scaIssueDto, scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto.toBuilder() .setCvssScore(new BigDecimal("2.1")) .setBaseSeverity(ScaSeverity.BLOCKER) .build(), - scaReleaseDto -> scaReleaseDto, + scaReleaseDto -> scaReleaseDto.toBuilder().setNewInPullRequest(true).build(), scaIssueReleaseDto -> scaIssueReleaseDto.toBuilder().setSeverity(ScaSeverity.BLOCKER).build()); // high cvss but low severity - var issue6 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "6", componentDto.uuid(), projectData.projectUuid(), + var issue6 = db.getScaIssuesReleasesDetailsDbTester().insertIssue(ScaIssueType.VULNERABILITY, "6", componentDto.uuid(), scaIssueDto -> scaIssueDto, scaVulnerabilityIssueDto -> scaVulnerabilityIssueDto.toBuilder() .setCvssScore(new BigDecimal("9.1")) .setBaseSeverity(ScaSeverity.INFO) .build(), - scaReleaseDto -> scaReleaseDto, + scaReleaseDto -> scaReleaseDto.toBuilder().setNewInPullRequest(true).build(), scaIssueReleaseDto -> scaIssueReleaseDto.toBuilder().setSeverity(ScaSeverity.INFO).build()); return new QueryTestData(projectData, componentDto, diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java index 3c56f96ffb3..6bd14b26948 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/sca/ScaReleasesDaoIT.java @@ -120,7 +120,7 @@ class ScaReleasesDaoIT { ComponentDto componentDto = prepareComponentDto("1"); ScaReleaseDto scaReleaseDto = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "1"); - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null); + ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null); List<ScaReleaseDto> results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.all()); assertThat(results).hasSize(1); @@ -135,7 +135,7 @@ class ScaReleasesDaoIT { ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3"); ScaReleaseDto scaReleaseDto4 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "4"); - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null); + ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, null); List<ScaReleaseDto> page1Results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.forPage(1).andSize(2)); List<ScaReleaseDto> page2Results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.forPage(2).andSize(2)); @@ -170,14 +170,14 @@ class ScaReleasesDaoIT { @SuppressWarnings("unused") ScaReleaseDto scaReleaseDto4 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "4", PackageManager.MAVEN, "some.foo.bar"); - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, "foo.bar"); + ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, "foo.bar"); List<ScaReleaseDto> results = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesQuery, Pagination.all()); assertThat(results).hasSize(2); assertThat(results.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); assertThat(results.get(1)).usingRecursiveComparison().isEqualTo(scaReleaseDto3); - ScaReleasesQuery scaReleasesCaseInsensitiveQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, "Foo.Bar"); + ScaReleasesQuery scaReleasesCaseInsensitiveQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, null, null, "Foo.Bar"); List<ScaReleaseDto> resultsCaseInsensitive = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesCaseInsensitiveQuery, Pagination.all()); assertThat(resultsCaseInsensitive).hasSize(2); @@ -191,13 +191,13 @@ class ScaReleasesDaoIT { ScaReleaseDto scaReleaseDto1 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "1", 2, true, PackageManager.MAVEN, "foo.bar"); ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto.uuid(), "2", 3, false, PackageManager.MAVEN, "foo.bar"); - ScaReleasesQuery scaReleasesDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), true, null, null); + ScaReleasesQuery scaReleasesDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), true, null, null, null); List<ScaReleaseDto> resultsDirect = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesDirectQuery, Pagination.all()); assertThat(resultsDirect).hasSize(1); assertThat(resultsDirect.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); - ScaReleasesQuery scaReleasesNoDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), false, null, null); + ScaReleasesQuery scaReleasesNoDirectQuery = new ScaReleasesQuery(componentDto.branchUuid(), false, null, null, null); List<ScaReleaseDto> resultsNoDirect = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesNoDirectQuery, Pagination.all()); assertThat(resultsNoDirect).hasSize(1); @@ -211,14 +211,14 @@ class ScaReleasesDaoIT { ScaReleaseDto scaReleaseDto2 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "2", PackageManager.NPM, "foo.bar"); ScaReleaseDto scaReleaseDto3 = db.getScaReleasesDbTester().insertScaRelease(componentDto.uuid(), "3", PackageManager.CARGO, "foo.bar"); - ScaReleasesQuery scaReleasesMavenQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, List.of(PackageManager.MAVEN.name()), null); + ScaReleasesQuery scaReleasesMavenQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, List.of(PackageManager.MAVEN.name()), null, null); List<ScaReleaseDto> resultsMaven = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesMavenQuery, Pagination.all()); assertThat(resultsMaven).hasSize(1); assertThat(resultsMaven.get(0)).usingRecursiveComparison().isEqualTo(scaReleaseDto1); ScaReleasesQuery scaReleasesNpmAndCargoQuery = new ScaReleasesQuery(componentDto.branchUuid(), null, - List.of(PackageManager.NPM.name(), PackageManager.CARGO.name()), null); + List.of(PackageManager.NPM.name(), PackageManager.CARGO.name()), null, null); List<ScaReleaseDto> resultsNpm = scaReleasesDao.selectByQuery(db.getSession(), scaReleasesNpmAndCargoQuery, Pagination.all()); assertThat(resultsNpm).hasSize(2); @@ -259,11 +259,11 @@ class ScaReleasesDaoIT { db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "2", 2, true, PackageManager.MAVEN, "foo.bar.mee"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.foo"); - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, "foo"); + ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, "foo"); assertThat(scaReleasesDao.countByQuery(db.getSession(), scaReleasesQuery)).isEqualTo(2); - assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null))).isEqualTo(3); - assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery("another_branch_uuid", null, null, null))).isZero(); + assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, null))).isEqualTo(3); + assertThat(scaReleasesDao.countByQuery(db.getSession(), new ScaReleasesQuery("another_branch_uuid", null, null, null, null))).isZero(); } private ComponentDto prepareComponentDto(String suffix) { @@ -279,13 +279,13 @@ class ScaReleasesDaoIT { db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "3", 3, true, PackageManager.MAVEN, "bar.foo"); db.getScaReleasesDbTester().insertScaReleaseWithDependency(componentDto1.uuid(), "4", 4, true, PackageManager.PYPI, "bar.foo"); - ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null); + ScaReleasesQuery scaReleasesQuery = new ScaReleasesQuery(componentDto1.branchUuid(), null, null, null, null); List<ScaReleaseByPackageManagerCountDto> releaseCounts = scaReleasesDao.countReleasesByPackageManager(db.getSession(), scaReleasesQuery); assertThat(releaseCounts).hasSize(3); assertThat(releaseCounts).extracting("packageManager", "releaseCount") - .containsExactlyInAnyOrder(Tuple.tuple(PackageManager.MAVEN.name(), 2), - Tuple.tuple(PackageManager.NPM.name(), 1), - Tuple.tuple(PackageManager.PYPI.name(), 1)); + .containsExactlyInAnyOrder(Tuple.tuple(PackageManager.MAVEN.name(), 2), + Tuple.tuple(PackageManager.NPM.name(), 1), + Tuple.tuple(PackageManager.PYPI.name(), 1)); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java index 30d73abcf7c..838712480ee 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssueReleaseDetailsDto.java @@ -45,6 +45,7 @@ public record ScaIssueReleaseDetailsDto(String scaIssueReleaseUuid, String scaIssueUuid, String scaReleaseUuid, ScaIssueType scaIssueType, + boolean newInPullRequest, String packageUrl, String vulnerabilityId, String spdxLicenseId, @@ -59,6 +60,7 @@ public record ScaIssueReleaseDetailsDto(String scaIssueReleaseUuid, .setScaIssueUuid(scaIssueUuid) .setScaReleaseUuid(scaReleaseUuid) .setScaIssueType(scaIssueType) + .setNewInPullRequest(newInPullRequest) .setPackageUrl(packageUrl) .setVulnerabilityId(vulnerabilityId) .setSpdxLicenseId(spdxLicenseId) @@ -73,6 +75,7 @@ public record ScaIssueReleaseDetailsDto(String scaIssueReleaseUuid, private String scaIssueUuid; private String scaReleaseUuid; private ScaIssueType scaIssueType; + private boolean newInPullRequest; private String packageUrl; private String vulnerabilityId; private String spdxLicenseId; @@ -105,6 +108,11 @@ public record ScaIssueReleaseDetailsDto(String scaIssueReleaseUuid, return this; } + public Builder setNewInPullRequest(boolean newInPullRequest) { + this.newInPullRequest = newInPullRequest; + return this; + } + public Builder setPackageUrl(String packageUrl) { this.packageUrl = packageUrl; return this; @@ -136,8 +144,8 @@ public record ScaIssueReleaseDetailsDto(String scaIssueReleaseUuid, } public ScaIssueReleaseDetailsDto build() { - return new ScaIssueReleaseDetailsDto(scaIssueReleaseUuid, severity, scaIssueUuid, scaReleaseUuid, scaIssueType, packageUrl, vulnerabilityId, spdxLicenseId, - vulnerabilityBaseSeverity, cweIds, cvssScore); + return new ScaIssueReleaseDetailsDto(scaIssueReleaseUuid, severity, scaIssueUuid, scaReleaseUuid, scaIssueType, + newInPullRequest, packageUrl, vulnerabilityId, spdxLicenseId, vulnerabilityBaseSeverity, cweIds, cvssScore); } } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java index a718581ffdf..ba990981b4b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQuery.java @@ -35,6 +35,7 @@ public record ScaIssuesReleasesDetailsQuery( Sort sort, @Nullable String vulnerabilityIdSubstring, @Nullable String packageNameSubstring, + @Nullable Boolean newInPullRequest, @Nullable List<ScaIssueType> types, @Nullable List<ScaSeverity> severities, @Nullable List<PackageManager> packageManagers) { @@ -70,6 +71,7 @@ public record ScaIssuesReleasesDetailsQuery( .setSort(sort) .setVulnerabilityIdSubstring(vulnerabilityIdSubstring) .setPackageNameSubstring(packageNameSubstring) + .setNewInPullRequest(newInPullRequest) .setTypes(types) .setSeverities(severities) .setPackageManagers(packageManagers); @@ -112,6 +114,7 @@ public record ScaIssuesReleasesDetailsQuery( private Sort sort; private String vulnerabilityIdSubstring; private String packageNameSubstring; + private Boolean newInPullRequest; private List<ScaIssueType> types; private List<ScaSeverity> severities; private List<PackageManager> packageManagers; @@ -136,6 +139,11 @@ public record ScaIssuesReleasesDetailsQuery( return this; } + public Builder setNewInPullRequest(@Nullable Boolean newInPullRequest) { + this.newInPullRequest = newInPullRequest; + return this; + } + public Builder setTypes(@Nullable List<ScaIssueType> types) { this.types = types; return this; @@ -152,7 +160,7 @@ public record ScaIssuesReleasesDetailsQuery( } public ScaIssuesReleasesDetailsQuery build() { - return new ScaIssuesReleasesDetailsQuery(branchUuid, sort, vulnerabilityIdSubstring, packageNameSubstring, types, severities, packageManagers); + return new ScaIssuesReleasesDetailsQuery(branchUuid, sort, vulnerabilityIdSubstring, packageNameSubstring, newInPullRequest, types, severities, packageManagers); } } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java index 309d2be61bc..ae6ba76f39f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDependenciesDto.java @@ -33,6 +33,7 @@ import java.util.List; * @param version package version e.g. "1.25.6" * @param licenseExpression an SPDX license expression (NOT a single license, can have parens/AND/OR) * @param known is this package and version known to Sonar (if not it be internal, could be malicious, could be from a weird repo) + * @param newInPullRequest is it newly added in a PR (always false when not on a PR) * @param createdAt timestamp it was created * @param updatedAt timestamp it was last updated */ @@ -45,6 +46,7 @@ public record ScaReleaseDependenciesDto( String version, String licenseExpression, boolean known, + boolean newInPullRequest, long createdAt, long updatedAt, List<ScaDependencyDto> dependencies) { @@ -59,6 +61,7 @@ public record ScaReleaseDependenciesDto( release.version(), release.licenseExpression(), release.known(), + release.newInPullRequest(), release.createdAt(), release.updatedAt(), dependencies); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java index 4fe56325093..292a9fa76a9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleaseDto.java @@ -34,7 +34,7 @@ import static com.google.common.base.Preconditions.checkArgument; * @param version package version e.g. "1.25.6" * @param licenseExpression an SPDX license expression (NOT a single license, can have parens/AND/OR) * @param known is this package and version known to Sonar (if not it be internal, could be malicious, could be from a weird repo) - * @param newInPullRequest is it newly added in a PR + * @param newInPullRequest is it newly added in a PR (always false when not on a PR) * @param createdAt timestamp it was created * @param updatedAt timestamp it was last updated */ diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java index 79c293652bb..8a8b4b9d57f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/sca/ScaReleasesQuery.java @@ -31,6 +31,7 @@ public record ScaReleasesQuery( String branchUuid, @Nullable Boolean direct, @Nullable List<String> packageManagers, + @Nullable Boolean newInPullRequest, @Nullable String query) { /** diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml index 5f293547d1d..b9a84c1fd3d 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaIssuesReleasesDetailsMapper.xml @@ -10,6 +10,7 @@ <arg column="sca_issue_uuid" javaType="String"/> <arg column="sca_release_uuid" javaType="String"/> <arg column="sca_issue_type" javaType="org.sonar.db.sca.ScaIssueType" jdbcType="VARCHAR"/> + <arg column="new_in_pull_request" javaType="_boolean"/> <arg column="package_url" javaType="String"/> <arg column="vulnerability_id" javaType="String"/> <arg column="spdx_license_id" javaType="String"/> @@ -27,6 +28,7 @@ sir.sca_issue_uuid, sir.sca_release_uuid, si.sca_issue_type, + sr.new_in_pull_request, si.package_url, si.vulnerability_id, si.spdx_license_id, @@ -73,6 +75,9 @@ <if test="query.packageNameSubstring != null and query.packageNameSubstring.length > 0"> AND lower(sr.package_name) LIKE #{query.packageNameLowercaseEscapedAsLikeValue, jdbcType=VARCHAR} ESCAPE '/' </if> + <if test="query.newInPullRequest != null"> + AND sr.new_in_pull_request = #{query.newInPullRequest, jdbcType=BOOLEAN} + </if> <if test="query.types != null"> <if test="query.types.isEmpty()"> AND 1=0 diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml index 5db918bb1d7..192df570755 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/sca/ScaReleasesMapper.xml @@ -114,6 +114,9 @@ #{packageManager,jdbcType=VARCHAR} </foreach> </if> + <if test="query.newInPullRequest != null"> + AND sr.new_in_pull_request = #{query.newInPullRequest,jdbcType=BOOLEAN} + </if> <if test="query.query() != null"> AND lower(sr.package_name) LIKE #{query.likeQuery} ESCAPE '/' </if> diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java index 893f191389f..4511f4b468e 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssueReleaseDetailsDtoTest.java @@ -33,6 +33,7 @@ class ScaIssueReleaseDetailsDtoTest { "scaIssueUuid", "scaReleaseUuid", ScaIssueType.VULNERABILITY, + true, "packageUrl", "vulnerabilityId", "spdxLicenseId", diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java index 6d9f67b14eb..6518a619220 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/sca/ScaIssuesReleasesDetailsQueryTest.java @@ -30,7 +30,7 @@ class ScaIssuesReleasesDetailsQueryTest { @Test void test_toBuilder_build_shouldRoundTrip() { var query = new ScaIssuesReleasesDetailsQuery("branchUuid", ScaIssuesReleasesDetailsQuery.Sort.IDENTITY_ASC, - "vulnerabilityIdSubstring", "packageNameSubstring", + "vulnerabilityIdSubstring", "packageNameSubstring", true, List.of(ScaIssueType.VULNERABILITY), List.of(ScaSeverity.BLOCKER), List.of(PackageManager.NPM)); AssertionsForClassTypes.assertThat(query.toBuilder().build()).isEqualTo(query); } diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java index a60c8c7f705..960934a4d11 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/sca/ScaIssuesReleasesDetailsDbTester.java @@ -21,7 +21,6 @@ package org.sonar.db.sca; import java.util.Optional; import java.util.function.Function; -import javax.annotation.Nullable; import org.sonar.db.DbClient; import org.sonar.db.DbTester; @@ -34,43 +33,42 @@ public class ScaIssuesReleasesDetailsDbTester { this.dbClient = db.getDbClient(); } - public ScaIssueReleaseDetailsDto fromDtos(@Nullable String projectUuid, ScaIssueReleaseDto scaIssueReleaseDto, ScaIssueDto scaIssueDto, - Optional<ScaVulnerabilityIssueDto> scaVulnerabilityIssueDtoOptional) { + public ScaIssueReleaseDetailsDto fromDtos(ScaIssueReleaseDto scaIssueReleaseDto, ScaIssueDto scaIssueDto, + Optional<ScaVulnerabilityIssueDto> scaVulnerabilityIssueDtoOptional, boolean newInPullRequest) { // this should emulate what the mapper does when joining these tables return new ScaIssueReleaseDetailsDto(scaIssueReleaseDto.uuid(), scaIssueReleaseDto.severity(), scaIssueReleaseDto.scaIssueUuid(), scaIssueReleaseDto.scaReleaseUuid(), scaIssueDto.scaIssueType(), - scaIssueDto.packageUrl(), scaIssueDto.vulnerabilityId(), scaIssueDto.spdxLicenseId(), + newInPullRequest, scaIssueDto.packageUrl(), scaIssueDto.vulnerabilityId(), scaIssueDto.spdxLicenseId(), scaVulnerabilityIssueDtoOptional.map(ScaVulnerabilityIssueDto::baseSeverity).orElse(null), scaVulnerabilityIssueDtoOptional.map(ScaVulnerabilityIssueDto::cweIds).orElse(null), scaVulnerabilityIssueDtoOptional.map(ScaVulnerabilityIssueDto::cvssScore).orElse(null)); } private ScaIssueReleaseDetailsDto insertIssue(ScaIssueDto scaIssue, Optional<ScaVulnerabilityIssueDto> scaVulnerabilityIssueDtoOptional, - String suffix, String componentUuid, - @Nullable String projectUuid) { + String suffix, String componentUuid) { // insertScaRelease has suffix and componentUuid swapped vs. our own method... var scaRelease = db.getScaReleasesDbTester().insertScaRelease(componentUuid, suffix); var scaIssueRelease = new ScaIssueReleaseDto("sca-issue-release-uuid-" + suffix, scaIssue, scaRelease, ScaSeverity.INFO, 1L, 2L); dbClient.scaIssuesReleasesDao().insert(db.getSession(), scaIssueRelease); - return fromDtos(projectUuid, scaIssueRelease, scaIssue, scaVulnerabilityIssueDtoOptional); + return fromDtos(scaIssueRelease, scaIssue, scaVulnerabilityIssueDtoOptional, scaRelease.newInPullRequest()); } public ScaIssueReleaseDetailsDto insertVulnerabilityIssue(String suffix, String componentUuid) { var entry = db.getScaIssuesDbTester().insertVulnerabilityIssue(suffix); - return insertIssue(entry.getKey(), Optional.of(entry.getValue()), suffix, componentUuid, null); + return insertIssue(entry.getKey(), Optional.of(entry.getValue()), suffix, componentUuid); } public ScaIssueReleaseDetailsDto insertProhibitedLicenseIssue(String suffix, String componentUuid) { var scaIssue = db.getScaIssuesDbTester().insertProhibitedLicenseIssue(suffix); - return insertIssue(scaIssue, Optional.empty(), suffix, componentUuid, null); + return insertIssue(scaIssue, Optional.empty(), suffix, componentUuid); } - public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid, @Nullable String projectUuid) { - return insertIssue(scaIssueType, suffix, componentUuid, projectUuid, + public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid) { + return insertIssue(scaIssueType, suffix, componentUuid, null, null, null, null); } - public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid, @Nullable String projectUuid, + public ScaIssueReleaseDetailsDto insertIssue(ScaIssueType scaIssueType, String suffix, String componentUuid, Function<ScaIssueDto, ScaIssueDto> scaIssueModifier, Function<ScaVulnerabilityIssueDto, ScaVulnerabilityIssueDto> scaVulnerabilityIssueModifier, Function<ScaReleaseDto, ScaReleaseDto> scaReleaseModifier, @@ -104,6 +102,6 @@ public class ScaIssuesReleasesDetailsDbTester { scaIssueRelease = scaIssueReleaseModifier.apply(scaIssueRelease); } dbClient.scaIssuesReleasesDao().insert(db.getSession(), scaIssueRelease); - return fromDtos(projectUuid, scaIssueRelease, scaIssue, Optional.ofNullable(scaVulnerabilityIssue)); + return fromDtos(scaIssueRelease, scaIssue, Optional.ofNullable(scaVulnerabilityIssue), scaRelease.newInPullRequest()); } } |