Skip to content

Commit d5bee2c

Browse files
committed
Merge branch 'release/v11.2.6' of https://github.com/utmstack/UTMStack into release/v11.2.6
2 parents 13030a0 + 9904393 commit d5bee2c

File tree

37 files changed

+1436
-226
lines changed

37 files changed

+1436
-226
lines changed

backend/src/main/java/com/park/utmstack/config/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public final class Constants {
161161

162162
public static final String CONF_TYPE_PASSWORD = "password";
163163
public static final String CONF_TYPE_FILE = "file";
164+
public static final String MASKED_VALUE = "*****";
164165

165166
public static final String API_KEY_HEADER = "Utm-Api-Key";
166167
public static final List<String> API_ENDPOINT_IGNORE = Collections.emptyList();

backend/src/main/java/com/park/utmstack/domain/application_modules/factory/impl/ModuleSocAi.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@ public List<ModuleRequirement> checkRequirements(Long serverId) throws Exception
4545
public List<ModuleConfigurationKey> getConfigurationKeys(Long groupId) throws Exception {
4646
List<ModuleConfigurationKey> keys = new ArrayList<>();
4747

48-
// soc_ai_key
49-
keys.add(ModuleConfigurationKey.builder()
50-
.withGroupId(groupId)
51-
.withConfKey("utmstack.socai.key")
52-
.withConfName("Key")
53-
.withConfDescription("OpenAI Connection key")
54-
.withConfDataType("password")
55-
.withConfRequired(true)
56-
.build());
57-
5848
keys.add(ModuleConfigurationKey.builder()
5949
.withGroupId(groupId)
6050
.withConfKey("utmstack.socai.incidentCreation")

backend/src/main/java/com/park/utmstack/domain/application_modules/validators/UtmModuleConfigValidator.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ public boolean validate(UtmModule module, List<UtmModuleGroupConfiguration> keys
3535
List<UtmModuleGroupConfDTO> configDTOs = dbConfigs.stream()
3636
.map(dbConf -> {
3737
UtmModuleGroupConfiguration override = findInKeys(keys, dbConf.getConfKey());
38-
UtmModuleGroupConfiguration source = override != null ? override : dbConf;
39-
40-
return new UtmModuleGroupConfDTO(
41-
source.getConfKey(),
42-
override != null ? source.getConfValue() : decryptIfNeeded(source.getConfDataType(), source.getConfValue())
43-
);
38+
String value;
39+
if (override != null && !Constants.MASKED_VALUE.equals(override.getConfValue())) {
40+
// User provided a new value — use it as plaintext
41+
value = override.getConfValue();
42+
} else {
43+
// No override or masked — decrypt from DB
44+
value = decryptIfNeeded(dbConf.getConfDataType(), dbConf.getConfValue());
45+
}
46+
return new UtmModuleGroupConfDTO(dbConf.getConfKey(), value);
4447
})
4548
.toList();
4649

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ public UtmIntegrationConf save(UtmIntegrationConf utmIntegrationConf) throws Exc
4040
final String ctx = CLASSNAME + ".save";
4141
try {
4242
String dataType = utmIntegrationConf.getConfDatatype();
43-
if (StringUtils.hasText(dataType) && dataType.equals("password"))
43+
if (StringUtils.hasText(dataType) && dataType.equals("password")
44+
&& !Constants.MASKED_VALUE.equals(utmIntegrationConf.getConfValue()))
4445
utmIntegrationConf.setConfValue(CipherUtil.encrypt(utmIntegrationConf.getConfValue(), System.getenv(Constants.ENV_ENCRYPTION_KEY)));
4546
return utmIntegrationConfRepository.save(utmIntegrationConf);
4647
} catch (Exception e) {

backend/src/main/java/com/park/utmstack/service/application_modules/UtmModuleGroupConfigurationService.java

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,41 @@ public void createConfigurationKeys(List<UtmModuleGroupConfiguration> keys) thro
5050
}
5151

5252
/**
53-
* Update configuration of the application modules
54-
*
55-
* @param keys List of configuration keys to save
53+
* Update configuration of the application modules.
54+
* Password/file fields with the masked value are skipped (not changed).
55+
* Password/file fields with a new value are encrypted before saving.
5656
*/
5757
public UtmModule updateConfigurationKeys(Long moduleId, List<UtmModuleGroupConfiguration> keys) {
5858
final String ctx = CLASSNAME + ".updateConfigurationKeys";
5959
try {
6060
if (CollectionUtils.isEmpty(keys))
6161
throw new ApiException("No configuration keys were provided to update", HttpStatus.BAD_REQUEST);
62+
6263
for (UtmModuleGroupConfiguration key : keys) {
64+
boolean isSensitive = isSensitiveType(key.getConfDataType());
65+
66+
// Skip masked values — the user did not change this field
67+
if (isSensitive && Constants.MASKED_VALUE.equals(key.getConfValue())) {
68+
continue;
69+
}
70+
6371
if (key.getConfRequired() && !StringUtils.hasText(key.getConfValue()))
6472
throw new Exception(String.format("No value was found for required configuration: %1$s (%2$s)", key.getConfName(), key.getConfKey()));
65-
if (key.getConfDataType().equals("password") || key.getConfDataType().equals("file"))
73+
74+
// Encrypt new sensitive values
75+
if (isSensitive) {
6676
key.setConfValue(CipherUtil.encrypt(key.getConfValue(), System.getenv(Constants.ENV_ENCRYPTION_KEY)));
77+
}
78+
}
79+
80+
// Remove masked entries so they don't overwrite DB values
81+
List<UtmModuleGroupConfiguration> toSave = keys.stream()
82+
.filter(k -> !(isSensitiveType(k.getConfDataType()) && Constants.MASKED_VALUE.equals(k.getConfValue())))
83+
.collect(Collectors.toList());
84+
85+
if (!toSave.isEmpty()) {
86+
moduleConfigurationRepository.saveAll(toSave);
6787
}
68-
moduleConfigurationRepository.saveAll(keys);
6988

7089
List<ModuleName> needRestartModules = Arrays.asList(ModuleName.AWS_IAM_USER, ModuleName.AZURE,
7190
ModuleName.GCP, ModuleName.SOPHOS);
@@ -83,32 +102,27 @@ public UtmModule updateConfigurationKeys(Long moduleId, List<UtmModuleGroupConfi
83102
}
84103

85104
/**
86-
* Find all configurations of a module group
87-
*
88-
* @param groupId Identifier of the group to get the configurations
89-
* @return A list of configuration of a group
90-
* @throws Exception In case of any error
105+
* Find all configurations of a module group.
106+
* Sensitive values (password, file) are masked before returning.
91107
*/
92108
public List<UtmModuleGroupConfiguration> findAllByGroupId(Long groupId) throws Exception {
93109
final String ctx = CLASSNAME + ".findAllByGroupId";
94110
try {
95-
return moduleConfigurationRepository.findAllByGroupId(groupId);
111+
List<UtmModuleGroupConfiguration> configs = moduleConfigurationRepository.findAllByGroupId(groupId);
112+
maskSensitiveValues(configs);
113+
return configs;
96114
} catch (Exception e) {
97115
throw new Exception(ctx + ": " + e.getMessage());
98116
}
99117
}
100118

101119
/**
102120
* Gets all configuration parameter for a group and convert it to a map
103-
*
104-
* @param groupId Identifier of a group
105-
* @return A map with the module group configuration
106-
* @throws Exception In case of any error
107121
*/
108122
public Map<String, String> getGroupConfigurationAsMap(Long groupId) throws Exception {
109123
final String ctx = CLASSNAME + ".getGroupConfigurationAsMap";
110124
try {
111-
List<UtmModuleGroupConfiguration> configurations = findAllByGroupId(groupId);
125+
List<UtmModuleGroupConfiguration> configurations = moduleConfigurationRepository.findAllByGroupId(groupId);
112126

113127
if (CollectionUtils.isEmpty(configurations))
114128
return Collections.emptyMap();
@@ -121,18 +135,30 @@ public Map<String, String> getGroupConfigurationAsMap(Long groupId) throws Excep
121135

122136
/**
123137
* Find a configuration parameter by his group and key
124-
*
125-
* @param groupId Identifier of the group to the param belongs
126-
* @param confKey Key word of the configuration parameter
127-
* @return A ${@link UtmModuleGroupConfiguration} object with the configuration parameter information
128-
* @throws Exception In case of any error
129138
*/
130139
public UtmModuleGroupConfiguration findByGroupIdAndConfKey(Long groupId, String confKey) throws Exception {
131140
final String ctx = CLASSNAME + ".findByGroupIdAndConfKey";
132141
try {
133-
return moduleConfigurationRepository.findByGroupIdAndConfKey(groupId, confKey);
142+
UtmModuleGroupConfiguration config = moduleConfigurationRepository.findByGroupIdAndConfKey(groupId, confKey);
143+
if (config != null && isSensitiveType(config.getConfDataType())) {
144+
config.setConfValue(Constants.MASKED_VALUE);
145+
}
146+
return config;
134147
} catch (Exception e) {
135148
throw new Exception(ctx + ": " + e.getMessage());
136149
}
137150
}
151+
152+
private boolean isSensitiveType(String dataType) {
153+
return Constants.CONF_TYPE_PASSWORD.equals(dataType) || Constants.CONF_TYPE_FILE.equals(dataType);
154+
}
155+
156+
private void maskSensitiveValues(List<UtmModuleGroupConfiguration> configs) {
157+
if (configs == null) return;
158+
for (UtmModuleGroupConfiguration config : configs) {
159+
if (isSensitiveType(config.getConfDataType()) && StringUtils.hasText(config.getConfValue())) {
160+
config.setConfValue(Constants.MASKED_VALUE);
161+
}
162+
}
163+
}
138164
}

backend/src/main/java/com/park/utmstack/service/application_modules/UtmModuleGroupService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ public void updateCollectorConfigurationKeys(CollectorConfigDTO collectorConfig)
250250
} else {
251251
for (UtmModuleGroupConfiguration key : keys) {
252252
if (key.getConfDataType().equals("password")) {
253+
if (Constants.MASKED_VALUE.equals(key.getConfValue())) {
254+
continue;
255+
}
253256
key.setConfValue(CipherUtil.encrypt(key.getConfValue(), System.getenv(Constants.ENV_ENCRYPTION_KEY)));
254257
}
255258
}

backend/src/main/java/com/park/utmstack/service/collectors/CollectorOpsService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,9 @@ public void updateCollectorConfigurationKeys(CollectorConfigDTO collectorConfig)
436436
utmModuleGroupRepository.deleteAll(configs);
437437
} else {
438438
for (UtmModuleGroupConfiguration key : keys) {
439+
if (key.getConfDataType().equals("password") && Constants.MASKED_VALUE.equals(key.getConfValue())) {
440+
continue;
441+
}
439442
if (key.getConfRequired() && !StringUtils.hasText(key.getConfValue()))
440443
throw new Exception(String.format("No value was found for required configuration: %1$s (%2$s)", key.getConfName(), key.getConfKey()));
441444
if (key.getConfDataType().equals("password"))

backend/src/main/java/com/park/utmstack/web/rest/application_modules/UtmModuleGroupResource.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,19 @@ public ResponseEntity<UtmModuleGroup> updateUtmConfigurationGroup(@Valid @Reques
131131
public ResponseEntity<List<UtmModuleGroup>> getModuleGroups(@RequestParam Long moduleId) {
132132
final String ctx = CLASSNAME + ".getModuleGroups";
133133
try {
134-
return ResponseEntity.ok(moduleGroupService.findAllByModuleId(moduleId));
134+
List<UtmModuleGroup> groups = moduleGroupService.findAllByModuleId(moduleId);
135+
for (UtmModuleGroup group : groups) {
136+
if (group.getModuleGroupConfigurations() != null) {
137+
for (UtmModuleGroupConfiguration conf : group.getModuleGroupConfigurations()) {
138+
if ((Constants.CONF_TYPE_PASSWORD.equals(conf.getConfDataType())
139+
|| Constants.CONF_TYPE_FILE.equals(conf.getConfDataType()))
140+
&& conf.getConfValue() != null) {
141+
conf.setConfValue(Constants.MASKED_VALUE);
142+
}
143+
}
144+
}
145+
}
146+
return ResponseEntity.ok(groups);
135147
} catch (Exception e) {
136148
String msg = ctx + ": " + e.getMessage();
137149
log.error(msg);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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="20260409002" author="Yorjander">
8+
<sql>
9+
UPDATE utm_module
10+
SET module_description = 'SOC AI uses advanced language models to investigate Security Operations Center alerts by analyzing large volumes of data, identifying patterns, and providing insights into potential security incidents. By leveraging natural language processing capabilities, security analysts can efficiently triage alerts, prioritize threats, and gather contextual information to aid in incident response and remediation.',
11+
module_icon = 'soc-ai.svg'
12+
WHERE module_name = 'SOC_AI';
13+
14+
UPDATE utm_module_group_configuration
15+
SET conf_visibility = '{"dependsOn": "utmstack.socai.provider", "values": ["custom"]}'
16+
WHERE conf_key = 'utmstack.socai.url';
17+
18+
UPDATE utm_module_group_configuration
19+
SET conf_visibility = '{"dependsOn": "utmstack.socai.provider", "values": ["anthropic", "custom"]}'
20+
WHERE conf_key = 'utmstack.socai.maxTokens';
21+
22+
DELETE FROM utm_module_group_configuration
23+
WHERE conf_key = 'utmstack.socai.key';
24+
</sql>
25+
</changeSet>
26+
</databaseChangeLog>

backend/src/main/resources/config/liquibase/master.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,4 +591,6 @@
591591

592592
<include file="/config/liquibase/changelog/20260409001_add_shell_to_alert_response_rule.xml" relativeToChangelogFile="false"/>
593593

594+
<include file="/config/liquibase/changelog/20260409002_update_socai_config.xml" relativeToChangelogFile="false"/>
595+
594596
</databaseChangeLog>

0 commit comments

Comments
 (0)