Skip to content

Commit 0ce9911

Browse files
Backlog/v11 added option disabling tw integration oss (#2572)
* fix[frontend](config): show ThreatWinds toggle in Community edition * fix[backend](tw-config): allow disabling ThreatWinds toggle in Community * feat(config): sync utmstack.tw.enable from database to feeds plugin YAML * fix[backend](config-params): stamp modification_time/user on saveAll --------- Co-authored-by: JocLRojas <joc.l.rojas02@gmail.com>
1 parent 10c6d20 commit 0ce9911

10 files changed

Lines changed: 115 additions & 55 deletions

File tree

‎backend/src/main/java/com/park/utmstack/domain/shared_types/enums/SectionType.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public enum SectionType {
1010
SYSTEM_LICENSE,
1111
INSTANCE_UPDATE_FREQUENCY,
1212
INSTANCE_ENABLE_SEND_LOGS,
13-
THREATWINDS_CREDENTIALS
13+
THREAT_INTELLIGENCE
1414

1515

1616
}

‎backend/src/main/java/com/park/utmstack/service/UtmConfigurationParameterService.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.park.utmstack.domain.application_events.enums.ApplicationEventType;
66
import com.park.utmstack.domain.tfa.TfaMethod;
77
import com.park.utmstack.repository.UtmConfigurationParameterRepository;
8+
import com.park.utmstack.security.SecurityUtils;
89
import com.park.utmstack.service.application_events.ApplicationEventService;
910
import com.park.utmstack.service.tfa.TfaService;
1011
import com.park.utmstack.util.CipherUtil;
@@ -20,6 +21,7 @@
2021
import org.springframework.util.CollectionUtils;
2122
import org.springframework.util.StringUtils;
2223

24+
import java.time.Instant;
2325
import java.util.*;
2426
import java.util.stream.Collectors;
2527

@@ -102,6 +104,8 @@ public void saveAll(List<UtmConfigurationParameter> params) throws UtmMailExcept
102104

103105
Map<String, String> cfg = new HashMap<>();
104106
List<UtmConfigurationParameter> toSave = new ArrayList<>();
107+
Instant now = Instant.now();
108+
String user = SecurityUtils.getCurrentUserLogin().orElse(Constants.SYSTEM_ACCOUNT);
105109
for (UtmConfigurationParameter p : params) {
106110
boolean isPassword = Constants.CONF_TYPE_PASSWORD.equalsIgnoreCase(p.getConfParamDatatype());
107111
if (isPassword && Constants.MASKED_VALUE.equals(p.getConfParamValue())) {
@@ -110,6 +114,8 @@ public void saveAll(List<UtmConfigurationParameter> params) throws UtmMailExcept
110114
cfg.put(p.getConfParamShort(), p.getConfParamValue());
111115
if (StringUtils.hasText(p.getConfParamValue()) && isPassword)
112116
p.setConfParamValue(CipherUtil.encrypt(p.getConfParamValue(), System.getenv(Constants.ENV_ENCRYPTION_KEY)));
117+
p.setModificationTime(now);
118+
p.setModificationUser(user);
113119
toSave.add(p);
114120
}
115121
configParamRepository.saveAll(toSave);

‎backend/src/main/java/com/park/utmstack/service/validators/tw_config/TwConfigValidatorService.java‎

Lines changed: 0 additions & 43 deletions
This file was deleted.

‎backend/src/main/java/com/park/utmstack/web/rest/UtmConfigurationParameterResource.java‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.park.utmstack.service.dto.UtmConfigurationParameterCriteria;
1111
import com.park.utmstack.service.mail_config.MailConfigService;
1212
import com.park.utmstack.service.validators.email.EmailValidatorService;
13-
import com.park.utmstack.service.validators.tw_config.TwConfigValidatorService;
1413
import com.park.utmstack.util.ResponseUtil;
1514
import com.park.utmstack.util.exceptions.UtmMailException;
1615
import com.park.utmstack.web.rest.util.PaginationUtil;
@@ -52,7 +51,6 @@ public class UtmConfigurationParameterResource {
5251
private final EmailValidatorService emailValidatorService;
5352
private final MailConfigService mailConfigService;
5453
private final UtmStackService utmStackService;
55-
private final TwConfigValidatorService twConfigValidatorService;
5654

5755
/**
5856
* PUT /utm-configuration-parameters : Updates an existing utmConfigurationParameter.
@@ -70,10 +68,6 @@ public ResponseEntity<Void> updateConfigurationParameters(@Valid @RequestBody Li
7068
for (UtmConfigurationParameter parameter : parameters) {
7169
Errors errors = new BeanPropertyBindingResult(parameter, "utmConfigurationParameter");
7270

73-
if(parameter.getConfParamShort().equals("utmstack.tw.enable")){
74-
twConfigValidatorService.validate(parameter, errors);
75-
}
76-
7771
if(StringUtils.hasText(parameter.getConfParamRegexp())){
7872
emailValidatorService.validate(parameter, errors);
7973
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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="20260910001" author="Alex">
8+
9+
<delete tableName="utm_configuration_parameter">
10+
<where>id IN (40, 41)</where>
11+
</delete>
12+
13+
<update tableName="utm_configuration_section">
14+
<column name="section" value="Threat Intelligence"/>
15+
<column name="description" value="Threat Intelligence integration settings."/>
16+
<column name="short_name" value="THREAT_INTELLIGENCE"/>
17+
<where>id = 10</where>
18+
</update>
19+
20+
</changeSet>
21+
</databaseChangeLog>

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,5 +604,7 @@
604604
<include file="/config/liquibase/changelog/20260623001_migrate_compliance_report_config_to_control_config.xml" relativeToChangelogFile="false"/>
605605

606606
<include file="/config/liquibase/changelog/20260831001_update_login_failed_menu_event_code.xml" relativeToChangelogFile="false"/>
607-
607+
608+
<include file="/config/liquibase/changelog/20260910001_cleanup_threatwinds_params.xml" relativeToChangelogFile="false"/>
609+
608610
</databaseChangeLog>

‎frontend/src/app/shared/components/utm/config/app-config-sections/app-config-sections.component.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ <h6 class="font-weight-semibold mb-2">{{section.section | titlecase}}</h6>
4848
<div *ngIf="configs.length >0 && !loading" class="d-flex gap-3 flex-wrap w-100">
4949
<ng-container *ngFor="let conf of getConfigs()">
5050
<div [ngClass]="conf.confParamDatatype === configDataTypeEnum.List || conf.confParamDatatype === configDataTypeEnum.EmailList || conf.confParamDatatype === ConfigDataTypeEnum.Cron ? 'w-100 order-8':'w-30'"
51-
class="form-group mb-4" *ngIf="(conf.confParamShort !== 'utmstack.tw.enable') || (conf.confParamShort === 'utmstack.tw.enable' && versionType === VERSION_TYPE.ENTERPRISE)">
51+
class="form-group mb-4">
5252
<label [for]="'sectionParam'+conf.id"
5353
class="pb-1 span-small-icon d-flex justify-content-between align-items-center">
5454
<span>

‎plugins/config/go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.25.5
55
require (
66
github.com/lib/pq v1.12.3
77
github.com/threatwinds/go-sdk v1.1.31
8+
google.golang.org/protobuf v1.36.12
89
gopkg.in/yaml.v3 v3.0.1
910
sigs.k8s.io/yaml v1.6.0
1011
)
@@ -54,5 +55,4 @@ require (
5455
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
5556
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
5657
google.golang.org/grpc v1.83.2 // indirect
57-
google.golang.org/protobuf v1.36.11 // indirect
5858
)

‎plugins/config/go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:
148148
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
149149
google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
150150
google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
151-
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
152-
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
151+
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
152+
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
153153
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
154154
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
155155
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

‎plugins/config/main.go‎

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"database/sql"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"os"
89
"path/filepath"
@@ -14,6 +15,7 @@ import (
1415
"github.com/threatwinds/go-sdk/utils"
1516

1617
_ "github.com/lib/pq"
18+
"google.golang.org/protobuf/types/known/structpb"
1719
"gopkg.in/yaml.v3"
1820
k8syaml "sigs.k8s.io/yaml"
1921
)
@@ -82,6 +84,8 @@ type ConfigState struct {
8284
FiltersCount int
8385
PatternsLastUpdate time.Time
8486
PatternsCount int
87+
TwEnableLastUpdate time.Time
88+
TwEnableCount int
8589
}
8690

8791
func (b *ExpressionBackend) ToExpression() Expression {
@@ -423,6 +427,20 @@ func main() {
423427
return
424428
}
425429

430+
enabled, err := getTwEnableConfig(db)
431+
if err != nil {
432+
_ = catcher.Error("failed to get feeds toggle", err, map[string]any{"process": "plugin_com.utmstack.config"})
433+
time.Sleep(30 * time.Second)
434+
return
435+
}
436+
437+
err = writeFeedsConfig(enabled)
438+
if err != nil {
439+
_ = catcher.Error("failed to write feeds config", err, map[string]any{"process": "plugin_com.utmstack.config"})
440+
time.Sleep(30 * time.Second)
441+
return
442+
}
443+
426444
*state = newState
427445
}()
428446

@@ -446,6 +464,7 @@ func hasChanges(db *sql.DB, state *ConfigState) (bool, ConfigState, error) {
446464
{"SELECT MAX(rule_last_update) FROM utm_correlation_rules", "SELECT COUNT(*) FROM utm_correlation_rules WHERE rule_active = true", &newState.RulesLastUpdate, &newState.RulesCount, state.RulesLastUpdate, state.RulesCount},
447465
{"SELECT MAX(updated_at) FROM utm_logstash_filter", "SELECT COUNT(*) FROM utm_logstash_filter WHERE is_active = true", &newState.FiltersLastUpdate, &newState.FiltersCount, state.FiltersLastUpdate, state.FiltersCount},
448466
{"SELECT MAX(last_update) FROM utm_regex_pattern", "SELECT COUNT(*) FROM utm_regex_pattern", &newState.PatternsLastUpdate, &newState.PatternsCount, state.PatternsLastUpdate, state.PatternsCount},
467+
{"SELECT MAX(modification_time) FROM utm_configuration_parameter WHERE conf_param_short = 'utmstack.tw.enable'", "SELECT COUNT(*) FROM utm_configuration_parameter WHERE conf_param_short = 'utmstack.tw.enable'", &newState.TwEnableLastUpdate, &newState.TwEnableCount, state.TwEnableLastUpdate, state.TwEnableCount},
449468
}
450469

451470
for _, q := range queries {
@@ -915,3 +934,64 @@ func writePatterns(patterns map[string]string) error {
915934

916935
return nil
917936
}
937+
938+
func getTwEnableConfig(db *sql.DB) (bool, error) {
939+
var value string
940+
err := db.QueryRow(`SELECT conf_param_value FROM utm_configuration_parameter WHERE conf_param_short = 'utmstack.tw.enable' LIMIT 1`).Scan(&value)
941+
if err != nil {
942+
if errors.Is(err, sql.ErrNoRows) {
943+
return true, nil
944+
}
945+
return true, catcher.Error("failed to fetch utmstack.tw.enable", err, map[string]any{"process": "plugin_com.utmstack.config"})
946+
}
947+
enabled, parseErr := strconv.ParseBool(value)
948+
if parseErr != nil {
949+
catcher.Warn("failed to parse utmstack.tw.enable value; defaulting to enabled", map[string]any{
950+
"value": value,
951+
"error": parseErr.Error(),
952+
"process": "plugin_com.utmstack.config",
953+
})
954+
return true, nil
955+
}
956+
return enabled, nil
957+
}
958+
959+
func writeFeedsConfig(enabled bool) error {
960+
filePath, err := utils.MkdirJoin(plugins.WorkDir, "pipeline")
961+
if err != nil {
962+
return catcher.Error("cannot create pipeline directory", err, nil)
963+
}
964+
965+
file, err := os.Create(filePath.FileJoin("system_plugins_feeds.yaml"))
966+
if err != nil {
967+
return catcher.Error("failed to create file", err, map[string]any{"process": "plugin_com.utmstack.config"})
968+
}
969+
970+
defer func() {
971+
if err := file.Close(); err != nil {
972+
_ = catcher.Error("failed to close file", err, map[string]any{"process": "plugin_com.utmstack.config"})
973+
}
974+
}()
975+
976+
feedsStruct, err := structpb.NewStruct(map[string]any{"enabled": enabled})
977+
if err != nil {
978+
return catcher.Error("failed to build feeds struct", err, map[string]any{"process": "plugin_com.utmstack.config"})
979+
}
980+
981+
config := plugins.Config{
982+
Plugins: map[string]*structpb.Value{
983+
"feeds": structpb.NewStructValue(feedsStruct),
984+
},
985+
}
986+
987+
bytes, err := k8syaml.Marshal(config)
988+
if err != nil {
989+
return catcher.Error("failed to marshal feeds config", err, map[string]any{"process": "plugin_com.utmstack.config"})
990+
}
991+
992+
if _, err := file.Write(bytes); err != nil {
993+
return catcher.Error("failed to write to file", err, map[string]any{"process": "plugin_com.utmstack.config"})
994+
}
995+
996+
return nil
997+
}

0 commit comments

Comments
 (0)