Skip to content

Commit

Permalink
Project delete event handling for domain scan (3) mercedes-benz#87
Browse files Browse the repository at this point in the history
- introduce delete product result
- upgraded product result entity to have also product id inside
- introduce common ProjectDataDeleteService
- added tests
  • Loading branch information
de-jcup committed Nov 26, 2019
1 parent c10118d commit 2462630
Show file tree
Hide file tree
Showing 22 changed files with 308 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ protected List<ProductResult> executeWithAdapter(SecHubExecutionContext context,

/* execute checkmarx by adapter and return product result */
String xml = checkmarxAdapter.start(checkMarxConfig);
ProductResult result = new ProductResult(context.getSechubJobUUID(), getIdentifier(), xml);
ProductResult result = new ProductResult(context.getSechubJobUUID(),projectId, getIdentifier(), xml);
return Collections.singletonList(result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,11 @@ protected List<ProductResult> executeWithAdapter(SecHubExecutionContext context,
setTargetIPs(data.getIPs()).
setTargetURIs(data.getURIs()).build();
/* @formatter:on */
String projectId = context.getConfiguration().getProjectId();

/* execute nessus by adapter and return product result */
String xml = nessusAdapter.start(nessusConfig);
ProductResult result = new ProductResult(context.getSechubJobUUID(), getIdentifier(), xml);
ProductResult result = new ProductResult(context.getSechubJobUUID(),projectId, getIdentifier(), xml);
return Collections.singletonList(result);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ protected List<ProductResult> executeWithAdapter(SecHubExecutionContext context,

/* execute NETSPARKER by adapter and return product result */
String xml = netsparkerAdapter.start(netsparkerConfig);
ProductResult result = new ProductResult(context.getSechubJobUUID(), getIdentifier(), xml);
String projectId = context.getConfiguration().getProjectId();
ProductResult result = new ProductResult(context.getSechubJobUUID(),projectId, getIdentifier(), xml);
results.add(result);
}
return results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private ProductResult createReport(SecHubExecutionContext context) {

if (foundProductResults.isEmpty()) {
LOG.warn("{} no product results for {} found, will return an empty sereco JSON as result! ", traceLogId, getSupportedProducts());
return new ProductResult(secHubJobUUID, getIdentifier(), "{}");
return new ProductResult(secHubJobUUID, projectId, getIdentifier(), "{}");
}

return createReport(projectId, secHubJobUUID, traceLogId, foundProductResults);
Expand All @@ -76,7 +76,7 @@ private ProductResult createReport(String projectId, UUID secHubJobUUID, UUIDTra
}
String json = workspace.createReport();
/* fetch + return all vulnerabilities as JSON */
return new ProductResult(secHubJobUUID, getIdentifier(), json);
return new ProductResult(secHubJobUUID, projectId, getIdentifier(), json);
}

private void importProductResult(UUIDTraceLogID traceLogId, Workspace workspace, ProductResult productResult) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.scan;

import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.daimler.sechub.domain.scan.log.ProjectScanLogRepository;
import com.daimler.sechub.domain.scan.product.ProductResultRepository;
import com.daimler.sechub.domain.scan.report.ScanReportRepository;
import com.daimler.sechub.sharedkernel.Step;
import com.daimler.sechub.sharedkernel.logging.LogSanitizer;
import com.daimler.sechub.sharedkernel.usecases.admin.project.UseCaseAdministratorDeleteProject;
import com.daimler.sechub.sharedkernel.validation.UserInputAssertion;

/**
* This service will delete all project data from domain scan in ONE transaction.
* @author Albert Tregnaghi
*
*/
@Service
public class ProjectDataDeleteService {

private static final Logger LOG = LoggerFactory.getLogger(ProjectDataDeleteService.class);


@Autowired
ProjectScanLogRepository scanLogRepository;

@Autowired
ProductResultRepository productResultRepository;

@Autowired
ScanReportRepository scanReportRepository;


@Autowired
UserInputAssertion assertion;

@Autowired
LogSanitizer logSanitizer;

@Transactional
@UseCaseAdministratorDeleteProject(@Step(number=8,name="delete all project scan data"))
public void deleteAllDataForProject(String projectId) {
assertion.isValidProjectId(projectId);

productResultRepository.deleteAllResultsForProject(projectId);
scanReportRepository.deleteAllReportsForProject(projectId);
scanLogRepository.deleteAllLogDataForProject(projectId);

LOG.info("Deleted all data (results,reports, scanlogs) for project:{}",logSanitizer.sanitize(projectId, 30));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.daimler.sechub.domain.scan.access.ScanGrantUserAccessToProjectService;
import com.daimler.sechub.domain.scan.access.ScanRevokeUserAccessAtAllService;
import com.daimler.sechub.domain.scan.access.ScanRevokeUserAccessFromProjectService;
import com.daimler.sechub.domain.scan.log.ProjectScanLogDeleteService;
import com.daimler.sechub.sharedkernel.messaging.AsynchronMessageHandler;
import com.daimler.sechub.sharedkernel.messaging.DomainMessage;
import com.daimler.sechub.sharedkernel.messaging.IsReceivingAsyncMessage;
Expand Down Expand Up @@ -39,7 +38,7 @@ public class ScanMessageHandler implements AsynchronMessageHandler{
ScanDeleteAnyAccessToProjectAtAllService deleteAllProjectAccessService;

@Autowired
ProjectScanLogDeleteService deleteScanLogService;
ProjectDataDeleteService projectDataDeleteService;


@Override
Expand Down Expand Up @@ -86,8 +85,10 @@ private void handleUserDeleted(DomainMessage request) {
@IsReceivingAsyncMessage(MessageID.PROJECT_DELETED)
private void handleProjectDeleted(DomainMessage request) {
ProjectMessage data = request.get(MessageDataKeys.PROJECT_DELETE_DATA);
/* first cut access */
deleteAllProjectAccessService.deleteAnyAccessDataForProject(data.getProjectId());
deleteScanLogService.deleteAllLogDataForProject(data.getProjectId());
/* now delete data */
projectDataDeleteService.deleteAllDataForProject(data.getProjectId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class ScanDeleteAnyAccessToProjectAtAllService {
LogSanitizer logSanitizer;

@Transactional
@UseCaseAdministratorDeleteProject(@Step(number=7,name="revoke user from schedule access"))
@UseCaseAdministratorDeleteProject(@Step(number=7,name="revoke any scan access from project"))
public void deleteAnyAccessDataForProject(String projectId) {
assertion.isValidProjectId(projectId);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ protected List<ProductResult> execute(ProductExecutor executor, SecHubExecutionC
* @param traceLogID
*/
protected void executeAndPersistResults(List<? extends ProductExecutor> executors, SecHubExecutionContext context, UUIDTraceLogID traceLogID) {
String projectId = context.getConfiguration().getProjectId();

for (ProductExecutor productExecutor : executors) {
List<ProductResult> productResults=Collections.emptyList();
try {
Expand All @@ -115,7 +117,7 @@ protected void executeAndPersistResults(List<? extends ProductExecutor> executor
getMockableLog().error("Product executor failed:"+productExecutor.getIdentifier()+" "+traceLogID,e);

productResults=new ArrayList<ProductResult>();
ProductResult fallbackResult = new ProductResult(context.getSechubJobUUID(),productExecutor.getIdentifier(),"");
ProductResult fallbackResult = new ProductResult(context.getSechubJobUUID(),projectId, productExecutor.getIdentifier(),"");
productResults.add(fallbackResult);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class ProductResult {

public static final String COLUMN_RESULT = "RESULT";

public static final String COLUMN_PROJECT_ID = "PROJECT_ID";

public static final String COLUMN_STARTED = "STARTED";
public static final String COLUMN_ENDED = "ENDED";
/* +-----------------------------------------------------------------------+ */
Expand Down Expand Up @@ -76,6 +78,9 @@ public UUID getUUID() {
@Column(name = "VERSION")
Integer version;

@Column(name = COLUMN_PROJECT_ID, nullable = false)
private String projectId;

@Column(name = COLUMN_STARTED) // remark: we setup hibernate to use UTC settings - see application.properties
LocalDateTime started;

Expand All @@ -88,25 +93,31 @@ public UUID getUUID() {

/**
* Create the product result
*
* @param report
* @param secHubJobUUID
* @param projectId
* @param productIdentifier
* @param result
* as string
*/
public ProductResult(UUID secHubJobUUID, ProductIdentifier productIdentifier, String result) {
public ProductResult(UUID secHubJobUUID, String projectId, ProductIdentifier productIdentifier, String result) {
if (secHubJobUUID == null) {
throw new IllegalArgumentException("SecHub JOB UUID may not be null!");
}
if (productIdentifier == null) {
throw new IllegalArgumentException("Product identifier not be null!");
}
this.secHubJobUUID = secHubJobUUID;
this.projectId=projectId;
this.productIdentifier = productIdentifier;
this.result = result;

}

public String getProjectId() {
return projectId;
}


public ProductIdentifier getProductIdentifier() {
return productIdentifier;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.scan.product;

import static com.daimler.sechub.domain.scan.product.ProductResult.*;

import java.util.UUID;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

public interface ProductResultRepository extends JpaRepository<ProductResult, UUID>, ProductResultRepositoryCustom {

@Modifying
@Query(value = "DELETE FROM " + TABLE_NAME + " where " + COLUMN_PROJECT_ID + " = ?1", nativeQuery=true)
void deleteAllResultsForProject(String projectId);

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
// SPDX-License-Identifier: MIT
package com.daimler.sechub.domain.scan.report;

import static com.daimler.sechub.domain.scan.report.ScanReport.*;

import java.util.UUID;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

public interface ScanReportRepository extends JpaRepository<ScanReport, UUID> {

public ScanReport findBySecHubJobUUID(UUID secHubJobUUID);

@Modifying
@Query(value = "DELETE FROM " + TABLE_NAME + " where " + COLUMN_PROJECT_ID + " = ?1", nativeQuery = true)
void deleteAllReportsForProject(String projectId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.daimler.sechub.domain.scan;

import static org.mockito.Mockito.*;

import org.junit.Before;
import org.junit.Test;

import com.daimler.sechub.domain.scan.log.ProjectScanLogRepository;
import com.daimler.sechub.domain.scan.product.ProductResultRepository;
import com.daimler.sechub.domain.scan.report.ScanReportRepository;
import com.daimler.sechub.sharedkernel.logging.LogSanitizer;
import com.daimler.sechub.sharedkernel.validation.UserInputAssertion;

public class ProjectDataDeleteServiceTest {

private ProjectDataDeleteService serviceToTest;
private ProjectScanLogRepository projectScanLogRepository;
private ProductResultRepository productResultRepository;
private ScanReportRepository scanReportRepository;

@Before
public void before() {
projectScanLogRepository= mock(ProjectScanLogRepository.class);
productResultRepository = mock(ProductResultRepository.class);
scanReportRepository = mock(ScanReportRepository.class);

serviceToTest = new ProjectDataDeleteService();
serviceToTest.logSanitizer=mock(LogSanitizer.class);
serviceToTest.assertion=mock(UserInputAssertion.class);

serviceToTest.scanLogRepository=projectScanLogRepository;
serviceToTest.productResultRepository=productResultRepository;
serviceToTest.scanReportRepository=scanReportRepository;
}

@Test
public void deleteAllDataForProject_triggers_deleteAllResultsForProject() {
/* execute */
serviceToTest.deleteAllDataForProject("project-1");

/* test */
verify(productResultRepository).deleteAllResultsForProject("project-1");

}

@Test
public void deleteAllDataForProject_triggers_deleteAllReportsForProject() {
/* execute */
serviceToTest.deleteAllDataForProject("project-1");

/* test */
verify(scanReportRepository).deleteAllReportsForProject("project-1");

}

@Test
public void deleteAllDataForProject_triggers_deleteAllLogDataForProject() {
/* execute */
serviceToTest.deleteAllDataForProject("project-1");

/* test */
verify(projectScanLogRepository).deleteAllLogDataForProject("project-1");

}

}
Loading

0 comments on commit 2462630

Please sign in to comment.