Skip to content

Commit 5f41514

Browse files
fix[backend](initial-setup):added RuleYml to parse rules yml
1 parent cd28b0e commit 5f41514

2 files changed

Lines changed: 93 additions & 70 deletions

File tree

backend/src/main/java/com/park/utmstack/service/DefinitionSyncService.java

Lines changed: 63 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
import com.park.utmstack.service.dto.correlation.AdversaryType;
1212
import com.park.utmstack.service.dto.correlation.UtmCorrelationRulesDTO;
1313
import com.park.utmstack.service.dto.correlation.UtmCorrelationRulesMapper;
14+
import com.park.utmstack.service.dto.correlation.RuleYaml;
1415
import com.park.utmstack.service.logstash_filter.UtmLogstashFilterService;
15-
import lombok.Data;
1616
import lombok.RequiredArgsConstructor;
1717
import org.slf4j.Logger;
1818
import org.slf4j.LoggerFactory;
@@ -21,9 +21,7 @@
2121
import org.springframework.transaction.annotation.Transactional;
2222
import org.yaml.snakeyaml.Yaml;
2323

24-
import javax.annotation.PostConstruct;
2524
import java.io.IOException;
26-
import java.lang.Exception;
2725
import java.nio.file.Files;
2826
import java.nio.file.Path;
2927
import java.nio.file.Paths;
@@ -172,57 +170,69 @@ private Set<String> syncRules() {
172170
paths.filter(path -> Files.isRegularFile(path) && isYamlFile(path)).forEach(path -> {
173171
try {
174172
String content = Files.readString(path);
175-
RuleYaml ruleYaml = yaml.loadAs(content, RuleYaml.class);
176-
if (ruleYaml == null || ruleYaml.getName() == null) {
177-
log.warn("Skipping invalid rule file: {}", path);
178-
return;
173+
Object yamlObj = yaml.load(content);
174+
List<Map<String, Object>> rawRules = new ArrayList<>();
175+
176+
if (yamlObj instanceof List) {
177+
rawRules.addAll((List<Map<String, Object>>) yamlObj);
178+
} else if (yamlObj instanceof Map) {
179+
rawRules.add((Map<String, Object>) yamlObj);
179180
}
180181

181-
foundRules.add(ruleYaml.getName());
182-
Optional<UtmCorrelationRules> ruleOpt = rulesRepository.findOneByRuleName(ruleYaml.getName());
183-
UtmCorrelationRulesDTO ruleDto = new UtmCorrelationRulesDTO();
182+
for (Map<String, Object> rawRule : rawRules) {
183+
RuleYaml ruleYaml = mapToRuleYaml(rawRule);
184+
if (ruleYaml == null || ruleYaml.getName() == null) {
185+
log.warn("Skipping invalid rule in file: {}", path);
186+
continue;
187+
}
184188

185-
if (ruleOpt.isPresent()) {
186-
ruleDto.setId(ruleOpt.get().getId());
187-
} else {
188-
ruleDto.setId(rulesService.getSystemSequenceNextValue());
189-
}
189+
foundRules.add(ruleYaml.getName());
190+
Optional<UtmCorrelationRules> ruleOpt = rulesRepository.findOneByRuleName(ruleYaml.getName());
191+
UtmCorrelationRulesDTO ruleDto = new UtmCorrelationRulesDTO();
190192

191-
ruleDto.setName(ruleYaml.getName());
192-
ruleDto.setCategory(ruleYaml.getCategory());
193-
ruleDto.setTechnique(ruleYaml.getTechnique());
194-
ruleDto.setAdversary(ruleYaml.getAdversary() != null ? ruleYaml.getAdversary() : AdversaryType.origin);
195-
ruleDto.setDescription(ruleYaml.getDescription());
196-
ruleDto.setReferences(ruleYaml.getReferences());
197-
ruleDto.setDefinition(ruleYaml.getWhere());
198-
ruleDto.setGroupBy(ruleYaml.getGroupBy());
199-
ruleDto.setDeduplicateBy(ruleYaml.getDeduplicateBy());
200-
ruleDto.setAfterEvents(ruleYaml.getAfterEvents());
201-
ruleDto.setSystemOwner(true);
202-
ruleDto.setRuleActive(true);
203-
204-
if (ruleYaml.getImpact() != null) {
205-
ruleDto.setConfidentiality(ruleYaml.getImpact().getConfidentiality());
206-
ruleDto.setIntegrity(ruleYaml.getImpact().getIntegrity());
207-
ruleDto.setAvailability(ruleYaml.getImpact().getAvailability());
208-
}
193+
if (ruleOpt.isPresent()) {
194+
ruleDto.setId(ruleOpt.get().getId());
195+
} else if (ruleYaml.getId() != null) {
196+
ruleDto.setId(ruleYaml.getId());
197+
} else {
198+
ruleDto.setId(rulesService.getSystemSequenceNextValue());
199+
}
209200

210-
// Map dataTypes strings to UtmDataTypes entities
211-
if (ruleYaml.getDataTypes() != null) {
212-
Set<UtmDataTypes> dataTypes = ruleYaml.getDataTypes().stream()
213-
.map(dtName -> dataTypesRepository.findOneByDataType(dtName.toLowerCase()))
214-
.filter(Optional::isPresent)
215-
.map(Optional::get)
216-
.collect(Collectors.toSet());
217-
ruleDto.setDataTypes(dataTypes);
218-
}
201+
ruleDto.setName(ruleYaml.getName());
202+
ruleDto.setCategory(ruleYaml.getCategory());
203+
ruleDto.setTechnique(ruleYaml.getTechnique());
204+
ruleDto.setAdversary(ruleYaml.getAdversary() != null ? ruleYaml.getAdversary() : AdversaryType.origin);
205+
ruleDto.setDescription(ruleYaml.getDescription());
206+
ruleDto.setReferences(ruleYaml.getReferences());
207+
ruleDto.setDefinition(ruleYaml.getWhere());
208+
ruleDto.setGroupBy(ruleYaml.getGroupBy());
209+
ruleDto.setDeduplicateBy(ruleYaml.getDeduplicateBy());
210+
ruleDto.setAfterEvents(ruleYaml.getAfterEvents());
211+
ruleDto.setSystemOwner(true);
212+
ruleDto.setRuleActive(true);
213+
214+
if (ruleYaml.getImpact() != null) {
215+
ruleDto.setConfidentiality(ruleYaml.getImpact().getConfidentiality());
216+
ruleDto.setIntegrity(ruleYaml.getImpact().getIntegrity());
217+
ruleDto.setAvailability(ruleYaml.getImpact().getAvailability());
218+
}
219219

220-
UtmCorrelationRules entity = rulesMapper.toEntity(ruleDto);
221-
if (ruleOpt.isPresent()) {
222-
rulesService.updateRule(entity, true);
220+
// Map dataTypes strings to UtmDataTypes entities
221+
if (ruleYaml.getDataTypes() != null) {
222+
Set<UtmDataTypes> dataTypes = ruleYaml.getDataTypes().stream()
223+
.map(dtName -> dataTypesRepository.findOneByDataType(dtName.toLowerCase()))
224+
.filter(Optional::isPresent)
225+
.map(Optional::get)
226+
.collect(Collectors.toSet());
227+
ruleDto.setDataTypes(dataTypes);
228+
}
223229

224-
} else {
225-
rulesService.save(entity, true);
230+
UtmCorrelationRules entity = rulesMapper.toEntity(ruleDto);
231+
if (ruleOpt.isPresent()) {
232+
rulesService.updateRule(entity, true);
233+
} else {
234+
rulesService.save(entity, true);
235+
}
226236
}
227237

228238
} catch (Exception e) {
@@ -235,6 +245,12 @@ private Set<String> syncRules() {
235245
return foundRules;
236246
}
237247

248+
private RuleYaml mapToRuleYaml(Map<String, Object> map) {
249+
Yaml yaml = new Yaml();
250+
String dump = yaml.dump(map);
251+
return yaml.loadAs(dump, RuleYaml.class);
252+
}
253+
238254
private void cleanupOrphanedFilters(Set<Long> currentFilterIds) {
239255
if (currentFilterIds.isEmpty()) return;
240256
List<UtmLogstashFilter> systemFilters = filterRepository.findAllBySystemOwnerIsTrue();
@@ -272,27 +288,4 @@ private String getFileNameWithoutExtension(Path path) {
272288
int lastDotIndex = fileName.lastIndexOf('.');
273289
return (lastDotIndex == -1) ? fileName : fileName.substring(0, lastDotIndex);
274290
}
275-
276-
@Data
277-
public static class RuleYaml {
278-
private List<String> dataTypes;
279-
private String name;
280-
private ImpactYaml impact;
281-
private String category;
282-
private String technique;
283-
private AdversaryType adversary;
284-
private String description;
285-
private List<String> references;
286-
private String where;
287-
private List<com.park.utmstack.domain.correlation.rules.SearchRequest> afterEvents;
288-
private List<String> groupBy;
289-
private List<String> deduplicateBy;
290-
}
291-
292-
@Data
293-
public static class ImpactYaml {
294-
private Integer confidentiality;
295-
private Integer integrity;
296-
private Integer availability;
297-
}
298291
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.park.utmstack.service.dto.correlation;
2+
3+
import com.park.utmstack.domain.correlation.rules.SearchRequest;
4+
import com.park.utmstack.domain.shared_types.alert.Impact;
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
10+
import java.util.List;
11+
12+
@Data
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
public class RuleYaml {
17+
private Long id;
18+
private List<String> dataTypes;
19+
private String name;
20+
private Impact impact;
21+
private String category;
22+
private String technique;
23+
private AdversaryType adversary;
24+
private String description;
25+
private List<String> references;
26+
private String where;
27+
private List<SearchRequest> afterEvents;
28+
private List<String> groupBy;
29+
private List<String> deduplicateBy;
30+
}

0 commit comments

Comments
 (0)