From 98806af8e250006de7523df0cf2cd923a29fb19f Mon Sep 17 00:00:00 2001 From: majewm15 <-> Date: Thu, 23 Nov 2023 13:16:06 +0100 Subject: [PATCH] Issue #105 - Vulnerability History - extend to history of severities --- .../controller/ProjectRestController.java | 10 ++++++ .../api/project/model/ProjectVulnHistory.java | 36 +++++++++++++++++++ .../project/service/ProjectRestService.java | 10 ++++++ .../OperateOnVulnHistoryService.java | 34 ++++++++++++++++++ .../service/ProjectRestServiceTest.java | 16 ++++++--- 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/mixeway/api/project/model/ProjectVulnHistory.java diff --git a/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java b/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java index fbfae0fd..27a82eac 100644 --- a/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java +++ b/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java @@ -68,6 +68,16 @@ public ResponseEntity> showProjectVulnerabilities(@Pa return projectService.showVulnerabilitiesForProject(id, principal); } @PreAuthorize("hasAuthority('ROLE_USER')") + @GetMapping(value = "/{id}/vulnerabilities/history") + public ResponseEntity> showProjectVulnerabilitiesHistory(@PathVariable("id")Long id, Principal principal) { + return projectService.showVulnerabilitiesHistoryForProject(id, 7, principal); + } + @PreAuthorize("hasAuthority('ROLE_USER')") + @GetMapping(value = "/{id}/vulnerabilities/history/days/{limit}") + public ResponseEntity> showProjectVulnerabilitiesHistoryWithLimit(@PathVariable("id")Long id, @PathVariable("limit") int limit, Principal principal) { + return projectService.showVulnerabilitiesHistoryForProject(id, limit, principal); + } + @PreAuthorize("hasAuthority('ROLE_USER')") @GetMapping(value = "/{id}/vulnerabilities/{vulnId}") public ResponseEntity showVulnerability(@PathVariable("id")Long id, @PathVariable("vulnId")Long vulnId, Principal principal) { return projectService.showVulnerability(id,vulnId, principal); diff --git a/src/main/java/io/mixeway/api/project/model/ProjectVulnHistory.java b/src/main/java/io/mixeway/api/project/model/ProjectVulnHistory.java new file mode 100644 index 00000000..e9d61eb6 --- /dev/null +++ b/src/main/java/io/mixeway/api/project/model/ProjectVulnHistory.java @@ -0,0 +1,36 @@ +package io.mixeway.api.project.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.LinkedList; +import java.util.List; + +@Builder +@AllArgsConstructor +@Getter +@Setter +public class ProjectVulnHistory { + private Long infrastructure; + private Long infrastructureCritical; + private Long infrastructureHigh; + private Long infrastructureMedium; + private Long infrastructureLow; + private Long webApp; + private Long webAppCritical; + private Long webAppHigh; + private Long webAppMedium; + private Long webAppLow; + private Long code; + private Long codeCritical; + private Long codeHigh; + private Long codeMedium; + private Long codeLow; + private Long audit; + private Long softwarePacketVulnNumber; + private String name; + private String inserted; + +} diff --git a/src/main/java/io/mixeway/api/project/service/ProjectRestService.java b/src/main/java/io/mixeway/api/project/service/ProjectRestService.java index cb720496..9260bf99 100644 --- a/src/main/java/io/mixeway/api/project/service/ProjectRestService.java +++ b/src/main/java/io/mixeway/api/project/service/ProjectRestService.java @@ -163,6 +163,16 @@ public ResponseEntity> showVulnerabilitiesForProject( } } + public ResponseEntity> showVulnerabilitiesHistoryForProject(Long id, int limit, Principal principal) { + Optional project = findProjectService.findProjectById(id); + if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){ + List vulns = operateOnVulnHistoryService.getVulnHistory(project.get(), limit); + return new ResponseEntity<>(vulns ,HttpStatus.OK); + } else { + return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED); + } + } + public ResponseEntity showVulnerability(Long id, Long vulnId, Principal principal) { Optional project = findProjectService.findProjectById(id); if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){ diff --git a/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java b/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java index 674bdabc..a705426e 100644 --- a/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java +++ b/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java @@ -1,5 +1,6 @@ package io.mixeway.domain.service.vulnhistory; +import io.mixeway.api.project.model.ProjectVulnHistory; import io.mixeway.api.project.model.ProjectVulnTrendChart; import io.mixeway.api.project.model.ProjectVulnTrendChartSerie; import io.mixeway.config.Constants; @@ -12,6 +13,7 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; /** * @author gsiewruk @@ -73,4 +75,36 @@ public ProjectVulnTrendChart getVulnTrendChart(Project project, int limit){ projectVulnTrendChart.setSeries(series); return projectVulnTrendChart; } + + public List getVulnHistory(Project project, int limit){ + return vulnHistoryRepository.getVulnHistoryLimit(project.getId(),limit) + .stream().map(vulnHistory -> ProjectVulnHistory.builder() + + .infrastructure(vulnHistory.getInfrastructureVulnHistory()) + .infrastructureCritical(vulnHistory.getInfrastructureVulnCriticalHistory()) + .infrastructureHigh(vulnHistory.getInfrastructureVulnHighHistory()) + .infrastructureMedium(vulnHistory.getInfrastructureVulnMediumHistory()) + .infrastructureLow(vulnHistory.getInfrastructureVulnLowHistory()) + + .webApp(vulnHistory.getWebAppVulnHistory()) + .webAppCritical(vulnHistory.getWebAppVulnCriticalHistory()) + .webAppHigh(vulnHistory.getWebAppVulnHighHistory()) + .webAppMedium(vulnHistory.getWebAppVulnMediumHistory()) + .webAppLow(vulnHistory.getWebAppVulnLowHistory()) + + .code(vulnHistory.getCodeVulnHistory()) + .codeCritical(vulnHistory.getCodeVulnCriticalHistory()) + .codeHigh(vulnHistory.getCodeVulnHighHistory()) + .codeMedium(vulnHistory.getCodeVulnMediumHistory()) + .codeLow(vulnHistory.getCodeVulnLowHistory()) + + .audit(vulnHistory.getAuditVulnHistory()) + .softwarePacketVulnNumber(vulnHistory.getSoftwarePacketVulnNumber()) + .name(vulnHistory.getName()) + .inserted(vulnHistory.getInserted()) + + .build() + ).collect(Collectors.toList()); + + } } diff --git a/src/test/java/io/mixeway/api/project/service/ProjectRestServiceTest.java b/src/test/java/io/mixeway/api/project/service/ProjectRestServiceTest.java index f6f0a364..69a67d1d 100644 --- a/src/test/java/io/mixeway/api/project/service/ProjectRestServiceTest.java +++ b/src/test/java/io/mixeway/api/project/service/ProjectRestServiceTest.java @@ -1,9 +1,6 @@ package io.mixeway.api.project.service; -import io.mixeway.api.project.model.ContactList; -import io.mixeway.api.project.model.ProjectVulnTrendChart; -import io.mixeway.api.project.model.RiskCards; -import io.mixeway.api.project.model.VulnAuditorSettings; +import io.mixeway.api.project.model.*; import io.mixeway.db.entity.*; import io.mixeway.db.repository.ProjectVulnerabilityRepository; import io.mixeway.db.repository.UserRepository; @@ -166,6 +163,17 @@ void showVulnerabilitiesForProject() { assertNotNull(showVulnTrendChart.getBody()); } + @Test + void showVulnerabilitiesHistoryForProject() { + + Mockito.when(principal.getName()).thenReturn("project_service"); + Project project = getOrCreateProjectService.getProjectId("project_service","project_service",principal); + + ResponseEntity> projectVulnHistory = projectRestService.showVulnerabilitiesHistoryForProject(project.getId(), 3, principal); + assertEquals(HttpStatus.OK, projectVulnHistory.getStatusCode()); + assertNotNull(projectVulnHistory.getBody()); + } + @Test @Transactional @Order(1)