Skip to content

Commit 022a050

Browse files
committed
Merge remote-tracking branch 'origin/v11' into backlog/extend-visualization-creation-flow-to-include-SQL
# Conflicts: # backend/src/main/java/com/park/utmstack/service/dto/elastic/SqlSearchDto.java # backend/src/main/resources/config/liquibase/master.xml # frontend/src/app/data-management/adversary-management/adversary-alerts-graph/adversary-alerts-graph.component.html # frontend/src/app/data-management/adversary-management/adversary-alerts-graph/adversary-alerts-graph.component.ts # frontend/src/app/log-analyzer/explorer/log-analyzer-view/log-analyzer-view.component.html # frontend/src/app/shared/components/code-editor/code-editor.component.html # frontend/src/app/shared/components/code-editor/code-editor.component.ts # frontend/src/app/shared/directives/enterprise/enterprise.directive.ts # frontend/src/app/shared/services/version/app-version.service.ts # frontend/src/environments/environment.ts
2 parents dab82cd + 02447d5 commit 022a050

44 files changed

Lines changed: 588 additions & 287 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.

CHANGELOG.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
# UTMStack 11.0.3
1+
# UTMStack 11.1.4 – Release Notes
22

3-
This is the release notes for **UTMStack v11.0.3**, a minor update focused on bug fixes and performance improvements.
3+
The **UTMStack v11.1.4** update delivers important fixes and usability improvements to enhance stability and user experience.
44

5-
## Fixed Issues
6-
7-
- Fixed a bug in the SOC-AI integration that caused occasional failures when generating insights.
8-
- Fixed a bug when trying to enroll and authenticate by TFA.
9-
10-
## Enhancements
11-
12-
- SIEM configuration now adapts to the Sovereign Cloud Model implemented by the provider in each region for Azure and Microsoft 365 integrations.
5+
## Improvements & Fixes
6+
- Refined the styling of download links to improve clarity and accessibility.
7+
- Resolved a syntax error in the UTMStack installation command, ensuring smoother setup.
8+
- Corrected the display of pipeline card statuses and improved accuracy of event processing counts.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ The installation can be performed using an installer file or an [ISO image](http
105105

106106
- Execute the installer without parameters: `./installer`
107107

108-
Once UTMStack is installed, use admin as the user and the password generated during the installation for the default user to login. You can found the password and other generated configurations in /root/utmstack.yml
108+
Once UTMStack is installed, use admin as the user and the password generated during the installation for the default user to login. You can find the password and other generated configurations in /root/utmstack.yml
109109
Note: Use HTTPS in front of your server name or IP to access the login page.
110110

111111
### Required ports

agent/logservice/processor.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,16 @@ func (l *LogProcessor) CleanCountedLogs() {
174174
for range ticker.C {
175175
dataRetention, err := GetDataRetention()
176176
if err != nil {
177-
utils.Logger.ErrorF("error getting data retention: %s", err)
178-
continue
177+
utils.Logger.ErrorF("error getting data retention: %s, creating default retention file", err)
178+
if err := SetDataRetention(""); err != nil {
179+
utils.Logger.ErrorF("error creating default data retention: %s", err)
180+
continue
181+
}
182+
dataRetention, err = GetDataRetention()
183+
if err != nil {
184+
utils.Logger.ErrorF("error reading newly created data retention: %s", err)
185+
continue
186+
}
179187
}
180188
l.db.Lock()
181189
_, err = l.db.DeleteOld(&models.Log{}, dataRetention)
Lines changed: 14 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
package com.park.utmstack.domain.logstash_pipeline;
22

3+
import com.park.utmstack.domain.application_modules.UtmModule;
34
import com.park.utmstack.service.logstash_pipeline.enums.PipelineStatus;
5+
import lombok.*;
6+
47
import org.hibernate.annotations.GenericGenerator;
58

69
import javax.persistence.*;
710
import javax.validation.constraints.Size;
811
import java.io.Serializable;
912

10-
/**
11-
* A UtmLogstashPipeline.
12-
*/
1313
@Entity
1414
@Table(name = "utm_logstash_pipeline")
15+
@Getter
16+
@Setter
17+
@NoArgsConstructor
18+
@AllArgsConstructor
19+
@Builder
1520
public class UtmLogstashPipeline implements Serializable {
1621

1722
private static final long serialVersionUID = 1L;
@@ -48,103 +53,14 @@ public class UtmLogstashPipeline implements Serializable {
4853
@Column(name = "events_out")
4954
private Long eventsOut;
5055

56+
@OneToOne
57+
@JoinColumn(name = "module_name", referencedColumnName = "module_name", insertable = false, updatable = false)
58+
private UtmModule utmModule;
5159

52-
public UtmLogstashPipeline(){}
53-
public UtmLogstashPipeline(Long id, String pipelineId,
54-
String pipelineName,
55-
String pipelineStatus,
56-
String moduleName,
57-
Boolean systemOwner,
58-
String pipelineDescription,
59-
Boolean pipelineInternal,
60-
Long eventsOut) {
61-
this.id = id;
62-
this.pipelineId = pipelineId;
63-
this.pipelineName = pipelineName;
64-
this.pipelineStatus = pipelineStatus;
65-
this.moduleName = moduleName;
66-
this.systemOwner = systemOwner;
67-
this.pipelineDescription = pipelineDescription;
68-
this.pipelineInternal = pipelineInternal==null?false:pipelineInternal;
69-
this.eventsOut = eventsOut==null?0L:eventsOut;
70-
}
71-
72-
public Long getId() {
73-
return id;
74-
}
75-
76-
public void setId(Long id) {
77-
this.id = id;
78-
}
79-
80-
public String getPipelineId() {
81-
return pipelineId;
82-
}
83-
84-
public void setPipelineId(String pipelineId) {
85-
this.pipelineId = pipelineId;
86-
}
87-
88-
public String getPipelineName() {
89-
return pipelineName;
90-
}
91-
92-
public void setPipelineName(String pipelineName) {
93-
this.pipelineName = pipelineName;
94-
}
95-
96-
public String getPipelineStatus() {
97-
return pipelineStatus;
98-
}
99-
100-
public void setPipelineStatus(String pipelineStatus) {
101-
this.pipelineStatus = pipelineStatus;
102-
}
103-
104-
public String getModuleName() {
105-
return moduleName;
106-
}
107-
108-
public void setModuleName(String moduleName) {
109-
this.moduleName = moduleName;
110-
}
111-
112-
public Boolean getSystemOwner() {
113-
return systemOwner;
114-
}
115-
116-
public void setSystemOwner(Boolean systemOwner) {
117-
this.systemOwner = systemOwner;
118-
}
119-
120-
public String getPipelineDescription() {
121-
return pipelineDescription;
122-
}
123-
124-
public void setPipelineDescription(String pipelineDescription) {
125-
this.pipelineDescription = pipelineDescription;
126-
}
127-
128-
public Boolean getPipelineInternal() {
129-
return pipelineInternal;
130-
}
131-
132-
public void setPipelineInternal(Boolean pipelineInternal) {
133-
this.pipelineInternal = pipelineInternal;
134-
}
135-
136-
public Long getEventsOut() {
137-
return eventsOut;
138-
}
139-
140-
public void setEventsOut(Long eventsOut) {
141-
this.eventsOut = eventsOut;
142-
}
143-
144-
public void setDefaults(){
60+
public void setDefaults() {
14561
this.systemOwner = false;
146-
this.pipelineInternal = this.pipelineInternal==null?false:this.pipelineInternal;
147-
this.eventsOut = this.eventsOut==null?0L:this.eventsOut;
62+
this.pipelineInternal = this.pipelineInternal == null ? false : this.pipelineInternal;
63+
this.eventsOut = this.eventsOut == null ? 0L : this.eventsOut;
14864
this.pipelineStatus = PipelineStatus.PIPELINE_STATUS_DOWN.get();
14965
}
15066
}

backend/src/main/java/com/park/utmstack/event_processor/EventProcessorManagerService.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.park.utmstack.domain.application_modules.UtmModule;
55
import com.park.utmstack.domain.application_modules.UtmModuleGroup;
66
import com.park.utmstack.domain.application_modules.enums.ModuleName;
7+
import com.park.utmstack.service.dto.application_modules.ModuleDTO;
8+
import com.park.utmstack.service.dto.application_modules.UtmModuleMapper;
79
import com.park.utmstack.service.web_clients.rest_template.RestTemplateService;
810
import com.park.utmstack.util.CipherUtil;
911
import lombok.RequiredArgsConstructor;
@@ -34,7 +36,7 @@ public class EventProcessorManagerService {
3436
System.getenv(Constants.ENV_EVENT_PROCESSOR_HOST) + ":" +
3537
System.getenv(Constants.ENV_EVENT_PROCESSOR_PORT);
3638

37-
public void updateModule(UtmModule module) {
39+
public void updateModule(ModuleDTO module) {
3840
final String ctx = CLASSNAME + ".updateModule";
3941

4042
String url = UriComponentsBuilder
@@ -60,10 +62,19 @@ public void updateModule(UtmModule module) {
6062

6163
public void decryptModuleConfig (UtmModule module){
6264
Set<UtmModuleGroup> groups = module.getModuleGroups();
65+
decryptModuleGroupsConfig(groups, module.getModuleName());
66+
}
67+
68+
public void decryptModuleConfig (ModuleDTO moduleDTO){
69+
Set<UtmModuleGroup> groups = moduleDTO.getModuleGroups();
70+
decryptModuleGroupsConfig(groups, moduleDTO.getModuleName());
71+
}
72+
73+
private void decryptModuleGroupsConfig(Set<UtmModuleGroup> groups, ModuleName moduleName) {
6374
groups.forEach((gp) -> {
6475
gp.getModuleGroupConfigurations().forEach((gpc) -> {
6576
if ((gpc.getConfDataType().equals(Constants.CONF_TYPE_PASSWORD) && StringUtils.hasText(gpc.getConfValue()))
66-
|| (gpc.getConfDataType().equals(Constants.CONF_TYPE_FILE) && StringUtils.hasText(gpc.getConfValue())) && typeFileNeedsDecryptList.contains(module.getModuleName())) {
77+
|| (gpc.getConfDataType().equals(Constants.CONF_TYPE_FILE) && StringUtils.hasText(gpc.getConfValue())) && typeFileNeedsDecryptList.contains(moduleName)) {
6778
gpc.setConfValue(CipherUtil.decrypt(gpc.getConfValue(), System.getenv(Constants.ENV_ENCRYPTION_KEY)));
6879
}
6980
});

backend/src/main/java/com/park/utmstack/repository/application_modules/UtmModuleRepository.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.springframework.stereotype.Repository;
1111

1212
import java.util.List;
13+
import java.util.Optional;
1314

1415

1516
/**
@@ -19,8 +20,8 @@
1920
@Repository
2021
public interface UtmModuleRepository extends JpaRepository<UtmModule, Long>, JpaSpecificationExecutor<UtmModule> {
2122

22-
@EntityGraph(attributePaths = {"moduleGroups", "moduleGroups.moduleGroupConfigurations"})
23-
UtmModule findByServerIdAndModuleName(Long serverId, ModuleName shortName);
23+
@EntityGraph(attributePaths = {"server", "filters", "moduleGroups", "moduleGroups.moduleGroupConfigurations"})
24+
Optional<UtmModule> findByServerIdAndModuleName(Long serverId, ModuleName shortName);
2425

2526
Integer countAllByModuleNameAndModuleActiveIsTrue(ModuleName shortName);
2627

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
import com.park.utmstack.repository.application_modules.UtmModuleRepository;
99
import com.park.utmstack.event_processor.EventProcessorManagerService;
1010
import com.park.utmstack.util.CipherUtil;
11+
import com.park.utmstack.util.exceptions.ApiException;
1112
import lombok.RequiredArgsConstructor;
12-
import org.apache.commons.lang3.SerializationUtils;
13+
import org.springframework.http.HttpStatus;
1314
import org.springframework.stereotype.Service;
1415
import org.springframework.transaction.annotation.Transactional;
1516
import org.springframework.util.CollectionUtils;
@@ -53,11 +54,11 @@ public void createConfigurationKeys(List<UtmModuleGroupConfiguration> keys) thro
5354
* @param keys List of configuration keys to save
5455
* @throws Exception In case of any error
5556
*/
56-
public void updateConfigurationKeys(Long moduleId, List<UtmModuleGroupConfiguration> keys) throws Exception {
57+
public UtmModule updateConfigurationKeys(Long moduleId, List<UtmModuleGroupConfiguration> keys) throws Exception {
5758
final String ctx = CLASSNAME + ".updateConfigurationKeys";
5859
try {
5960
if (CollectionUtils.isEmpty(keys))
60-
return;
61+
throw new ApiException("No configuration keys were provided to update", HttpStatus.BAD_REQUEST);
6162
for (UtmModuleGroupConfiguration key : keys) {
6263
if (key.getConfRequired() && !StringUtils.hasText(key.getConfValue()))
6364
throw new Exception(String.format("No value was found for required configuration: %1$s (%2$s)", key.getConfName(), key.getConfKey()));
@@ -67,14 +68,14 @@ public void updateConfigurationKeys(Long moduleId, List<UtmModuleGroupConfigurat
6768
moduleConfigurationRepository.saveAll(keys);
6869

6970
List<ModuleName> needRestartModules = Arrays.asList(ModuleName.AWS_IAM_USER, ModuleName.AZURE,
70-
ModuleName.GCP, ModuleName.SOPHOS);
71+
ModuleName.GCP, ModuleName.SOPHOS);
7172

72-
moduleRepository.findById(moduleId).ifPresent(module -> {
73-
module.setNeedsRestart(needRestartModules.contains(module.getModuleName()));
74-
moduleRepository.save(module);
75-
UtmModule detached = SerializationUtils.clone(module);
76-
eventProcessorManagerService.updateModule(detached);
77-
});
73+
return moduleRepository.findById(moduleId)
74+
.map(module -> {
75+
module.setNeedsRestart(needRestartModules.contains(module.getModuleName()));
76+
return moduleRepository.save(module);
77+
})
78+
.orElseThrow(() -> new ApiException(String.format("Module with ID %1$s not found", moduleId), HttpStatus.NOT_FOUND));
7879
} catch (Exception e) {
7980
throw new Exception(ctx + ": " + e.getMessage());
8081
}

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

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
import com.park.utmstack.repository.UtmModuleGroupRepository;
99
import com.park.utmstack.repository.application_modules.UtmModuleRepository;
1010
import com.park.utmstack.service.UtmMenuService;
11-
import com.park.utmstack.event_processor.EventProcessorManagerService;
1211
import com.park.utmstack.service.dto.application_modules.ModuleActivationDTO;
1312
import com.park.utmstack.service.index_pattern.UtmIndexPatternService;
1413
import com.park.utmstack.service.logstash_filter.UtmLogstashFilterService;
1514
import lombok.RequiredArgsConstructor;
16-
import org.apache.commons.lang3.SerializationUtils;
1715
import org.slf4j.Logger;
1816
import org.slf4j.LoggerFactory;
1917
import org.springframework.data.domain.Page;
@@ -24,7 +22,6 @@
2422

2523
import java.util.List;
2624
import java.util.NoSuchElementException;
27-
import java.util.Objects;
2825
import java.util.Optional;
2926

3027
/**
@@ -43,7 +40,6 @@ public class UtmModuleService {
4340
private final UtmIndexPatternService indexPatternService;
4441
private final UtmLogstashFilterService logstashFilterService;
4542
private final UtmModuleGroupRepository moduleGroupRepository;
46-
private final EventProcessorManagerService eventProcessorManagerService;
4743

4844

4945
/**
@@ -56,30 +52,29 @@ public class UtmModuleService {
5652
public UtmModule activateDeactivate(ModuleActivationDTO moduleActivationDTO) {
5753
final String ctx = CLASSNAME + ".activateDeactivate";
5854

59-
long serverId = moduleActivationDTO.getServerId();
60-
ModuleName nameShort = moduleActivationDTO.getModuleName();
61-
boolean activationStatus = moduleActivationDTO.getActivationStatus();
55+
long serverId = moduleActivationDTO.getServerId();
56+
ModuleName nameShort = moduleActivationDTO.getModuleName();
57+
boolean activationStatus = moduleActivationDTO.getActivationStatus();
6258

63-
UtmModule module = moduleRepository.findByServerIdAndModuleName(serverId, nameShort);
59+
return moduleRepository.findByServerIdAndModuleName(serverId, nameShort)
60+
.map(module -> {
61+
module.setModuleActive(activationStatus);
62+
module = moduleRepository.save(module);
6463

65-
if (Objects.isNull(module))
66-
throw new NoSuchElementException(String.format("Definition of the module %1$s not found for the server ID %2$s", nameShort.name(), serverId));
64+
List<ModuleName> nonRemovableConf = List.of(ModuleName.SOC_AI);
6765

68-
module.setModuleActive(activationStatus);
69-
module = moduleRepository.save(module);
66+
if (!activationStatus && !nonRemovableConf.contains(nameShort))
67+
moduleGroupRepository.deleteAllByModuleId(module.getId());
7068

71-
List<ModuleName> nonRemovableConf = List.of(ModuleName.SOC_AI);
69+
enableDisableModuleMenus(nameShort, activationStatus);
70+
enableDisableModuleIndexPatterns(nameShort, activationStatus);
71+
enableDisableModuleFilter(nameShort, activationStatus);
7272

73-
if (!activationStatus && !nonRemovableConf.contains(nameShort))
74-
moduleGroupRepository.deleteAllByModuleId(module.getId());
75-
76-
enableDisableModuleMenus(nameShort, activationStatus);
77-
enableDisableModuleIndexPatterns(nameShort, activationStatus);
78-
enableDisableModuleFilter(nameShort, activationStatus);
79-
UtmModule detached = SerializationUtils.clone(module);
80-
eventProcessorManagerService.updateModule(detached);
81-
82-
return module;
73+
return module;
74+
})
75+
.orElseThrow(() -> new NoSuchElementException(
76+
String.format("Definition of the module %1$s not found for the server ID %2$s", nameShort.name(), serverId)
77+
));
8378
}
8479

8580
private void enableDisableModuleMenus(ModuleName nameShort, Boolean activationStatus) {
@@ -186,11 +181,12 @@ public Optional<UtmModule> findOne(Long id) {
186181

187182
public UtmModule findByServerIdAndModuleName(Long serverId, ModuleName shortName) {
188183
final String ctx = CLASSNAME + ".findByServerIdAndModuleName";
189-
try {
190-
return moduleRepository.findByServerIdAndModuleName(serverId, shortName);
191-
} catch (Exception e) {
192-
throw new RuntimeException(ctx + ": " + e.getMessage());
193-
}
184+
185+
return moduleRepository.findByServerIdAndModuleName(serverId, shortName)
186+
.orElseThrow(() -> new NoSuchElementException(
187+
String.format("%s: The module %s not found for the server ID %s", ctx, shortName.name(), serverId)
188+
));
189+
194190
}
195191

196192
public boolean isModuleActive(ModuleName shortName) {

backend/src/main/java/com/park/utmstack/service/dto/logstash_pipeline/UtmLogstashPipelineDTO.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ public UtmLogstashPipelineDTO(UtmLogstashPipeline pipeline) {
5555

5656
@JsonIgnore
5757
public UtmLogstashPipeline getPipeline(UtmLogstashPipeline utmLogstashPipeline) {
58-
if (utmLogstashPipeline==null) utmLogstashPipeline = new UtmLogstashPipeline();
58+
if (utmLogstashPipeline==null){
59+
utmLogstashPipeline = new UtmLogstashPipeline();
60+
utmLogstashPipeline.setDefaults();
61+
}
5962
utmLogstashPipeline.setId(this.getId());
6063
utmLogstashPipeline.setPipelineName(this.getPipelineName());
6164
utmLogstashPipeline.setModuleName(this.getModuleName());

0 commit comments

Comments
 (0)