Skip to content

Commit ec918e2

Browse files
committed
[backend] feat: refact processors
1 parent 3459043 commit ec918e2

48 files changed

Lines changed: 2208 additions & 738 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

openaev-api/src/main/java/io/openaev/output_processor/AbstractOutputProcessor.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ public boolean validate(JsonNode jsonNode) {
6363
* Convert JSON node to finding value string. Override this method if handler supports findings.
6464
* Default returns empty string with warning log.
6565
*/
66-
@Override
6766
public String toFindingValue(JsonNode jsonNode) {
68-
log.warn("Handler {} does not implement toFindingValue, returning empty string", type);
67+
log.debug("Handler {} does not implement toFindingValue, returning empty string", type);
6968
return "";
7069
}
7170

@@ -74,7 +73,7 @@ public String toFindingValue(JsonNode jsonNode) {
7473
* returns empty list.
7574
*/
7675
public List<String> toFindingAssets(JsonNode jsonNode) {
77-
log.warn("Handler {} does not implement toFindingAssets, returning an empty list", type);
76+
log.debug("Handler {} does not implement toFindingAssets, returning an empty list", type);
7877
return Collections.emptyList();
7978
}
8079

@@ -83,7 +82,7 @@ public List<String> toFindingAssets(JsonNode jsonNode) {
8382
* returns empty list.
8483
*/
8584
public List<String> toFindingUsers(JsonNode jsonNode) {
86-
log.warn("Handler {} does not implement toFindingUsers, returning an empty list", type);
85+
log.debug("Handler {} does not implement toFindingUsers, returning an empty list", type);
8786
return Collections.emptyList();
8887
}
8988

@@ -92,11 +91,20 @@ public List<String> toFindingUsers(JsonNode jsonNode) {
9291
* returns empty list.
9392
*/
9493
public List<String> toFindingTeams(JsonNode jsonNode) {
95-
log.warn("Handler {} does not implement toFindingTeams, returning an empty list", type);
94+
log.debug("Handler {} does not implement toFindingTeams, returning an empty list", type);
9695
return Collections.emptyList();
9796
}
9897

99-
// Utility methods
98+
// UTILITY methods
99+
/**
100+
* Builds a string representation from a JSON node.
101+
*
102+
* <p>If the node is an array, concatenates all elements (with quotes trimmed) separated by
103+
* spaces. Otherwise, returns the node's text value with quotes trimmed.
104+
*
105+
* @param jsonNode the JSON node to process
106+
* @return a string representation of the node's value(s)
107+
*/
100108
protected String buildString(@NotNull final JsonNode jsonNode) {
101109
if (jsonNode.isArray()) {
102110
List<String> values = new ArrayList<>();
@@ -108,6 +116,16 @@ protected String buildString(@NotNull final JsonNode jsonNode) {
108116
return trimQuotes(jsonNode.asText());
109117
}
110118

119+
/**
120+
* Builds a string representation from a specific key in a JSON node.
121+
*
122+
* <p>If the key is missing or null, returns an empty string. Otherwise, delegates to {@link
123+
* #buildString(JsonNode)}.
124+
*
125+
* @param jsonNode the JSON node to process
126+
* @param key the key to extract
127+
* @return a string representation of the value at the given key, or empty string if not present
128+
*/
111129
protected String buildString(@NotNull final JsonNode jsonNode, @NotBlank final String key) {
112130
JsonNode valueNode = jsonNode.get(key);
113131
if (valueNode == null || valueNode.isNull()) {
@@ -116,6 +134,12 @@ protected String buildString(@NotNull final JsonNode jsonNode, @NotBlank final S
116134
return buildString(valueNode);
117135
}
118136

137+
/**
138+
* Removes leading and trailing quotes from a string value.
139+
*
140+
* @param value the string to trim
141+
* @return the string without leading/trailing quotes
142+
*/
119143
protected String trimQuotes(@NotBlank final String value) {
120144
return value.replaceAll("^\"|\"$", "");
121145
}

openaev-api/src/main/java/io/openaev/output_processor/AssetOutputProcessor.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package io.openaev.output_processor;
22

3+
import com.fasterxml.jackson.databind.JsonNode;
34
import io.openaev.database.model.ContractOutputTechnicalType;
45
import io.openaev.database.model.ContractOutputType;
6+
import io.openaev.rest.inject.service.ContractOutputContext;
7+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
58
import java.util.List;
69
import org.springframework.stereotype.Component;
710

@@ -11,4 +14,14 @@ public class AssetOutputProcessor extends AbstractOutputProcessor {
1114
public AssetOutputProcessor() {
1215
super(ContractOutputType.Asset, ContractOutputTechnicalType.Object, List.of(), false);
1316
}
17+
18+
@Override
19+
public void process(
20+
ExecutionProcessingContext ctx,
21+
ContractOutputContext contractOutputContext,
22+
JsonNode structuredOutputNode) {
23+
// The current implementation of the AssetOutputProcessor does not generate findings, but it can
24+
// be extended in the future to do so if needed.
25+
// For now, it simply validates the input and does not perform any additional processing.
26+
}
1427
}

openaev-api/src/main/java/io/openaev/output_processor/CVEOutputProcessor.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import io.openaev.database.model.ContractOutputField;
55
import io.openaev.database.model.ContractOutputTechnicalType;
66
import io.openaev.database.model.ContractOutputType;
7+
import io.openaev.rest.finding.FindingService;
8+
import io.openaev.rest.inject.service.ContractOutputContext;
9+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
10+
import io.openaev.service.InjectExpectationService;
711
import java.util.ArrayList;
812
import java.util.Collections;
913
import java.util.List;
@@ -17,7 +21,11 @@ public class CVEOutputProcessor extends AbstractOutputProcessor {
1721
private static final String HOST = "host";
1822
private static final String SEVERITY = "severity";
1923

20-
public CVEOutputProcessor() {
24+
private final FindingService findingService;
25+
private final InjectExpectationService injectExpectationService;
26+
27+
public CVEOutputProcessor(
28+
FindingService findingService, InjectExpectationService injectExpectationService) {
2129
super(
2230
ContractOutputType.CVE,
2331
ContractOutputTechnicalType.Object,
@@ -27,14 +35,33 @@ public CVEOutputProcessor() {
2735
new ContractOutputField(HOST, ContractOutputTechnicalType.Text, true),
2836
new ContractOutputField(SEVERITY, ContractOutputTechnicalType.Text, true)),
2937
true);
38+
this.findingService = findingService;
39+
this.injectExpectationService = injectExpectationService;
3040
}
3141

3242
@Override
3343
public boolean validate(JsonNode jsonNode) {
3444
return jsonNode.hasNonNull(ID) && jsonNode.hasNonNull(HOST) && jsonNode.hasNonNull(SEVERITY);
3545
}
3646

37-
// Findings
47+
@Override
48+
public void process(
49+
ExecutionProcessingContext executionContext,
50+
ContractOutputContext contractOutputContext,
51+
JsonNode structuredOutputNode) {
52+
findingService.generateFindings(
53+
executionContext,
54+
contractOutputContext,
55+
structuredOutputNode,
56+
this::validate,
57+
this::toFindingValue,
58+
this::toFindingAssets,
59+
this::toFindingTeams,
60+
this::toFindingUsers);
61+
injectExpectationService.matchesVulnerabilityExpectations(
62+
executionContext, structuredOutputNode);
63+
}
64+
3865
@Override
3966
public String toFindingValue(JsonNode jsonNode) {
4067
return buildString(jsonNode, ID);

openaev-api/src/main/java/io/openaev/output_processor/CredentialsOutputProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import io.openaev.database.model.ContractOutputField;
55
import io.openaev.database.model.ContractOutputTechnicalType;
66
import io.openaev.database.model.ContractOutputType;
7+
import io.openaev.rest.finding.FindingService;
8+
import io.openaev.rest.inject.service.ContractOutputContext;
9+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
710
import java.util.List;
811
import org.springframework.stereotype.Component;
912

@@ -13,21 +16,40 @@ public class CredentialsOutputProcessor extends AbstractOutputProcessor {
1316
private static final String USERNAME = "username";
1417
private static final String PASSWORD = "password";
1518

16-
public CredentialsOutputProcessor() {
19+
private final FindingService findingService;
20+
21+
public CredentialsOutputProcessor(FindingService findingService) {
1722
super(
1823
ContractOutputType.Credentials,
1924
ContractOutputTechnicalType.Object,
2025
List.of(
2126
new ContractOutputField(USERNAME, ContractOutputTechnicalType.Text, true),
2227
new ContractOutputField(PASSWORD, ContractOutputTechnicalType.Text, true)),
2328
true);
29+
this.findingService = findingService;
2430
}
2531

2632
@Override
2733
public boolean validate(JsonNode jsonNode) {
2834
return jsonNode.hasNonNull(USERNAME) && jsonNode.hasNonNull(PASSWORD);
2935
}
3036

37+
@Override
38+
public void process(
39+
ExecutionProcessingContext executionContext,
40+
ContractOutputContext contractOutputContext,
41+
JsonNode structuredOutputNode) {
42+
findingService.generateFindings(
43+
executionContext,
44+
contractOutputContext,
45+
structuredOutputNode,
46+
this::validate,
47+
this::toFindingValue,
48+
this::toFindingAssets,
49+
this::toFindingTeams,
50+
this::toFindingUsers);
51+
}
52+
3153
@Override
3254
public String toFindingValue(JsonNode jsonNode) {
3355
String username = buildString(jsonNode, USERNAME);

openaev-api/src/main/java/io/openaev/output_processor/IPv4OutputProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.fasterxml.jackson.databind.JsonNode;
44
import io.openaev.database.model.ContractOutputTechnicalType;
55
import io.openaev.database.model.ContractOutputType;
6+
import io.openaev.rest.finding.FindingService;
7+
import io.openaev.rest.inject.service.ContractOutputContext;
8+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
69
import java.util.List;
710
import org.apache.commons.validator.routines.InetAddressValidator;
811
import org.springframework.stereotype.Component;
@@ -12,15 +15,34 @@ public class IPv4OutputProcessor extends AbstractOutputProcessor {
1215

1316
private static final InetAddressValidator VALIDATOR = InetAddressValidator.getInstance();
1417

15-
public IPv4OutputProcessor() {
18+
private final FindingService findingService;
19+
20+
public IPv4OutputProcessor(FindingService findingService) {
1621
super(ContractOutputType.IPv4, ContractOutputTechnicalType.Text, List.of(), true);
22+
this.findingService = findingService;
1723
}
1824

1925
@Override
2026
public boolean validate(JsonNode jsonNode) {
2127
return VALIDATOR.isValidInet4Address(jsonNode.asText());
2228
}
2329

30+
@Override
31+
public void process(
32+
ExecutionProcessingContext executionContext,
33+
ContractOutputContext contractOutputContext,
34+
JsonNode structuredOutputNode) {
35+
findingService.generateFindings(
36+
executionContext,
37+
contractOutputContext,
38+
structuredOutputNode,
39+
this::validate,
40+
this::toFindingValue,
41+
this::toFindingAssets,
42+
this::toFindingTeams,
43+
this::toFindingUsers);
44+
}
45+
2446
@Override
2547
public String toFindingValue(JsonNode jsonNode) {
2648
return buildString(jsonNode);

openaev-api/src/main/java/io/openaev/output_processor/IPv6OutputProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import com.fasterxml.jackson.databind.JsonNode;
44
import io.openaev.database.model.ContractOutputTechnicalType;
55
import io.openaev.database.model.ContractOutputType;
6+
import io.openaev.rest.finding.FindingService;
7+
import io.openaev.rest.inject.service.ContractOutputContext;
8+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
69
import java.util.List;
710
import org.apache.commons.validator.routines.InetAddressValidator;
811
import org.springframework.stereotype.Component;
@@ -12,15 +15,34 @@ public class IPv6OutputProcessor extends AbstractOutputProcessor {
1215

1316
private static final InetAddressValidator VALIDATOR = InetAddressValidator.getInstance();
1417

15-
public IPv6OutputProcessor() {
18+
private final FindingService findingService;
19+
20+
public IPv6OutputProcessor(FindingService findingService) {
1621
super(ContractOutputType.IPv6, ContractOutputTechnicalType.Text, List.of(), true);
22+
this.findingService = findingService;
1723
}
1824

1925
@Override
2026
public boolean validate(JsonNode jsonNode) {
2127
return VALIDATOR.isValidInet6Address(jsonNode.asText());
2228
}
2329

30+
@Override
31+
public void process(
32+
ExecutionProcessingContext executionContext,
33+
ContractOutputContext contractOutputContext,
34+
JsonNode structuredOutputNode) {
35+
findingService.generateFindings(
36+
executionContext,
37+
contractOutputContext,
38+
structuredOutputNode,
39+
this::validate,
40+
this::toFindingValue,
41+
this::toFindingAssets,
42+
this::toFindingTeams,
43+
this::toFindingUsers);
44+
}
45+
2446
@Override
2547
public String toFindingValue(JsonNode jsonNode) {
2648
return buildString(jsonNode);

openaev-api/src/main/java/io/openaev/output_processor/NumberOutputProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,40 @@
33
import com.fasterxml.jackson.databind.JsonNode;
44
import io.openaev.database.model.ContractOutputTechnicalType;
55
import io.openaev.database.model.ContractOutputType;
6+
import io.openaev.rest.finding.FindingService;
7+
import io.openaev.rest.inject.service.ContractOutputContext;
8+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
69
import java.util.List;
710
import org.springframework.stereotype.Component;
811

912
@Component
1013
public class NumberOutputProcessor extends AbstractOutputProcessor {
1114

12-
public NumberOutputProcessor() {
15+
private final FindingService findingService;
16+
17+
public NumberOutputProcessor(FindingService findingService) {
1318
super(ContractOutputType.Number, ContractOutputTechnicalType.Number, List.of(), true);
19+
this.findingService = findingService;
1420
}
1521

1622
@Override
1723
public String toFindingValue(JsonNode jsonNode) {
1824
return buildString(jsonNode);
1925
}
26+
27+
@Override
28+
public void process(
29+
ExecutionProcessingContext executionContext,
30+
ContractOutputContext contractOutputContext,
31+
JsonNode structuredOutputNode) {
32+
findingService.generateFindings(
33+
executionContext,
34+
contractOutputContext,
35+
structuredOutputNode,
36+
this::validate,
37+
this::toFindingValue,
38+
this::toFindingAssets,
39+
this::toFindingTeams,
40+
this::toFindingUsers);
41+
}
2042
}

openaev-api/src/main/java/io/openaev/output_processor/OutputProcessor.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import io.openaev.database.model.ContractOutputField;
55
import io.openaev.database.model.ContractOutputTechnicalType;
66
import io.openaev.database.model.ContractOutputType;
7+
import io.openaev.rest.inject.service.ContractOutputContext;
8+
import io.openaev.rest.inject.service.ExecutionProcessingContext;
79
import java.util.List;
810

911
/**
@@ -28,12 +30,11 @@ public interface OutputProcessor {
2830
/** Validate that the JSON node is correctly formatted for this type */
2931
boolean validate(JsonNode jsonNode);
3032

31-
// FINDING methods
32-
String toFindingValue(JsonNode jsonNode);
33-
34-
List<String> toFindingAssets(JsonNode jsonNode);
35-
36-
List<String> toFindingUsers(JsonNode jsonNode);
37-
38-
List<String> toFindingTeams(JsonNode jsonNode);
33+
/**
34+
* Process a set of operations like generating findings, matching expectations and process assets.
35+
*/
36+
void process(
37+
ExecutionProcessingContext ctx,
38+
ContractOutputContext contractOutputContext,
39+
JsonNode structuredOutputNode);
3940
}

0 commit comments

Comments
 (0)