Skip to content

Commit ca4b268

Browse files
committed
[backend] wip
1 parent 8d16a2e commit ca4b268

15 files changed

+346
-125
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package io.openbas.rest.payload;
2+
3+
import static io.openbas.helper.StreamHelper.iterableToSet;
4+
import static java.time.Instant.now;
5+
6+
import io.openbas.database.model.ContractOutputElement;
7+
import io.openbas.database.model.OutputParser;
8+
import io.openbas.database.repository.ContractOutputElementRepository;
9+
import io.openbas.database.repository.TagRepository;
10+
import io.openbas.rest.payload.form.ContractOutputElementInput;
11+
import io.openbas.rest.payload.form.OutputParserInput;
12+
import java.time.Instant;
13+
import java.util.HashSet;
14+
import java.util.Set;
15+
import java.util.stream.Collectors;
16+
import lombok.RequiredArgsConstructor;
17+
import lombok.extern.java.Log;
18+
import org.springframework.beans.BeanUtils;
19+
import org.springframework.stereotype.Component;
20+
21+
@Log
22+
@RequiredArgsConstructor
23+
@Component
24+
public class ContractOutputElementUtils {
25+
26+
private final TagRepository tagRepository;
27+
private final ContractOutputElementRepository contractOutputElementRepository;
28+
private final RegexGroupUtils regexGroupUtils;
29+
30+
public void copyContractOutputElements(
31+
Set<?> inputElements, OutputParser outputParser, boolean copyId) {
32+
if (inputElements != null) {
33+
Set<ContractOutputElement> contractOutputElements =
34+
inputElements.stream()
35+
.map(
36+
inputElement -> {
37+
ContractOutputElement contractOutputElement = new ContractOutputElement();
38+
BeanUtils.copyProperties(inputElement, contractOutputElement);
39+
if (!copyId) {
40+
contractOutputElement.setId(null);
41+
}
42+
contractOutputElement.setOutputParser(outputParser);
43+
44+
Instant now = now();
45+
contractOutputElement.setCreatedAt(now);
46+
contractOutputElement.setUpdatedAt(now);
47+
48+
if (inputElement instanceof ContractOutputElementInput) {
49+
ContractOutputElementInput contractOutputElementInput =
50+
(ContractOutputElementInput) inputElement;
51+
contractOutputElement.setTags(
52+
iterableToSet(
53+
tagRepository.findAllById(contractOutputElementInput.getTagIds())));
54+
regexGroupUtils.copyRegexGroups(
55+
contractOutputElementInput.getRegexGroups(),
56+
contractOutputElement,
57+
copyId);
58+
} else {
59+
ContractOutputElement contractOutputElementInstance =
60+
(ContractOutputElement) inputElement;
61+
contractOutputElement.setTags(
62+
iterableToSet(new HashSet<>(contractOutputElementInstance.getTags())));
63+
regexGroupUtils.copyRegexGroups(
64+
contractOutputElement.getRegexGroups(), contractOutputElement, copyId);
65+
}
66+
return contractOutputElement;
67+
})
68+
.collect(Collectors.toSet());
69+
70+
outputParser.setContractOutputElements(contractOutputElements);
71+
}
72+
}
73+
74+
public void removeOrphanContractOutputElements(Set<OutputParserInput> outputParserInputs) {
75+
outputParserInputs.stream()
76+
.forEach(
77+
outputParserInput -> {
78+
Set<ContractOutputElementInput> contractOutputElementInputToBeUpdated =
79+
outputParserInput.getContractOutputElements().stream()
80+
.filter(coe -> coe.getId() != null)
81+
.collect(Collectors.toSet());
82+
if (contractOutputElementInputToBeUpdated.isEmpty()) {
83+
contractOutputElementRepository.deleteByOutPutParserId(outputParserInput.getId());
84+
}
85+
contractOutputElementRepository.deleteByOutPutParserAndIdNotIn(
86+
outputParserInput.getId(),
87+
contractOutputElementInputToBeUpdated.stream()
88+
.map(ContractOutputElementInput::getId)
89+
.collect(Collectors.toList()));
90+
91+
regexGroupUtils.removeOrphanRegexGroups(contractOutputElementInputToBeUpdated);
92+
});
93+
}
94+
}
Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package io.openbas.rest.payload;
22

3-
import static io.openbas.helper.StreamHelper.iterableToSet;
43
import static java.time.Instant.now;
54

65
import io.openbas.database.model.*;
7-
import io.openbas.database.repository.TagRepository;
6+
import io.openbas.database.repository.OutputParserRepository;
87
import io.openbas.rest.payload.form.*;
9-
import java.util.HashSet;
8+
import java.time.Instant;
109
import java.util.Set;
1110
import java.util.stream.Collectors;
1211
import lombok.RequiredArgsConstructor;
@@ -19,29 +18,35 @@
1918
@Component
2019
public class OutputParserUtils {
2120

22-
private final TagRepository tagRepository;
21+
private final OutputParserRepository outputParserRepository;
22+
private final ContractOutputElementUtils contractOutputElementUtils;
2323

24-
public <T> void copyOutputParsers(Set<T> inputParsers, Payload target) {
24+
public <T> void copyOutputParsers(Set<T> inputParsers, Payload target, boolean copyId) {
2525
if (inputParsers != null) {
2626
Set<OutputParser> outputParsers =
2727
inputParsers.stream()
2828
.map(
2929
inputParser -> {
3030
OutputParser outputParser = new OutputParser();
3131
BeanUtils.copyProperties(inputParser, outputParser);
32-
outputParser.setId(null);
32+
if (!copyId) {
33+
outputParser.setId(null);
34+
}
3335
outputParser.setPayload(target);
34-
outputParser.setCreatedAt(now());
35-
outputParser.setUpdatedAt(now());
36+
37+
Instant now = now();
38+
outputParser.setCreatedAt(now);
39+
outputParser.setUpdatedAt(now);
3640

3741
// Handle contract output elements based on the input type
3842
if (inputParser instanceof OutputParserInput) {
3943
OutputParserInput parserInput = (OutputParserInput) inputParser;
40-
copyContractOutputElements(
41-
parserInput.getContractOutputElements(), outputParser);
44+
contractOutputElementUtils.copyContractOutputElements(
45+
parserInput.getContractOutputElements(), outputParser, copyId);
4246
} else if (inputParser instanceof OutputParser) {
4347
OutputParser parser = (OutputParser) inputParser;
44-
copyContractOutputElements(parser.getContractOutputElements(), outputParser);
48+
contractOutputElementUtils.copyContractOutputElements(
49+
parser.getContractOutputElements(), outputParser, copyId);
4550
}
4651

4752
return outputParser;
@@ -52,61 +57,18 @@ public <T> void copyOutputParsers(Set<T> inputParsers, Payload target) {
5257
}
5358
}
5459

55-
private void copyContractOutputElements(Set<?> inputElements, OutputParser outputParser) {
56-
if (inputElements != null) {
57-
Set<ContractOutputElement> contractOutputElements =
58-
inputElements.stream()
59-
.map(
60-
inputElement -> {
61-
ContractOutputElement contractOutputElement = new ContractOutputElement();
62-
BeanUtils.copyProperties(inputElement, contractOutputElement);
63-
contractOutputElement.setId(null);
64-
contractOutputElement.setOutputParser(outputParser);
65-
contractOutputElement.setCreatedAt(now());
66-
contractOutputElement.setUpdatedAt(now());
60+
public void removeOrphanOutputParsers(
61+
Set<OutputParserInput> outputParserInputs, String payloadId) {
6762

68-
if (inputElement instanceof ContractOutputElementInput) {
69-
ContractOutputElementInput contractOutputElementInput =
70-
(ContractOutputElementInput) inputElement;
71-
contractOutputElement.setTags(
72-
iterableToSet(
73-
tagRepository.findAllById(contractOutputElementInput.getTagIds())));
74-
copyRegexGroups(
75-
contractOutputElementInput.getRegexGroups(), contractOutputElement);
76-
} else {
77-
ContractOutputElement contractOutputElementInstance =
78-
(ContractOutputElement) inputElement;
79-
contractOutputElement.setTags(
80-
iterableToSet(new HashSet<>(contractOutputElementInstance.getTags())));
81-
copyRegexGroups(
82-
contractOutputElement.getRegexGroups(), contractOutputElement);
83-
}
84-
return contractOutputElement;
85-
})
86-
.collect(Collectors.toSet());
63+
Set<OutputParserInput> toBeUpdated =
64+
outputParserInputs.stream().filter(op -> op.getId() != null).collect(Collectors.toSet());
8765

88-
outputParser.setContractOutputElements(contractOutputElements);
66+
if (toBeUpdated.isEmpty()) {
67+
outputParserRepository.deleteByPayloadId(payloadId);
8968
}
90-
}
69+
outputParserRepository.deleteByPayloadIdAndIdNotIn(
70+
payloadId, toBeUpdated.stream().map(OutputParserInput::getId).collect(Collectors.toList()));
9171

92-
private void copyRegexGroups(Set<?> inputElements, ContractOutputElement contractOutputElement) {
93-
if (inputElements != null) {
94-
Set<RegexGroup> regexGroups =
95-
inputElements.stream()
96-
.map(
97-
inputElement -> {
98-
RegexGroup regexGroup = new RegexGroup();
99-
BeanUtils.copyProperties(inputElement, regexGroup);
100-
regexGroup.setId(null);
101-
regexGroup.setContractOutputElement(contractOutputElement);
102-
regexGroup.setCreatedAt(now());
103-
regexGroup.setUpdatedAt(now());
104-
105-
return regexGroup;
106-
})
107-
.collect(Collectors.toSet());
108-
109-
contractOutputElement.setRegexGroups(regexGroups);
110-
}
72+
contractOutputElementUtils.removeOrphanContractOutputElements(toBeUpdated);
11173
}
11274
}

openbas-api/src/main/java/io/openbas/rest/payload/PayloadUtils.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public static void validateArchitecture(String payloadType, Payload.PAYLOAD_EXEC
113113
}
114114

115115
// -- COPY PROPERTIES --
116-
public Payload copyProperties(Object payloadInput, Payload target) {
116+
public Payload copyProperties(Object payloadInput, Payload target, boolean copyId) {
117117
if (payloadInput == null) {
118118
throw new IllegalArgumentException("Input payload cannot be null");
119119
}
@@ -122,13 +122,13 @@ public Payload copyProperties(Object payloadInput, Payload target) {
122122

123123
if (payloadInput instanceof PayloadCreateInput) {
124124
outputParserUtils.copyOutputParsers(
125-
((PayloadCreateInput) payloadInput).getOutputParsers(), target);
125+
((PayloadCreateInput) payloadInput).getOutputParsers(), target, copyId);
126126
} else if (payloadInput instanceof PayloadUpdateInput) {
127127
outputParserUtils.copyOutputParsers(
128-
((PayloadUpdateInput) payloadInput).getOutputParsers(), target);
128+
((PayloadUpdateInput) payloadInput).getOutputParsers(), target, copyId);
129129
} else if (payloadInput instanceof PayloadUpsertInput) {
130130
outputParserUtils.copyOutputParsers(
131-
((PayloadUpsertInput) payloadInput).getOutputParsers(), target);
131+
((PayloadUpsertInput) payloadInput).getOutputParsers(), target, copyId);
132132
} else {
133133
throw new IllegalArgumentException("Unsupported payload input type");
134134
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package io.openbas.rest.payload;
2+
3+
import static java.time.Instant.now;
4+
5+
import io.openbas.database.model.ContractOutputElement;
6+
import io.openbas.database.model.RegexGroup;
7+
import io.openbas.database.repository.RegexGroupRepository;
8+
import io.openbas.rest.payload.form.ContractOutputElementInput;
9+
import io.openbas.rest.payload.form.RegexGroupInput;
10+
import java.time.Instant;
11+
import java.util.List;
12+
import java.util.Objects;
13+
import java.util.Set;
14+
import java.util.stream.Collectors;
15+
import lombok.RequiredArgsConstructor;
16+
import lombok.extern.java.Log;
17+
import org.springframework.beans.BeanUtils;
18+
import org.springframework.stereotype.Component;
19+
20+
@Log
21+
@RequiredArgsConstructor
22+
@Component
23+
public class RegexGroupUtils {
24+
25+
private final RegexGroupRepository regexGroupRepository;
26+
27+
public void copyRegexGroups(
28+
Set<?> inputElements, ContractOutputElement contractOutputElement, boolean copyId) {
29+
if (inputElements != null) {
30+
Set<RegexGroup> regexGroups =
31+
inputElements.stream()
32+
.map(
33+
inputElement -> {
34+
RegexGroup regexGroup = new RegexGroup();
35+
BeanUtils.copyProperties(inputElement, regexGroup);
36+
if (!copyId) {
37+
regexGroup.setId(null);
38+
}
39+
regexGroup.setContractOutputElement(contractOutputElement);
40+
41+
Instant now = now();
42+
regexGroup.setCreatedAt(now);
43+
regexGroup.setUpdatedAt(now);
44+
45+
return regexGroup;
46+
})
47+
.collect(Collectors.toSet());
48+
49+
contractOutputElement.setRegexGroups(regexGroups);
50+
}
51+
}
52+
53+
public void removeOrphanRegexGroups(Set<ContractOutputElementInput> contractOutputElementInputs) {
54+
contractOutputElementInputs.stream()
55+
.forEach(
56+
contractOutputElementInput -> {
57+
List<String> regexGroupInputToBeUpdated =
58+
contractOutputElementInput.getRegexGroups().stream()
59+
.map(RegexGroupInput::getId)
60+
.filter(Objects::nonNull)
61+
.toList();
62+
if (regexGroupInputToBeUpdated.isEmpty()) {
63+
regexGroupRepository.deleteByContractOutputElementId(
64+
contractOutputElementInput.getId());
65+
}
66+
regexGroupRepository.deleteByContractOutputElementAndIdNotIn(
67+
contractOutputElementInput.getId(), regexGroupInputToBeUpdated);
68+
});
69+
}
70+
}

openbas-api/src/main/java/io/openbas/rest/payload/form/ContractOutputElementInput.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
@Data
1515
public class ContractOutputElementInput {
1616

17+
@JsonProperty("contract_output_element_id")
18+
private String id;
19+
1720
@JsonProperty("contract_output_element_is_finding")
1821
@Schema(
1922
description =

openbas-api/src/main/java/io/openbas/rest/payload/form/OutputParserInput.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
@Data
1313
public class OutputParserInput {
1414

15+
@JsonProperty("output_parser_id")
16+
private String id;
17+
1518
@JsonProperty("output_parser_mode")
1619
@Schema(description = "Paser Mode: STDOUT, STDERR, READ_FILE")
1720
@NotNull

openbas-api/src/main/java/io/openbas/rest/payload/form/RegexGroupInput.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
@Data
99
public class RegexGroupInput {
1010

11+
@JsonProperty("regex_group_id")
12+
private String id;
13+
1114
@JsonProperty("regex_group_field")
1215
@Schema(description = "Field")
1316
@NotBlank

openbas-api/src/main/java/io/openbas/rest/payload/service/PayloadCreationService.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private Payload create(PayloadCreateInput input) {
4343
switch (payloadType) {
4444
case COMMAND:
4545
Command commandPayload = new Command();
46-
payloadUtils.copyProperties(input, commandPayload);
46+
payloadUtils.copyProperties(input, commandPayload, false);
4747
commandPayload.setAttackPatterns(
4848
fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
4949
commandPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
@@ -52,7 +52,7 @@ private Payload create(PayloadCreateInput input) {
5252
return commandPayload;
5353
case EXECUTABLE:
5454
Executable executablePayload = new Executable();
55-
payloadUtils.copyProperties(input, executablePayload);
55+
payloadUtils.copyProperties(input, executablePayload, false);
5656
executablePayload.setAttackPatterns(
5757
fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
5858
executablePayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
@@ -63,7 +63,7 @@ private Payload create(PayloadCreateInput input) {
6363
return executablePayload;
6464
case FILE_DROP:
6565
FileDrop fileDropPayload = new FileDrop();
66-
payloadUtils.copyProperties(input, fileDropPayload);
66+
payloadUtils.copyProperties(input, fileDropPayload, false);
6767
fileDropPayload.setAttackPatterns(
6868
fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
6969
fileDropPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
@@ -78,7 +78,7 @@ private Payload create(PayloadCreateInput input) {
7878
return fileDropPayload;
7979
case DNS_RESOLUTION:
8080
DnsResolution dnsResolutionPayload = new DnsResolution();
81-
payloadUtils.copyProperties(input, dnsResolutionPayload);
81+
payloadUtils.copyProperties(input, dnsResolutionPayload, false);
8282
dnsResolutionPayload.setAttackPatterns(
8383
fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
8484
dnsResolutionPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));
@@ -87,7 +87,7 @@ private Payload create(PayloadCreateInput input) {
8787
return dnsResolutionPayload;
8888
case NETWORK_TRAFFIC:
8989
NetworkTraffic networkTrafficPayload = new NetworkTraffic();
90-
payloadUtils.copyProperties(input, networkTrafficPayload);
90+
payloadUtils.copyProperties(input, networkTrafficPayload, false);
9191
networkTrafficPayload.setAttackPatterns(
9292
fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
9393
networkTrafficPayload.setTags(iterableToSet(tagRepository.findAllById(input.getTagIds())));

0 commit comments

Comments
 (0)