Skip to content

Commit 29fe2af

Browse files
committed
fix[backend]: solved problem with merge
1 parent e7725e2 commit 29fe2af

File tree

10 files changed

+180
-17
lines changed

10 files changed

+180
-17
lines changed

backend/src/main/java/com/park/utmstack/domain/application_modules/UtmModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class UtmModule implements Serializable {
3232
@Column(name = "pretty_name")
3333
private String prettyName;
3434

35-
@Enumerated(EnumType.STRING)
35+
@Convert(converter = com.park.utmstack.domain.application_modules.enums.ModuleNameConverter.class)
3636
@Column(name = "module_name")
3737
private ModuleName moduleName;
3838

backend/src/main/java/com/park/utmstack/domain/application_modules/enums/ModuleName.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,7 @@ public enum ModuleName {
6666
ORACLE,
6767
SURICATA,
6868
UTMSTACK,
69-
CROWDSTRIKE
69+
CROWDSTRIKE,
70+
SYSLOG_GENERIC,
71+
WINDOWS_EVENTS
7072
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.park.utmstack.domain.application_modules.enums;
2+
3+
import javax.persistence.AttributeConverter;
4+
import javax.persistence.Converter;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
@Converter(autoApply = true)
9+
public class ModuleNameConverter implements AttributeConverter<ModuleName, String> {
10+
private static final Logger log = LoggerFactory.getLogger(ModuleNameConverter.class);
11+
12+
@Override
13+
public String convertToDatabaseColumn(ModuleName attribute) {
14+
return attribute == null ? null : attribute.name();
15+
}
16+
17+
@Override
18+
public ModuleName convertToEntityAttribute(String dbData) {
19+
if (dbData == null) {
20+
return null;
21+
}
22+
try {
23+
return ModuleName.valueOf(dbData);
24+
} catch (IllegalArgumentException e) {
25+
log.warn("Unknown ModuleName in database: '{}'. Mapping to null to prevent crash. ---", dbData);
26+
return null;
27+
}
28+
}
29+
}

backend/src/main/java/com/park/utmstack/domain/logstash_filter/UtmLogstashFilter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ public class UtmLogstashFilter implements Serializable, AuditableDTO {
6767
private Instant updatedAt;
6868

6969
@JsonIgnore
70-
@ManyToOne(fetch = FetchType.LAZY)
71-
@JoinColumn(name = "module_name", referencedColumnName = "module_name",insertable = false, updatable = false)
70+
@ManyToOne(fetch = FetchType.LAZY, optional = true)
71+
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.IGNORE)
72+
@JoinColumn(name = "module_name", referencedColumnName = "module_name", insertable = false, updatable = false, nullable = true)
7273
private UtmModule module;
7374

7475
public UtmLogstashFilter() {

backend/src/main/java/com/park/utmstack/repository/correlation/rules/UtmCorrelationRulesRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ Page<UtmCorrelationRules> searchByFilters(@Param("ruleName") String ruleName,
5656

5757
Optional<UtmCorrelationRules> findOneByRuleName(String ruleName);
5858

59+
List<UtmCorrelationRules> findAllBySystemOwnerIsTrue();
60+
5961
Optional<UtmCorrelationRules> findFirstBySystemOwnerIsTrueOrderByIdDesc();
6062
}

backend/src/main/java/com/park/utmstack/repository/logstash_filter/UtmLogstashFilterRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public interface UtmLogstashFilterRepository extends JpaRepository<UtmLogstashFi
2020

2121
void deleteAllBySystemOwnerIsTrueAndIdNotIn(List<Long> ids);
2222

23+
List<UtmLogstashFilter> findAllBySystemOwnerIsTrue();
24+
2325
@Query(nativeQuery = true, value = "select utm_logstash_filter.* from utm_logstash_filter where :nameShort = any(string_to_array(utm_logstash_filter.module_name, ','))")
2426
List<UtmLogstashFilter> findAllByModuleName(@Param("nameShort") String nameShort);
2527

backend/src/main/java/com/park/utmstack/service/correlation/rules/UtmCorrelationRulesService.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ public UtmCorrelationRulesService(UtmCorrelationRulesRepository utmCorrelationRu
6262
* @return the persisted entity.
6363
*/
6464
public UtmCorrelationRules save(UtmCorrelationRules rule) {
65+
return save(rule, false);
66+
}
67+
68+
public UtmCorrelationRules save(UtmCorrelationRules rule, boolean forcedSystemMode) {
6569
final String ctx = CLASSNAME + ".saveRule";
6670
log.debug("Request to save UtmCorrelationRules : {}", rule);
6771

@@ -72,6 +76,10 @@ public UtmCorrelationRules save(UtmCorrelationRules rule) {
7276
}
7377
}
7478

79+
if (forcedSystemMode) {
80+
rule.setSystemOwner(true);
81+
}
82+
7583
rule.setDataTypes(this.saveDataTypes(rule));
7684
rule.setRuleLastUpdate(Instant.now(Clock.systemUTC()));
7785
return utmCorrelationRulesRepository.save(rule);
@@ -86,6 +94,11 @@ public UtmCorrelationRules save(UtmCorrelationRules rule) {
8694
* */
8795
@Transactional
8896
public void updateRule(UtmCorrelationRules correlationRule) throws Exception {
97+
updateRule(correlationRule, false);
98+
}
99+
100+
@Transactional
101+
public void updateRule(UtmCorrelationRules correlationRule, boolean forcedSystemMode) throws Exception {
89102
final String ctx = CLASSNAME + ".updateRule";
90103
Long id = correlationRule.getId();
91104
if (id == null) {
@@ -99,7 +112,12 @@ public void updateRule(UtmCorrelationRules correlationRule) throws Exception {
99112
if (correlationRule.getDataTypes().isEmpty()) {
100113
throw new BadRequestException(ctx + ": The rule must have at least one data type.");
101114
}
102-
if(optionalCorrelationRule.get().getSystemOwner() && !utmStackService.isInDevelop()) {
115+
116+
if (forcedSystemMode) {
117+
correlationRule.setSystemOwner(true);
118+
}
119+
120+
if(optionalCorrelationRule.get().getSystemOwner() && !utmStackService.isInDevelop() && !forcedSystemMode) {
103121
throw new BadRequestException(ctx + ": System's rules can't be updated.");
104122
}
105123
correlationRule.setDataTypes(this.saveDataTypes(correlationRule));
@@ -140,12 +158,17 @@ public void setRuleActivation(Long ruleId, boolean setActive) throws Exception {
140158
* */
141159
@Transactional
142160
public void deleteRule (Long id) throws Exception {
161+
deleteRule(id, false);
162+
}
163+
164+
@Transactional
165+
public void deleteRule (Long id, boolean forcedSystemMode) throws Exception {
143166
final String ctx = CLASSNAME + ".deleteRule";
144167
Optional<UtmCorrelationRules> find = utmCorrelationRulesRepository.findById(id);
145168
if (find.isEmpty()) {
146169
throw new BadRequestException(ctx + ": The rule you're trying to delete is not present in database.");
147170
}
148-
if(find.get().getSystemOwner()) {
171+
if(find.get().getSystemOwner() && !forcedSystemMode) {
149172
throw new BadRequestException(ctx + ": System's rules can't be removed.");
150173
}
151174
utmCorrelationRulesRepository.deleteById(id);

backend/src/main/java/com/park/utmstack/service/logstash_filter/UtmLogstashFilterService.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,10 @@ public List<UtmLogstashFilter> filtersByPipelineId(Long pipelineId) {
114114
throw new RuntimeException(ctx + ": " + e.getMessage());
115115
}
116116
}
117+
118+
public Long getSystemSequenceNextValue() {
119+
return logstashFilterRepository.findFirstBySystemOwnerIsTrueOrderByIdDesc()
120+
.map(filter -> filter.getId() + 1)
121+
.orElse(1L);
122+
}
117123
}

backend/src/main/java/com/park/utmstack/util/CipherUtil.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,32 @@
1414

1515
public class CipherUtil {
1616
private static final String CLASSNAME = "CipherUtil";
17-
private static SecretKeySpec secretKey;
18-
private static IvParameterSpec iv;
1917
private static final String CIPHER_INSTANCE = "AES/CBC/PKCS5Padding";
18+
private static final int ITERATION_COUNT = 65536;
19+
private static final int KEY_LENGTH = 128;
2020

21-
private static void setKey(String myKey) throws Exception {
22-
final String ctx = CLASSNAME + ".";
21+
private static class CryptoContext {
22+
final SecretKeySpec secretKey;
23+
final IvParameterSpec iv;
24+
25+
CryptoContext(SecretKeySpec secretKey, IvParameterSpec iv) {
26+
this.secretKey = secretKey;
27+
this.iv = iv;
28+
}
29+
}
30+
31+
private static CryptoContext getCryptoContext(String myKey) throws Exception {
32+
final String ctx = CLASSNAME + ".getCryptoContext";
2333
try {
2434
byte[] salt = myKey.getBytes(StandardCharsets.UTF_8);
2535
MessageDigest sha = MessageDigest.getInstance("SHA-1");
2636
salt = sha.digest(salt);
27-
KeySpec spec = new PBEKeySpec(myKey.toCharArray(), salt, 65536, 128); // AES-256
37+
KeySpec spec = new PBEKeySpec(myKey.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);
2838
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
2939
byte[] key = f.generateSecret(spec).getEncoded();
30-
secretKey = new SecretKeySpec(key, "AES");
31-
iv = new IvParameterSpec(Arrays.copyOf(salt, 16));
40+
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
41+
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOf(salt, 16));
42+
return new CryptoContext(secretKey, iv);
3243
} catch (Exception e) {
3344
throw new Exception(ctx + ": " + e.getMessage());
3445
}
@@ -37,9 +48,9 @@ private static void setKey(String myKey) throws Exception {
3748
public static String encrypt(String str, String secret) {
3849
final String ctx = CLASSNAME + ".encrypt";
3950
try {
40-
setKey(secret);
51+
CryptoContext context = getCryptoContext(secret);
4152
Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE);
42-
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
53+
cipher.init(Cipher.ENCRYPT_MODE, context.secretKey, context.iv);
4354
return Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
4455
} catch (Exception e) {
4556
throw new RuntimeException(ctx + ": " + e.getMessage());
@@ -49,9 +60,9 @@ public static String encrypt(String str, String secret) {
4960
public static String decrypt(String str, String secret) {
5061
final String ctx = CLASSNAME + ".decrypt";
5162
try {
52-
setKey(secret);
63+
CryptoContext context = getCryptoContext(secret);
5364
Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE);
54-
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
65+
cipher.init(Cipher.DECRYPT_MODE, context.secretKey, context.iv);
5566
return new String(cipher.doFinal(Base64.getDecoder().decode(str)));
5667
} catch (Exception e) {
5768
throw new RuntimeException(ctx + ": " + e.getMessage());
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<databaseChangeLog
3+
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
6+
7+
<changeSet id="20260403001" author="Alex">
8+
<comment>Refactor SOCAI configuration to support multi-provider presets and visibility rules</comment>
9+
<sql dbms="postgresql" splitStatements="false">
10+
<![CDATA[
11+
do $$
12+
declare
13+
grp_id integer;
14+
begin
15+
-- 1. Get the Group ID for SOC_AI
16+
select id into grp_id from public.utm_module_group
17+
where module_id = (select id from public.utm_module where module_name = 'SOC_AI')
18+
limit 1;
19+
20+
IF grp_id IS NOT NULL THEN
21+
-- 2. Cleanup old keys that might conflict or are being renamed/refactored
22+
DELETE FROM public.utm_module_group_configuration
23+
WHERE group_id = grp_id
24+
AND conf_key IN ('utmstack.socai.custom.url', 'utmstack.socai.custom.model', 'utmstack.socai.provider');
25+
26+
-- 3. Update Existing Behavioral Keys (Behavior Section)
27+
UPDATE public.utm_module_group_configuration
28+
SET conf_name = 'Auto-create incidents for "possible incident"',
29+
conf_description = 'If set to "true", the system will create incidents based on analysis of alerts.'
30+
WHERE group_id = grp_id AND conf_key = 'utmstack.socai.incidentCreation';
31+
32+
UPDATE public.utm_module_group_configuration
33+
SET conf_name = 'Change alert status after analysis',
34+
conf_description = 'If set to "true", SOC Ai will automatically change the status of alerts.'
35+
WHERE group_id = grp_id AND conf_key = 'utmstack.socai.changeAlertStatus';
36+
37+
-- 4. Insert/Re-insert Provider Preset (Connection Section)
38+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type, conf_options)
39+
VALUES (grp_id, 'utmstack.socai.provider', 'Provider Preset', 'Select your AI provider', 'openai', true, 'select',
40+
'[{"value": "openai", "label": "OpenAI"}, {"value": "anthropic", "label": "Anthropic"}, {"value": "azure", "label": "Azure OpenAI"}, {"value": "ollama", "label": "Ollama (Local)"}, {"value": "custom", "label": "Custom"}]')
41+
ON CONFLICT (group_id, conf_key) DO UPDATE SET conf_options = EXCLUDED.conf_options, conf_name = EXCLUDED.conf_name;
42+
43+
-- 5. Insert Connection Details
44+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type)
45+
VALUES (grp_id, 'utmstack.socai.url', 'API URL', 'Auto-filled by preset (editable)', 'https://api.openai.com/v1/chat/completions', true, 'text')
46+
ON CONFLICT (group_id, conf_key) DO NOTHING;
47+
48+
-- Update existing model key
49+
UPDATE public.utm_module_group_configuration
50+
SET conf_name = 'Model', conf_description = 'Choose the AI model'
51+
WHERE group_id = grp_id AND conf_key = 'utmstack.socai.model';
52+
53+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type)
54+
VALUES (grp_id, 'utmstack.socai.maxTokens', 'Max Tokens', 'Required for Anthropic', '4096', false, 'number')
55+
ON CONFLICT (group_id, conf_key) DO NOTHING;
56+
57+
-- 6. Update Authentication (API Key mapping)
58+
UPDATE public.utm_module_group_configuration
59+
SET conf_name = 'API Key',
60+
conf_description = 'Authentication key for the provider',
61+
conf_visibility = '{"dependsOn": "utmstack.socai.provider", "values": ["openai", "anthropic", "azure"]}'
62+
WHERE group_id = grp_id AND conf_key = 'utmstack.socai.key';
63+
64+
-- 7. Insert Custom Auth Fields (Visible only for Custom preset)
65+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type, conf_options, conf_visibility)
66+
VALUES (grp_id, 'utmstack.socai.authType', 'Auth Type', 'Select authentication method', 'custom-headers', false, 'select',
67+
'[{"value": "custom-headers", "label": "Custom Headers"}, {"value": "none", "label": "None"}]',
68+
'{"dependsOn": "utmstack.socai.provider", "values": ["custom"]}')
69+
ON CONFLICT (group_id, conf_key) DO NOTHING;
70+
71+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type, conf_visibility)
72+
VALUES (grp_id, 'utmstack.socai.customHeaders', 'Custom Headers', 'JSON format for custom headers (e.g. {"Authorization": "Bearer sk-xxx"})', '{}', false, 'text',
73+
'{"dependsOn": "utmstack.socai.provider", "values": ["custom"]}')
74+
ON CONFLICT (group_id, conf_key) DO NOTHING;
75+
76+
-- 8. Insert new behavior key
77+
INSERT INTO public.utm_module_group_configuration (group_id, conf_key, conf_name, conf_description, conf_value, conf_required, conf_data_type)
78+
VALUES (grp_id, 'utmstack.socai.autoAnalyze', 'Auto-analyze alerts', 'If enabled, the system will automatically send alerts for analysis.', 'true', false, 'bool')
79+
ON CONFLICT (group_id, conf_key) DO NOTHING;
80+
81+
END IF;
82+
end;
83+
$$ language plpgsql;
84+
]]>
85+
</sql>
86+
</changeSet>
87+
</databaseChangeLog>

0 commit comments

Comments
 (0)