Skip to content
Snippets Groups Projects
Commit 690621e7 authored by Martin Lowe's avatar Martin Lowe :flag_ca:
Browse files

Merge branch 'zacharysabourin/main/3' into 'main'

feat: Add id path endpoint + tests

See merge request !3
parents 33c13568 a3f22bf2
No related branches found
No related tags found
1 merge request!3feat: Add id path endpoint + tests
Pipeline #7250 passed
......@@ -13,9 +13,79 @@ paths:
/cve:
get:
tags:
- CVEs
summary: CVE hello
- CVEs
summary: CVE List
description: Returns a 200 when called. Pop goes the weasel!
responses:
200:
description: Success
\ No newline at end of file
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/cves'
500:
description: Error while retrieving data
/cve/{id}:
parameters:
name: id
in: path
description: The id of the CVE to retrieve
required: true
schema:
type: string
get:
summary: CVE
description: Returns a CVE entry that has a matching id
responses:
200:
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/cve'
404:
description: CVE not found
500:
description: Error while retrieving data
components:
schemas:
cves:
type: array
items:
$ref: '#/components/schemas/cve'
cve:
type: object
properties:
id:
type: string
description: CVE id containing year
date:
type: string
description: The date of the report
project:
type: string
description: The project where the vulerability exists
link:
type: string
description: Link to the report
request_link:
type: string
description: Link to the request where the vulnerability was tracked
cve_pull_request:
type:
- string
- 'null'
description: Link to pull request that includes the vulnerability
live_link:
type: string
description: Link to the cve.mitre.org page for the vulnerability
status:
type: string
description: The current status of the vulerability (eg, Complete, Assigned, Reported)
year:
type: integer
description: The year the vulnerability was found
top_level_project:
type: string
description: The top level project where the vulnerability was found
......@@ -13,11 +13,13 @@
package org.eclipsefoundation.cve.resources;
import java.util.List;
import java.util.Objects;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
......@@ -31,7 +33,7 @@ import org.eclipsefoundation.cve.service.CveSourceService;
/**
* Retrieves working group definitions from the working groups service.
*
* @author Martin Lowe
* @author Martin Lowe, Zachary Sabourin
*/
@Path("cve")
@Produces(MediaType.APPLICATION_JSON)
......@@ -51,4 +53,17 @@ public class CveResource {
}
return Response.ok(out).build();
}
@GET
@Path("/{id}")
public Response getById(@PathParam("id") String id) {
CveData cve = cveSource.getCve(id);
//Returns 404 if status isn't "completed"
if(Objects.isNull(cve) || !cve.getStatus().equalsIgnoreCase("completed")) {
return Response.status(404).build();
}
return Response.ok(cve).build();
}
}
......@@ -29,6 +29,8 @@ public interface CveSourceService {
* @return all known CVE data objects.
*/
List<CveData> getAllCves();
CveData getCve(String id);
/**
* Retrieves a list of all public CVEs. Any non-public CVEs will be filtered out for security.
......
......@@ -27,4 +27,9 @@ public class DefaultCveSourceService implements CveSourceService {
public List<CveData> getAllCves() {
return Collections.emptyList();
}
@Override
public CveData getCve(String id) {
return null;
}
}
......@@ -12,6 +12,9 @@ package org.eclipsefoundation.cve.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipsefoundation.core.helper.DateTimeHelper;
import org.eclipsefoundation.cve.model.CveData;
......@@ -76,5 +79,11 @@ public class StubbedCveSourceService implements CveSourceService {
public List<CveData> getAllCves() {
return new ArrayList<>(this.internal);
}
@Override
public CveData getCve(String id) {
Optional<CveData> matchingCve = internal.stream().filter(cve -> cve.getId().equalsIgnoreCase(id)).findFirst();
return matchingCve.isEmpty() ? null : matchingCve.get();
}
}
package org.eclipsefoundation.cve;
import static io.restassured.RestAssured.given;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchemaInClasspath;
import org.eclipsefoundation.cve.test.helpers.SchemaNamespaceHelper;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
@QuarkusTest
class CveResourceTest {
public final static String CVES_BASE_URL = "/cve";
public final static String CVE_BASE_URL = CVES_BASE_URL + "/{id}";
public final static String VALID_CVE_ID = "cve-2020-27225";
public final static String INVALID_CVE_ID = "jim-bob-2022";
@Test
void getAll_success() {
given()
.when()
.get(CVES_BASE_URL)
.then()
.statusCode(200);
}
@Test
void getAll_success_validResponseFormat() {
given()
.when()
.get(CVES_BASE_URL)
.then()
.contentType(ContentType.JSON)
.statusCode(200);
}
@Test
void getAll_success_matchingSpec() {
given()
.when()
.get(CVES_BASE_URL)
.then()
.assertThat()
.body(matchesJsonSchemaInClasspath(SchemaNamespaceHelper.CVES_SCHEMA_PATH));
}
@Test
void getAll_failure_invalidFormatTEXT() {
given()
.accept(ContentType.TEXT)
.when()
.get(CVES_BASE_URL)
.then()
.statusCode(500);
}
@Test
void getAll_failure_invalidFormatXML() {
given()
.accept(ContentType.XML)
.when()
.get(CVES_BASE_URL)
.then()
.statusCode(500);
}
@Test
void getById_success() {
given()
.when()
.get(CVE_BASE_URL, VALID_CVE_ID)
.then()
.statusCode(200);
}
@Test
void getById_success_validResponseFormat() {
given()
.when()
.get(CVE_BASE_URL, VALID_CVE_ID)
.then()
.contentType(ContentType.JSON)
.statusCode(200);
}
@Test
void getById_success_matchingSpec() {
given()
.when()
.get(CVE_BASE_URL, VALID_CVE_ID)
.then()
.assertThat()
.body(matchesJsonSchemaInClasspath(SchemaNamespaceHelper.CVE_SCHEMA_PATH));
}
@Test
void getById_failure_invalidId() {
given()
.when()
.get(CVE_BASE_URL, INVALID_CVE_ID)
.then()
.statusCode(404);
}
@Test
void getById_failure_invalidFormatTEXT() {
given()
.accept(ContentType.TEXT)
.when()
.get(CVE_BASE_URL, VALID_CVE_ID)
.then()
.statusCode(500);
}
@Test
void getById_failure_invalidFormatXML() {
given()
.accept(ContentType.XML)
.when()
.get(CVE_BASE_URL, VALID_CVE_ID)
.then()
.statusCode(500);
}
}
\ No newline at end of file
package org.eclipsefoundation.cve;
import static io.restassured.RestAssured.given;
import org.junit.jupiter.api.Test;
import io.quarkus.test.junit.QuarkusTest;
@QuarkusTest
class GreetingResourceTest {
@Test
void testHelloEndpoint() {
given().when().get("/cve").then().statusCode(200);
}
}
\ No newline at end of file
package org.eclipsefoundation.cve.test.helpers;
public class SchemaNamespaceHelper {
public static final String BASE_SCHEMA_PATH = "schemas/";
public static final String BASE_SCHEMA_PATH_SUFFIX = "-schema.json";
public static final String CVE_SCHEMA_PATH = BASE_SCHEMA_PATH + "cve"
+ BASE_SCHEMA_PATH_SUFFIX;
public static final String CVES_SCHEMA_PATH = BASE_SCHEMA_PATH + "cves"
+ BASE_SCHEMA_PATH_SUFFIX;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment