diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 8cc630b3..ec6770e7 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -18,23 +18,23 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- mixeway-scan:
- name: Mixeway Scanning
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Prepare variables
- id: vars
- shell: bash
- run: |
- echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
- echo "::set-output name=sha_short::$(git rev-parse HEAD)"
- - name: Prepare Mixeway docker image
- run: |
- docker pull mixeway/scanner:latest
- - name: Run Scan
- run: |
- docker run -e MODE=STANDALONE -e OSS_USERNAME=${{ secrets.oss_username }} -e OSS_KEY=${{ secrets.oss_key }} -e COMMIT_ID=${{ steps.vars.outputs.sha_short }} -e BRANCH=${{ steps.vars.outputs.branch }} -e MIXEWAY_PROJECT_NAME=${{ github.event.repository.name }} -e MIXEWAY_PROJECT_ID=${{ secrets.mixeway_project_id }} -e MIXEWAY_KEY=${{ secrets.mixeway_key }} -v $PWD:/opt/sources mixeway/scanner:latest
+# mixeway-scan:
+# name: Mixeway Scanning
+# runs-on: ubuntu-latest
+# steps:
+# - uses: actions/checkout@v1
+# - name: Prepare variables
+# id: vars
+# shell: bash
+# run: |
+# echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+# echo "::set-output name=sha_short::$(git rev-parse HEAD)"
+# - name: Prepare Mixeway docker image
+# run: |
+# docker pull mixeway/scanner:latest
+# - name: Run Scan
+# run: |
+# docker run -e MODE=STANDALONE -e OSS_USERNAME=${{ secrets.oss_username }} -e OSS_KEY=${{ secrets.oss_key }} -e COMMIT_ID=${{ steps.vars.outputs.sha_short }} -e BRANCH=${{ steps.vars.outputs.branch }} -e MIXEWAY_PROJECT_NAME=${{ github.event.repository.name }} -e MIXEWAY_PROJECT_ID=${{ secrets.mixeway_project_id }} -e MIXEWAY_KEY=${{ secrets.mixeway_key }} -v $PWD:/opt/sources mixeway/scanner:latest
integration-testing:
name: Integration test
diff --git a/.github/workflows/deploybeta.yml b/.github/workflows/deploybeta.yml
index 6bdbceb4..ef3d3df6 100644
--- a/.github/workflows/deploybeta.yml
+++ b/.github/workflows/deploybeta.yml
@@ -25,23 +25,23 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- mixeway-scan:
- name: Mixeway Scanning
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Prepare variables
- id: vars
- shell: bash
- run: |
- echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
- echo "::set-output name=sha_short::$(git rev-parse HEAD)"
- - name: Prepare Mixeway docker image
- run: |
- docker pull mixeway/scanner:latest
- - name: Run Scan
- run: |
- docker run -e MODE=STANDALONE -e OSS_USERNAME=${{ secrets.oss_username }} -e OSS_KEY=${{ secrets.oss_key }} -e COMMIT_ID=${{ steps.vars.outputs.sha_short }} -e BRANCH=${{ steps.vars.outputs.branch }} -e MIXEWAY_PROJECT_NAME=${{ github.event.repository.name }} -e MIXEWAY_PROJECT_ID=${{ secrets.mixeway_project_id }} -e MIXEWAY_KEY=${{ secrets.mixeway_key }} -v $PWD:/opt/sources mixeway/scanner:latest
+# mixeway-scan:
+# name: Mixeway Scanning
+# runs-on: ubuntu-latest
+# steps:
+# - uses: actions/checkout@v1
+# - name: Prepare variables
+# id: vars
+# shell: bash
+# run: |
+# echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
+# echo "::set-output name=sha_short::$(git rev-parse HEAD)"
+# - name: Prepare Mixeway docker image
+# run: |
+# docker pull mixeway/scanner:latest
+# - name: Run Scan
+# run: |
+# docker run -e MODE=STANDALONE -e OSS_USERNAME=${{ secrets.oss_username }} -e OSS_KEY=${{ secrets.oss_key }} -e COMMIT_ID=${{ steps.vars.outputs.sha_short }} -e BRANCH=${{ steps.vars.outputs.branch }} -e MIXEWAY_PROJECT_NAME=${{ github.event.repository.name }} -e MIXEWAY_PROJECT_ID=${{ secrets.mixeway_project_id }} -e MIXEWAY_KEY=${{ secrets.mixeway_key }} -v $PWD:/opt/sources mixeway/scanner:latest
integration-testing:
name: Integration test
diff --git a/pom.xml b/pom.xml
index ffd63d33..772ad9e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
io.mixeway
mixeway
- 1.8.0
+ 1.8.2
jar
Mixeway
@@ -183,7 +183,7 @@
com.google.guava
guava
- 30.0-jre
+ 32.0.0-jre
@@ -297,7 +297,7 @@
ch.qos.logback
logback-core
- 1.2.9
+ 1.3.12
diff --git a/src/main/java/io/mixeway/api/cicd/controller/CICDController.java b/src/main/java/io/mixeway/api/cicd/controller/CICDController.java
new file mode 100644
index 00000000..18e81477
--- /dev/null
+++ b/src/main/java/io/mixeway/api/cicd/controller/CICDController.java
@@ -0,0 +1,117 @@
+package io.mixeway.api.cicd.controller;
+
+import io.mixeway.api.cicd.model.LoadSCA;
+import io.mixeway.api.cicd.service.CICDService;
+import io.mixeway.api.cioperations.model.LoadVulnModel;
+import io.mixeway.api.cioperations.model.ZapReportModel;
+import io.mixeway.api.protocol.cioperations.GetInfoRequest;
+import io.mixeway.api.protocol.cioperations.PrepareCIOperation;
+import io.mixeway.api.protocol.securitygateway.SecurityGatewayResponse;
+import io.mixeway.utils.Status;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.security.*;
+import java.security.cert.CertificateException;
+
+@RequiredArgsConstructor
+@Controller
+@RequestMapping("/v3/api/cicd")
+@PreAuthorize("hasAuthority('ROLE_API')")
+public class CICDController {
+ private final CICDService cicdService;
+
+
+ /**
+ *
+ * Request that meant to create CodeProject or return CodeProject by repoUrl contained in getInfoRequest
+ *
+ * @param getInfoRequest - info with repoURL and branch
+ */
+ @PostMapping(value = "/codeproject/info")
+ public ResponseEntity getCPInfo(@Valid @RequestBody GetInfoRequest getInfoRequest, Principal principal) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ return cicdService.getCPInfo(getInfoRequest, principal);
+ }
+
+ /**
+ *
+ * Request that meant to
+ * 1. Create or get proper branch for CodeProject with given ID
+ * 2. Call SCA scanner to load vulnerabilities and link those with pair codeproject - codeprojectbranch
+ *
+ * @param loadSCA
+ */
+ @PostMapping(value = "/codeproject/load/sca")
+ public ResponseEntity loadSca(@Valid @RequestBody LoadSCA loadSCA, Principal principal) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ return cicdService.loadSca(loadSCA, principal);
+ }
+
+
+ /**
+ *
+ * Request that load vulnerabilities from arbitrary sources such as GitLeaks and KICS:
+ * 1. Create or get proper branch for CodeProject with given ID
+ * 2. Load vulnerabilities to DB and link those with pair CodeProject - CodeProjectBranch
+ *
+ */
+ @PreAuthorize("hasAuthority('ROLE_API')")
+ @PostMapping(value="/codeproject/loadvulns/{codeProjectId}")
+ public ResponseEntity loadVulns (@RequestBody LoadVulnModel loadVulnModel,
+ @PathVariable(value = "codeProjectId") Long id,
+ Principal principal) throws Exception {
+ return cicdService.loadVulnerabilitiesFromCICDToProject(
+ loadVulnModel.getVulns(),
+ id,
+ loadVulnModel.getBranch(),
+ loadVulnModel.getCommitId(),
+ principal);
+ }
+
+ /**
+ *
+ * Request that start SAST Scan for given scope:
+ * 1. Create or get proper branch for CodeProject with given ID
+ * 2. Load vulnerabilities to DB and link those with pair CodeProject - CodeProjectBranch
+ *
+ */
+ @PreAuthorize("hasAuthority('ROLE_API')")
+ @PostMapping(value = "/codeproject/run/sast")
+ public ResponseEntity performSastScanForCodeProject( @RequestBody LoadSCA loadSCA, Principal principal) throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
+ return cicdService.performSastScanForCodeProject(loadSCA, principal);
+ }
+
+
+ /**
+ *
+ * Request that load vulnerabilities from arbitrary sources such as ZAP:
+ * 1. Create or get proper branch for CodeProject with given ID
+ * 2. Load vulnerabilities to DB and link those with pair CodeProject - CodeProjectBranch
+ * TODO Upload report ZAP with info regarding repoUrl to link repo with webapp
+ *
+ */
+
+ @PreAuthorize("hasAuthority('ROLE_API')")
+ @PostMapping(value="/loadvulns/zap/{ciid}")
+ public ResponseEntity loadVulnsZap (@RequestBody ZapReportModel loadVulnModel,
+ @PathVariable(value = "ciid") String ciid,
+ Principal principal) throws Exception {
+ return cicdService.loadVulnZap(loadVulnModel,ciid,principal);
+ }
+
+ /**
+ * Validate State of security for given CodeProject and Branch
+ */
+ @CrossOrigin(origins="*")
+ @PreAuthorize("hasAuthority('ROLE_API')")
+ @PostMapping(value = "/codeproject/validate",produces = "application/json")
+ public ResponseEntity cicdValidate(@RequestBody LoadSCA loadSCA,
+ Principal principal) throws UnknownHostException {
+ return cicdService.validate(loadSCA, principal);
+ }
+}
diff --git a/src/main/java/io/mixeway/api/cicd/model/CodeProjectInfo.java b/src/main/java/io/mixeway/api/cicd/model/CodeProjectInfo.java
new file mode 100644
index 00000000..b470f341
--- /dev/null
+++ b/src/main/java/io/mixeway/api/cicd/model/CodeProjectInfo.java
@@ -0,0 +1,7 @@
+package io.mixeway.api.cicd.model;
+
+public class CodeProjectInfo {
+
+
+
+}
diff --git a/src/main/java/io/mixeway/api/cicd/model/LoadSCA.java b/src/main/java/io/mixeway/api/cicd/model/LoadSCA.java
new file mode 100644
index 00000000..bddc3980
--- /dev/null
+++ b/src/main/java/io/mixeway/api/cicd/model/LoadSCA.java
@@ -0,0 +1,16 @@
+package io.mixeway.api.cicd.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class LoadSCA {
+ private Long codeProjectId;
+ private String branch;
+ private String commitId;
+}
diff --git a/src/main/java/io/mixeway/api/cicd/service/CICDService.java b/src/main/java/io/mixeway/api/cicd/service/CICDService.java
new file mode 100644
index 00000000..56c13e8a
--- /dev/null
+++ b/src/main/java/io/mixeway/api/cicd/service/CICDService.java
@@ -0,0 +1,207 @@
+package io.mixeway.api.cicd.service;
+
+import io.mixeway.api.cicd.model.LoadSCA;
+import io.mixeway.api.cioperations.model.ZapReportModel;
+import io.mixeway.api.protocol.OpenSourceConfig;
+import io.mixeway.api.protocol.cioperations.GetInfoRequest;
+import io.mixeway.api.protocol.cioperations.InfoScanPerformed;
+import io.mixeway.api.protocol.cioperations.PrepareCIOperation;
+import io.mixeway.api.protocol.securitygateway.SecurityGatewayResponse;
+import io.mixeway.api.protocol.vulnerability.Vuln;
+import io.mixeway.config.Constants;
+import io.mixeway.db.entity.*;
+import io.mixeway.domain.service.cioperations.CreateCiOperationsService;
+import io.mixeway.domain.service.cioperations.FindCiOperationsService;
+import io.mixeway.domain.service.cioperations.UpdateCiOperationsService;
+import io.mixeway.domain.service.scanmanager.code.CreateOrGetCodeProjectService;
+import io.mixeway.domain.service.scanmanager.code.FindCodeProjectService;
+import io.mixeway.domain.service.scanmanager.code.GetOrCreateCodeProjectBranchService;
+import io.mixeway.domain.service.scanmanager.code.UpdateCodeProjectService;
+import io.mixeway.domain.service.vulnmanager.VulnTemplate;
+import io.mixeway.scanmanager.service.code.CodeScanService;
+import io.mixeway.scanmanager.service.opensource.OpenSourceScanService;
+import io.mixeway.scanmanager.service.webapp.WebAppScanService;
+import io.mixeway.utils.*;
+import io.mixeway.utils.ScannerType;
+import io.mixeway.utils.Status;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.security.*;
+import java.security.cert.CertificateException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+@Log4j2
+public class CICDService {
+ private final CreateOrGetCodeProjectService createOrGetCodeProjectService;
+ private final OpenSourceScanService openSourceScanService;
+ private final FindCodeProjectService findCodeProjectService;
+ private final FindCiOperationsService findCiOperationsService;
+ private final CreateCiOperationsService createCiOperationsService;
+ private final UpdateCodeProjectService updateCodeProjectService;
+ private final GetOrCreateCodeProjectBranchService getOrCreateCodeProjectBranchService;
+ private final PermissionFactory permissionFactory;
+ private final CodeScanService codeScanService;
+ private final WebAppScanService webAppScanService;
+ private final VulnTemplate vulnTemplate;
+ private final SecurityQualityGateway securityQualityGateway;
+ private final UpdateCiOperationsService updateCiOperationsService;
+
+
+ public ResponseEntity getCPInfo(GetInfoRequest getInfoRequest, Principal principal) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ CodeProject codeProject = createOrGetCodeProjectService.createOrGetCodeProject(getInfoRequest.getRepoUrl(), getInfoRequest.getBranch(), getInfoRequest.getRepoName(), principal);
+ if (StringUtils.isBlank(codeProject.getdTrackUuid())) {
+ openSourceScanService.createProjectOnOpenSourceScanner(codeProject);
+ }
+ OpenSourceConfig openSourceConfig = openSourceScanService
+ .getOpenSourceScannerConfiguration(
+ codeProject.getProject().getId(),
+ codeProject.getName(),
+ codeProject.getName(),
+ principal)
+ .getBody();
+ // FOR NOW owasp dtrack hardcoded
+ return new ResponseEntity<>(new PrepareCIOperation(openSourceConfig, codeProject, "OWASP Dependency Track"), HttpStatus.OK);
+
+ }
+
+ public ResponseEntity loadSca(LoadSCA loadSCA, Principal principal) throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
+ Optional codeProject = findCodeProjectService.findById(loadSCA.getCodeProjectId());
+ if (codeProject.isPresent() ){
+ Optional ciOperations = findCiOperationsService.findByCodeProjectAndCommitId(codeProject.get(), loadSCA.getCommitId());
+ if (!ciOperations.isPresent()){
+ createCiOperationsService.create(codeProject.get(), loadSCA);
+ }
+ CodeProjectBranch codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), loadSCA.getBranch());
+ updateCodeProjectService.changeCommitId(loadSCA.getCommitId(), codeProject.get());
+ openSourceScanService.loadVulnerabilitiesForBranch(codeProject.get(), loadSCA.getBranch());
+ return new ResponseEntity<>(HttpStatus.OK);
+ } else {
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ }
+
+ @Transactional
+ public ResponseEntity loadVulnerabilitiesFromCICDToProject(List vulns, Long projectId,
+ String branch,
+ String commitId, Principal principal) {
+ Optional codeProject = findCodeProjectService.findById(projectId);
+ if (codeProject.isPresent() && permissionFactory.canUserAccessProject(principal, codeProject.get().getProject())) {
+ CodeProjectBranch codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), branch);
+ updateCodeProjectService.changeCommitId(commitId, codeProject.get());
+
+
+ // to support legacy application where client call SAST while it should be IAC
+ List sastVulns = vulns.stream().filter(v -> v.getScannerType().equals(ScannerType.IAC)).collect(Collectors.toList());
+ if (sastVulns.size() > 0 ){
+ codeScanService.loadVulnsFromCICDToCodeProjectForBranch(codeProject.get(), sastVulns, ScannerType.IAC, codeProjectBranch);
+ } else {
+ codeScanService.loadVulnsFromCICDToCodeProjectForBranch(codeProject.get(), new ArrayList<>(), ScannerType.IAC, codeProjectBranch);
+ }
+ List gitLeaksVulns = vulns.stream().filter(v -> v.getScannerType().equals(ScannerType.GITLEAKS)).collect(Collectors.toList());
+ if (gitLeaksVulns.size() > 0 ){
+ codeScanService.loadVulnsFromCICDToCodeProjectForBranch(codeProject.get(), gitLeaksVulns, ScannerType.GITLEAKS, codeProjectBranch);
+ } else {
+ codeScanService.loadVulnsFromCICDToCodeProjectForBranch(codeProject.get(), new ArrayList<>(), ScannerType.GITLEAKS, codeProjectBranch);
+ }
+ //FOR NOW THIS FUNCTIONALITY IS NOT MIGRATED TO V3
+// List openSourceVulns = vulns.stream().filter(v -> v.getScannerType().equals(ScannerType.OPENSOURCE)).collect(Collectors.toList());
+// if (openSourceVulns.size() > 0) {
+// openSourceScanService.loadVulnsFromCICDToCodeProject(codeProject.get(), openSourceVulns);
+// } else {
+// openSourceScanService.loadVulnsFromCICDToCodeProject(codeProject.get(), new ArrayList<>());
+// }
+
+ return new ResponseEntity<>(new Status("Vulnerabilities uploaded"), HttpStatus.OK);
+
+ } else {
+ return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+
+ }
+
+ public ResponseEntity performSastScanForCodeProject(LoadSCA loadSCA, Principal principal) {
+ Optional codeProject = findCodeProjectService.findById(loadSCA.getCodeProjectId());
+ if (codeProject.isPresent() && permissionFactory.canUserAccessProject(principal, codeProject.get().getProject())) {
+ CodeProjectBranch codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), loadSCA.getBranch());
+ updateCodeProjectService.updateActiveBranch(codeProject.get(), codeProjectBranch);
+ codeScanService.putCodeProjectToQueue(codeProject.get().getId(),principal);
+
+ log.info("[CICD] {} put SAST Project in queue - {}", principal.getName(), codeProject.get().getName());
+ return new ResponseEntity<>(HttpStatus.OK);
+ } else {
+ log.error("[CICD] {} tries to run SAST scan for id {} but project doesnt exist or user has no permission to do so.", principal.getName(), loadSCA.getCodeProjectId());
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ }
+
+ /**
+ * ZAP reports
+ */
+
+ @Transactional
+ public ResponseEntity loadVulnZap(ZapReportModel loadVulnModel, String ciid, Principal principal) throws ParseException {
+ log.info("ZAP DAST JSON report received for ciid {}", ciid);
+ return webAppScanService.prepareAndLoadZapVulns(loadVulnModel,ciid,principal);
+ }
+
+ public ResponseEntity validate(LoadSCA loadSCA, Principal principal) throws UnknownHostException {
+ Optional codeProject = findCodeProjectService.findById(loadSCA.getCodeProjectId());
+ if (codeProject.isPresent() && permissionFactory.canUserAccessProject(principal, codeProject.get().getProject())) {
+ CodeProjectBranch codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), loadSCA.getBranch());
+
+
+ List vulns = vulnTemplate.projectVulnerabilityRepository.findByCodeProjectAndCodeProjectBranch(codeProject.get(), codeProjectBranch).stream().filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED)).collect(Collectors.toList());
+ List vulnList = new ArrayList<>();
+ vulns.removeIf(projectVulnerability -> projectVulnerability.getGrade() == 0);
+ for (ProjectVulnerability pv : vulns){
+ if (pv.getVulnerabilitySource().getId().equals(vulnTemplate.SOURCE_OPENSOURCE.getId())){
+ vulnList.add(new Vuln(pv,null,null,pv.getCodeProject(),Constants.VULN_TYPE_OPENSOURCE));
+ } else if (pv.getVulnerabilitySource().getId().equals(vulnTemplate.SOURCE_SOURCECODE.getId())){
+ vulnList.add(new Vuln(pv,null,null,pv.getCodeProject(),Constants.VULN_TYPE_SOURCECODE));
+ } else if (pv.getVulnerabilitySource().getId().equals(vulnTemplate.SOURCE_GITLEAKS.getId())){
+ vulnList.add(new Vuln(pv,null,null,pv.getCodeProject(),Constants.VULN_TYPE_SOURCECODE));
+ } else if (pv.getVulnerabilitySource().getId().equals(vulnTemplate.SOURCE_IAC.getId())){
+ vulnList.add(new Vuln(pv,null,null,pv.getCodeProject(),Constants.VULN_TYPE_SOURCECODE));
+ }
+ }
+ vulnList.removeIf(vuln -> vuln.getId() == null);
+ SecurityGatewayEntry securityGatewayEntry = securityQualityGateway.buildGatewayResponse(vulns);
+ updateCiOperationWithSecurityGatewayResponse(codeProject.get(), securityGatewayEntry);
+ return new ResponseEntity(
+ new SecurityGatewayResponse(securityGatewayEntry.isPassed(),
+ securityGatewayEntry.isPassed() ? Constants.SECURITY_GATEWAY_PASSED : Constants.SECURITY_GATEWAY_FAILED,
+ vulnList),
+ HttpStatus.OK);
+
+
+ }else {
+ log.error("[CICD] {} tries to run Validate project of id {} but project doesnt exist or user has no permission to do so.", principal.getName(), loadSCA.getCodeProjectId());
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ }
+
+ /**
+ * Updating CIOperations entry (for codeproject, branch and commitid) with scan performed, result and vulnerabilities number
+ * @param codeProject to edit cioperations
+ * @param securityGatewayEntry to check vulnerabilities number
+ */
+ private void updateCiOperationWithSecurityGatewayResponse(CodeProject codeProject, SecurityGatewayEntry securityGatewayEntry) {
+ Optional ciOperations = findCiOperationsService.findByCodeProjectAndCommitId(codeProject, codeProject.getCommitid());
+ ciOperations.ifPresent(operations -> updateCiOperationsService.updateCiOperations(operations, securityGatewayEntry, codeProject));
+ }
+}
diff --git a/src/main/java/io/mixeway/api/cioperations/controller/CiOperationsController.java b/src/main/java/io/mixeway/api/cioperations/controller/CiOperationsController.java
index 93021207..e2d11351 100644
--- a/src/main/java/io/mixeway/api/cioperations/controller/CiOperationsController.java
+++ b/src/main/java/io/mixeway/api/cioperations/controller/CiOperationsController.java
@@ -77,16 +77,16 @@ public ResponseEntity codeScan(@PathVariable(value = "projectId") Long i
Principal principal) throws IOException, CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, JSONException, ParseException {
return ciOperationsService.codeScan(id,groupName,projectName,commitId, principal);
}
- @CrossOrigin(origins="*")
- @PreAuthorize("hasAuthority('ROLE_API')")
- @GetMapping(value = "/project/{projectId}/code/verify/{codeGroup}/{codeProject}/{commitid}",produces = "application/json")
- public ResponseEntity codeVerify(@PathVariable(value = "codeGroup") String codeGroup,
- @PathVariable(value = "codeProject") String codeProject,
- @PathVariable(value = "projectId") Long id,
- @PathVariable("commitid") String commitid,
- Principal principal) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
- return ciOperationsService.codeVerify(codeGroup, codeProject, id, commitid, principal);
- }
+// @CrossOrigin(origins="*")
+// @PreAuthorize("hasAuthority('ROLE_API')")
+// @GetMapping(value = "/project/{projectId}/code/verify/{codeGroup}/{codeProject}/{commitid}",produces = "application/json")
+// public ResponseEntity codeVerify(@PathVariable(value = "codeGroup") String codeGroup,
+// @PathVariable(value = "codeProject") String codeProject,
+// @PathVariable(value = "projectId") Long id,
+// @PathVariable("commitid") String commitid,
+// Principal principal) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+// return ciOperationsService.codeVerify(codeGroup, codeProject, id, commitid, principal);
+// }
@CrossOrigin(origins="*")
diff --git a/src/main/java/io/mixeway/api/dashboard/service/DashboardService.java b/src/main/java/io/mixeway/api/dashboard/service/DashboardService.java
index fa3924f2..4c704dd4 100644
--- a/src/main/java/io/mixeway/api/dashboard/service/DashboardService.java
+++ b/src/main/java/io/mixeway/api/dashboard/service/DashboardService.java
@@ -163,7 +163,7 @@ public ResponseEntity getRootStatistics(Principal princi
findProjectService.count(),
getScanNumberService.getNumberOfScansRunning(),
getScanNumberService.getNumberOfScansInQueue(),
- vulnTemplate.projectVulnerabilityRepository.count()
+ vulnTemplate.projectVulnerabilityRepository.countVulns()
);
dashboardTopStatistics.setStatisticCard(statisticCard);
dashboardTopStatistics.setProjectVulnerabilityList(projectVulnerabilities.stream().limit(5).collect(Collectors.toList()));
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..5204e7b6 100644
--- a/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java
+++ b/src/main/java/io/mixeway/api/project/controller/ProjectRestController.java
@@ -17,7 +17,7 @@
@RestController()
@RequestMapping("/v2/api/show/project")
-public class ProjectRestController {
+public class ProjectRestController {
private final ProjectRestService projectService;
ProjectRestController(ProjectRestService projectRestService){
@@ -110,4 +110,18 @@ public ResponseEntity getProjectByCiid(@PathVariable("ciid") String cii
return projectService.getProjectByCiid(ciid, principal);
}
+ @PreAuthorize("hasAuthority('ROLE_USER')")
+ @GetMapping(value = "/{id}/detailstats")
+ public ResponseEntity detailStats(@PathVariable("id") Long id, Principal principal) {
+ return projectService.detailStats(id, principal);
+ }
+
+ @PreAuthorize("hasAuthority('ROLE_USER')")
+ @GetMapping(value = "/{id}/detailedhistory")
+ public ResponseEntity> detailedHistory(@PathVariable("id") Long id, Principal principal) {
+ return projectService.detailedHistory(id, principal);
+ }
+
+
+
}
diff --git a/src/main/java/io/mixeway/api/project/model/DetailStats.java b/src/main/java/io/mixeway/api/project/model/DetailStats.java
new file mode 100644
index 00000000..f6973ef2
--- /dev/null
+++ b/src/main/java/io/mixeway/api/project/model/DetailStats.java
@@ -0,0 +1,16 @@
+package io.mixeway.api.project.model;
+
+import lombok.*;
+
+@Builder
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+public class DetailStats {
+ private int detectedVulnerabilities;
+ private int resolvedVulnerabilities;
+ private int avgTimeToFix;
+ private int resolvedCriticals;
+
+}
diff --git a/src/main/java/io/mixeway/api/project/service/ProjectAuditService.java b/src/main/java/io/mixeway/api/project/service/ProjectAuditService.java
index 0973e64d..9eb64ad4 100644
--- a/src/main/java/io/mixeway/api/project/service/ProjectAuditService.java
+++ b/src/main/java/io/mixeway/api/project/service/ProjectAuditService.java
@@ -34,7 +34,6 @@ public ResponseEntity> getAuditForCodeVulnerability(Code
settings.getLocation(),
createOrGetVulnerabilityService.createOrGetVulnerability(settings.getVulnerability()
));
- log.info("Test");
return new ResponseEntity<>(vulnerabiltyAudits, HttpStatus.OK);
}
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..35fc9f37 100644
--- a/src/main/java/io/mixeway/api/project/service/ProjectRestService.java
+++ b/src/main/java/io/mixeway/api/project/service/ProjectRestService.java
@@ -114,7 +114,7 @@ public ResponseEntity> showSeverityChart(Long id, Principal
HashMap pieData = new HashMap<>();
if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){
for (String severity : severityList){
- pieData.put(severity,vulnTemplate.projectVulnerabilityRepository.countByProjectAndSeverity(project.get(), severity));
+ pieData.put(severity,vulnTemplate.projectVulnerabilityRepository.countVulnsbyProject(project.get(), severity));
}
return new ResponseEntity<>(pieData,HttpStatus.OK);
} else {
@@ -155,7 +155,7 @@ public ResponseEntity> showVulnerabilitiesForProject(
Optional project = findProjectService.findProjectById(id);
if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){
List vulns;
- try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository.findByProject(project.get())) {
+ try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository.findByProject(project.get()).filter(projectVulnerability -> !projectVulnerability.getStatus().getId().equals(vulnTemplate.STATUS_REMOVED.getId()))) {
return new ResponseEntity<>(vulnsForProject.collect(Collectors.toList()),HttpStatus.OK);
}
} else {
@@ -199,8 +199,16 @@ public ResponseEntity setGradeForVulnerability(Long id, Long vulnId,int
if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){
Optional projectVulnerability = vulnTemplate.projectVulnerabilityRepository.findById(vulnId);
if (projectVulnerability.isPresent() && projectVulnerability.get().getProject().getId().equals(project.get().getId()) && (grade==1 || grade==0)) {
- projectVulnerability.get().setGrade(grade);
- log.info("{} - changed Grade for Vulnerability {} to {}", principal.getName(), projectVulnerability.get().getId(), grade);
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository
+ .findByVulnerabilityAndLocationAndDescription(
+ projectVulnerability.get().getVulnerability(),
+ projectVulnerability.get().getLocation(),
+ projectVulnerability.get().getDescription()
+ );
+ projectVulnerabilities.forEach(pv -> pv.setGrade(grade));
+
+ //projectVulnerability.get().setGrade(grade);
+ log.info("{} - changed Grade for Vulnerability {} to {}, affected vulnerabilities in {} branches", principal.getName(), projectVulnerability.get().getId(), grade, 0);
return new ResponseEntity<>( HttpStatus.OK);
}
} else {
@@ -226,9 +234,9 @@ public ResponseEntity showProjectStats(Long id, Principal principa
.repos(project.get().getCodes().size())
.webApps(project.get().getWebapps().size())
.assets(project.get().getAssets().size())
- .vulnCrit(projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL) || pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)).count())
- .vulnMedium(projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM)).count())
- .vulnLow(projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW)).count())
+ .vulnCrit(projectVulnerabilities.stream().filter(pv -> (pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL) || pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)) && !Objects.equals(pv.getStatus().getId(), vulnTemplate.STATUS_REMOVED.getId()) && pv.getGrade()!=0).count())
+ .vulnMedium(projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM) && !Objects.equals(pv.getStatus().getId(), vulnTemplate.STATUS_REMOVED.getId()) && pv.getGrade()!=0).count())
+ .vulnLow(projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW) && !Objects.equals(pv.getStatus().getId(), vulnTemplate.STATUS_REMOVED.getId()) && pv.getGrade()!=0).count())
.build();
return new ResponseEntity<>(projectStats, HttpStatus.OK);
@@ -241,4 +249,49 @@ public ResponseEntity getProjectByCiid(String ciid, Principal principal
Optional project = findProjectService.findProjectByCiid(ciid);
return project.map(value -> new ResponseEntity<>(value, HttpStatus.OK)).orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
+
+ public ResponseEntity detailStats(Long id, Principal principal) {
+ Optional project = findProjectService.findProjectById(id);
+ if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository.findByProject(project.get()).collect(Collectors.toList());
+ int detectedVulnerabilities = projectVulnerabilities.size();
+ long detectedCriticalVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.API_SEVERITY_CRITICAL)).count();
+ long resolvedCriticalVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.API_SEVERITY_CRITICAL) && Objects.equals(pv.getStatus().getId(), vulnTemplate.STATUS_REMOVED.getId()) && pv.getGrade()!=0).count();
+ List solvedVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getStatus().getId().equals(vulnTemplate.STATUS_REMOVED.getId())).collect(Collectors.toList());
+ int percentResolvedCritical = (int) Math.ceil(((double) resolvedCriticalVulnerabilities / detectedCriticalVulnerabilities) * 100);
+ int avgTimeToFix= (int) Math.ceil(calculateAverageDifferenceInDays(solvedVulnerabilities));
+ DetailStats detailStats = DetailStats.builder()
+ .resolvedCriticals(percentResolvedCritical)
+ .detectedVulnerabilities(detectedVulnerabilities)
+ .resolvedVulnerabilities(solvedVulnerabilities.size())
+ .avgTimeToFix(avgTimeToFix)
+ .build();
+ return new ResponseEntity<>(detailStats, HttpStatus.OK);
+ }
+ return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
+ }
+
+ private static double calculateAverageDifferenceInDays(List list) {
+ if (list == null || list.isEmpty()) {
+ // Handle this case as per your requirements, could throw an exception or return 0
+ return 0;
+ }
+
+ long sumOfDifferences = 0;
+ for (ProjectVulnerability pv : list) {
+ sumOfDifferences += pv.calculateDifferenceInDays();
+ }
+
+ // Calculate the average
+ return sumOfDifferences / (double) list.size();
+ }
+
+ public ResponseEntity> detailedHistory(Long id, Principal principal) {
+ Optional project = findProjectService.findProjectById(id);
+ if (project.isPresent() && permissionFactory.canUserAccessProject(principal, project.get())){
+ List vulnHistories = operateOnVulnHistoryService.getLatestVulnHistoryForProject(project.get());
+ return new ResponseEntity<>(vulnHistories, HttpStatus.OK);
+ }
+ return new ResponseEntity<>(HttpStatus.EXPECTATION_FAILED);
+ }
}
diff --git a/src/main/java/io/mixeway/api/protocol/vulnerability/Vuln.java b/src/main/java/io/mixeway/api/protocol/vulnerability/Vuln.java
index ffc45a11..a3da96df 100644
--- a/src/main/java/io/mixeway/api/protocol/vulnerability/Vuln.java
+++ b/src/main/java/io/mixeway/api/protocol/vulnerability/Vuln.java
@@ -58,7 +58,7 @@ public Vuln(ProjectVulnerability projectVulnerability, St
} else if ((target instanceof CodeProject) && projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_OPENSOURCE)){
CodeProject cp = (CodeProject)target;
this.setId(projectVulnerability.getId());
- this.setLocation(cp.getName());
+ this.setLocation(cp.getName() + " / " + projectVulnerability.getSoftwarePacket().getName());
this.setType(Constants.API_SCANNER_PACKAGE);
this.setVulnerabilityName(projectVulnerability.getVulnerability().getName());
this.setSeverity(projectVulnerability.getVulnerability().getSeverity() == null ? projectVulnerability.getSeverity() : projectVulnerability.getVulnerability().getSeverity());
@@ -69,7 +69,11 @@ public Vuln(ProjectVulnerability projectVulnerability, St
this.setDateCreated(projectVulnerability.getInserted());
this.setPacketName(projectVulnerability.getSoftwarePacket().getName());
this.setGrade(projectVulnerability.getGrade());
- } else if ((target instanceof CodeProject) && projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_SOURCECODE)){
+ } else if ((target instanceof CodeProject) &&
+ (projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULNEARBILITY_SOURCE_GITLEAKS) ||
+ projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_SOURCECODE) ||
+ projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULNEARBILITY_SOURCE_IAC))
+ ){
this.setGrade(projectVulnerability.getGrade());
this.setId(projectVulnerability.getId());
this.setVulnerabilityName(projectVulnerability.getVulnerability().getName());
diff --git a/src/main/java/io/mixeway/api/statistic/service/VulnsService.java b/src/main/java/io/mixeway/api/statistic/service/VulnsService.java
index 1ea257f3..c29cbd13 100644
--- a/src/main/java/io/mixeway/api/statistic/service/VulnsService.java
+++ b/src/main/java/io/mixeway/api/statistic/service/VulnsService.java
@@ -159,9 +159,9 @@ public ResponseEntity> getGlobalStatistics(Principal princ
for (Project project: projects){
GlobalStatistic globalStatistic = new GlobalStatistic();
List codeVulns = getProjectVulnerabilitiesService
- .getProjectVulnerabilitiesForProjectAndSourceAndSeverity(project, vulnTemplate.SOURCE_SOURCECODE, Arrays.asList("Critical", "High")) ;
+ .getProjectVulnerabilitiesForProjectAndSourceAndSeverity(project, vulnTemplate.SOURCE_SOURCECODE, Arrays.asList("Critical", "High"));
List scaVulns = getProjectVulnerabilitiesService
- .getProjectVulnerabilitiesForProjectAndSourceAndSeverity(project, vulnTemplate.SOURCE_OPENSOURCE, Arrays.asList("Critical", "High")) ;
+ .getProjectVulnerabilitiesForProjectAndSourceAndSeverity(project, vulnTemplate.SOURCE_OPENSOURCE, Arrays.asList("Critical", "High"));
globalStatistic.setProject(project.getName());
globalStatistic.setCodeVulns(codeVulns.size());
globalStatistic.setScaVulns(scaVulns.size());
diff --git a/src/main/java/io/mixeway/api/vulnmanage/model/Vuln.java b/src/main/java/io/mixeway/api/vulnmanage/model/Vuln.java
index 08b8f577..fa6b7ec0 100644
--- a/src/main/java/io/mixeway/api/vulnmanage/model/Vuln.java
+++ b/src/main/java/io/mixeway/api/vulnmanage/model/Vuln.java
@@ -71,7 +71,7 @@ public Vuln(ProjectVulnerability projectVulnerability, St
this.setDateCreated(projectVulnerability.getInserted());
this.setPacketName(projectVulnerability.getSoftwarePacket().getName());
this.setGrade(projectVulnerability.getGrade());
- } else if ((target instanceof CodeProject) && projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_SOURCECODE)){
+ } else if ((target instanceof CodeProject) && (projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_SOURCECODE) || projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULNEARBILITY_SOURCE_IAC) || projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULNEARBILITY_SOURCE_GITLEAKS) )){
this.setGrade(projectVulnerability.getGrade());
this.setId(projectVulnerability.getId());
this.setVulnerabilityName(projectVulnerability.getVulnerability().getName());
@@ -87,7 +87,8 @@ public Vuln(ProjectVulnerability projectVulnerability, St
this.setDateCreated(projectVulnerability.getInserted());
this.setType(Constants.API_SCANNER_CODE);
}catch (Exception e){
- log.info("asd");
+ e.printStackTrace();
+ log.info("problem with vuln for {}", projectVulnerability.getCodeProject().getName());
}
} else if ((target instanceof WebApp) && projectVulnerability.getVulnerabilitySource().getName().equals(Constants.VULN_TYPE_WEBAPP)){
this.setGrade(projectVulnerability.getGrade());
diff --git a/src/main/java/io/mixeway/api/vulnmanage/service/GetVulnerabilitiesService.java b/src/main/java/io/mixeway/api/vulnmanage/service/GetVulnerabilitiesService.java
index 993c53ee..35ef317a 100644
--- a/src/main/java/io/mixeway/api/vulnmanage/service/GetVulnerabilitiesService.java
+++ b/src/main/java/io/mixeway/api/vulnmanage/service/GetVulnerabilitiesService.java
@@ -7,6 +7,7 @@
import io.mixeway.config.Constants;
import io.mixeway.db.entity.*;
import io.mixeway.db.repository.*;
+import io.mixeway.domain.service.scanmanager.code.FindCodeProjectService;
import io.mixeway.domain.service.vulnmanager.VulnTemplate;
import io.mixeway.scanmanager.service.opensource.OpenSourceScanService;
import lombok.extern.log4j.Log4j2;
@@ -78,6 +79,9 @@ public class GetVulnerabilitiesService {
@Autowired
SecurityGatewayRepository securityGatewayRepository;
+ @Autowired
+ FindCodeProjectService findCodeProjectService;
+
ArrayList severitiesNot = new ArrayList() {{
add("Log");
add("Info");
@@ -110,17 +114,45 @@ private Vulnerabilities setPackageVulns(Vulnerabilities vulns, Project project)
List tmpVulns = vulns.getVulnerabilities();
List softVuln = null;
if (project != null) {
- try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySource(project, vulnTemplate.SOURCE_OPENSOURCE)) {
+ try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySource(project, vulnTemplate.SOURCE_OPENSOURCE).filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
softVuln = vulnsForProject.collect(Collectors.toList());
}
}
else {
try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_OPENSOURCE)) {
+ .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_OPENSOURCE)
+ .filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
softVuln = vulnsForProject.collect(Collectors.toList());
}
}
+ softVuln.removeIf(projectVulnerability -> projectVulnerability.getGrade() == 0);
+
+
+ // Usuniecie duplikatach w branchach
+ Map uniqueVulnsMap = new HashMap<>();
+
for (ProjectVulnerability projectVulnerability : softVuln) {
+ CodeProjectBranch codeProjectBranch = projectVulnerability.getCodeProjectBranch();
+ CodeProject codeProject = projectVulnerability.getCodeProject();
+
+ if (codeProjectBranch != null && codeProject != null) {
+ String branchName = codeProjectBranch.getName();
+ String projectBranch = codeProject.getBranch();
+
+ if (branchName != null && branchName.equals(projectBranch)) {
+ String uniqueKey = branchName + "_" + projectBranch + "_" + projectVulnerability.getId(); // Tworzenie unikalnego klucza
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
+ }
+ } else if ( codeProjectBranch == null && codeProject != null ){
+ String uniqueKey = UUID.randomUUID().toString();
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
+ }
+ }
+
+ List uniqueVulns = new ArrayList<>(uniqueVulnsMap.values());
+
+
+ for (ProjectVulnerability projectVulnerability : uniqueVulns) {
// for (Asset a : projectVulnerability.getSoftwarePacket().getAssets()) {
// String hostname;
// AtomicReference ipAddress = null;
@@ -130,8 +162,13 @@ private Vulnerabilities setPackageVulns(Vulnerabilities vulns, Project project)
// Vuln v = new Vuln(projectVulnerability, hostname, ipAddress.get(), a, Constants.API_SCANNER_PACKAGE);
// tmpVulns.add(v);
// }
- Vuln v = new Vuln(projectVulnerability, null, null,projectVulnerability.getCodeProject(), Constants.API_SCANNER_PACKAGE);
- tmpVulns.add(v);
+ try {
+ Vuln v = new Vuln(projectVulnerability, null, null, projectVulnerability.getCodeProject(), Constants.API_SCANNER_PACKAGE);
+ tmpVulns.add(v);
+ } catch (NullPointerException e ){
+ e.printStackTrace();
+ log.error("[Export for SCA Vulns] Error during exporting vuln for {}", projectVulnerability.getProject().getName());
+ }
}
vulns.setVulnerabilities(tmpVulns);
return vulns;
@@ -165,20 +202,56 @@ private Vulnerabilities setAuditResults(Vulnerabilities vulns,Project project) {
private Vulnerabilities setCodeVulns(Vulnerabilities vulns, Project project) throws UnknownHostException {
List tmpVulns = vulns.getVulnerabilities();
- List codeVulns = null;
+ List codeVulns = new ArrayList<>();
if (project != null) {
- try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectAndVulnerabilitySourceAndAnalysisNot(project, vulnTemplate.SOURCE_SOURCECODE, Constants.FORTIFY_NOT_AN_ISSUE)) {
- codeVulns = vulnsForProject.collect(Collectors.toList());
- }
+ List sastSources = Arrays.asList(vulnTemplate.SOURCE_SOURCECODE, vulnTemplate.SOURCE_GITLEAKS, vulnTemplate.SOURCE_IAC);
+ List projects = Collections.singletonList(project);
+ List codeProjectsWithVulnManageEnabled = findCodeProjectService.getCodeProjectsInListOfProjects(projects);
+ List projectVulnerabilities =
+ vulnTemplate.projectVulnerabilityRepository.findVulnerabilitiesForCode(codeProjectsWithVulnManageEnabled, sastSources)
+ .stream()
+ .filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))
+ .collect(Collectors.toList());
+ codeVulns.addAll(projectVulnerabilities);
}
else {
- try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectInAndVulnerabilitySourceAndAnalysisNot(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_SOURCECODE, Constants.FORTIFY_NOT_AN_ISSUE)){
- codeVulns = vulnsForProject.collect(Collectors.toList());
+ List enabledVulnManageProjects = projectRepository.findByEnableVulnManage(true);
+ List codeProjectsWithVulnManageEnabled = findCodeProjectService.getCodeProjectsInListOfProjects(enabledVulnManageProjects);
+ List sastSources = Arrays.asList(vulnTemplate.SOURCE_SOURCECODE, vulnTemplate.SOURCE_GITLEAKS, vulnTemplate.SOURCE_IAC);
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository.findVulnerabilitiesForCode(codeProjectsWithVulnManageEnabled, sastSources)
+ .stream()
+ .filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))
+ .collect(Collectors.toList());;
+ codeVulns.addAll(projectVulnerabilities);
+ }
+
+ codeVulns.removeIf(projectVulnerability -> projectVulnerability.getGrade() == 0);
+
+ // Return only vulnerabilities in default branch
+ Map uniqueVulnsMap = new HashMap<>();
+
+ for (ProjectVulnerability projectVulnerability : codeVulns) {
+ CodeProjectBranch codeProjectBranch = projectVulnerability.getCodeProjectBranch();
+ CodeProject codeProject = projectVulnerability.getCodeProject();
+
+ if (codeProjectBranch != null && codeProject != null) {
+ String branchName = codeProjectBranch.getName();
+ String projectBranch = codeProject.getBranch();
+
+ if (branchName != null && branchName.equals(projectBranch)) {
+ String uniqueKey = branchName + "_" + projectBranch + "_" + projectVulnerability.getId(); // Tworzenie unikalnego klucza
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
+ }
+ } else if ( codeProjectBranch == null && codeProject != null ){
+ String uniqueKey = UUID.randomUUID().toString();
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
}
}
- for (ProjectVulnerability cv : codeVulns) {
+
+ List uniqueVulns = new ArrayList<>(uniqueVulnsMap.values());
+
+
+ for (ProjectVulnerability cv : uniqueVulns) {
Vuln v = new Vuln(cv, null, null,new CodeProject(), Constants.API_SCANNER_PACKAGE);
tmpVulns.add(v);
}
@@ -191,13 +264,13 @@ private Vulnerabilities setWebApplicationVulns(Vulnerabilities vulns,Project pro
if (project != null) {
//webAppVulns = new ArrayList<>(webAppVulnRepository.findByWebAppIn(project.getWebapps()));
try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectAndVulnerabilitySource(project, vulnTemplate.SOURCE_WEBAPP)) {
+ .findByProjectAndVulnerabilitySource(project, vulnTemplate.SOURCE_WEBAPP).filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
webAppVulns = vulnsForProject.collect(Collectors.toList());
}
}
else {
try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_WEBAPP)) {
+ .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_WEBAPP).filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
webAppVulns = vulnsForProject.collect(Collectors.toList());
}
}
@@ -213,12 +286,12 @@ private Vulnerabilities setInfrastructureVulns(Vulnerabilities vulns,Project pro
List infraVulns = null;
if (project != null) {
try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectAndVulnerabilitySource(project,vulnTemplate.SOURCE_NETWORK)) {
+ .findByProjectAndVulnerabilitySource(project,vulnTemplate.SOURCE_NETWORK).filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
infraVulns = vulnsForProject.collect(Collectors.toList());
}
} else {
try (Stream vulnsForProject = vulnTemplate.projectVulnerabilityRepository
- .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_NETWORK)) {
+ .findByProjectInAndVulnerabilitySource(projectRepository.findByEnableVulnManage(true),vulnTemplate.SOURCE_NETWORK).filter(projectVulnerability -> !projectVulnerability.getStatus().equals(vulnTemplate.STATUS_REMOVED))) {
infraVulns = vulnsForProject.collect(Collectors.toList());
}
}
diff --git a/src/main/java/io/mixeway/db/entity/CiOperations.java b/src/main/java/io/mixeway/db/entity/CiOperations.java
index 65d6e5fd..ffa4999f 100644
--- a/src/main/java/io/mixeway/db/entity/CiOperations.java
+++ b/src/main/java/io/mixeway/db/entity/CiOperations.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.mixeway.api.cicd.model.LoadSCA;
import io.mixeway.api.protocol.cioperations.InfoScanPerformed;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.OnDelete;
@@ -43,6 +44,12 @@ public CiOperations(CodeProject codeProject, InfoScanPerformed infoScanPerformed
this.commitId = infoScanPerformed.getCommitId();
this.openSourceScan = true;
}
+ public CiOperations(CodeProject codeProject, LoadSCA loadSCA) {
+ this.codeProject = codeProject;
+ this.project = codeProject.getProject();
+ this.commitId = loadSCA.getCommitId();
+ this.openSourceScan = true;
+ }
public Date getEnded() {
diff --git a/src/main/java/io/mixeway/db/entity/CodeProject.java b/src/main/java/io/mixeway/db/entity/CodeProject.java
index 093aaace..3a8b54aa 100755
--- a/src/main/java/io/mixeway/db/entity/CodeProject.java
+++ b/src/main/java/io/mixeway/db/entity/CodeProject.java
@@ -34,6 +34,7 @@ public class CodeProject implements VulnSource {
@JsonIgnore private Boolean skipAllScan;
@JsonIgnore private String additionalPath;
@JsonIgnore private boolean inQueue;
+ @JsonIgnore private Set branches;
@JsonIgnore private Set softwarePackets;
private String branch;
@JsonIgnore
@@ -51,10 +52,20 @@ public class CodeProject implements VulnSource {
@JsonIgnore private String scope;
@JsonIgnore private int remoteid;
private String appClient;
+ private String activeBranch;
@JsonIgnore
private Project project;
+ @Column(name="activebranch")
+ public String getActiveBranch() {
+ return activeBranch;
+ }
+
+ public void setActiveBranch(String activeBranch) {
+ this.activeBranch = activeBranch;
+ }
+
public String getRemotename() {
return remotename;
}
@@ -148,6 +159,18 @@ public CodeProject(String projectName, String branch, String commitid) {
this.skipAllScan = true;
this.inQueue = false;
+ }
+ public CodeProject(Project project, String projectName, String branch, String commitid, String repoUrl, String repoUsername, String repoPassword) {
+ this.project = project;
+ this.name = projectName;
+ this.branch = branch;
+ this.commitid = commitid;
+ this.skipAllScan = true;
+ this.inQueue = false;
+ this.repoUrl = repoUrl;
+ this.repoUsername = repoUsername;
+ this.repoPassword = repoPassword;
+
}
public CodeProject() {
@@ -184,7 +207,7 @@ public String getBranch() {
return branch;
}
- public void setBranch(String branch) {
+ protected void setBranch(String branch) {
this.branch = branch;
}
@@ -304,6 +327,16 @@ public void setName(String name) {
public Set getVulns() {
return vulns;
}
+
+ @OneToMany(mappedBy = "codeProject", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ public Set getBranches() {
+ return branches;
+ }
+
+ public void setBranches(Set branches) {
+ this.branches = branches;
+ }
+
public void setVulns(Set vulns) {
this.vulns = vulns;
}
diff --git a/src/main/java/io/mixeway/db/entity/CodeProjectBranch.java b/src/main/java/io/mixeway/db/entity/CodeProjectBranch.java
new file mode 100644
index 00000000..89406de2
--- /dev/null
+++ b/src/main/java/io/mixeway/db/entity/CodeProjectBranch.java
@@ -0,0 +1,55 @@
+package io.mixeway.db.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import javax.persistence.*;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static org.apache.commons.lang3.Validate.notNull;
+
+@Entity
+@EntityScan
+@Table(name = "codeprojectbranch")
+@EntityListeners(AuditingEntityListener.class)
+public class CodeProjectBranch {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ @ManyToOne(fetch = FetchType.EAGER, optional = false)
+ @JoinColumn(name = "codeproject_id", nullable = false)
+ @JsonIgnore
+ private CodeProject codeProject;
+ private String inserted;
+ private String name;
+
+ protected CodeProjectBranch(){}
+
+ public CodeProjectBranch(CodeProject project, String name){
+ notNull(name);
+ notNull(project);
+ this.inserted = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
+ this.name = name;
+ this.codeProject = project;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public CodeProject getCodeProject() {
+ return codeProject;
+ }
+
+ public String getInserted() {
+ return inserted;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/io/mixeway/db/entity/ProjectVulnerability.java b/src/main/java/io/mixeway/db/entity/ProjectVulnerability.java
index 2204f73c..df2bc798 100644
--- a/src/main/java/io/mixeway/db/entity/ProjectVulnerability.java
+++ b/src/main/java/io/mixeway/db/entity/ProjectVulnerability.java
@@ -18,6 +18,9 @@
import javax.persistence.*;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@@ -34,7 +37,6 @@
indexes = {
@Index(columnList = "id",name="projectvulnerability_index")
})
-@EntityListeners(AuditingEntityListener.class)
public class ProjectVulnerability {
private static final Logger log = LoggerFactory.getLogger(ProjectVulnerability.class);
@@ -90,6 +92,13 @@ public class ProjectVulnerability {
@OnDelete(action = OnDeleteAction.CASCADE)
@Audited(targetAuditMode = NOT_AUDITED)
private Status status;
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "codeprojectbranch_id")
+ @OnDelete(action = OnDeleteAction.CASCADE)
+ @Audited(targetAuditMode = NOT_AUDITED)
+ private CodeProjectBranch codeProjectBranch;
+
+ private String created;
@Audited
private String analysis;
@@ -117,7 +126,7 @@ public class ProjectVulnerability {
*/
public ProjectVulnerability(V source,CodeProject codeProject, Vulnerability vulnerability, String description,
String recommendation, String severity, String port, String location, String analysis,
- VulnerabilitySource vulnerabilitySource, CisRequirement cisRequirement) {
+ VulnerabilitySource vulnerabilitySource, CisRequirement cisRequirement, CodeProjectBranch codeProjectBranch) {
this.location = location;
if (source instanceof Interface){
this.anInterface = (Interface)source;
@@ -143,7 +152,13 @@ public ProjectVulnerability(V source,CodeProject codeProj
this.severity = (severity.toLowerCase());
this.port = port;
this.analysis = analysis;
+ if (analysis != null && analysis.equals(Constants.FORTIFY_NOT_AN_ISSUE)){
+ this.grade = 0;
+ } else if (analysis != null && analysis.equals(Constants.FORTIFY_ANALYSIS_EXPLOITABLE)){
+ this.grade = 1;
+ }
this.vulnerabilitySource = vulnerabilitySource;
+ this.codeProjectBranch = codeProjectBranch;
}
/**
@@ -154,7 +169,7 @@ public ProjectVulnerability(V source,CodeProject codeProj
* @param softwarePacketVuln
*/
public ProjectVulnerability(CodeProject codeProject, Vulnerability vuln, VulnerabilityModel vulnerabilityModel,
- SoftwarePacket softwarePacketVuln, VulnerabilitySource vulnerabilitySource) {
+ SoftwarePacket softwarePacketVuln, VulnerabilitySource vulnerabilitySource, CodeProjectBranch codeProjectBranch) {
this.location = softwarePacketVuln.getName();
this.codeProject = codeProject;
this.project = codeProject.getProject();
@@ -164,6 +179,15 @@ public ProjectVulnerability(CodeProject codeProject, Vulnerability vuln, Vulnera
this.severity = vulnerabilityModel.getSeverity().toLowerCase();
this.recommendation = vulnerabilityModel.getRecomendations();
this.description = vulnerabilityModel.getDescription();
+ this.codeProjectBranch = codeProjectBranch;
+ }
+
+ public CodeProjectBranch getCodeProjectBranch() {
+ return codeProjectBranch;
+ }
+
+ public void setCodeProjectBranch(CodeProjectBranch codeProjectBranch) {
+ this.codeProjectBranch = codeProjectBranch;
}
public CisRequirement getCisRequirement() {
@@ -330,6 +354,13 @@ public ProjectVulnerability(){
}
+ public String getCreated() {
+ return created;
+ }
+
+ public void setCreated(String created) {
+ this.created = created;
+ }
/**
* Updates information for vulnerability of type OpenSource
@@ -401,14 +432,17 @@ public boolean equals(Object o) {
if (other.externalId > 0) {
return other.externalId == this.externalId;
- } else if (StringUtils.isNotEmpty(other.location)) {
- return (other.location.equals(this.location) && other.vulnerability.getId().equals(this.vulnerability.getId()));
- } else if (other.softwarePacket != null) {
+ } else if (StringUtils.isNotEmpty(other.location) && other.codeProjectBranch ==null) {
+ return (other.location.equals(this.location) && other.vulnerability.getId().equals(this.vulnerability.getId()) );
+ } else if (StringUtils.isNotEmpty(other.location) && (other.codeProjectBranch !=null && this.codeProjectBranch!=null)) {
+ return (other.location.equals(this.location) && other.vulnerability.getId().equals(this.vulnerability.getId()) && other.codeProjectBranch.getId().equals(this.getCodeProjectBranch().getId()));
+ } else if (other.softwarePacket != null && (other.codeProjectBranch !=null && this.codeProjectBranch!=null)) {
return (other.softwarePacket.getId().equals(this.softwarePacket.getId()) && other.getVulnerability().getId().equals(this.getVulnerability().getId()) &&
- this.vulnerabilitySource.getId().equals(other.vulnerabilitySource.getId()));
- } else if (other.codeProject != null) {
+ this.vulnerabilitySource.getId().equals(other.vulnerabilitySource.getId()) && other.codeProjectBranch.getId().equals(this.getCodeProjectBranch().getId()));
+ } else if (other.codeProject != null && (other.codeProjectBranch !=null && this.codeProjectBranch!=null)) {
return (other.codeProject.getId().equals(this.codeProject.getId()) && other.getVulnerability().getId().equals(this.getVulnerability().getId()) &&
- this.vulnerabilitySource.getId().equals(other.vulnerabilitySource.getId()) && other.location.equals(this.getLocation()));
+ this.vulnerabilitySource.getId().equals(other.vulnerabilitySource.getId()) && other.location.equals(this.getLocation())
+ && other.codeProjectBranch.getId().equals(this.getCodeProjectBranch().getId()));
} else if (this.vulnerability != null) {
return (other.location.equals(this.location) && (other.vulnerability.getId().equals(this.vulnerability.getId())) &&
this.vulnerabilitySource.getId().equals(other.vulnerabilitySource.getId()));
@@ -418,6 +452,7 @@ public boolean equals(Object o) {
}
} catch (NullPointerException e){
if (this.vulnerability != null) {
+ e.printStackTrace();
log.error("[Project Entity] Error during equal method in project enity: this.vulnerability.id={},this.vulnerabilitySource.id={},this.location={} and " +
"o.vulnerability.id={},o.vulnerabilitySource.id={},o.location={}", this.vulnerability.getId(), this.vulnerabilitySource.getId(), this.location,
other.getVulnerability().getId(), other.getVulnerabilitySource().getId(), other.getLocation());
@@ -439,9 +474,11 @@ public final int hashCode() {
@PrePersist
public void prePersist() {
this.inserted = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
+ this.created= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
this.severity = org.apache.commons.lang3.StringUtils.capitalize(this.severity);
}
+
@PreUpdate
public void preUpdate() {
this.inserted = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
@@ -460,4 +497,13 @@ public String getCustomSeverity(){
public void removeTicket() throws URISyntaxException {
BugTrackingService.deleteTicket(this);
}
+
+ public long calculateDifferenceInDays() {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
+
+ LocalDateTime createdDateTime = LocalDateTime.parse(this.created, formatter);
+ LocalDateTime insertedDateTime = LocalDateTime.parse(this.inserted, formatter);
+
+ return ChronoUnit.DAYS.between(createdDateTime, insertedDateTime);
+ }
}
diff --git a/src/main/java/io/mixeway/db/entity/VulnHistory.java b/src/main/java/io/mixeway/db/entity/VulnHistory.java
index dcd809f6..608ebd0a 100755
--- a/src/main/java/io/mixeway/db/entity/VulnHistory.java
+++ b/src/main/java/io/mixeway/db/entity/VulnHistory.java
@@ -36,6 +36,26 @@ public class VulnHistory {
private String name;
private String inserted;
private Project project;
+ private Long resolvedVulnerabilities;
+ private Long avgTimeToFix;
+ private Long percentResolvedCriticals;
+ private Long codeCritVuln;
+ private Long codeHighVuln;
+ private Long codeMediumVuln;
+ private Long codeLowVuln;
+ private Long scaCritVuln;
+ private Long scaHighVuln;
+ private Long scaMediumVuln;
+ private Long scaLowVuln;
+ private Long webAppCritVuln;
+ private Long webAppHighVuln;
+ private Long webAppMediumVuln;
+ private Long webAppLowVuln;
+ private Long assetCritVuln;
+ private Long assetHighVuln;
+ private Long assetMediumVuln;
+ private Long assetLowVuln;
+
@Column(name = "softwarepacketvulnnumber")
public Long getSoftwarePacketVulnNumber() {
@@ -110,4 +130,174 @@ public void setProject(Project project) {
this.project = project;
}
+ @Column(name="resolvedvulnerabilities")
+ public Long getResolvedVulnerabilities() {
+ return resolvedVulnerabilities;
+ }
+
+ public void setResolvedVulnerabilities(Long resolvedVulnerabilities) {
+ this.resolvedVulnerabilities = resolvedVulnerabilities;
+ }
+
+ @Column(name="avgtimetofix")
+ public Long getAvgTimeToFix() {
+ return avgTimeToFix;
+ }
+
+ public void setAvgTimeToFix(Long avgTimeToFix) {
+ this.avgTimeToFix = avgTimeToFix;
+ }
+
+ @Column(name="percentresolvedcriticals")
+ public Long getPercentResolvedCriticals() {
+ return percentResolvedCriticals;
+ }
+
+ public void setPercentResolvedCriticals(Long percentResolvedCriticals) {
+ this.percentResolvedCriticals = percentResolvedCriticals;
+ }
+
+ @Column(name="codecritvuln")
+ public Long getCodeCritVuln() {
+ return codeCritVuln;
+ }
+
+ public void setCodeCritVuln(Long codeCritVuln) {
+ this.codeCritVuln = codeCritVuln;
+ }
+
+ @Column(name="codehighvuln")
+ public Long getCodeHighVuln() {
+ return codeHighVuln;
+ }
+
+ public void setCodeHighVuln(Long codeHighVuln) {
+ this.codeHighVuln = codeHighVuln;
+ }
+
+ @Column(name="codemediumvuln")
+ public Long getCodeMediumVuln() {
+ return codeMediumVuln;
+ }
+
+ public void setCodeMediumVuln(Long codeMediumVuln) {
+ this.codeMediumVuln = codeMediumVuln;
+ }
+
+ @Column(name="codelowvuln")
+ public Long getCodeLowVuln() {
+ return codeLowVuln;
+ }
+
+ public void setCodeLowVuln(Long codeLowVuln) {
+ this.codeLowVuln = codeLowVuln;
+ }
+
+ @Column(name="scacritvuln")
+ public Long getScaCritVuln() {
+ return scaCritVuln;
+ }
+
+ public void setScaCritVuln(Long scaCritVuln) {
+ this.scaCritVuln = scaCritVuln;
+ }
+
+ @Column(name="scahighvuln")
+ public Long getScaHighVuln() {
+ return scaHighVuln;
+ }
+
+ public void setScaHighVuln(Long scaHighVuln) {
+ this.scaHighVuln = scaHighVuln;
+ }
+
+ @Column(name="scamediumvuln")
+ public Long getScaMediumVuln() {
+ return scaMediumVuln;
+ }
+
+ public void setScaMediumVuln(Long scaMediumVuln) {
+ this.scaMediumVuln = scaMediumVuln;
+ }
+
+ @Column(name="scalowvuln")
+ public Long getScaLowVuln() {
+ return scaLowVuln;
+ }
+
+ public void setScaLowVuln(Long scaLowVuln) {
+ this.scaLowVuln = scaLowVuln;
+ }
+
+ @Column(name="webappcritvuln")
+ public Long getWebAppCritVuln() {
+ return webAppCritVuln;
+ }
+
+ public void setWebAppCritVuln(Long webAppCritVuln) {
+ this.webAppCritVuln = webAppCritVuln;
+ }
+
+ @Column(name="webapphighvuln")
+ public Long getWebAppHighVuln() {
+ return webAppHighVuln;
+ }
+
+ public void setWebAppHighVuln(Long webAppHighVuln) {
+ this.webAppHighVuln = webAppHighVuln;
+ }
+
+ @Column(name="webappmediumvuln")
+ public Long getWebAppMediumVuln() {
+ return webAppMediumVuln;
+ }
+
+ public void setWebAppMediumVuln(Long webAppMediumVuln) {
+ this.webAppMediumVuln = webAppMediumVuln;
+ }
+
+ @Column(name="webapplowvuln")
+ public Long getWebAppLowVuln() {
+ return webAppLowVuln;
+ }
+
+ public void setWebAppLowVuln(Long webAppLowVuln) {
+ this.webAppLowVuln = webAppLowVuln;
+ }
+
+ @Column(name="assetcritvuln")
+ public Long getAssetCritVuln() {
+ return assetCritVuln;
+ }
+
+ public void setAssetCritVuln(Long assetCritVuln) {
+ this.assetCritVuln = assetCritVuln;
+ }
+
+ @Column(name="assethighvuln")
+ public Long getAssetHighVuln() {
+ return assetHighVuln;
+ }
+
+ public void setAssetHighVuln(Long assetHighVuln) {
+ this.assetHighVuln = assetHighVuln;
+ }
+
+ @Column(name="assetmediumvuln")
+ public Long getAssetMediumVuln() {
+ return assetMediumVuln;
+ }
+
+ public void setAssetMediumVuln(Long assetMediumVuln) {
+ this.assetMediumVuln = assetMediumVuln;
+ }
+
+ @Column(name="assetlowvuln")
+ public Long getAssetLowVuln() {
+ return assetLowVuln;
+ }
+
+ public void setAssetLowVuln(Long assetLowVuln) {
+ this.assetLowVuln = assetLowVuln;
+ }
}
diff --git a/src/main/java/io/mixeway/db/repository/CodeProjectBranchRepository.java b/src/main/java/io/mixeway/db/repository/CodeProjectBranchRepository.java
new file mode 100644
index 00000000..c2a86020
--- /dev/null
+++ b/src/main/java/io/mixeway/db/repository/CodeProjectBranchRepository.java
@@ -0,0 +1,13 @@
+package io.mixeway.db.repository;
+
+import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
+import io.mixeway.db.entity.CodeScan;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface CodeProjectBranchRepository extends JpaRepository {
+ List findCodeProjectBranchByCodeProject(CodeProject codeProject);
+ CodeProjectBranch findCodeProjectBranchByCodeProjectAndName(CodeProject project, String name);
+}
diff --git a/src/main/java/io/mixeway/db/repository/CodeProjectRepository.java b/src/main/java/io/mixeway/db/repository/CodeProjectRepository.java
index d6c0b628..82922c6e 100755
--- a/src/main/java/io/mixeway/db/repository/CodeProjectRepository.java
+++ b/src/main/java/io/mixeway/db/repository/CodeProjectRepository.java
@@ -55,4 +55,10 @@ public interface CodeProjectRepository extends JpaRepository
List findBydTrackUuidNotNullAndRepoUrlNotNull();
@Query("select cp from CodeProject cp where cp.remotename is null and cp.repoUrl is not null and cp.dTrackUuid is null")
List getCodeProjectsForSynchro();
+
+ @Modifying
+ @Query("UPDATE CodeProject e SET e.branch = :branch WHERE e.id = :id")
+ void updateCodeProjectBranch(@Param("id") Long id, @Param("branch") String branch);
+
+ List findByProjectIn(List enabledVulnManageProjects);
}
diff --git a/src/main/java/io/mixeway/db/repository/ProjectVulnerabilityRepository.java b/src/main/java/io/mixeway/db/repository/ProjectVulnerabilityRepository.java
index e6b9f97a..9971a381 100644
--- a/src/main/java/io/mixeway/db/repository/ProjectVulnerabilityRepository.java
+++ b/src/main/java/io/mixeway/db/repository/ProjectVulnerabilityRepository.java
@@ -30,23 +30,26 @@ public interface ProjectVulnerabilityRepository extends JpaRepository findByProjectAndVulnerabilitySourceAndAnalysisNot(Project project, VulnerabilitySource source, String analyis);
Stream findByProjectAndVulnerabilitySourceInAndAnalysisNot(Project project, List source, String analyis);
@Query(value="select count(pv.*) as value, v.name as namee from projectvulnerability pv, vulnerability v, vulnerabilitysource source where v.id=pv.vulnerability_id " +
- "and pv.severity in ('Critical','High') and analysis != 'Not an Issue' and source.id=pv.vulnerabilitysource_id and source.name='SourceCode' and pv.project_id in :projects and v.severity!='skip' group by v.id order by value desc limit 10", nativeQuery = true)
+ "and pv.severity in ('Critical','High') and pv.status_id!=3 and analysis != 'Not an Issue' and source.id=pv.vulnerabilitysource_id and source.name='SourceCode' and pv.project_id in :projects and v.severity!='skip' group by v.id order by value desc limit 10", nativeQuery = true)
List top10CodeVulns(@Param("projects") List projects);
@Query(value="select count(pv.*) as value, cp.name || '( '|| p.name||')' as namee from projectvulnerability pv, " +
- "codeproject cp, project p, vulnerability v where v.id=pv.vulnerability_id and v.severity!='skip' and p.id=pv.project_id and cp.id=pv.codeproject_id and pv.project_id in :projects group by cp.id, p.name order by value desc limit 10", nativeQuery = true)
+ "codeproject cp, project p, vulnerability v where pv.status_id!=3 and v.id=pv.vulnerability_id and v.severity!='skip' and p.id=pv.project_id and cp.id=pv.codeproject_id and pv.project_id in :projects group by cp.id, p.name order by value desc limit 10", nativeQuery = true)
List top10CodeProjects(@Param("projects") List projects);
Long countByCodeProjectInAndSeverityAndAnalysis(List codeProject, String severity, String analysis);
Long countByCodeProjectInAndSeverityAndAnalysisNot(List codeProject, String severity, String analysis);
Stream findByVulnerabilitySourceAndAnalysisNot(VulnerabilitySource vulnerabilitySource, String analysisNot);
Stream findByProjectInAndVulnerabilitySourceAndAnalysisNot(List project,VulnerabilitySource vulnerabilitySource, String analysisNot);
+ Stream findByProjectInAndVulnerabilitySourceAndAnalysisNotOrAnalysisIsNull(List project,VulnerabilitySource vulnerabilitySource, String analysisNot);
Stream findByCodeProjectAndVulnerabilitySource(CodeProject cp, VulnerabilitySource vulnerabilitySource);
+ Stream findByCodeProjectAndVulnerabilitySourceAndCodeProjectBranch(CodeProject cp, VulnerabilitySource vulnerabilitySource, CodeProjectBranch codeProjectBranch);
List findByVulnerabilitySourceAndCodeProject(VulnerabilitySource vulnerabilitySource, CodeProject cp);
+ List findByVulnerabilitySourceAndCodeProjectAndCodeProjectBranch(VulnerabilitySource vulnerabilitySource, CodeProject cp, CodeProjectBranch codeProjectBranch);
Stream findByProjectAndVulnerabilitySourceAndAnalysis(Project project, VulnerabilitySource vs, String analysis);
@Query(value = "select ((count(*) filter (where pv.severity='Critical') * :critWage) + (count(*) filter (where pv.severity='High') * :highWage)) from " +
- "projectvulnerability pv, vulnerability v where v.id=pv.vulnerability_id and v.severity!='skip' and pv.project_id=:project_id and pv.vulnerabilitysource_id = (select id from vulnerabilitysource where name='SourceCode')", nativeQuery = true)
+ "projectvulnerability pv, vulnerability v where pv.status_id!=3 and v.id=pv.vulnerability_id and v.severity!='skip' and pv.project_id=:project_id and pv.vulnerabilitysource_id in (select id from vulnerabilitysource where name='SourceCode' or name='IaC' or name='GitLeaks')", nativeQuery = true)
int countCodeRiskForProject(@Param("project_id")Long project_id,@Param("critWage") int critWage, @Param("highWage") int highWage);
@Query(value = "select ((count(*) filter (where pv.severity='Critical') * :critWage) + (count(*) filter (where pv.severity='High') * :highWage)) from " +
- "projectvulnerability pv, vulnerability v where v.id=pv.vulnerability_id and v.severity!='skip'and pv.codeproject_id =:codeProject_id and pv.analysis !=:analysis and pv.vulnerabilitysource_id = (select id from vulnerabilitysource where name='SourceCode')", nativeQuery = true)
+ "projectvulnerability pv, vulnerability v where pv.status_id!=3 and v.id=pv.vulnerability_id and v.severity!='skip'and pv.codeproject_id =:codeProject_id and pv.analysis !=:analysis and pv.vulnerabilitysource_id = (select id from vulnerabilitysource where name='SourceCode')", nativeQuery = true)
int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("critWage") int critWage, @Param("highWage") int highWage,
@Param("analysis") String analysis);
@Query(value="select count(*) from projectvulnerability where codeproject_id=?1 and severity=?2 and analysis=?3 and vulnerabilitysource_id = (select id from vulnerabilitysource where name='SourceCode'", nativeQuery = true)
@@ -57,7 +60,7 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
List findByProjectAndVulnerabilitySourceAndSeverityNotIn(Project project, VulnerabilitySource vulnerabilitySource, List severities);
- List findByProjectAndVulnerabilitySourceAndSeverityIn(Project project, VulnerabilitySource vulnerabilitySource, List severities);
+ List findByProjectAndVulnerabilitySourceAndSeverityInAndStatusNot(Project project, VulnerabilitySource vulnerabilitySource, List severities, Status status);
List findByAnInterface(Interface anInterface);
@@ -65,11 +68,11 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
@Query(value="select distinct v.port from ProjectVulnerability v where v.anInterface = :interface and v.vulnerabilitySource.name='Service Detection'")
List getPortsFromInfraVulnForInterface(@Param("interface") Interface anInterface);
@Query(value="select count(pv.*) as value, v.name as namee from projectvulnerability pv, vulnerability v, vulnerabilitysource vs where " +
- "vs.id=pv.vulnerabilitysource_id and pv.vulnerability_id=v.id and vs.name='Network' and pv.severity in ('Critic','Critical','High') and pv.project_id in :projects group " +
+ "vs.id=pv.vulnerabilitysource_id and pv.status_id!=3 and pv.vulnerability_id=v.id and vs.name='Network' and pv.severity in ('Critic','Critical','High') and pv.project_id in :projects group " +
"by v.name order by value desc limit 10", nativeQuery = true)
List top10InfraVulns(@Param("projects") List projects);
@Query(value="select count(*) as value, i.privateip||' ('||p.name||')' as namee from project p, projectvulnerability iv, interface i, asset a,vulnerabilitysource so where p.id=iv.project_Id and so.id=iv.vulnerabilitysource_id " +
- "and so.name='Network' and iv.project_id in :projects and iv.interface_id=i.id and i.asset_id=a.id and iv.severity in ('Critical','High') group by namee order by value desc limit 10",nativeQuery = true)
+ "and so.name='Network' and iv.status_id!=3 and iv.project_id in :projects and iv.interface_id=i.id and i.asset_id=a.id and iv.severity in ('Critical','High') group by namee order by value desc limit 10",nativeQuery = true)
List top10Interfaces(@Param("projects") List projects);
Long countByAnInterfaceInAndSeverity(List interfaces, String severity);
Stream findByanInterfaceInAndSeverityNotIn(List interfaces, List severities);
@@ -77,11 +80,11 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
@Query(value = "SELECT i from ProjectVulnerability i where i.anInterface in :interfaces and i.port like '%www%'")
List getVulnsByInterfacesAndWithWWW(@Param("interfaces") List interfaces);
@Query(value = "select ((count(*) filter (where severity='Critical') * :critWage) + (count(*) filter (where severity='High') * :highWage) + (count(*) filter (where severity='Medium') * :mediumWage)) from " +
- "projectvulnerability where interface_id in (select id from interface where asset_id in (select id from asset where project_id =:project_id)) and " +
+ "projectvulnerability where status_id != 3 and interface_id in (select id from interface where asset_id in (select id from asset where project_id =:project_id)) and " +
"vulnerabilitysource_id = (select id from vulnerabilitysource where name='Network')", nativeQuery = true)
int countNetworkRiskForProject(@Param("project_id")Long project_id,@Param("critWage") int critWage, @Param("highWage") int highWage,@Param("mediumWage") int mediumWage);
@Query(value = "select ((count(*) filter (where severity='Critical') * :critWage) + (count(*) filter (where severity='High') * :highWage) + (count(*) filter (where severity='Medium') * :mediumWage)) from " +
- "projectvulnerability where interface_id =:interface_id and vulnerabilitysource_id = (select id from vulnerabilitysource where name='Network')", nativeQuery = true)
+ "projectvulnerability where status_id!=3 and interface_id =:interface_id and vulnerabilitysource_id = (select id from vulnerabilitysource where name='Network')", nativeQuery = true)
int countRiskForInterface(@Param("interface_id")Long interface_id,@Param("critWage") int critWage, @Param("highWage") int highWage,@Param("mediumWage") int mediumWage);
//
@@ -93,12 +96,12 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
Optional findBySoftwarePacketAndVulnerabilityAndCodeProject(SoftwarePacket softwarePacket, Vulnerability vulnerability, CodeProject codeProject);
@Query(value = "select count(spv) as value, sp.name as namee from softwarepacket sp inner join projectvulnerability spv on " +
"spv.softwarepacket_id=sp.id inner join vulnerabilitysource vs on vs.id=spv.vulnerabilitysource_id where vs.name='OpenSource' and " +
- "spv.severity in ('Critic', 'Critical', 'High') and spv.project_id in :projects group by sp.name order by value desc limit 10", nativeQuery = true)
+ "spv.severity in ('Critic', 'Critical', 'High') and spv.status_id!=3 and spv.project_id in :projects group by sp.name order by value desc limit 10", nativeQuery = true)
List top10OpenSource(@Param("projects") List projects);
@Query(value="select count(spv) as value, cp.name||' ('||p.name||')' as namee from codeproject cp " +
"inner join projectvulnerability spv on cp.id = spv.codeproject_id inner join project p on " +
"p.id=spv.project_id inner join vulnerabilitysource vs on vs.id=spv.vulnerabilitysource_id where vs.name='OpenSource' and spv.severity in " +
- "('Critic', 'Critical', 'High') and spv.project_id in :projects group by cp.name, p.name order by value desc limit 10", nativeQuery = true)
+ "('Critic', 'Critical', 'High') and spv.status_id!=3 and spv.project_id in :projects group by cp.name, p.name order by value desc limit 10", nativeQuery = true)
List top10OpenSourceCodeProjects(@Param("projects") List projects);
Optional findByVulnerabilityAndVulnerabilitySource(Vulnerability vulnerability, VulnerabilitySource vulnerabilitySource);
@Query(value="select spv.* from projectvulnerability spv, codeproject_softwarepacket csp where spv.softwarepacket_id = csp.softwarepacket_id " +
@@ -109,11 +112,11 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
//
@Query(value = "select count(*) as value, w.url ||' ('||p.name||')' as namee from project p, projectvulnerability wv, webapp w, " +
- "vulnerabilitysource vs where vs.id=wv.vulnerabilitysource_id and vs.name='WebApplication' and p.id=wv.project_id and w.id=wv.webapp_id " +
+ "vulnerabilitysource vs where wv.status_id != 3 and vs.id=wv.vulnerabilitysource_id and vs.name='WebApplication' and p.id=wv.project_id and w.id=wv.webapp_id " +
"and wv.severity in ('High','Critical') and wv.project_id in :projects group by w.url,p.name order by value desc limit 10", nativeQuery = true)
List top10WebApps(@Param("projects") List projects);
@Query(value = "select count(pv.*) as value, v.name as namee from projectvulnerability pv, vulnerability v, vulnerabilitysource vs where " +
- "vs.id=pv.vulnerabilitysource_id and pv.vulnerability_id=v.id and vs.name='WebApplication' and pv.severity in ('Critic','Critical','High') and pv.project_id in :projects" +
+ "vs.id=pv.vulnerabilitysource_id and pv.status_id!=3 and pv.vulnerability_id=v.id and vs.name='WebApplication' and pv.severity in ('Critic','Critical','High') and pv.project_id in :projects" +
" group by v.name order by value desc limit 10", nativeQuery = true)
List top10WebAppVulns(@Param("projects") List projects);
Long countByWebAppInAndSeverity(List webApps, String severity);
@@ -123,10 +126,10 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
void deleteByWebApp(WebApp webApp);
Stream findByWebAppInAndVulnerabilitySourceAndSeverityIn(List webApps, VulnerabilitySource vulnerabilitySource, List severities);
@Query(value = "select ((count(*) filter (where severity='Critical') * :critWage) + (count(*) filter (where severity='High') * :highWage) + (count(*) filter (where severity='Medium') * :mediumWage)) from " +
- "projectvulnerability where webapp_id in (select id from webapp where project_id=:project_id) and vulnerabilitysource_id = (select id from vulnerabilitysource where name='WebApplication')", nativeQuery = true)
+ "projectvulnerability where status_id!=3 and webapp_id in (select id from webapp where project_id=:project_id) and vulnerabilitysource_id = (select id from vulnerabilitysource where name='WebApplication')", nativeQuery = true)
int countWebAppRiskForProject(@Param("project_id")Long project_id,@Param("critWage") int critWage, @Param("highWage") int highWage,@Param("mediumWage") int mediumWage);
@Query(value = "select ((count(*) filter (where severity='Critical') * :critWage) + (count(*) filter (where severity='High') * :highWage) + (count(*) filter (where severity='Medium') * :mediumWage)) from " +
- "projectvulnerability where webapp_id =:webapp_id and vulnerabilitysource_id = (select id from vulnerabilitysource where name='WebApplication')", nativeQuery = true)
+ "projectvulnerability where status_id!=3 and webapp_id =:webapp_id and vulnerabilitysource_id = (select id from vulnerabilitysource where name='WebApplication')", nativeQuery = true)
int countRiskForWebApp(@Param("webapp_id")Long webapp_id,@Param("critWage") int critWage, @Param("highWage") int highWage,@Param("mediumWage") int mediumWage);
//
@@ -151,6 +154,11 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
@Query(value = "update projectvulnerability set status_id = :status where id in :vulns", nativeQuery = true)
void updateVulnState(@Param("vulns") List tmpVulns,@Param("status") Long status);
+ @Modifying
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
+ @Query(value = "update projectvulnerability set status_id = :status where id in :vulns and codeprojectbranch_id = :branch", nativeQuery = true)
+ void updateVulnStateForBranch(@Param("vulns") List tmpVulns,@Param("status") Long status, @Param("branch") Long branch);
+
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
void deleteByStatus(Status status);
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
@@ -160,6 +168,9 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
int deleteByStatusAndCodeProjectAndVulnerabilitySource(Status status, CodeProject codeProject, VulnerabilitySource vulnerabilitySource);
+ @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="5000")})
+ int deleteByStatusAndCodeProjectAndVulnerabilitySourceAndCodeProjectBranch(Status status, CodeProject codeProject, VulnerabilitySource vulnerabilitySource, CodeProjectBranch codeProjectBranch);
+
@Modifying
@Query(value = "delete from ProjectVulnerability pv where pv.id in :ids")
int deleteProjectVulnerabilityIn(@Param("ids") List ids);
@@ -180,13 +191,27 @@ int countRiskForCodeProject(@Param("codeProject_id")Long codeProject_id,@Param("
void transferCodeProjectVulnerabilities(long newProjectId, long oldProjectId, long codeProjectId);
Long countBySeverityIn(List severities);
- @Query(value="select p.id, count(pv.id) from project p, projectvulnerability pv, vulnerability v where v.id=pv.vulnerability_id and (v. severity is null or v.severity!='skip') and pv.project_id = p.id and pv.severity in ('Critical', 'High', 'Medium') group by p.id order by count desc limit 10", nativeQuery = true)
+ @Query(value="select p.id, count(pv.id) from project p, projectvulnerability pv, vulnerability v where v.id=pv.vulnerability_id and (v. severity is null or v.severity!='skip') and pv.project_id = p.id and pv.severity in ('Critical', 'High', 'Medium') and pv.status_id!=3 group by p.id order by count desc limit 10", nativeQuery = true)
List top10VulnerableProjects();
- @Query(value="select v.id, count(pv.id) from vulnerability v, projectvulnerability pv where (v. severity is null or v.severity!='skip') and pv.vulnerability_id = v.id and pv.severity in ('Critical', 'High', 'Medium') group by v.id order by count desc limit 10", nativeQuery = true)
+ @Query(value="select v.id, count(pv.id) from vulnerability v, projectvulnerability pv where (v. severity is null or v.severity!='skip') and pv.vulnerability_id = v.id and pv.severity in ('Critical', 'High', 'Medium') and pv.status_id!=3 group by v.id order by count desc limit 10", nativeQuery = true)
List top10Vulnerabilities();
List findByCodeProjectAndStatus(CodeProject codeProject, Status status);
List findByWebAppAndStatus(WebApp webApp, Status status);
List findByProjectAndVulnerability(Project project, Vulnerability vulnerability);
long countByProjectAndSeverity(Project project, String severity);
+ @Query("SELECT count(*) FROM ProjectVulnerability pv WHERE pv.project = :project AND pv.severity = :severity AND pv.grade!=0 AND pv.status.id != 3")
+ long countVulnsbyProject(@Param("project") Project project, @Param("severity") String severity);
+
+
+ Optional findBySoftwarePacketAndVulnerabilityAndCodeProjectAndCodeProjectBranch(SoftwarePacket sPacket, Vulnerability vuln, CodeProject codeProject, CodeProjectBranch codeProjectBranch);
+
+ @Query("SELECT pv FROM ProjectVulnerability pv WHERE pv.codeProject IN :codeProjects AND pv.vulnerabilitySource IN :sources AND pv.grade!=0")
+ List findVulnerabilitiesForCode(@Param("codeProjects") List codeProjects, @Param("sources") List sources);
+
+ List findByVulnerabilityAndLocationAndDescription(Vulnerability vulnerability, String location, String description);
+
+ List findByCodeProjectAndCodeProjectBranch(CodeProject codeProject, CodeProjectBranch codeProjectBranch);
+ @Query("SELECT count(*) FROM ProjectVulnerability pv where pv.status.id!=3")
+ long countVulns();
}
diff --git a/src/main/java/io/mixeway/domain/service/cioperations/CreateCiOperationsService.java b/src/main/java/io/mixeway/domain/service/cioperations/CreateCiOperationsService.java
index 7b6f6980..a90b88aa 100644
--- a/src/main/java/io/mixeway/domain/service/cioperations/CreateCiOperationsService.java
+++ b/src/main/java/io/mixeway/domain/service/cioperations/CreateCiOperationsService.java
@@ -1,5 +1,6 @@
package io.mixeway.domain.service.cioperations;
+import io.mixeway.api.cicd.model.LoadSCA;
import io.mixeway.api.protocol.cioperations.InfoScanPerformed;
import io.mixeway.db.entity.CiOperations;
import io.mixeway.db.entity.CodeProject;
@@ -33,6 +34,9 @@ public void create(SASTRequestVerify verifyRequest, Project project, String comm
public CiOperations create(CodeProject codeProject, InfoScanPerformed infoScanPerformed) {
return ciOperationsRepository.save(new CiOperations(codeProject, infoScanPerformed));
}
+ public CiOperations create(CodeProject codeProject, LoadSCA loadSca) {
+ return ciOperationsRepository.save(new CiOperations(codeProject, loadSca));
+ }
public CiOperations create(SecurityGatewayEntry securityGatewayEntry, CodeProject codeProject, Optional optionalCiOperations){
CiOperations ciOperations = optionalCiOperations.orElseGet(CiOperations::new);
ciOperations.setResult(securityGatewayEntry.isPassed() ? "Ok" : "Not Ok");
diff --git a/src/main/java/io/mixeway/domain/service/projectvulnerability/DeleteProjectVulnerabilityService.java b/src/main/java/io/mixeway/domain/service/projectvulnerability/DeleteProjectVulnerabilityService.java
index b19d499c..4f0347f1 100644
--- a/src/main/java/io/mixeway/domain/service/projectvulnerability/DeleteProjectVulnerabilityService.java
+++ b/src/main/java/io/mixeway/domain/service/projectvulnerability/DeleteProjectVulnerabilityService.java
@@ -22,8 +22,8 @@ public class DeleteProjectVulnerabilityService {
private final ProjectVulnerabilityRepository projectVulnerabilityRepository;
private final VulnTemplate vulnTemplate;
- public void deleteProjectVulnerabilityWithStatus(Project project, Status status) {
- List toRemove = vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySource(project, vulnTemplate.SOURCE_SOURCECODE).filter(v -> v.getStatus().getId().equals(status.getId())).collect(Collectors.toList());
+ public void deleteProjectVulnerabilityWithStatus(Project project, Status status, VulnerabilitySource vulnerabilitySource) {
+ List toRemove = vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySource(project, vulnerabilitySource).filter(v -> v.getStatus().getId().equals(status.getId())).collect(Collectors.toList());
if (toRemove.size() > 0) {
vulnTemplate.projectVulnerabilityRepository.deleteAll(toRemove);
log.info("[ProjectVulnerability] Removed {} Project Vulnerabilities with status {} for project {}", toRemove.size(),status.getName(),project.getName());
diff --git a/src/main/java/io/mixeway/domain/service/projectvulnerability/GetProjectVulnerabilitiesService.java b/src/main/java/io/mixeway/domain/service/projectvulnerability/GetProjectVulnerabilitiesService.java
index 5a55f432..b81bf191 100644
--- a/src/main/java/io/mixeway/domain/service/projectvulnerability/GetProjectVulnerabilitiesService.java
+++ b/src/main/java/io/mixeway/domain/service/projectvulnerability/GetProjectVulnerabilitiesService.java
@@ -31,7 +31,7 @@ public List getProjectVulnerabilitiesForSource(VulnSource
}
public List getProjectVulnerabilitiesForProjectAndSourceAndSeverity(Project project, VulnerabilitySource vulnerabilitySource,List severities){
- return vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceAndSeverityIn(project,vulnerabilitySource, severities);
+ return vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceAndSeverityInAndStatusNot(project,vulnerabilitySource, severities, vulnTemplate.STATUS_REMOVED);
}
public List getProjectVulnerablitiesForCodeProject(CodeProject codeProject, String filter) {
@@ -93,5 +93,25 @@ public List getOldVulnsForCodeProjectAndSource(CodeProject
return codeVulns;
}
+ /**
+ * Getting old vulnerabilities for CodeProject, and set status to removed v3API
+ *
+ * @param codeProject CodeProject to delate vulns for
+ * @return List of deleted vulns to set proper status
+ */
+// @Transactional(propagation = Propagation.REQUIRES_NEW)
+ @Transactional
+ public List getOldVulnsForCodeProjectAndSourceForBranch(CodeProject codeProject, VulnerabilitySource vulnerabilitySource, CodeProjectBranch codeProjectBranch){
+ List codeVulns = vulnTemplate.projectVulnerabilityRepository.findByCodeProjectAndVulnerabilitySourceAndCodeProjectBranch(codeProject, vulnerabilitySource, codeProjectBranch).collect(Collectors.toList());
+ if (codeVulns.size() > 0) {
+ vulnTemplate.projectVulnerabilityRepository.updateVulnState(codeVulns.stream().map(ProjectVulnerability::getId).collect(Collectors.toList()),
+ vulnTemplate.STATUS_REMOVED.getId());
+ codeVulns.forEach(pv -> pv.setStatus(vulnTemplate.STATUS_REMOVED));
+ }
+
+ return codeVulns;
+ }
+
+
}
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateCodeProjectBranchService.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateCodeProjectBranchService.java
new file mode 100644
index 00000000..ede3bd38
--- /dev/null
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateCodeProjectBranchService.java
@@ -0,0 +1,19 @@
+package io.mixeway.domain.service.scanmanager.code;
+
+import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
+import io.mixeway.db.repository.CodeProjectBranchRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+@Service
+@Log4j2
+@RequiredArgsConstructor
+public class CreateCodeProjectBranchService {
+ private final CodeProjectBranchRepository codeProjectBranchRepository;
+
+ public CodeProjectBranch createCodeProjectBranch(CodeProject codeProject, String branch){
+ return codeProjectBranchRepository.save(new CodeProjectBranch(codeProject,branch));
+ }
+}
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateOrGetCodeProjectService.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateOrGetCodeProjectService.java
index 754b98b7..4e77c1d5 100644
--- a/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateOrGetCodeProjectService.java
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/CreateOrGetCodeProjectService.java
@@ -3,7 +3,9 @@
import io.mixeway.api.project.model.CodeProjectPutModel;
import io.mixeway.config.Constants;
import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
import io.mixeway.db.entity.Project;
+import io.mixeway.db.repository.CodeProjectBranchRepository;
import io.mixeway.db.repository.CodeProjectRepository;
import io.mixeway.domain.service.project.GetOrCreateProjectService;
import io.mixeway.scanmanager.model.CodeScanRequestModel;
@@ -34,40 +36,39 @@ public class CreateOrGetCodeProjectService {
private final CodeProjectRepository codeProjectRepository;
private final VaultHelper vaultHelper;
private final GetOrCreateProjectService getOrCreateProjectService;
+ private final GetOrCreateCodeProjectBranchService getOrCreateCodeProjectBranchService;
public CodeProject getOrCreateCodeProject(Project project, String projectName, String codeDefaultBranch) {
Optional codeProject = codeProjectRepository.findByProjectAndName(project, projectName);
+ codeProject.ifPresent(value -> getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(value, codeDefaultBranch));
return codeProject.orElseGet(() -> createCodeProject(project, projectName, codeDefaultBranch));
}
public CodeProject createCodeProject(Project project, String projectName, String codeDefaultBranch) {
- CodeProject codeProject = new CodeProject();
- codeProject.setProject(project);
- codeProject.setName(projectName);
- codeProject.setBranch(codeDefaultBranch);
- return codeProjectRepository.saveAndFlush(codeProject);
+ CodeProject codeProject = new CodeProject(project, projectName, (codeDefaultBranch == null || codeDefaultBranch.isEmpty()) ? "master" : codeDefaultBranch, null,null,null,null);
+ codeProject = codeProjectRepository.saveAndFlush(codeProject);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+ return codeProject;
}
public CodeProject createCodeProject(CodeScanRequestModel codeScanRequest, Project project) {
- CodeProject codeProject = new CodeProject();
- codeProject.setBranch(codeScanRequest.getBranch());
- codeProject.setRepoUrl(codeScanRequest.getRepoUrl());
- codeProject.setName(codeScanRequest.getCodeProjectName());
- codeProject.setProject(project);
- codeProject.setRepoUsername(codeScanRequest.getRepoUsername());
- codeProject.setRepoPassword(codeScanRequest.getRepoPassword());
+ String branch = codeScanRequest.getBranch();
+ CodeProject codeProject = new CodeProject(project, codeScanRequest.getCodeProjectName(), (branch == null || branch.isEmpty()) ? "master" : branch, null,codeScanRequest.getRepoUrl(), codeScanRequest.getRepoUsername(), codeScanRequest.getRepoPassword());
+
codeProject.setTechnique(codeScanRequest.getTech());
- return codeProjectRepository.saveAndFlush(codeProject);
+
+ codeProject = codeProjectRepository.saveAndFlush(codeProject);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+ return codeProject;
}
public CodeProject createCodeProject(String repoUrl, String repoName, String branch, Principal principal, Project project) {
- CodeProject codeProject = new CodeProject();
- codeProject.setRepoUrl(repoUrl);
- codeProject.setName(repoName);
- codeProject.setBranch(branch);
- codeProject.setProject(project);
- return codeProjectRepository.saveAndFlush(codeProject);
+ CodeProject codeProject = new CodeProject(project, repoName, (branch == null || branch.isEmpty()) ? "master" : branch, null,repoUrl,null,null);
+
+ codeProject = codeProjectRepository.saveAndFlush(codeProject);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+ return codeProject;
}
public CodeProject createOrGetCodeProject(String repoUrl, String branch, String codeProjectName, Principal principal) throws MalformedURLException {
@@ -79,28 +80,44 @@ public CodeProject createOrGetCodeProject(String repoUrl, String branch, String
Optional codeProject = codeProjectRepository.findByRepoUrlOrRepoUrlAndName(repoUrl, repoUrl+".git", codeProjectName);
if (codeProject.isPresent()){
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), branch);
return codeProject.get();
} else {
Project project = getOrCreateProjectService.getProjectByName(name, principal);
- CodeProject codeProject1 = createCodeProject(project, name, "master");
- codeProject1.setBranch(branch);
- codeProject1.setRepoUrl(repoUrl);
- return codeProjectRepository.saveAndFlush(codeProject1);
+ CodeProject codeProject1 = new CodeProject(project,
+ name,
+ (branch == null || branch.isEmpty()) ? "master" : branch,
+ null,
+ repoUrl,
+ null,
+ null);
+
+ codeProject1 = codeProjectRepository.saveAndFlush(codeProject1);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject1, codeProject1.getBranch());
+
+ return codeProject1;
}
}
public CodeProject createOrGetCodeProject(String repoUrl, String branch, Principal principal, Project project) throws MalformedURLException {
Optional codeProject = codeProjectRepository.findByProjectAndRepoUrl(project, repoUrl);
if (codeProject.isPresent()){
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject.get(), branch);
return codeProject.get();
} else {
URL repo = new URL(repoUrl.split("\\.git")[0]);
String projectName, codeProjectName = null;
String[] repoUrlParts = repo.getPath().split("/");
String name = repoUrlParts[repoUrlParts.length-1];
- CodeProject codeProject1 = createCodeProject(project, name, "master");
- codeProject1.setBranch(branch);
- codeProject1.setRepoUrl(repoUrl);
- return codeProjectRepository.saveAndFlush(codeProject1);
+ CodeProject codeProject1 = new CodeProject(project,
+ name,
+ (branch == null || branch.isEmpty()) ? "master" : branch,
+ null,
+ repoUrl,
+ null,
+ null);
+ codeProject1 = codeProjectRepository.saveAndFlush(codeProject1);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject1, codeProject1.getBranch());
+ return codeProject1;
}
}
@@ -116,13 +133,18 @@ public void createCodeProject(Project project, CodeGroupPutModel codeGroupPutMod
codeProject.setVersionIdsingle(codeGroupPutModel.getVersionIdSingle());
codeProject.setProject(project);
codeProject.setAppClient(codeGroupPutModel.getAppClient());
+ String branch = codeGroupPutModel.getBranch();
+ //codeProject.setBranch((branch == null || branch.isEmpty()) ? "master" : branch);
+
String uuidToken = UUID.randomUUID().toString();
if (StringUtils.isNotBlank(codeGroupPutModel.getGitpassword()) && vaultHelper.savePassword(codeGroupPutModel.getGitpassword(), uuidToken)) {
codeProject.setRepoPassword(uuidToken);
} else {
codeProject.setRepoPassword(codeGroupPutModel.getGitpassword());
}
- codeProjectRepository.saveAndFlush(codeProject);
+ codeProject= codeProjectRepository.saveAndFlush(codeProject);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+
}
}
@@ -148,16 +170,21 @@ private String setRepoUrl(CodeGroupPutModel codeGroupPutModel) {
public void createCodeProject(Project project, CodeProjectPutModel codeProjectPutModel) {
Optional codeProjectOptional = codeProjectRepository.findByProjectAndName(project, codeProjectPutModel.getCodeProjectName());
if (!codeProjectOptional.isPresent()){
- CodeProject codeProject = new CodeProject();
+ CodeProject codeProject = new CodeProject(
+ codeProjectPutModel.getCodeProjectName(),
+ codeProjectPutModel.getBranch()!=null && !codeProjectPutModel.getBranch().equals("") ? codeProjectPutModel.getBranch() : Constants.CODE_DEFAULT_BRANCH,
+ null);
codeProject.setProject(project);
- codeProject.setName(codeProjectPutModel.getCodeProjectName());
codeProject.setSkipAllScan(false);
codeProject.setdTrackUuid(codeProjectPutModel.getDTrackUuid());
- codeProject.setBranch(codeProjectPutModel.getBranch()!=null && !codeProjectPutModel.getBranch().equals("") ? codeProjectPutModel.getBranch() : Constants.CODE_DEFAULT_BRANCH);
codeProject.setAdditionalPath(codeProjectPutModel.getAdditionalPath());
codeProject.setRepoUrl(codeProjectPutModel.getProjectGiturl());
codeProject.setTechnique(codeProjectPutModel.getProjectTech());
- codeProjectRepository.save(codeProject);
+ codeProject = codeProjectRepository.saveAndFlush(codeProject);
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+
+ } else {
+ getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProjectOptional.get(), codeProjectOptional.get().getBranch());
}
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/FindCodeProjectService.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/FindCodeProjectService.java
index a4ccfbc8..c46641b8 100644
--- a/src/main/java/io/mixeway/domain/service/scanmanager/code/FindCodeProjectService.java
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/FindCodeProjectService.java
@@ -59,4 +59,8 @@ public List getCodeProjectsWithOSIntegrationEnabled() {
public List findProjectWithoutOSIntegration(){
return codeProjectRepository.getCodeProjectsForSynchro();
}
+
+ public List getCodeProjectsInListOfProjects(List enabledVulnManageProjects) {
+ return codeProjectRepository.findByProjectIn(enabledVulnManageProjects);
+ }
}
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/GetOrCreateCodeProjectBranchService.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/GetOrCreateCodeProjectBranchService.java
new file mode 100644
index 00000000..6822f60b
--- /dev/null
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/GetOrCreateCodeProjectBranchService.java
@@ -0,0 +1,26 @@
+package io.mixeway.domain.service.scanmanager.code;
+
+import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
+import io.mixeway.db.repository.CodeProjectBranchRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+@Service
+@Log4j2
+@RequiredArgsConstructor
+public class GetOrCreateCodeProjectBranchService {
+ private final CodeProjectBranchRepository codeProjectBranchRepository;
+ private final CreateCodeProjectBranchService createCodeProjectBranchService;
+
+ public CodeProjectBranch getOrCreateCodeProjectBranch(CodeProject codeProject, String branch){
+ CodeProjectBranch codeProjectBranch = codeProjectBranchRepository.findCodeProjectBranchByCodeProjectAndName(codeProject,branch);
+ if (codeProjectBranch == null){
+ codeProjectBranch = createCodeProjectBranchService.createCodeProjectBranch(codeProject,branch);
+ } else {
+ return codeProjectBranch;
+ }
+ return codeProjectBranch;
+ }
+}
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/OperateOnCodeProject.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/OperateOnCodeProject.java
index f4f66c56..54770cf4 100644
--- a/src/main/java/io/mixeway/domain/service/scanmanager/code/OperateOnCodeProject.java
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/OperateOnCodeProject.java
@@ -9,7 +9,9 @@
import io.mixeway.utils.VaultHelper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
+import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
@@ -56,9 +58,10 @@ public void setVersionId(CodeProject codeProject, EditCodeProjectModel editCodeP
codeProjectRepository.save(codeProject);
}
+ @Modifying
+ @Transactional
public void setBranch(CodeProject codeProject, String branch) {
- codeProject.setBranch(branch);
- codeProjectRepository.save(codeProject);
+ codeProjectRepository.updateCodeProjectBranch(codeProject.getId(), branch);
}
public void setRepoUsername(CodeProject codeProject, EditCodeProjectModel editCodeProjectModel) {
diff --git a/src/main/java/io/mixeway/domain/service/scanmanager/code/UpdateCodeProjectService.java b/src/main/java/io/mixeway/domain/service/scanmanager/code/UpdateCodeProjectService.java
index 3ea22ae2..8c8e47b9 100644
--- a/src/main/java/io/mixeway/domain/service/scanmanager/code/UpdateCodeProjectService.java
+++ b/src/main/java/io/mixeway/domain/service/scanmanager/code/UpdateCodeProjectService.java
@@ -1,6 +1,7 @@
package io.mixeway.domain.service.scanmanager.code;
import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
import io.mixeway.db.entity.Project;
import io.mixeway.db.repository.CodeProjectRepository;
import io.mixeway.scanmanager.model.CodeScanRequestModel;
@@ -36,8 +37,8 @@ public class UpdateCodeProjectService {
*/
@Transactional
public CodeProject updateCodeProject(CodeScanRequestModel codeScanRequest, CodeProject codeProject) {
+ codeProjectRepository.updateCodeProjectBranch(codeProject.getId(), codeScanRequest.getBranch());
codeProject.setTechnique(codeScanRequest.getTech());
- codeProject.setBranch(codeScanRequest.getBranch());
codeProject.setRepoUrl(codeScanRequest.getRepoUrl());
log.info("{} - Updated CodeProject [{}] {}", "ScanManager", codeProject.getProject().getName(), codeProject.getName());
return codeProjectRepository.saveAndFlush(codeProject);
@@ -49,7 +50,6 @@ public CodeProject updateCodeProject(CodeScanRequestModel codeScanRequest, CodeP
@Transactional
public CodeProject updateCodeProjectAndPutToQueue(CodeScanRequestModel codeScanRequest, CodeProject codeProject) {
codeProject.setTechnique(codeScanRequest.getTech());
- codeProject.setBranch(codeScanRequest.getBranch());
codeProject.setRepoUrl(codeScanRequest.getRepoUrl());
codeProject.setInQueue(true);
codeProject.setRequestId(UUID.randomUUID().toString());
@@ -118,4 +118,11 @@ public void updateOpenSourceSettings(CodeProject codeProject, String remoteId, S
codeProject.setRemotename(remoteName);
codeProjectRepository.save(codeProject);
}
+
+ @Transactional
+ public void updateActiveBranch(CodeProject codeProject, CodeProjectBranch codeProjectBranch) {
+ codeProject.setActiveBranch(codeProjectBranch.getName());
+ codeProjectRepository.save(codeProject);
+ log.info("[UpdateCodeProject] Updated project {} set branch to {}", codeProject.getName(), codeProjectBranch.getName());
+ }
}
diff --git a/src/main/java/io/mixeway/domain/service/vulnhistory/CreateVulnHistoryService.java b/src/main/java/io/mixeway/domain/service/vulnhistory/CreateVulnHistoryService.java
index d3c679fd..0f7d84b1 100644
--- a/src/main/java/io/mixeway/domain/service/vulnhistory/CreateVulnHistoryService.java
+++ b/src/main/java/io/mixeway/domain/service/vulnhistory/CreateVulnHistoryService.java
@@ -1,11 +1,10 @@
package io.mixeway.domain.service.vulnhistory;
import io.mixeway.config.Constants;
-import io.mixeway.db.entity.Project;
-import io.mixeway.db.entity.VulnHistory;
-import io.mixeway.db.entity.VulnerabilitySource;
+import io.mixeway.db.entity.*;
import io.mixeway.db.repository.NodeAuditRepository;
import io.mixeway.db.repository.VulnHistoryRepository;
+import io.mixeway.domain.service.scanmanager.code.FindCodeProjectService;
import io.mixeway.domain.service.vulnmanager.VulnTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -13,10 +12,7 @@
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
import java.util.stream.Collectors;
@@ -29,36 +25,83 @@ public class CreateVulnHistoryService {
private final VulnHistoryRepository vulnHistoryRepository;
private final VulnTemplate vulnTemplate;
private final NodeAuditRepository nodeAuditRepository;
+ private final FindCodeProjectService findCodeProjectService;
- private List severities = new ArrayList(){{
+ private final List severities = new ArrayList(){{
add("Medium" );
add("High");
add("Critical");
}};
- private List scores = new ArrayList(){{
+ private final List scores = new ArrayList(){{
add("WARN" );
add("FAIL");
}};
- private List critSeverities = new ArrayList(){{
+ private final List critSeverities = new ArrayList(){{
add("High");
add("Critical");
}};
+
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public void createScheduled(Project project){
+ final List codeSources = new ArrayList(){{
+ add(vulnTemplate.SOURCE_SOURCECODE);
+ add(vulnTemplate.SOURCE_IAC);
+ add(vulnTemplate.SOURCE_GITLEAKS);
+ }};
+ final List scaSources = new ArrayList(){{
+ add(vulnTemplate.SOURCE_OPENSOURCE);
+ }};
+
VulnHistory vulnHistory = new VulnHistory();
vulnHistory.setName(Constants.VULN_HISTORY_ALL);
- vulnHistory.setInfrastructureVulnHistory(createInfraVulnHistory(project));
- vulnHistory.setWebAppVulnHistory(createWebAppVulnHistory(project));
- vulnHistory.setCodeVulnHistory(createCodeVulnHistory(project));
+ createInfraVulnHistory(project, vulnHistory);
+ createWebAppVulnHistory(project, vulnHistory);
+ createCodeVulnHistory(project, codeSources, vulnHistory);
+ createSCAVulnHistory(project, scaSources, vulnHistory);
+ createAdditionalInfo(project, vulnHistory);
+
+
+
vulnHistory.setAuditVulnHistory(createAuditHistory(project));
- vulnHistory.setSoftwarePacketVulnNumber((long) createSoftwarePacketHistory(project));
+
vulnHistory.setProject(project);
vulnHistory.setInserted(format.format(new Date()));
vulnHistoryRepository.save(vulnHistory);
}
+
+ private void createAdditionalInfo(Project project, VulnHistory vulnHistory) {
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository.findByProject(project).collect(Collectors.toList());
+ int detectedVulnerabilities = projectVulnerabilities.size();
+ long detectedCriticalVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.API_SEVERITY_CRITICAL)).count();
+ long resolvedCriticalVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.API_SEVERITY_CRITICAL) && Objects.equals(pv.getStatus().getId(), vulnTemplate.STATUS_REMOVED.getId()) && pv.getGrade()!=0).count();
+ long acknowlegedVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getSeverity().equals(Constants.API_SEVERITY_CRITICAL) && pv.getGrade() == 0).count();
+ resolvedCriticalVulnerabilities += acknowlegedVulnerabilities;
+ List solvedVulnerabilities = projectVulnerabilities.stream().filter(pv -> pv.getStatus().getId().equals(vulnTemplate.STATUS_REMOVED.getId())).collect(Collectors.toList());
+ int percentResolvedCritical = (int) Math.ceil(((double) resolvedCriticalVulnerabilities / detectedCriticalVulnerabilities) * 100);
+ int avgTimeToFix= (int) Math.ceil(calculateAverageDifferenceInDays(solvedVulnerabilities));
+ vulnHistory.setAvgTimeToFix((long)avgTimeToFix);
+ vulnHistory.setPercentResolvedCriticals((long)percentResolvedCritical);
+ vulnHistory.setResolvedVulnerabilities(projectVulnerabilities.stream().filter(pv -> pv.getStatus().getId().equals(vulnTemplate.STATUS_REMOVED.getId())).count());
+
+ }
+ private static double calculateAverageDifferenceInDays(List list) {
+ if (list == null || list.isEmpty()) {
+ // Handle this case as per your requirements, could throw an exception or return 0
+ return 0;
+ }
+
+ long sumOfDifferences = 0;
+ for (ProjectVulnerability pv : list) {
+ sumOfDifferences += pv.calculateDifferenceInDays();
+ }
+
+ // Calculate the average
+ return sumOfDifferences / (double) list.size();
+ }
+
public void create(Project project, String date, Long infra, Long webApp, Long code, Long audit, Long software){
VulnHistory vulnHistory = new VulnHistory();
vulnHistory.setName(Constants.VULN_HISTORY_ALL);
@@ -71,10 +114,14 @@ public void create(Project project, String date, Long infra, Long webApp, Long c
vulnHistory.setInserted(date);
vulnHistoryRepository.save(vulnHistory);
}
- private Long createWebAppVulnHistory(Project p){
- return vulnTemplate.projectVulnerabilityRepository
- .findByWebAppInAndVulnerabilitySourceAndSeverityIn(new ArrayList<>(p.getWebapps()),vulnTemplate.SOURCE_WEBAPP, severities).count();
-
+ private void createWebAppVulnHistory(Project p, VulnHistory vulnHistory){
+ List webAppVulns = vulnTemplate.projectVulnerabilityRepository
+ .findByWebAppInAndVulnerabilitySource(new ArrayList<>(p.getWebapps()),vulnTemplate.SOURCE_WEBAPP).stream().filter(pv -> pv.getGrade()!=0 && !pv.getStatus().getId().equals(vulnTemplate.STATUS_REMOVED.getId())).collect(Collectors.toList());
+ vulnHistory.setWebAppVulnHistory(webAppVulns.stream().filter(pv -> severities.contains(pv.getSeverity())).count());
+ vulnHistory.setWebAppCritVuln(webAppVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL)).count());
+ vulnHistory.setWebAppHighVuln(webAppVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)).count());
+ vulnHistory.setWebAppMediumVuln(webAppVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM)).count());
+ vulnHistory.setWebAppLowVuln(webAppVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW)).count());
}
/**
@@ -83,30 +130,93 @@ private Long createWebAppVulnHistory(Project p){
* IaC
* GitLeaks
*
- * @param p
- * @return
*/
- private Long createCodeVulnHistory(Project p){
- List codeSources = new ArrayList(){{
- add(vulnTemplate.SOURCE_SOURCECODE);
- add(vulnTemplate.SOURCE_IAC);
- add(vulnTemplate.SOURCE_GITLEAKS);
- }};
- return vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceInAndAnalysisNot(p,codeSources, Constants.FORTIFY_NOT_AN_ISSUE).count();
+ private void createCodeVulnHistory(Project p, List list, VulnHistory vulnHistory){
+
+ List projects = Collections.singletonList(p);
+ List codeProjects = findCodeProjectService.getCodeProjectsInListOfProjects(projects);
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository.findVulnerabilitiesForCode(codeProjects, list);
+ projectVulnerabilities.removeIf(projectVulnerability -> projectVulnerability.getGrade() == 0);
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_LOW));
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_MEDIUM));
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_INFO));
+
+ // Return only vulnerabilities in default branch
+ Map uniqueVulnsMap = new HashMap<>();
+
+ for (ProjectVulnerability projectVulnerability : projectVulnerabilities) {
+ CodeProjectBranch codeProjectBranch = projectVulnerability.getCodeProjectBranch();
+ CodeProject codeProject = projectVulnerability.getCodeProject();
+
+ if (codeProjectBranch != null && codeProject != null) {
+ String branchName = codeProjectBranch.getName();
+ String projectBranch = codeProject.getBranch();
+
+ if (branchName != null && branchName.equals(projectBranch)) {
+ String uniqueKey = branchName + "_" + projectBranch + "_" + projectVulnerability.getId(); // Tworzenie unikalnego klucza
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
+ }
+ }
+ }
+
+ List uniqueVulns = new ArrayList<>(uniqueVulnsMap.values());
+
+ vulnHistory.setCodeVulnHistory((long)uniqueVulns.size());
+ vulnHistory.setCodeCritVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL)).count());
+ vulnHistory.setCodeHighVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)).count());
+ vulnHistory.setCodeMediumVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM)).count());
+ vulnHistory.setCodeLowVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW)).count());
}
- private Long createInfraVulnHistory(Project p){
- return getInfraVulnsForProject(p);
+
+ private void createSCAVulnHistory(Project p, List list, VulnHistory vulnHistory){
+
+ List projects = Collections.singletonList(p);
+ List codeProjects = findCodeProjectService.getCodeProjectsInListOfProjects(projects);
+ List projectVulnerabilities = vulnTemplate.projectVulnerabilityRepository.findVulnerabilitiesForCode(codeProjects, list);
+ projectVulnerabilities.removeIf(projectVulnerability -> projectVulnerability.getGrade() == 0);
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_LOW));
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_MEDIUM));
+ projectVulnerabilities.removeIf(projectVulnerability -> Objects.equals(projectVulnerability.getSeverity(), Constants.API_SEVERITY_INFO));
+
+ // Return only vulnerabilities in default branch
+ Map uniqueVulnsMap = new HashMap<>();
+
+ for (ProjectVulnerability projectVulnerability : projectVulnerabilities) {
+ CodeProjectBranch codeProjectBranch = projectVulnerability.getCodeProjectBranch();
+ CodeProject codeProject = projectVulnerability.getCodeProject();
+
+ if (codeProjectBranch != null && codeProject != null) {
+ String branchName = codeProjectBranch.getName();
+ String projectBranch = codeProject.getBranch();
+
+ if (branchName != null && branchName.equals(projectBranch)) {
+ String uniqueKey = branchName + "_" + projectBranch + "_" + projectVulnerability.getId(); // Tworzenie unikalnego klucza
+ uniqueVulnsMap.put(uniqueKey, projectVulnerability);
+ }
+ }
+ }
+
+ List uniqueVulns = new ArrayList<>(uniqueVulnsMap.values());
+
+ vulnHistory.setSoftwarePacketVulnNumber((long)uniqueVulns.size());
+ vulnHistory.setScaCritVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL)).count());
+ vulnHistory.setScaHighVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)).count());
+ vulnHistory.setScaMediumVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM)).count());
+ vulnHistory.setScaLowVuln(uniqueVulns.stream().filter(pv -> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW)).count());
+ }
+ private VulnHistory createInfraVulnHistory(Project p, VulnHistory vulnHistory){
+ List infraVulns =vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceAndSeverityInAndStatusNot(p, vulnTemplate.SOURCE_NETWORK, severities, vulnTemplate.STATUS_REMOVED).stream().filter(pv -> pv.getGrade()!=0).collect(Collectors.toList());
+ vulnHistory.setInfrastructureVulnHistory((long)infraVulns.size());
+ vulnHistory.setAssetCritVuln(infraVulns.stream().filter(pv-> pv.getSeverity().equals(Constants.VULN_CRITICALITY_CRITICAL)).count());
+ vulnHistory.setAssetHighVuln(infraVulns.stream().filter(pv-> pv.getSeverity().equals(Constants.VULN_CRITICALITY_HIGH)).count());
+ vulnHistory.setAssetMediumVuln(infraVulns.stream().filter(pv-> pv.getSeverity().equals(Constants.VULN_CRITICALITY_MEDIUM)).count());
+ vulnHistory.setAssetLowVuln(infraVulns.stream().filter(pv-> pv.getSeverity().equals(Constants.VULN_CRITICALITY_LOW)).count());
+ return vulnHistory;
}
private Long createAuditHistory(Project p){
return (long)(nodeAuditRepository.findByNodeInAndScoreIn(p.getNodes(),scores).size());
}
- private int createSoftwarePacketHistory(Project project) {
- return (int) vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceAndSeverityIn(project, vulnTemplate.SOURCE_OPENSOURCE, critSeverities)
- .stream().filter(pv -> !Objects.equals(pv.getVulnerability().getSeverity(), Constants.SKIP_VULENRABILITY)).count();
- }
- private long getInfraVulnsForProject(Project project){
- return vulnTemplate.projectVulnerabilityRepository.findByProjectAndVulnerabilitySourceAndSeverityIn(project, vulnTemplate.SOURCE_NETWORK, severities).size();
- }
+
}
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..43c45c7b 100644
--- a/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java
+++ b/src/main/java/io/mixeway/domain/service/vulnhistory/OperateOnVulnHistoryService.java
@@ -73,4 +73,9 @@ public ProjectVulnTrendChart getVulnTrendChart(Project project, int limit){
projectVulnTrendChart.setSeries(series);
return projectVulnTrendChart;
}
+
+ public List getLatestVulnHistoryForProject(Project project){
+ return vulnHistoryRepository.getVulnHistoryLimit(project.getId(), 30);
+ }
+
}
diff --git a/src/main/java/io/mixeway/domain/service/vulnmanager/VulnTemplate.java b/src/main/java/io/mixeway/domain/service/vulnmanager/VulnTemplate.java
index 020db5aa..2bc7540b 100644
--- a/src/main/java/io/mixeway/domain/service/vulnmanager/VulnTemplate.java
+++ b/src/main/java/io/mixeway/domain/service/vulnmanager/VulnTemplate.java
@@ -110,7 +110,7 @@ public void vulnerabilityPersistListSoftware(List oldTmpVu
List newVulns = new ArrayList<>();
for (ProjectVulnerability projectVulnerability : projectVulnerabilities
.stream()
- .filter(distinctByKeys(ProjectVulnerability::getCodeProject, ProjectVulnerability::getSoftwarePacket, ProjectVulnerability::getVulnerability, ProjectVulnerability::getSeverity))
+ .filter(distinctByKeys(ProjectVulnerability::getCodeProject, ProjectVulnerability::getSoftwarePacket, ProjectVulnerability::getVulnerability, ProjectVulnerability::getSeverity, ProjectVulnerability::getCodeProjectBranch))
.collect(Collectors.toList())){
List oldVulnsToKeep = oldTmpVulns.stream()
.filter(o -> o.equals(projectVulnerability))
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/acunetix/apiclient/AcunetixApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/acunetix/apiclient/AcunetixApiClient.java
index a772fedb..9e451327 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/acunetix/apiclient/AcunetixApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/acunetix/apiclient/AcunetixApiClient.java
@@ -265,7 +265,7 @@ public Boolean loadVulnerabilities(Scanner scanner, WebApp webApp, String pagina
Vulnerability vulnerability = vulnTemplate.createOrGetVulnerabilityService.createOrGetVulnerabilityWithRecommendationAndReferences(vulnFromAcu.getVt_name(),vulnFromAcu.getRecommendation(),prepareRefs(vulnFromAcu.getReferences()));
ProjectVulnerability vuln = new ProjectVulnerability(webApp,null,vulnerability,null,
null, AcunetixSeverity.resolveSeverity(vulnFromAcu.getSeverity()),null,vulnFromAcu.getAffects_url(),
- null,vulnTemplate.SOURCE_WEBAPP,null);
+ null,vulnTemplate.SOURCE_WEBAPP,null, null);
if (webApp.getCodeProject() != null) {
vuln.setCodeProject(webApp.getCodeProject());
}
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/apiclient/CheckmarxApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/apiclient/CheckmarxApiClient.java
index bb6ed757..c0a5343b 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/apiclient/CheckmarxApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/apiclient/CheckmarxApiClient.java
@@ -17,6 +17,7 @@
import io.mixeway.utils.SecureRestTemplate;
import io.mixeway.utils.VaultHelper;
import org.apache.commons.lang3.StringUtils;
+import org.apache.http.NoHttpResponseException;
import org.codehaus.jettison.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,6 +29,7 @@
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import java.io.ByteArrayInputStream;
@@ -73,9 +75,9 @@ public class CheckmarxApiClient implements CodeScanClient, SecurityScanner {
this.secureRestTemplate = secureRestTemplate;
}
@Override
- public void loadVulnerabilities(Scanner scanner, String urlToGetNext, Boolean single, CodeProject codeProject, List codeVulns) throws ParseException, JSONException, CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ public void loadVulnerabilities(Scanner scanner, String urlToGetNext, Boolean single, CodeProject codeProject, List codeVulns, CodeProjectBranch codeProjectBranch) throws ParseException, JSONException, CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
List cxResults = downloadResultsForScan(scanner,codeProject);
- processVulnReportForCodeProject(cxResults,codeProject,codeVulns);
+ processVulnReportForCodeProject(cxResults,codeProject,codeVulns, codeProjectBranch);
}
@Override
@@ -437,6 +439,8 @@ private boolean createScan(Scanner scanner, CodeProject codeProject) throws Cert
}
} catch (HttpClientErrorException e){
log.error("[Checkmarx] Error creating scan - {}", e.getStatusCode());
+ } catch (ResourceAccessException e) {
+ log.error("[Checkmarx] Error creating the scan - checkmarx not avaliable");
}
return false;
}
@@ -573,13 +577,13 @@ private List processCsvReport(String body, CodeProject code
* @param results
* @param codeProject
*/
- private void processVulnReportForCodeProject(List results, CodeProject codeProject, List oldVulns) {
+ private void processVulnReportForCodeProject(List results, CodeProject codeProject, List oldVulns, CodeProjectBranch codeProjectBranch) {
List vulnsToPersist = new ArrayList<>();
for (CxResultCsvTemplate cxVuln: results) {
Vulnerability vulnerability = vulnTemplate.createOrGetVulnerabilityService.createOrGetVulnerability(cxVuln.getQuery());
ProjectVulnerability projectVulnerability = new ProjectVulnerability(codeProject,codeProject,vulnerability,cxVuln.getDescription(),null,
- cxVuln.getSeverity(),null,cxVuln.getDstLocation()+":"+cxVuln.getDstLine(),getTag(cxVuln.getAnalysis()), vulnTemplate.SOURCE_SOURCECODE, null );
+ cxVuln.getSeverity(),null,cxVuln.getDstLocation()+":"+cxVuln.getDstLine(),getTag(cxVuln.getAnalysis()), vulnTemplate.SOURCE_SOURCECODE, null, codeProjectBranch );
vulnsToPersist.add(projectVulnerability);
}
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/model/CxSetGitRepo.java b/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/model/CxSetGitRepo.java
index 43e6b5f8..efd79e6d 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/model/CxSetGitRepo.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/checkmarx/model/CxSetGitRepo.java
@@ -11,6 +11,8 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
+import java.util.Objects;
+
@Setter
@Getter
@NoArgsConstructor
@@ -25,7 +27,11 @@ public CxSetGitRepo(CodeProject codeProject, String pass){
} else {
this.url = codeProject.getRepoUrl();
}
- this.branch = "refs/heads/" + codeProject.getBranch();
+ if (codeProject.getActiveBranch() != null && !Objects.equals(codeProject.getActiveBranch(), "")) {
+ this.branch = "refs/heads/" + codeProject.getActiveBranch();
+ } else {
+ this.branch = "refs/heads/" + codeProject.getBranch();
+ }
}
}
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/dependencytrack/apiclient/DependencyTrackApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/dependencytrack/apiclient/DependencyTrackApiClient.java
index b7eccff7..e69388d9 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/dependencytrack/apiclient/DependencyTrackApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/dependencytrack/apiclient/DependencyTrackApiClient.java
@@ -4,6 +4,7 @@
import io.mixeway.db.entity.Scanner;
import io.mixeway.db.entity.*;
import io.mixeway.db.repository.*;
+import io.mixeway.domain.service.scanmanager.code.GetOrCreateCodeProjectBranchService;
import io.mixeway.domain.service.vulnmanager.VulnTemplate;
import io.mixeway.scanmanager.integrations.dependencytrack.model.Component;
import io.mixeway.scanmanager.integrations.dependencytrack.model.DTrackCreateProject;
@@ -55,6 +56,7 @@ public class DependencyTrackApiClient implements SecurityScanner, OpenSourceScan
private final CodeProjectRepository codeProjectRepository;
private final CiOperationsRepository ciOperationsRepository;
private final VulnTemplate vulnTemplate;
+ private final GetOrCreateCodeProjectBranchService getOrCreateCodeProjectBranchService;
@Override
@@ -69,8 +71,11 @@ public boolean canProcessRequest() {
}
@Override
- public void loadVulnerabilities(CodeProject codeProject) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ public void loadVulnerabilities(CodeProject codeProject, CodeProjectBranch codeProjectBranch) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
List dTrack = scannerRepository.findByScannerType(scannerTypeRepository.findByNameIgnoreCase(Constants.SCANNER_TYPE_DEPENDENCYTRACK));
+ if (codeProjectBranch == null){
+ codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getBranch());
+ }
//Multiple dTrack instances not yet supported
if (dTrack.size() == 1 && codeProject.getdTrackUuid() != null){
RestTemplate restTemplate = secureRestTemplate.prepareClientWithCertificate(dTrack.get(0));
@@ -81,7 +86,7 @@ public void loadVulnerabilities(CodeProject codeProject) throws CertificateExcep
"/api/v1/vulnerability/project/" + codeProject.getdTrackUuid(), HttpMethod.GET, entity, new ParameterizedTypeReference>() {
});
if (response.getStatusCode() == HttpStatus.OK) {
- createVulns(codeProject, Objects.requireNonNull(response.getBody()));
+ createVulns(codeProject, Objects.requireNonNull(response.getBody()), codeProjectBranch);
updateCiOperations(codeProject);
} else {
log.error("Unable to get Findings from Dependency Track for project {}", codeProject.getdTrackUuid());
@@ -182,9 +187,9 @@ public void autoDiscovery() {
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
- public void createVulns(CodeProject codeProject, List body) throws URISyntaxException {
+ public void createVulns(CodeProject codeProject, List body, CodeProjectBranch codeProjectBranch) throws URISyntaxException {
List oldVulns = vulnTemplate.projectVulnerabilityRepository
- .findByVulnerabilitySourceAndCodeProject(vulnTemplate.SOURCE_OPENSOURCE, codeProject);
+ .findByVulnerabilitySourceAndCodeProjectAndCodeProjectBranch(vulnTemplate.SOURCE_OPENSOURCE, codeProject, codeProjectBranch);
List vulnsToPersist = new ArrayList<>();
for(DTrackVuln dTrackVuln : body){
List softwarePackets = new ArrayList<>();
@@ -204,16 +209,17 @@ public void createVulns(CodeProject codeProject, List body) throws U
Vulnerability vuln = vulnTemplate.createOrGetVulnerabilityService.createOrGetVulnerabilityWithDescAndReferences(dTrackVuln.getVulnId(), dTrackVuln.getDescription(),
dTrackVuln.getReferences(), dTrackVuln.getRecommendation());
Optional softwarePacketVulnerability = vulnTemplate.projectVulnerabilityRepository
- .findBySoftwarePacketAndVulnerabilityAndCodeProject(sPacket,vuln, codeProject);
+ .findBySoftwarePacketAndVulnerabilityAndCodeProjectAndCodeProjectBranch(sPacket,vuln, codeProject,codeProjectBranch);
if (!softwarePacketVulnerability.isPresent()){
ProjectVulnerability projectVulnerability = new ProjectVulnerability(sPacket,codeProject,vuln,dTrackVuln.getDescription(),dTrackVuln.getRecommendation(),
- dTrackVuln.getSeverity(), null, null, null,vulnTemplate.SOURCE_OPENSOURCE,null);
+ dTrackVuln.getSeverity(), null, null, null,vulnTemplate.SOURCE_OPENSOURCE,null, codeProjectBranch);
projectVulnerability.setStatus(vulnTemplate.STATUS_NEW);
vulnsToPersist.add(projectVulnerability);
} else {
softwarePacketVulnerability.get().setCodeProject(codeProject);
softwarePacketVulnerability.get().setInserted(dateFormat.format(new Date()));
softwarePacketVulnerability.get().setStatus(vulnTemplate.STATUS_EXISTING);
+ softwarePacketVulnerability.get().setCodeProjectBranch(codeProjectBranch);
vulnsToPersist.add(softwarePacketVulnerability.get()) ;
}
@@ -221,6 +227,7 @@ public void createVulns(CodeProject codeProject, List body) throws U
}
//codeProjectRepository.saveAndFlush(codeProject);
}
+ log.info("[Dependency-Track] Send {} vulns to persist for {}", vulnsToPersist.size(), codeProject.getName());
vulnTemplate.vulnerabilityPersistListSoftware(oldVulns,vulnsToPersist);
if (codeProject.getEnableJira()) {
vulnTemplate.processBugTracking(codeProject, vulnTemplate.SOURCE_OPENSOURCE);
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/nessus/apiclient/NessusApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/nessus/apiclient/NessusApiClient.java
index 028f1435..8dacde76 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/nessus/apiclient/NessusApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/nessus/apiclient/NessusApiClient.java
@@ -535,7 +535,7 @@ else if (vuln.getInt(Constants.NESSUS_SEVERITY) == 3)
Vulnerability vulnerability = vulnTemplate.createOrGetVulnerabilityService.createOrGetVulnerability(vuln.getString(Constants.NESSUS_PLUGIN_NAME));
ProjectVulnerability projectVulnerability = new ProjectVulnerability(i, null, vulnerability,bodyJ.getJSONObject(Constants.NESSUS_SCAN_INFO).getJSONObject(Constants.NESSUS_PLUGINDESCRIPTION)
.getJSONObject(Constants.NESSUS_PLUGINATTRIBUTES).getString(Constants.NESSUS_VULN_DESCRIPTION),
- null,threat, key,null,null, vulnTemplate.SOURCE_NETWORK,null);
+ null,threat, key,null,null, vulnTemplate.SOURCE_NETWORK,null,null);
projectVulnerability.updateStatusAndGrade(oldVulns, vulnTemplate);
projectVulnerabilities.add(projectVulnerability);
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/nexpose/apiclient/NexposeApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/nexpose/apiclient/NexposeApiClient.java
index 9de56a94..9bdcaafd 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/nexpose/apiclient/NexposeApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/nexpose/apiclient/NexposeApiClient.java
@@ -144,7 +144,7 @@ private void loadVulnerabilitiesForAsset(InfraScan scan, Interface intf, int id,
"Categories: "+ StringUtils.join(vulnDetails.getCategories(),", ")+"
" +
"
Proof:
"+result.getProof()+
"
Description:
"+vulnDetails.getDescription().getHtml(),null,
- setNexposeThreat(vulnDetails.getSeverity()),String.valueOf(result.getPort()),null,null, vulnTemplate.SOURCE_NETWORK,null);
+ setNexposeThreat(vulnDetails.getSeverity()),String.valueOf(result.getPort()),null,null, vulnTemplate.SOURCE_NETWORK,null,null);
projectVulnerability.updateStatusAndGrade(oldVulns, vulnTemplate);
vulnTemplate.projectVulnerabilityRepository.save(projectVulnerability);
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/nexusiq/apiclient/NexusIqApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/nexusiq/apiclient/NexusIqApiClient.java
index be6066d3..a66f987b 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/nexusiq/apiclient/NexusIqApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/nexusiq/apiclient/NexusIqApiClient.java
@@ -150,14 +150,14 @@ public boolean canProcessRequest() {
}
@Override
- public void loadVulnerabilities(CodeProject codeProject) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
+ public void loadVulnerabilities(CodeProject codeProject, CodeProjectBranch codeProjectBranch) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
Scanner scanner = getScannerService.getScannerByType(findScannerTypeService.findByName(Constants.SCANNER_TYPE_NEXUS_IQ));
if (scanner!=null) {
String getRawDataReportUrl = getRawDataUrl(scanner, codeProject);
RawReport rawReport = getRawReport(scanner, getRawDataReportUrl);
try {
if (rawReport != null )
- saveVulnerabilities(codeProject, rawReport);
+ saveVulnerabilities(codeProject, rawReport, codeProjectBranch);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
@@ -183,7 +183,7 @@ private void updateCiOperations(CodeProject codeProject) {
}
- private void saveVulnerabilities(CodeProject codeProject, RawReport rawReport) throws URISyntaxException {
+ private void saveVulnerabilities(CodeProject codeProject, RawReport rawReport, CodeProjectBranch codeProjectBranch) throws URISyntaxException {
List oldVulns = vulnTemplate.projectVulnerabilityRepository
.findByVulnerabilitySourceAndCodeProject(vulnTemplate.SOURCE_OPENSOURCE, codeProject);
List projectVulnerabilitiesFromReport = new ArrayList<>();
@@ -219,7 +219,8 @@ private void saveVulnerabilities(CodeProject codeProject, RawReport rawReport) t
null,
null,
vulnTemplate.SOURCE_OPENSOURCE,
- null);
+ null,
+ codeProjectBranch);
projectVulnerability.setStatus(vulnTemplate.STATUS_NEW);
projectVulnerabilitiesFromReport.add(projectVulnerability);
}
@@ -296,7 +297,8 @@ private String getRawDataUrl(Scanner scanner, CodeProject codeProject) throws Un
@Override
public boolean createProject(CodeProject codeProject) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException {
- return false;
+ this.autoDiscoveryProject(codeProject);
+ return true;
}
@Override
@@ -342,6 +344,21 @@ public void autoDiscovery() throws UnrecoverableKeyException, CertificateExcepti
}
log.info("[Nexus-IQ] Synchronization completed.");
}
+ public void autoDiscoveryProject(CodeProject codeProject) throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
+ Scanner scanner = getScannerService.getScannerByType(findScannerTypeService.findByName(Constants.SCANNER_TYPE_NEXUS_IQ));
+ if (scanner != null) {
+
+ List synchroList = loadNexusData(scanner);
+ log.info("[Nexus-IQ] Starting synchronization, found {} resources on remote nexus", synchroList.size());
+ Synchro sync = synchroList.stream().filter(s -> s.getRepoUrl().replace(".git","").equals(codeProject.getRepoUrl().replace(".git","")))
+ .findAny().orElse(null);
+ if (sync != null){
+ updateCodeProjectService.updateOpenSourceSettings(codeProject,sync.getId(), sync.getName());
+ log.info("[Nexus-IQ] Synchronized infos for {} with {} and {}", codeProject.getName(), sync.getId(), sync.getName());
+ }
+ }
+ log.info("[Nexus-IQ] Synchronization completed.");
+ }
private List loadNexusData(Scanner scanner) throws UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, KeyManagementException {
List synchroList = new ArrayList<>();
diff --git a/src/main/java/io/mixeway/scanmanager/integrations/openvas/apiclient/OpenVasApiClient.java b/src/main/java/io/mixeway/scanmanager/integrations/openvas/apiclient/OpenVasApiClient.java
index 673ae4b3..520a4c9d 100644
--- a/src/main/java/io/mixeway/scanmanager/integrations/openvas/apiclient/OpenVasApiClient.java
+++ b/src/main/java/io/mixeway/scanmanager/integrations/openvas/apiclient/OpenVasApiClient.java
@@ -183,7 +183,7 @@ public void loadVulnerabilities(InfraScan infraScan) throws JSONException, Certi
if (response.getStatusCode() == HttpStatus.OK) {
setVulnerabilities(infraScan, response.getBody());
//vulnTemplate.projectVulnerabilityRepository.deleteByStatusAndProject(vulnTemplate.STATUS_REMOVED, infraScan.getProject());
- deleteProjectVulnerabilityService.deleteProjectVulnerabilityWithStatus(infraScan.getProject(), vulnTemplate.STATUS_REMOVED);
+ deleteProjectVulnerabilityService.deleteProjectVulnerabilityWithStatus(infraScan.getProject(), vulnTemplate.STATUS_REMOVED, vulnTemplate.SOURCE_NETWORK);
infraScan.setRunning(false);
infraScan.setTaskId(null);
infraScanRepository.save(infraScan);
@@ -286,7 +286,7 @@ void setVulnerabilities(InfraScan ns, String body) throws JSONException {
if (intfActive != null) {
Vulnerability vulnerability = vulnTemplate.createOrGetVulnerabilityService.createOrGetVulnerability(v.getString(Constants.IF_VULN_NAME));
ProjectVulnerability projectVulnerability = new ProjectVulnerability(intfActive,null,vulnerability,v.getString(Constants.IF_VULN_DESC),null
- ,v.getString(Constants.IF_VULN_THREAT),v.getString(Constants.IF_VULN_PORT),null,null,vulnTemplate.SOURCE_NETWORK, null);
+ ,v.getString(Constants.IF_VULN_THREAT),v.getString(Constants.IF_VULN_PORT),null,null,vulnTemplate.SOURCE_NETWORK, null,null);
//projectVulnerability.updateStatusAndGrade(oldVulns, vulnTemplate);
vulnsToPersist.add(projectVulnerability);
scannerInterfaces.add(intfActive);
diff --git a/src/main/java/io/mixeway/scanmanager/service/audit/OpenScapService.java b/src/main/java/io/mixeway/scanmanager/service/audit/OpenScapService.java
index 8189ef2b..eea2c7dd 100644
--- a/src/main/java/io/mixeway/scanmanager/service/audit/OpenScapService.java
+++ b/src/main/java/io/mixeway/scanmanager/service/audit/OpenScapService.java
@@ -70,7 +70,7 @@ private List processVulnerabilitiesFromBenchmark(Benchmark
.filter(entry -> entry.getKey().getId().equals(ruleRef))
.map(Map.Entry::getValue).findFirst().get();
ProjectVulnerability projectVulnerability = new ProjectVulnerability(anInterface,null,null,rule.getDescription(),null,
- "High",null,null,null, vulnTemplate.SOURCE_CISBENCHMARK, cisRequirement );
+ "High",null,null,null, vulnTemplate.SOURCE_CISBENCHMARK, cisRequirement,null );
projectVulnerabilities.add(projectVulnerability);
diff --git a/src/main/java/io/mixeway/scanmanager/service/code/CodeScanClient.java b/src/main/java/io/mixeway/scanmanager/service/code/CodeScanClient.java
index 328ca6a7..730f1faa 100644
--- a/src/main/java/io/mixeway/scanmanager/service/code/CodeScanClient.java
+++ b/src/main/java/io/mixeway/scanmanager/service/code/CodeScanClient.java
@@ -1,6 +1,7 @@
package io.mixeway.scanmanager.service.code;
import io.mixeway.db.entity.CodeProject;
+import io.mixeway.db.entity.CodeProjectBranch;
import io.mixeway.db.entity.ProjectVulnerability;
import io.mixeway.db.entity.Scanner;
import io.mixeway.utils.SASTProject;
@@ -17,7 +18,7 @@
import java.util.List;
public interface CodeScanClient {
- void loadVulnerabilities(Scanner scanner, String urlToGetNext, Boolean single, CodeProject codeProject, List codeVulns) throws ParseException, JSONException, CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, URISyntaxException;
+ void loadVulnerabilities(Scanner scanner, String urlToGetNext, Boolean single, CodeProject codeProject, List codeVulns, CodeProjectBranch codeProjectBranch) throws ParseException, JSONException, CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, URISyntaxException;
Boolean runScan(CodeProject codeProject) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, JSONException, ParseException;
boolean isScanDone(CodeProject cp) throws CertificateException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, IOException, ParseException, JSONException;
boolean canProcessRequest(CodeProject cp);
diff --git a/src/main/java/io/mixeway/scanmanager/service/code/CodeScanService.java b/src/main/java/io/mixeway/scanmanager/service/code/CodeScanService.java
index f422a234..1a8ce7ba 100644
--- a/src/main/java/io/mixeway/scanmanager/service/code/CodeScanService.java
+++ b/src/main/java/io/mixeway/scanmanager/service/code/CodeScanService.java
@@ -53,9 +53,9 @@ public class CodeScanService {
private final GetOrCreateProjectService getOrCreateProjectService;
private final FindCodeProjectService findCodeProjectService;
private final UpdateCodeProjectService updateCodeProjectService;
- private final DeleteProjectVulnerabilityService deleteProjectVulnerabilityService;
private final GetScannerService getScannerService;
private final OperateOnCodeProject operateOnCodeProject;
+ private final GetOrCreateCodeProjectBranchService getOrCreateCodeProjectBranchService;
/**
* Method for getting CodeVulns for given names
@@ -191,11 +191,14 @@ public void getResultsForRunningScan() {
if (sastScanner.isPresent()) {
List codeProjectsRunning = findCodeProjectService.findRunningCodeProjectsLimit5();
for (CodeProject codeProject : codeProjectsRunning) {
- List codeVulns = getProjectVulnerabilitiesService.getOldVulnsForCodeProject(codeProject);
+ CodeProjectBranch codeProjectBranch = getOrCreateCodeProjectBranchService.getOrCreateCodeProjectBranch(codeProject, codeProject.getActiveBranch() != null ? codeProject.getActiveBranch() : codeProject.getBranch());
+ List codeVulns = getProjectVulnerabilitiesService.getOldVulnsForCodeProjectAndSourceForBranch(codeProject, vulnTemplate.SOURCE_SOURCECODE,codeProjectBranch );
for (CodeScanClient codeScanClient : codeScanClients) {
try {
if (codeScanClient.canProcessRequest(sastScanner.get()) && codeScanClient.isScanDone(codeProject)) {
- codeScanClient.loadVulnerabilities(sastScanner.get(), null, true, codeProject, codeVulns);
+ //CodeProjectBranch codeProjectBranch = findCodeProjectBranchService.findBranchForProjectAndRunning(codeProject);
+
+ codeScanClient.loadVulnerabilities(sastScanner.get(), null, true, codeProject, codeVulns, codeProjectBranch);
// TODO: end codescan
updateCiOperations.updateCiOperationsForSAST(codeProject);
updateCodeProjectService.endScan(codeProject);
@@ -203,7 +206,7 @@ public void getResultsForRunningScan() {
log.info("[CodeScan] Automatic integration with BugTracker enabled, proceeding...");
vulnTemplate.processBugTracking(codeProject, vulnTemplate.SOURCE_SOURCECODE);
}
- deleteProjectVulnerabilityService.deleteRemovedVulnerabilitiesInCodeProject(codeProject);
+ //deleteProjectVulnerabilityService.deleteRemovedVulnerabilitiesInCodeProject(codeProject);
//vulnTemplate.projectVulnerabilityRepository.deleteByStatusAndCodeProject(vulnTemplate.STATUS_REMOVED,codeProject);
} else {
log.debug("[CodeScan] Scan for {} is still running", codeProject.getName());
@@ -407,13 +410,50 @@ public void loadVulnsFromCICDToCodeProject(CodeProject codeProject, List sastVulns, ScannerType scannerType,CodeProjectBranch codeProjectBranch) {
+ if (sastVulns.isEmpty())
+ return;
+ VulnerabilitySource vulnerabilitySource = null;
+ if (scannerType.equals(ScannerType.SAST)){
+ vulnerabilitySource = vulnTemplate.SOURCE_SOURCECODE;
+ } else if (scannerType.equals(ScannerType.GITLEAKS)){
+ vulnerabilitySource = vulnTemplate.SOURCE_GITLEAKS;
+ } else if (scannerType.equals(ScannerType.IAC)){
+ vulnerabilitySource = vulnTemplate.SOURCE_IAC;
+ }
+ List