diff --git a/build.gradle b/build.gradle index 5dca4a5..143b951 100644 --- a/build.gradle +++ b/build.gradle @@ -1,60 +1,60 @@ plugins { - id 'java' - id 'org.springframework.boot' version '3.3.3' - id 'io.spring.dependency-management' version '1.1.6' - id 'org.asciidoctor.jvm.convert' version '4.0.3' + id 'java' + id 'org.springframework.boot' version '3.3.3' + id 'io.spring.dependency-management' version '1.1.6' + id 'org.asciidoctor.jvm.convert' version '4.0.3' } group = 'io.gardenlinux' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '21' + sourceCompatibility = '21' } repositories { - mavenCentral() + mavenCentral() } ext { - set('snippetsDir', file("build/generated-snippets")) + set('snippetsDir', file("build/generated-snippets")) } configurations { - asciidoctorExtensions + asciidoctorExtensions } dependencies { - asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' - implementation 'org.springframework.boot:spring-boot-starter-actuator' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - runtimeOnly 'org.postgresql:postgresql' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation 'org.springframework.boot:spring-boot-testcontainers' - testImplementation 'org.springframework.restdocs:spring-restdocs-restassured' - testImplementation 'org.testcontainers:junit-jupiter' - testImplementation 'org.testcontainers:postgresql' - testImplementation 'io.rest-assured:rest-assured:5.5.0' - testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + runtimeOnly 'org.postgresql:postgresql' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.boot:spring-boot-testcontainers' + testImplementation 'org.springframework.restdocs:spring-restdocs-restassured' + testImplementation 'org.testcontainers:junit-jupiter' + testImplementation 'org.testcontainers:postgresql' + testImplementation 'io.rest-assured:rest-assured:5.5.0' + testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0' + testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { - outputs.dir snippetsDir - useJUnitPlatform() + outputs.dir snippetsDir + useJUnitPlatform() } tasks.named('asciidoctor') { - configurations "asciidoctorExtensions" - inputs.dir snippetsDir - dependsOn test + configurations "asciidoctorExtensions" + inputs.dir snippetsDir + dependsOn test } bootJar { - dependsOn asciidoctor - from ("${asciidoctor.outputDir}/html5") { - into 'static/docs' - } + dependsOn asciidoctor + from("${asciidoctor.outputDir}/html5") { + into 'static/docs' + } } diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index 88b7204..a787ce4 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -39,7 +39,7 @@ The `data` field contains a full copy of the CVE as provided by https://nvd.nist === Get a list of CVEs by distro -To query all CVEs for a given distribution by codename, you may use this endpoint: +To query all CVEs for a given distribution by version, you may use this endpoint: include::{snippets}/getCveForDistro/curl-request.adoc[] @@ -49,12 +49,6 @@ The expected response looks like this: include::{snippets}/getCveForDistro/http-response.adoc[] -To use a specific distribution version number, use this endpoint: - -include::{snippets}/getCveForDistroByVersion/curl-request.adoc[] - -The expected response is the same as for the previous request. - === Get a list of CVEs for packages by distro This endpoint will give you all the CVE for a list of packages in a specified distro. @@ -94,14 +88,3 @@ include::{snippets}/getPackageWithVulnerabilities/curl-request.adoc[] The expected response looks like this: include::{snippets}/getPackageWithVulnerabilities/http-response.adoc[] - -=== Get Package With Vulnerabilities By Version - -Gives you a list of vulnerabilities for a specific package in a specifc version (i.e. a subset of the result from the previous query). - -include::{snippets}/getPackageWithVulnerabilitiesByVersion/curl-request.adoc[] - -The expected response looks like this: - -include::{snippets}/getPackageWithVulnerabilitiesByVersion/http-response.adoc[] - diff --git a/src/main/java/io/gardenlinux/glvd/GlvdController.java b/src/main/java/io/gardenlinux/glvd/GlvdController.java index 4d4c22a..7f5306c 100644 --- a/src/main/java/io/gardenlinux/glvd/GlvdController.java +++ b/src/main/java/io/gardenlinux/glvd/GlvdController.java @@ -29,31 +29,16 @@ ResponseEntity getCveId(@PathVariable("cveId") final String cveId) th return ResponseEntity.ok().body(glvdService.getCve(cveId)); } - @GetMapping("/{product}/{codename}") - ResponseEntity> getCveDistro(@PathVariable final String product, - @PathVariable final String codename) { - return ResponseEntity.ok().body(glvdService.getCveForDistribution(product, codename)); + @GetMapping("/{distro}/{distroVersion}") + ResponseEntity> getCveDistro(@PathVariable final String distro, + @PathVariable final String distroVersion) { + return ResponseEntity.ok().body(glvdService.getCveForDistribution(distro, distroVersion)); } - - @GetMapping("/{product}/version/{version}") - ResponseEntity> getCveDistroVersion(@PathVariable final String product, - @PathVariable final String version) { - return ResponseEntity.ok().body(glvdService.getCveForDistributionVersion(product, version)); - } - - - @GetMapping("/{product}/{codename}/packages/{packageList}") - ResponseEntity> getCvePackages(@PathVariable final String product, - @PathVariable final String codename, @PathVariable final String packageList) { - var cveForPackages = glvdService.getCveForPackages(product, codename, packageList); - return ResponseEntity.ok().body(cveForPackages); - } - - @GetMapping("/{product}/version/{version}/packages/{packageList}") - ResponseEntity> getCvePackagesVersion(@PathVariable final String product, - @PathVariable final String version, @PathVariable final String packageList) { - var cveForPackages = glvdService.getCveForPackagesVersion(product, version, packageList); + @GetMapping("/{distro}/{distroVersion}/packages/{packageList}") + ResponseEntity> getCvePackages(@PathVariable final String distro, + @PathVariable final String distroVersion, @PathVariable final String packageList) { + var cveForPackages = glvdService.getCveForPackages(distro, distroVersion, packageList); return ResponseEntity.ok().body(cveForPackages); } diff --git a/src/main/java/io/gardenlinux/glvd/GlvdService.java b/src/main/java/io/gardenlinux/glvd/GlvdService.java index 15cf015..cddd462 100644 --- a/src/main/java/io/gardenlinux/glvd/GlvdService.java +++ b/src/main/java/io/gardenlinux/glvd/GlvdService.java @@ -50,20 +50,12 @@ public CveEntity getCve(String cveId) throws NotFoundException { return cveRepository.findById(cveId).orElseThrow(NotFoundException::new); } - public List getCveForDistribution(String product, String codename) { - return cveRepository.cvesForDistribution(product, codename).stream().map(this::parseDbResponse).toList(); + public List getCveForDistribution(String distro, String distroVersion) { + return cveRepository.cvesForDistribution(distro, distroVersion).stream().map(this::parseDbResponse).toList(); } - public List getCveForDistributionVersion(String product, String version) { - return cveRepository.cvesForDistributionVersion(product, version).stream().map(this::parseDbResponse).toList(); - } - - public List getCveForPackages(String product, String codename, String packages) { - return cveRepository.cvesForPackageList(product, codename,"{"+packages+"}").stream().map(this::parseDbResponse).toList(); - } - - public List getCveForPackagesVersion(String product, String version, String packages) { - return cveRepository.cvesForPackageListVersion(product, version,"{"+packages+"}").stream().map(this::parseDbResponse).toList(); + public List getCveForPackages(String distro, String distroVersion, String packages) { + return cveRepository.cvesForPackageList(distro, distroVersion,"{"+packages+"}").stream().map(this::parseDbResponse).toList(); } public List getPackagesForDistro(String distro, String distroVersion) { diff --git a/src/main/java/io/gardenlinux/glvd/UiController.java b/src/main/java/io/gardenlinux/glvd/UiController.java index 1a26adc..d0342ca 100644 --- a/src/main/java/io/gardenlinux/glvd/UiController.java +++ b/src/main/java/io/gardenlinux/glvd/UiController.java @@ -34,7 +34,7 @@ public String getCveForDistribution( @RequestParam(name = "version", required = true) String version, Model model ) { - var sourcePackageCves = glvdService.getCveForDistributionVersion(distro, version); + var sourcePackageCves = glvdService.getCveForDistribution(distro, version); model.addAttribute("sourcePackageCves", sourcePackageCves); model.addAttribute("distro", distro); model.addAttribute("version", version); diff --git a/src/main/java/io/gardenlinux/glvd/db/CveRepository.java b/src/main/java/io/gardenlinux/glvd/db/CveRepository.java index 8f76691..9004b4d 100644 --- a/src/main/java/io/gardenlinux/glvd/db/CveRepository.java +++ b/src/main/java/io/gardenlinux/glvd/db/CveRepository.java @@ -8,24 +8,6 @@ public interface CveRepository extends JpaRepository { - @Query(value = """ - SELECT - deb_cve.deb_source AS source_package, - all_cve.cve_id AS cve_id, - all_cve."data" ->> 'published' AS cve_published_date - FROM - all_cve - INNER JOIN deb_cve USING (cve_id) - INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) - WHERE - dist_cpe.cpe_product = :product AND - dist_cpe.deb_codename = :codename AND - deb_cve.debsec_vulnerable = TRUE - ORDER BY - all_cve.cve_id - """, nativeQuery = true) - List cvesForDistribution(@Param("product") String product, @Param("codename") String codename); - @Query(value = """ SELECT deb_cve.deb_source AS source_package, @@ -36,32 +18,13 @@ INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) INNER JOIN deb_cve USING (cve_id) INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) WHERE - dist_cpe.cpe_product = :product AND - dist_cpe.cpe_version = :version AND - deb_cve.debsec_vulnerable = TRUE + dist_cpe.cpe_product = :distro AND + dist_cpe.cpe_version = :distroVersion AND + deb_cve.debsec_vulnerable = TRUE ORDER BY all_cve.cve_id """, nativeQuery = true) - List cvesForDistributionVersion(@Param("product") String product, @Param("version") String version); - - @Query(value = """ - SELECT - deb_cve.deb_source AS source_package, - all_cve.cve_id AS cve_id, - all_cve."data" ->> 'published' AS cve_published_date - FROM - all_cve - INNER JOIN deb_cve USING (cve_id) - INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) - WHERE - dist_cpe.cpe_product = :product AND - dist_cpe.deb_codename = :codename AND - deb_cve.deb_source = ANY(:packages ::TEXT[]) AND - deb_cve.debsec_vulnerable = TRUE - ORDER BY - all_cve.cve_id - """, nativeQuery = true) - List cvesForPackageList(@Param("product") String product, @Param("codename") String codename, @Param("packages") String packages); + List cvesForDistribution(@Param("distro") String distro, @Param("distroVersion") String distroVersion); @Query(value = """ SELECT @@ -73,14 +36,14 @@ INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) INNER JOIN deb_cve USING (cve_id) INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) WHERE - dist_cpe.cpe_product = :product AND - dist_cpe.cpe_version = :version AND + dist_cpe.cpe_product = :distro AND + dist_cpe.cpe_version = :distroVersion AND deb_cve.deb_source = ANY(:packages ::TEXT[]) AND - deb_cve.debsec_vulnerable = TRUE + deb_cve.debsec_vulnerable = TRUE ORDER BY all_cve.cve_id """, nativeQuery = true) - List cvesForPackageListVersion(@Param("product") String product, @Param("version") String version, @Param("packages") String packages); + List cvesForPackageList(@Param("distro") String distro, @Param("distroVersion") String distroVersion, @Param("packages") String packages); @Query(value = """ SELECT @@ -91,7 +54,7 @@ INNER JOIN dist_cpe ON (deb_cve.dist_id = dist_cpe.id) (debsrc.dist_id = dist_cpe.id) WHERE dist_cpe.cpe_product = :distro - AND dist_cpe.deb_codename = :distroVersion + AND dist_cpe.cpe_version = :distroVersion ORDER BY debsrc.deb_source""", nativeQuery = true) List packagesForDistribution(@Param("distro") String distro, @Param("distroVersion") String distroVersion); diff --git a/src/test/java/io/gardenlinux/glvd/GlvdControllerTest.java b/src/test/java/io/gardenlinux/glvd/GlvdControllerTest.java index 9970e15..9fa6361 100644 --- a/src/test/java/io/gardenlinux/glvd/GlvdControllerTest.java +++ b/src/test/java/io/gardenlinux/glvd/GlvdControllerTest.java @@ -101,20 +101,10 @@ public void shouldReturnCvesForBookworm() { .filter(document("getCveForDistro", preprocessRequest(modifyUris().scheme("https").host("glvd.gardenlinux.io").removePort()), preprocessResponse(prettyPrint()))) - .when().port(this.port).get("/v1/cves/gardenlinux/1592") + .when().port(this.port).get("/v1/cves/gardenlinux/1592.0") .then().statusCode(HttpStatus.SC_OK); } - @Test - public void shouldReturnCvesForBookwormByVersion() { - given(this.spec).accept("application/json") - .filter(document("getCveForDistroByVersion", - preprocessRequest(modifyUris().scheme("https").host("glvd.gardenlinux.io").removePort()), - preprocessResponse(prettyPrint()))) - .when().port(this.port).get("/v1/cves/gardenlinux/version/1592.0") - .then().statusCode(HttpStatus.SC_OK); - } - @Test public void shouldReturnCvesForListOfPackages() { given(this.spec).accept("application/json") @@ -125,16 +115,6 @@ public void shouldReturnCvesForListOfPackages() { .then().statusCode(HttpStatus.SC_OK); } - @Test - public void shouldReturnCvesForListOfPackagesByDistroVersion() { - given(this.spec).accept("application/json") - .filter(document("getCveForPackagesByDistroVersion", - preprocessRequest(modifyUris().scheme("https").host("glvd.gardenlinux.io").removePort()), - preprocessResponse(prettyPrint()))) - .when().port(this.port).get("/v1/cves/gardenlinux/version/1592.0/packages/crun,vim") - .then().statusCode(HttpStatus.SC_OK); - } - @Test public void shouldBeReady() { given(this.spec)