Skip to content
This repository was archived by the owner on Feb 26, 2021. It is now read-only.

Commit 45938eb

Browse files
authored
Merge pull request #107 from secureCodeBox/scan-duration
Add scan durationInMs, startDate & endDate fields to SecurityTest and ScanProcessExecution Models
2 parents c31f134 + 71ff9a8 commit 45938eb

11 files changed

Lines changed: 193 additions & 34 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
<camunda.spring.boot.starter.version>3.2.0</camunda.spring.boot.starter.version>
6161
<!-- END IMPORTANT -->
6262

63-
<spring-boot.version>2.1.5.RELEASE</spring-boot.version>
63+
<spring-boot.version>2.1.8.RELEASE</spring-boot.version>
6464
<swagger-version>2.9.0</swagger-version>
6565
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
6666
</properties>

scb-engine/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@
9595
<artifactId>camunda-bpm-spring-boot-starter-test</artifactId>
9696
<scope>test</scope>
9797
</dependency>
98+
99+
<dependency>
100+
<groupId>com.fasterxml.jackson.datatype</groupId>
101+
<artifactId>jackson-datatype-jdk8</artifactId>
102+
</dependency>
98103
</dependencies>
99104

100105
<build>

scb-engine/src/main/java/io/securecodebox/engine/execution/DefaultScanProcessExecution.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@
2020
package io.securecodebox.engine.execution;
2121

2222
import com.fasterxml.jackson.annotation.JsonIgnore;
23-
import com.fasterxml.jackson.core.JsonProcessingException;
24-
import com.fasterxml.jackson.databind.ObjectMapper;
2523
import io.securecodebox.constants.DefaultFields;
26-
import io.securecodebox.model.rest.Report;
24+
import io.securecodebox.engine.service.ExecutionTimeService;
2725
import io.securecodebox.model.execution.ScanProcessExecution;
2826
import io.securecodebox.model.execution.Scanner;
2927
import io.securecodebox.model.execution.Target;
3028
import io.securecodebox.model.findings.Finding;
3129
import io.securecodebox.scanprocess.ProcessVariableHelper;
32-
import java.util.Map;
3330
import org.camunda.bpm.engine.delegate.DelegateExecution;
3431
import org.camunda.bpm.engine.variable.value.BooleanValue;
3532
import org.camunda.bpm.engine.variable.value.StringValue;
3633
import org.springframework.beans.factory.annotation.Configurable;
3734
import org.springframework.util.StringUtils;
3835

3936
import java.util.Collections;
37+
import java.util.Date;
4038
import java.util.LinkedList;
4139
import java.util.List;
40+
import java.util.Map;
41+
import java.util.Optional;
4242
import java.util.UUID;
4343

4444
/**
@@ -51,8 +51,12 @@ public class DefaultScanProcessExecution implements ScanProcessExecution {
5151
@JsonIgnore
5252
protected DelegateExecution execution;
5353

54+
@JsonIgnore
55+
public ExecutionTimeService executionTimeService;
56+
5457
public DefaultScanProcessExecution(DelegateExecution execution) {
5558
this.execution = execution;
59+
this.executionTimeService = new ExecutionTimeService(execution);
5660
}
5761

5862
@Override
@@ -166,7 +170,7 @@ public boolean isAutomated() {
166170
}
167171

168172
@Override
169-
public String getScannerType(){
173+
public String getScannerType() {
170174
return (String) execution.getVariable(DefaultFields.PROCESS_SCANNER_TYPE.name());
171175
}
172176

@@ -175,7 +179,7 @@ public String getScannerType(){
175179
* Same as the Name of the securityTest. e.g. nmap
176180
*/
177181
@Override
178-
public String getName(){
182+
public String getName() {
179183
return (String) execution.getVariable(DefaultFields.PROCESS_NAME.name());
180184
}
181185

@@ -189,7 +193,28 @@ public void setName(String name) {
189193
}
190194

191195
@Override
192-
public Map<String, String> getMetaData(){
196+
public Map<String, String> getMetaData() {
193197
return (Map<String, String>) execution.getVariable(DefaultFields.PROCESS_META_DATA.name());
194198
}
199+
200+
@Override
201+
public Date getStartDate(){
202+
return executionTimeService.getStartDate();
203+
}
204+
205+
@Override
206+
public Optional<Date> getEndDate(){
207+
return executionTimeService.getEndDate();
208+
}
209+
210+
@Override
211+
public Long getDurationInMilliSeconds() {
212+
Date startTime = getStartDate();
213+
214+
if(startTime == null){
215+
return null;
216+
}
217+
218+
return getEndDate().orElseGet(Date::new).getTime() - startTime.getTime();
219+
}
195220
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.securecodebox.engine.service;
2+
3+
import org.camunda.bpm.engine.delegate.DelegateExecution;
4+
import org.camunda.bpm.engine.history.HistoricProcessInstance;
5+
6+
import java.util.Date;
7+
import java.util.Optional;
8+
9+
public class ExecutionTimeService {
10+
11+
private DelegateExecution execution;
12+
13+
public ExecutionTimeService(DelegateExecution execution){
14+
this.execution = execution;
15+
}
16+
17+
private Optional<HistoricProcessInstance> getHistoricProcessInstance(){
18+
return execution.getProcessEngineServices()
19+
.getHistoryService()
20+
.createHistoricProcessInstanceQuery()
21+
.processInstanceId(execution.getProcessInstanceId())
22+
.list()
23+
.stream()
24+
.findFirst();
25+
}
26+
27+
public Date getStartDate(){
28+
return getHistoricProcessInstance()
29+
.orElseThrow(() -> new RuntimeException("Failed to finding process"))
30+
.getStartTime();
31+
}
32+
33+
public Optional<Date> getEndDate(){
34+
return Optional.ofNullable(
35+
getHistoricProcessInstance()
36+
.orElseThrow(() -> new RuntimeException("Failed to finding process"))
37+
.getEndTime()
38+
);
39+
}
40+
}

scb-engine/src/main/java/io/securecodebox/engine/service/SecurityTestService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.LinkedList;
4040
import java.util.List;
4141
import java.util.Map;
42+
import java.util.Optional;
4243
import java.util.UUID;
4344
import java.util.function.Function;
4445
import java.util.stream.Collectors;
@@ -143,7 +144,7 @@ public SecurityTest getCompletedSecurityTest(UUID id) throws SecurityTestNotFoun
143144
List<Target> targets = getListValue(variables, DefaultFields.PROCESS_TARGETS, Target.class);
144145
Map<String, String> metaData = (Map<String, String>) variables.get(DefaultFields.PROCESS_META_DATA.name()).getValue();
145146

146-
return new SecurityTest(id, context, name, targets.get(0), report, metaData, tenant);
147+
return new SecurityTest(id, context, name, targets.get(0), report, metaData, tenant, process.getStartTime(), Optional.ofNullable(process.getEndTime()));
147148
}
148149

149150
private <T> List<T> getListValue(Map<String, HistoricVariableInstance> variables, DefaultFields name, Class<T> type) {

scb-engine/src/test/java/io/securecodebox/engine/execution/DefaultScanProcessExecutionTest.java

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
package io.securecodebox.engine.execution;
2121

2222
import com.fasterxml.jackson.databind.ObjectMapper;
23+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
2324
import io.securecodebox.TestHelper;
2425
import io.securecodebox.constants.DefaultFields;
26+
import io.securecodebox.engine.service.ExecutionTimeService;
2527
import io.securecodebox.model.execution.ScanProcessExecution;
2628
import io.securecodebox.model.execution.ScanProcessExecutionFactory;
2729
import io.securecodebox.model.findings.OsiLayer;
@@ -36,12 +38,15 @@
3638
import org.mockito.MockitoAnnotations;
3739
import org.mockito.stubbing.Answer;
3840

41+
import java.time.LocalDateTime;
42+
import java.time.ZoneOffset;
43+
import java.util.Date;
44+
import java.util.Optional;
3945
import java.util.UUID;
4046

4147
import static org.junit.Assert.assertEquals;
4248
import static org.junit.Assert.assertNotNull;
4349
import static org.mockito.Matchers.any;
44-
import static org.mockito.Matchers.anyString;
4550
import static org.mockito.Matchers.eq;
4651
import static org.mockito.Mockito.atLeastOnce;
4752
import static org.mockito.Mockito.doAnswer;
@@ -55,7 +60,7 @@
5560
*/
5661
public class DefaultScanProcessExecutionTest {
5762

58-
private static final String DEFAULT_EXECUTION = "{\"id\":\"5a4e9d37-09b0-4109-badd-d79dfa8fce2a\",\"context\":\"TEST_CONTEXT\",\"automated\":false,\"scanners\":[{\"id\":\"62fa8ffb-e3bc-433e-b322-9c02108c5171\",\"type\":\"Test_SCANNER\",\"findings\":[{\"id\":\"49bf7fd3-8512-4d73-a28f-608e493cd726\",\"name\":\"BAD_TEST_FINDIG\",\"description\":\"Some coder has tested this!\",\"category\":\"COOL_TEST_STUFF\",\"osi_layer\":\"NOT_APPLICABLE\",\"severity\":\"HIGH\",\"reference\":{\"id\":\"UNI_CODE_STUFF\",\"source\":\"RISCOOL\"},\"hint\":\"You might wan't to blame Rüdiger!\",\"attributes\":{\"TEST\":\"Kekse\",\"HORRIBLE\":\"Coke\"},\"location\":\"mett.brot.securecodebox.io\",\"false_positive\":false}],\"rawFindings\":\"[{\\\"pudding\\\":\\\"Bier\\\"}]\"}]}";
63+
private static final String DEFAULT_EXECUTION = "{\"id\":\"5a4e9d37-09b0-4109-badd-d79dfa8fce2a\",\"context\":\"TEST_CONTEXT\",\"automated\":false,\"scanners\":[{\"id\":\"62fa8ffb-e3bc-433e-b322-9c02108c5171\",\"type\":\"Test_SCANNER\",\"findings\":[{\"id\":\"49bf7fd3-8512-4d73-a28f-608e493cd726\",\"name\":\"BAD_TEST_FINDIG\",\"description\":\"Some coder has tested this!\",\"category\":\"COOL_TEST_STUFF\",\"osi_layer\":\"NOT_APPLICABLE\",\"severity\":\"HIGH\",\"reference\":{\"id\":\"UNI_CODE_STUFF\",\"source\":\"RISCOOL\"},\"hint\":\"You might wan't to blame Rüdiger!\",\"attributes\":{\"TEST\":\"Kekse\",\"HORRIBLE\":\"Coke\"},\"location\":\"mett.brot.securecodebox.io\",\"false_positive\":false}],\"rawFindings\":\"[{\\\"pudding\\\":\\\"Bier\\\"}]\"}],\"startDate\":504295320000,\"endDate\":504295620000,\"durationInMilliSeconds\":300000}";
5964
public static final String SCANNER_SERIALIZE_RESULT = "{\"id\":\"62fa8ffb-e3bc-433e-b322-9c02108c5171\",\"type\":\"Test_SCANNER\",\"findings\":[{\"id\":\"49bf7fd3-8512-4d73-a28f-608e493cd726\",\"name\":\"BAD_TEST_FINDIG\",\"description\":\"Some coder has tested this!\",\"category\":\"COOL_TEST_STUFF\",\"osi_layer\":\"NOT_APPLICABLE\",\"severity\":\"HIGH\",\"reference\":{\"id\":\"UNI_CODE_STUFF\",\"source\":\"RISCOOL\"},\"hint\":\"You might wan't to blame Rüdiger!\",\"attributes\":{\"TEST\":\"Kekse\",\"HORRIBLE\":\"Coke\"},\"location\":\"mett.brot.securecodebox.io\",\"false_positive\":false}],\"rawFindings\":\"[{\\\"pudding\\\":\\\"Bier\\\"}]\"}";
6065

6166
String findingCache = "";
@@ -66,37 +71,51 @@ public class DefaultScanProcessExecutionTest {
6671
@Mock
6772
ScanProcessExecutionFactory processExecutionFactory;
6873
@Mock
69-
DelegateExecution executionMock;
74+
DelegateExecution execution;
75+
@Mock
76+
ExecutionTimeService executionTimeService;
7077

7178
DefaultScanProcessExecution underTest;
7279

7380
@Before
7481
public void setUp() {
7582
MockitoAnnotations.initMocks(this);
76-
underTest = new DefaultScanProcessExecution(executionMock);
83+
underTest = new DefaultScanProcessExecution(execution);
84+
85+
objectMapper.registerModule(new Jdk8Module());
7786

78-
when(processExecutionFactory.get(executionMock)).thenReturn(underTest);
79-
when(executionMock.hasVariable(eq(DefaultFields.PROCESS_FINDINGS.name()))).thenReturn(true);
80-
when(executionMock.getVariable(eq(DefaultFields.PROCESS_FINDINGS.name()))).thenAnswer((answer) -> findingCache);
87+
when(executionTimeService.getStartDate()).thenReturn(
88+
Date.from(LocalDateTime.of(1985, 12, 24, 18, 2).toInstant(ZoneOffset.UTC))
89+
);
90+
when(executionTimeService.getEndDate()).thenReturn(Optional.of(
91+
Date.from(LocalDateTime.of(1985, 12, 24, 18, 7).toInstant(ZoneOffset.UTC))
92+
));
93+
underTest.executionTimeService = executionTimeService;
94+
95+
when(processExecutionFactory.get(execution)).thenReturn(underTest);
96+
when(execution.hasVariable(eq(DefaultFields.PROCESS_FINDINGS.name()))).thenReturn(true);
97+
when(execution.getVariable(eq(DefaultFields.PROCESS_FINDINGS.name()))).thenAnswer((answer) -> findingCache);
8198
doAnswer((Answer) invocation -> {
8299
findingCache = (String) ((ObjectValueImpl)invocation.getArgument(1)).getValue();
83100
return Void.TYPE;
84-
}).when(executionMock).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
101+
}).when(execution).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
85102

86-
when(executionMock.hasVariable(eq(DefaultFields.PROCESS_TARGETS.name()))).thenReturn(true);
87-
when(executionMock.getVariable(eq(DefaultFields.PROCESS_TARGETS.name()))).thenAnswer((answer) -> targetCache);
103+
when(execution.hasVariable(eq(DefaultFields.PROCESS_TARGETS.name()))).thenReturn(true);
104+
when(execution.getVariable(eq(DefaultFields.PROCESS_TARGETS.name()))).thenAnswer((answer) -> targetCache);
88105
doAnswer((Answer) invocation -> {
89106
targetCache = (String) ((ObjectValueImpl)invocation.getArgument(1)).getValue();
90107
return Void.TYPE;
91-
}).when(executionMock).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
108+
}).when(execution).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
92109
}
93110

94111
@Test
95112
public void testSerialize() throws Exception {
96113
DelegateExecution process = mockDelegateExcecution();
97114

98-
ScanProcessExecution execution = new DefaultScanProcessExecution(process);
99-
String s = objectMapper.writeValueAsString(execution);
115+
DefaultScanProcessExecution execution = new DefaultScanProcessExecution(process);
116+
117+
execution.executionTimeService = executionTimeService;
118+
String s = objectMapper.writeValueAsString((ScanProcessExecution) execution);
100119

101120
System.out.println(s);
102121
assertEquals(DEFAULT_EXECUTION, s);
@@ -126,9 +145,9 @@ public void testAppendAndClearFindings() throws Exception {
126145
underTest.appendFinding(TestHelper.createBasicFinding(finding1Id));
127146
underTest.appendFinding(TestHelper.createBasicFindingDifferent(finding2Id));
128147

129-
Mockito.verify(executionMock, times(2)).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
148+
Mockito.verify(execution, times(2)).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
130149

131-
ScanProcessExecution processExecution = processExecutionFactory.get(executionMock);
150+
ScanProcessExecution processExecution = processExecutionFactory.get(execution);
132151

133152
assertEquals(2, processExecution.getFindings().size());
134153

@@ -163,9 +182,9 @@ public void testAppendAndClearFindings() throws Exception {
163182
//
164183
underTest.clearFindings();
165184

166-
Mockito.verify(executionMock, atLeastOnce()).getVariable(eq(DefaultFields.PROCESS_FINDINGS.name()));
167-
Mockito.verify(executionMock, times(3)).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
168-
Mockito.verifyNoMoreInteractions(executionMock);
185+
Mockito.verify(execution, atLeastOnce()).getVariable(eq(DefaultFields.PROCESS_FINDINGS.name()));
186+
Mockito.verify(execution, times(3)).setVariable(eq(DefaultFields.PROCESS_FINDINGS.name()), any());
187+
Mockito.verifyNoMoreInteractions(execution);
169188
assertEquals(0, processExecution.getFindings().size());
170189
}
171190

@@ -177,9 +196,9 @@ public void testAppendAndClearTargets() throws Exception {
177196
underTest.appendTarget(TestHelper.createBaiscTarget());
178197
underTest.appendTarget(TestHelper.createTarget("http://w1.w2.www", "some wired"));
179198

180-
Mockito.verify(executionMock, times(2)).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
199+
Mockito.verify(execution, times(2)).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
181200

182-
ScanProcessExecution processExecution = processExecutionFactory.get(executionMock);
201+
ScanProcessExecution processExecution = processExecutionFactory.get(execution);
183202

184203
assertEquals(2, processExecution.getTargets().size());
185204

@@ -201,9 +220,9 @@ public void testAppendAndClearTargets() throws Exception {
201220
// Clear targets
202221
//
203222
underTest.clearTargets();
204-
Mockito.verify(executionMock, atLeastOnce()).getVariable(eq(DefaultFields.PROCESS_TARGETS.name()));
205-
Mockito.verify(executionMock, times(3)).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
206-
Mockito.verifyNoMoreInteractions(executionMock);
223+
Mockito.verify(execution, atLeastOnce()).getVariable(eq(DefaultFields.PROCESS_TARGETS.name()));
224+
Mockito.verify(execution, times(3)).setVariable(eq(DefaultFields.PROCESS_TARGETS.name()), any());
225+
Mockito.verifyNoMoreInteractions(execution);
207226
assertEquals(0, processExecution.getTargets().size());
208227

209228
}

scb-persistenceproviders/elasticsearch-persistenceprovider/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
<version>1.2.1</version>
7272
<scope>test</scope>
7373
</dependency>
74+
<dependency>
75+
<groupId>com.fasterxml.jackson.datatype</groupId>
76+
<artifactId>jackson-datatype-jdk8</artifactId>
77+
</dependency>
7478
</dependencies>
7579

7680
<build>

scb-persistenceproviders/elasticsearch-persistenceprovider/src/main/java/io/securecodebox/persistence/elasticsearch/ElasticSearchPersistenceProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.fasterxml.jackson.core.JsonProcessingException;
2323
import com.fasterxml.jackson.core.type.TypeReference;
2424
import com.fasterxml.jackson.databind.ObjectMapper;
25+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
2526
import io.securecodebox.model.findings.Finding;
2627
import io.securecodebox.model.securitytest.SecurityTest;
2728
import io.securecodebox.persistence.PersistenceException;
@@ -168,6 +169,7 @@ public void persist(SecurityTest securityTest) throws PersistenceException{
168169
}
169170

170171
ObjectMapper objectMapper = new ObjectMapper();
172+
objectMapper.registerModule(new Jdk8Module());
171173
try {
172174
checkForSecurityTestIdExistence(securityTest);
173175

@@ -336,6 +338,7 @@ private String readFileResource(String file) {
336338
private Map<String, Object> serializeAndRemove(Object object, String... toRemove) {
337339

338340
ObjectMapper objectMapper = new ObjectMapper();
341+
objectMapper.registerModule(new Jdk8Module());
339342
try {
340343
String jsonString = objectMapper.writeValueAsString(object);
341344
Map<String, Object> result = objectMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {
@@ -402,6 +405,7 @@ private void initializeKibana() throws IOException {
402405
// The index-pattern "securecodebox*" doesn't exist, we need to create it along with the import objects
403406

404407
ObjectMapper objectMapper = new ObjectMapper();
408+
objectMapper.registerModule(new Jdk8Module());
405409

406410
String kibanaFile = readFileResource("kibana-imports.json");
407411
List<KibanaData> dataElements = objectMapper.readValue(kibanaFile, objectMapper.getTypeFactory().constructCollectionType(List.class, KibanaData.class));

scb-persistenceproviders/s3-persistenceprovider/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
<dependency>
6767
<groupId>commons-io</groupId>
6868
<artifactId>commons-io</artifactId>
69-
<version>RELEASE</version>
69+
<version>2.6</version>
7070
</dependency>
7171
</dependencies>
7272

0 commit comments

Comments
 (0)