From 12e5f3d384a5e756fc0fe343fe1980ba1447e3cb Mon Sep 17 00:00:00 2001 From: Osmany Montero Date: Wed, 27 Dec 2023 19:59:26 +0200 Subject: [PATCH 01/46] Main (#179) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changing the base image to eclipse-temurin:11 (#177) * Moving images to eclipse-temurin, openjdk will be deprecated soon (#178) --------- Co-authored-by: Leonardo Mora López <41559395+leonardomoralopez89@users.noreply.github.com> Co-authored-by: Freddy R. Laffita Almaguer --- backend/Dockerfile | 2 +- user-auditor/Dockerfile | 2 +- web-pdf/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 217997d8e..3947d9d0b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:17-alpine +FROM eclipse-temurin:11 ADD target/utmstack.war ./ diff --git a/user-auditor/Dockerfile b/user-auditor/Dockerfile index 8bef02cdc..6e4d70319 100644 --- a/user-auditor/Dockerfile +++ b/user-auditor/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:17-alpine +FROM eclipse-temurin:17-alpine ADD target/user-auditor-1.0.0.jar ./ EXPOSE 8080 diff --git a/web-pdf/Dockerfile b/web-pdf/Dockerfile index 45e2f54bc..9a0ff9d7b 100644 --- a/web-pdf/Dockerfile +++ b/web-pdf/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:17-alpine +FROM eclipse-temurin:17-alpine ADD target/web-pdf-1.0.0.jar ./ EXPOSE 8080 From 337b860f1cf327d571bf3bbe2744bc2422ebac0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Mora=20L=C3=B3pez?= <41559395+leonardomoralopez89@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:36:21 +0200 Subject: [PATCH 02/46] main (#214) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Changing the base image to eclipse-temurin:11 (#177) * Moving images to eclipse-temurin, openjdk will be deprecated soon (#178) * force v10/release from old proyect * adding new active directory changes * Update active-directory.service.ts * adding ad users types * Adding azure filter fix was missing during moving to monorepo (#186) * Adding some files missing from old repository for user-auditor module * Fixing typo in licence information (#199) * Bugfix/agent/non printable chars (#195) * Fix issue Redline MISSING * Fix encryption key for master * Update agent-master compatibility table * Replace encryption mode * Bugfix log file too large * Fix linux agent uninstall command * Update privafy filter, add ordering filter support (#203) * Adding support for filter ordering issues (mutate) * Adding support multiple filters in the same pipeline * #170 Fixed select the agent but the list is empty (#196) Co-authored-by: manuel Co-authored-by: Jorge Dieguez Pérez * #176 Fixed the timeline component does not render correctly in the details of an alert (#194) Co-authored-by: manuel Co-authored-by: Jorge Dieguez Pérez * #183 Fixed tag name not displayed when deleting (#192) Co-authored-by: manuel Co-authored-by: Jorge Dieguez Pérez * Fix bug #169 Show a message describing that the alert has an inciden (#191) * Fix bug #169 Show a message describing that the alert has an incident already associated * #182 Fixed modal does not close when creating or associating an incident with an alert --------- Co-authored-by: manuel Co-authored-by: Jorge Dieguez Pérez * Update privafy filter (#206) * Adding support for filter ordering issues (mutate) * Adding support multiple filters in the same pipeline * Adding .gitignore to web-pdf * Fixing command_line field issues with kv transformation * Update privafy filter remove general message field (#207) * Adding support for filter ordering issues (mutate) * Adding support multiple filters in the same pipeline * Adding .gitignore to web-pdf * Fixing command_line field issues with kv transformation * Removing message from putput --------- Co-authored-by: Osmany Montero * Fix agent service is not starting automatically after being stopped (#209) * Refactoring and optimizing the method to build a CSV file from the result of a search query in elasticsearch (#211) * Fix mutate module duplicates input definition and not order filters added. (#212) --------- Co-authored-by: Freddy R. Laffita Almaguer Co-authored-by: jdieguez89 Co-authored-by: Jorge Dieguez Pérez Co-authored-by: Yorjander Hernandez Vergara <99102374+Kbayero@users.noreply.github.com> Co-authored-by: Manuel Abascal Co-authored-by: manuel Co-authored-by: Osmany Montero --- agent/agent/configuration/config.go | 98 ++++++- agent/agent/configuration/const.go | 1 + agent/agent/go.mod | 1 + agent/agent/go.sum | 2 + agent/agent/logservice/processor.go | 116 +++++--- agent/agent/redline/redline.go | 2 +- agent/agent/utils/crypt.go | 6 + agent/installer/main.go | 21 +- agent/installer/utils/files.go | 13 + agent/installer/utils/lock.go | 29 ++ agent/redline/protector/protector.go | 3 +- agent/redline/serv/service.go | 21 +- agent/versions.json | 6 + .../java/com/park/utmstack/util/UtilCsv.java | 71 ++--- .../20231215001_updating_azure_filter.xml | 262 ++++++++++++++++++ ...1_updating_syslog_json_generic_filters.xml | 161 +++++++++++ .../resources/config/liquibase/master.xml | 4 + filters/generic/generic.conf | 5 +- filters/json/json-input.conf | 8 +- filters/privafy/privafy.conf | 58 ++-- filters/syslog/syslog-generic.conf | 5 +- .../guide-linux-agent.component.ts | 11 +- .../guide-winlogbeat.component.ts | 2 +- frontend/src/app/app.component.html | 12 - frontend/src/app/app.component.ts | 8 +- frontend/src/app/app.constants.ts | 1 - .../enums/asset-map-filter-field.enum.ts | 2 +- .../blocks/interceptor/auth.interceptor.ts | 17 +- .../compliance-result-view.component.html | 3 +- .../compliance-result-view.component.ts | 52 +--- .../compliance/compliance-routing.module.ts | 6 - .../compliance-schedule.component.html | 107 ------- .../compliance-schedule.component.scss | 0 .../compliance-schedule.component.ts | 167 ----------- .../src/app/compliance/compliance.module.ts | 46 ++- .../shared/compliance-shared.module.ts | 23 +- .../utm-compliance-create.component.scss | 5 +- ...-compliance-schedule-create.component.html | 71 ----- ...-compliance-schedule-create.component.scss | 55 ---- ...tm-compliance-schedule-create.component.ts | 222 --------------- ...-compliance-schedule-delete.component.html | 17 -- ...-compliance-schedule-delete.component.scss | 0 ...tm-compliance-schedule-delete.component.ts | 38 --- .../utm-compliance-select.component.html | 96 ------- .../utm-compliance-select.component.scss | 0 .../utm-compliance-select.component.ts | 137 --------- .../models/time-frequency.ts | 31 --- .../utm-cp-cron-editor.component.html | 67 ----- .../utm-cp-cron-editor.component.scss | 46 --- .../utm-cp-cron-editor.component.ts | 159 ----------- .../services/compliance-schedule.service.ts | 44 --- .../cron-description-generator.service.ts | 139 ---------- .../type/compliance-schedule-filter.type.ts | 6 - .../shared/type/compliance-schedule.type.ts | 13 - .../src/app/core/auth/auth-jwt.service.ts | 17 +- frontend/src/app/core/login/login.service.ts | 4 - .../compliance-export.component.ts | 88 +----- .../dashboard-export-pdf.component.ts | 2 +- .../dashboard-overview.component.ts | 18 +- .../dashboard-render.component.ts | 17 +- .../alert-tags-management.component.ts | 2 +- .../alert-apply-incident.component.html | 12 +- .../alert-apply-incident.component.ts | 65 +++-- .../alert-history.component.scss | 3 +- .../active-filters.component.html | 4 +- .../active-filters.component.ts | 1 - .../utm-license/utm-license.component.html | 2 +- .../components/auth/login/login.component.ts | 10 +- .../utm-version-info.component.html | 2 +- .../utm-notification-alert.component.ts | 1 + .../dashboard-filter-select.component.html | 1 - .../dashboard-filter-select.component.ts | 26 +- .../services/change-filter-value.service.ts | 15 - .../utm-agent-detail.component.html | 6 +- .../utm-agent-select.component.html | 1 - .../utm-agent-select.component.ts | 4 +- .../services/util/export-pdf.service.ts | 30 -- .../types/filter/elastic-filter.type.ts | 3 - .../util/query-params-to-filter.util.ts | 63 ----- mutate/util/misc.py | 56 ++-- web-pdf/.gitignore | 33 +++ 81 files changed, 946 insertions(+), 2036 deletions(-) create mode 100644 agent/installer/utils/lock.go create mode 100644 backend/src/main/resources/config/liquibase/changelog/20231215001_updating_azure_filter.xml create mode 100644 backend/src/main/resources/config/liquibase/changelog/20231229001_updating_syslog_json_generic_filters.xml delete mode 100644 frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.html delete mode 100644 frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.scss delete mode 100644 frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.ts delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.html delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.scss delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.ts delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.html delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.scss delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.ts delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.html delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.scss delete mode 100644 frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.ts delete mode 100644 frontend/src/app/compliance/shared/components/utm-cp-cron-editor/models/time-frequency.ts delete mode 100644 frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.html delete mode 100644 frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.scss delete mode 100644 frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.ts delete mode 100644 frontend/src/app/compliance/shared/services/compliance-schedule.service.ts delete mode 100644 frontend/src/app/compliance/shared/services/cron-description-generator.service.ts delete mode 100644 frontend/src/app/compliance/shared/type/compliance-schedule-filter.type.ts delete mode 100644 frontend/src/app/compliance/shared/type/compliance-schedule.type.ts delete mode 100644 frontend/src/app/shared/components/utm/filters/services/change-filter-value.service.ts delete mode 100644 frontend/src/app/shared/services/util/export-pdf.service.ts create mode 100644 web-pdf/.gitignore diff --git a/agent/agent/configuration/config.go b/agent/agent/configuration/config.go index 97e819895..38ed72fbf 100644 --- a/agent/agent/configuration/config.go +++ b/agent/agent/configuration/config.go @@ -7,9 +7,14 @@ import ( "sync" aesCrypt "github.com/AtlasInsideCorp/AtlasInsideAES" + "github.com/google/uuid" "github.com/utmstack/UTMStack/agent/agent/utils" ) +type InstallationUUID struct { + UUID string `yaml:"uuid"` +} + type Config struct { Server string `yaml:"server"` AgentID uint `yaml:"agent-id"` @@ -31,12 +36,13 @@ func GetInitialConfig() (*Config, string) { } var ( - cnf Config - confOnce sync.Once + cnf = Config{} + confOnce sync.Once + instuuid = "" + instuuidOnce sync.Once ) func GetCurrentConfig() (*Config, error) { - cnf = Config{} var errR error confOnce.Do(func() { path, err := utils.GetMyPath() @@ -44,6 +50,9 @@ func GetCurrentConfig() (*Config, error) { errR = fmt.Errorf("failed to get current path: %v", err) return } + + uuidExists := utils.CheckIfPathExist(filepath.Join(path, UUIDFileName)) + var encryptConfig Config if err = utils.ReadYAML(filepath.Join(path, "config.yml"), &encryptConfig); err != nil { errR = fmt.Errorf("error reading config file: %v", err) @@ -51,10 +60,25 @@ func GetCurrentConfig() (*Config, error) { } // Get key - key, err := utils.GenerateKey(REPLACE_KEY) - if err != nil { - errR = fmt.Errorf("error geneating key: %v", err) - return + var key []byte + if uuidExists { + uuid, err := GetUUID() + if err != nil { + errR = fmt.Errorf("failed to get uuid: %v", err) + return + } + + key, err = utils.GenerateKeyByUUID(REPLACE_KEY, uuid) + if err != nil { + errR = fmt.Errorf("error geneating key: %v", err) + return + } + } else { + key, err = utils.GenerateKey(REPLACE_KEY) + if err != nil { + errR = fmt.Errorf("error geneating key: %v", err) + return + } } // Decrypt config @@ -69,6 +93,12 @@ func GetCurrentConfig() (*Config, error) { cnf.AgentKey = agentKey cnf.SkipCertValidation = encryptConfig.SkipCertValidation + if !uuidExists { + if err := SaveConfig(&cnf); err != nil { + errR = fmt.Errorf("error writing config file: %v", err) + return + } + } }) if errR != nil { return nil, errR @@ -83,8 +113,13 @@ func SaveConfig(cnf *Config) error { return fmt.Errorf("failed to get current path: %v", err) } + uuid, err := GenerateNewUUID() + if err != nil { + return fmt.Errorf("failed to generate uuid: %v", err) + } + // Get key - key, err := utils.GenerateKey(REPLACE_KEY) + key, err := utils.GenerateKeyByUUID(REPLACE_KEY, uuid) if err != nil { return fmt.Errorf("error geneating key: %v", err) } @@ -108,3 +143,50 @@ func SaveConfig(cnf *Config) error { } return nil } + +func GenerateNewUUID() (string, error) { + uuid, err := uuid.NewRandom() + if err != nil { + return "", fmt.Errorf("failed to generate uuid: %v", err) + } + + InstallationUUID := InstallationUUID{ + UUID: uuid.String(), + } + + path, err := utils.GetMyPath() + if err != nil { + return "", fmt.Errorf("failed to get current path: %v", err) + } + + if err = utils.WriteYAML(filepath.Join(path, UUIDFileName), InstallationUUID); err != nil { + return "", fmt.Errorf("error writing uuid file: %v", err) + } + + return InstallationUUID.UUID, nil +} + +func GetUUID() (string, error) { + var errR error + instuuidOnce.Do(func() { + path, err := utils.GetMyPath() + if err != nil { + errR = fmt.Errorf("failed to get current path: %v", err) + return + } + + var uuid = InstallationUUID{} + if err = utils.ReadYAML(filepath.Join(path, UUIDFileName), &uuid); err != nil { + errR = fmt.Errorf("error reading uuid file: %v", err) + return + } + + instuuid = uuid.UUID + }) + + if errR != nil { + return "", errR + } + + return instuuid, nil +} diff --git a/agent/agent/configuration/const.go b/agent/agent/configuration/const.go index 4a8b34044..5037b372b 100644 --- a/agent/agent/configuration/const.go +++ b/agent/agent/configuration/const.go @@ -26,6 +26,7 @@ const ( WinLockName = "utmstack_windows_collector.lock" RedlineLockName = "utmstack_redline.lock" RedlineServName = "UTMStackRedline" + UUIDFileName = "uuid.yml" ) type LogType string diff --git a/agent/agent/go.mod b/agent/agent/go.mod index 704b1028e..348ad7700 100644 --- a/agent/agent/go.mod +++ b/agent/agent/go.mod @@ -5,6 +5,7 @@ go 1.21.1 require ( github.com/AtlasInsideCorp/AtlasInsideAES v1.0.0 github.com/elastic/go-sysinfo v1.11.1 + github.com/google/uuid v1.3.1 github.com/kardianos/service v1.2.2 github.com/quantfall/holmes v1.3.0 google.golang.org/grpc v1.59.0 diff --git a/agent/agent/go.sum b/agent/agent/go.sum index 918546360..91aa57b40 100644 --- a/agent/agent/go.sum +++ b/agent/agent/go.sum @@ -25,6 +25,8 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= diff --git a/agent/agent/logservice/processor.go b/agent/agent/logservice/processor.go index f6831620c..13135ec1c 100644 --- a/agent/agent/logservice/processor.go +++ b/agent/agent/logservice/processor.go @@ -1,6 +1,7 @@ package logservice import ( + "bufio" context "context" "fmt" "os" @@ -24,9 +25,11 @@ type LogPipe struct { } var ( - processor LogProcessor - processorOnce sync.Once - LogQueue = make(chan LogPipe, 1000) + processor LogProcessor + processorOnce sync.Once + LogQueue = make(chan LogPipe, 1000) + MinutesForCleanLog = 10080 // 7 days in minutes(7*24*60) + MinutesForReportLogsCounted = time.Duration(5 * time.Minute) ) func GetLogProcessor() LogProcessor { @@ -41,17 +44,12 @@ func (l *LogProcessor) ProcessLogs(client LogServiceClient, ctx context.Context, reconnectDelay := configuration.InitialReconnectDelay invalidKeyCounter := 0 - path, err := utils.GetMyPath() - if err != nil { - h.FatalError("Failed to get current path: %v", err) - } - - filePath := filepath.Join(path, "logs_process") - utils.CreatePathIfNotExist(filePath) - fileNames := map[string]*os.File{} - defer func() { - for _, file := range fileNames { - file.Close() + logsProcessCounter := map[string]int{} + go func() { + for { + time.Sleep(MinutesForReportLogsCounted) + SaveCountedLogs(h, logsProcessCounter) + logsProcessCounter = map[string]int{} } }() @@ -104,38 +102,8 @@ func (l *LogProcessor) ProcessLogs(client LogServiceClient, ctx context.Context, continue } + logsProcessCounter[newLog.Src] += len(newLog.Logs) invalidKeyCounter = 0 - - fileIsOpen := false - for name := range fileNames { - if name == filepath.Join(filePath, string(newLog.Src)+".txt") { - fileIsOpen = true - } - } - - newFileName := filepath.Join(filePath, string(newLog.Src)+".txt") - if !fileIsOpen { - file, err := os.OpenFile(newFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - h.Error("error opening file: %s", err) - time.Sleep(reconnectDelay) - connectionTime = utils.IncrementReconnectTime(connectionTime, reconnectDelay, configuration.MaxConnectionTime) - reconnectDelay = utils.IncrementReconnectDelay(reconnectDelay, configuration.MaxReconnectDelay) - continue - } - fileNames[newFileName] = file - } - - for _, mylog := range newLog.Logs { - _, err = fileNames[newFileName].WriteString(fmt.Sprintf("%s\n", mylog)) - if err != nil { - h.Info("error writing to file: %s\n", err) - time.Sleep(reconnectDelay) - connectionTime = utils.IncrementReconnectTime(connectionTime, reconnectDelay, configuration.MaxConnectionTime) - reconnectDelay = utils.IncrementReconnectDelay(reconnectDelay, configuration.MaxReconnectDelay) - continue - } - } } } @@ -154,3 +122,61 @@ func (l *LogProcessor) ProcessLogsWithHighPriority(msg string, client LogService } return nil } + +func SaveCountedLogs(h *holmes.Logger, logsProcessCounter map[string]int) { + path, err := utils.GetMyPath() + if err != nil { + h.FatalError("Failed to get current path: %v", err) + } + + filePath := filepath.Join(path, "logs_process") + logFile := filepath.Join(filePath, "processed_logs.txt") + utils.CreatePathIfNotExist(filePath) + + file, err := os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + h.Error("error opening processed_logs.txt file: %s", err) + return + } + defer file.Close() + + var firstLogTime time.Time + var firstLine string + scanner := bufio.NewScanner(file) + for scanner.Scan() { + firstLine = scanner.Text() + break + } + + if firstLine != "" { + firstLogTime, err = time.Parse("2006/01/02 15:04:05.9999999 -0700 MST", strings.Split(firstLine, " - ")[0]) + if err != nil { + h.Error("error parsing first log time: %s", err) + return + } + + if !firstLogTime.IsZero() && time.Since(firstLogTime).Minutes() >= float64(MinutesForCleanLog) { + file.Close() + if err := os.Remove(logFile); err != nil { + h.Error("error removing processed_logs.txt file: %s", err) + return + } + file, err = os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + h.Error("error opening processed_logs.txt file: %s", err) + return + } + } + } + + for name, counter := range logsProcessCounter { + if counter > 0 { + _, err = file.WriteString(fmt.Sprintf("%v - %d logs from %s have been processed\n", time.Now().Format("2006/01/02 15:04:05.9999999 -0700 MST"), counter, name)) + if err != nil { + h.Error("error writing to processed_logs.txt file: %s", err) + continue + } + } + } + +} diff --git a/agent/agent/redline/redline.go b/agent/agent/redline/redline.go index 6b9ddb1ae..029a3cc2f 100644 --- a/agent/agent/redline/redline.go +++ b/agent/agent/redline/redline.go @@ -26,7 +26,7 @@ func CheckRedlineService(h *holmes.Logger) { if attempts >= 3 { h.Info("Redline service has been stopped") if err := utils.Execute(filepath.Join(path, bin), path, "send-log", fmt.Sprintf("%s service has been stopped", configuration.RedlineServName)); err != nil { - h.Error("error checking %s: error sending log : %v", err) + h.Error("error checking %s: error sending log : %v", configuration.RedlineServName, err) time.Sleep(time.Second * 5) continue } diff --git a/agent/agent/utils/crypt.go b/agent/agent/utils/crypt.go index dcbace7b2..6abb8a712 100644 --- a/agent/agent/utils/crypt.go +++ b/agent/agent/utils/crypt.go @@ -15,3 +15,9 @@ func GenerateKey(REPALCE_KEY string) ([]byte, error) { base64Key := base64.StdEncoding.EncodeToString(data) return []byte(REPALCE_KEY + base64Key), nil } + +func GenerateKeyByUUID(REPLACE_KEY string, uuid string) ([]byte, error) { + data := []byte(REPLACE_KEY + uuid) + base64Key := base64.StdEncoding.EncodeToString(data) + return []byte(base64Key), nil +} diff --git a/agent/installer/main.go b/agent/installer/main.go index bad19cdda..bf745fda9 100644 --- a/agent/installer/main.go +++ b/agent/installer/main.go @@ -63,6 +63,18 @@ func main() { h.FatalError("Error installing the UTMStack Agent: one or more of the requiered ports are closed. Please open ports 9000 and 50051.") } + err := utils.CreatePathIfNotExist(filepath.Join(path, "locks")) + if err != nil { + fmt.Printf("error creating locks path: %v", err) + h.FatalError("error creating locks path: %v", err) + } + + err = utils.SetLock(filepath.Join(path, "locks", "setup.lock")) + if err != nil { + fmt.Printf("error setting setup.lock: %v", err) + h.FatalError("error setting setup.lock: %v", err) + } + err = checkversion.CleanOldVersions(h) if err != nil { fmt.Printf("error cleaning old versions: %v", err) @@ -70,7 +82,7 @@ func main() { } // Download dependencies - err := depend.DownloadDependencies(servBins, ip, skip) + err = depend.DownloadDependencies(servBins, ip, skip) if err != nil { fmt.Printf("error downloading dependencies: %v", err) h.FatalError("error downloading dependencies: %v", err) @@ -85,6 +97,13 @@ func main() { h.Info("UTMStack Agent services installed correctly.") fmt.Println("UTMStack Agent services installed correctly.") + + err = utils.RemoveLock(filepath.Join(path, "locks", "setup.lock")) + if err != nil { + fmt.Printf("error removing setup.lock: %v", err) + h.FatalError("error removing setup.lock: %v", err) + } + time.Sleep(5 * time.Second) os.Exit(0) diff --git a/agent/installer/utils/files.go b/agent/installer/utils/files.go index 900a8efb4..70597446f 100644 --- a/agent/installer/utils/files.go +++ b/agent/installer/utils/files.go @@ -2,6 +2,7 @@ package utils import ( "encoding/json" + "fmt" "os" "path/filepath" @@ -81,3 +82,15 @@ func WriteJSON(path string, data interface{}) error { return nil } + +// CreatePathIfNotExist creates a specific path if not exist +func CreatePathIfNotExist(path string) error { + if _, err := os.Stat(path); os.IsNotExist(err) { + if err := os.Mkdir(path, 0755); err != nil { + return fmt.Errorf("error creating path: %v", err) + } + } else if err != nil { + return fmt.Errorf("error checking path: %v", err) + } + return nil +} diff --git a/agent/installer/utils/lock.go b/agent/installer/utils/lock.go new file mode 100644 index 000000000..1f7e8ce54 --- /dev/null +++ b/agent/installer/utils/lock.go @@ -0,0 +1,29 @@ +package utils + +import ( + "fmt" + "os" +) + +func SetLock(lockdir string) error { + if !CheckIfPathExist(lockdir) { + file, err := os.OpenFile(lockdir, os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm) + if err != nil { + return err + } + defer file.Close() + } + return nil +} + +func RemoveLock(lockdir string) error { + if CheckIfPathExist(lockdir) { + err := os.Remove(lockdir) + if err != nil { + return err + } + } else { + return fmt.Errorf("lock file %s not exists", lockdir) + } + return nil +} diff --git a/agent/redline/protector/protector.go b/agent/redline/protector/protector.go index 16e2f886d..784991d4d 100644 --- a/agent/redline/protector/protector.go +++ b/agent/redline/protector/protector.go @@ -26,7 +26,7 @@ func ProtectService(servName, lockName string, h *holmes.Logger) { if attempts >= 3 { h.Info("%s service has been stopped", servName) if err := utils.Execute(filepath.Join(path, bin), path, "send-log", fmt.Sprintf("%s service has been stopped", servName)); err != nil { - h.Error("error checking %s: error sending log : %v", err) + h.Error("error checking %s: error sending log : %v", servName, err) time.Sleep(time.Second * 5) continue } @@ -62,6 +62,5 @@ func ProtectService(servName, lockName string, h *holmes.Logger) { time.Sleep(time.Second * 5) continue } - } } diff --git a/agent/redline/serv/service.go b/agent/redline/serv/service.go index 1aba53290..3f699df2d 100644 --- a/agent/redline/serv/service.go +++ b/agent/redline/serv/service.go @@ -3,6 +3,7 @@ package serv import ( "os" "os/signal" + "path/filepath" "syscall" "time" @@ -27,21 +28,19 @@ func (p *program) Stop(s service.Service) error { } func (p *program) run() { -checkall: + path, err := utils.GetMyPath() + if err != nil { + h.FatalError("Failed to get current path: %v", err) + } + for { - for servName := range constants.GetServicesLock() { - isActive, err := utils.CheckIfServiceIsActive(servName) - if err != nil { - time.Sleep(time.Second * 5) - h.Error("error checking if %s service is active: %v", servName, err) - continue checkall - } else if !isActive { - time.Sleep(time.Second * 5) - continue checkall - } + if utils.CheckIfPathExist(filepath.Join(path, "locks", "setup.lock")) { + time.Sleep(time.Second * 5) + continue } break } + h.Info("UTMStackRedline started correctly") for servName, lockName := range constants.GetServicesLock() { go protector.ProtectService(servName, lockName, h) diff --git a/agent/versions.json b/agent/versions.json index 4da226325..ccaa3b488 100644 --- a/agent/versions.json +++ b/agent/versions.json @@ -5,6 +5,12 @@ "agent_version": "10.1.1", "updater_version": "10.1.2", "redline_version": "10.1.1" + }, + { + "master_version": "10.2.0", + "agent_version": "10.2.0", + "updater_version": "10.1.2", + "redline_version": "10.2.0" } ] } diff --git a/backend/src/main/java/com/park/utmstack/util/UtilCsv.java b/backend/src/main/java/com/park/utmstack/util/UtilCsv.java index 6799de796..762f2e423 100644 --- a/backend/src/main/java/com/park/utmstack/util/UtilCsv.java +++ b/backend/src/main/java/com/park/utmstack/util/UtilCsv.java @@ -1,9 +1,7 @@ package com.park.utmstack.util; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.PathNotFoundException; import com.park.utmstack.domain.shared_types.DataColumn; import com.park.utmstack.util.exceptions.UtmCsvException; import io.jsonwebtoken.lang.Assert; @@ -15,14 +13,13 @@ import javax.servlet.http.HttpServletResponse; import java.time.Instant; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.stream.StreamSupport; public class UtilCsv { private static final String CLASS_NAME = "UtilCsv"; @@ -36,38 +33,42 @@ public class UtilCsv { * @throws UtmCsvException In case of any error */ public static void prepareToDownload(HttpServletResponse response, DataColumn[] columns, List data) throws - UtmCsvException { + UtmCsvException { final String ctx = CLASS_NAME + ".prepareToDownload"; + final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withLocale(Locale.getDefault()).withZone(TimezoneUtil.getAppTimezone()); try { Assert.notEmpty(columns); Assert.notEmpty(data); - JsonElement parse = JsonParser.parseString(UtilSerializer.jsonSerialize(data)); - JsonArray elements = parse.getAsJsonArray(); + // Cleaning column names from .keyword termination + Arrays.stream(columns).forEach(column -> + column.setField(column.getField().replace(".keyword", ""))); + List rows = new ArrayList<>(); - elements.forEach(element -> { + data.forEach(d -> { String[] cells = new String[columns.length]; for (int i = 0; i < columns.length; i++) { - String field = columns[i].getField(); - String type = columns[i].getType(); - if (field.endsWith("keyword")) - field = field.replace(".keyword", ""); - JsonElement value = getPath(field.split("\\."), (JsonObject) element); - + String fieldName = columns[i].getField(); + String fieldType = columns[i].getType(); cells[i] = null; - if (value != null && !value.isJsonNull()) { - if (value.isJsonObject() || value.isJsonPrimitive()) { - if (type.equals("date")) - cells[i] = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withLocale(Locale.getDefault()).withZone( - ZoneId.systemDefault()).format(Instant.parse(value.getAsString())); - else - cells[i] = value.getAsString() - .replace("\n", " ").replace("\t", " "); - } else if (value.isJsonArray()) { - cells[i] = StreamSupport.stream(value.getAsJsonArray().spliterator(), false) - .map(JsonElement::getAsString).collect(Collectors.joining(",")); - } + + Object value; + try { + value = JsonPath.parse(d).read("$." + fieldName); + } catch (PathNotFoundException e) { + continue; + } + + if (value == null) + continue; + + if (value instanceof String) { + cells[i] = fieldType.equals("date") ? DATE_FORMATTER.format(Instant.parse(String.valueOf(value))) : + String.valueOf(value).replace("\n", " ").replace("\t", " "); + } else if (value instanceof List) { + cells[i] = ((List) value).stream().map(String::valueOf).collect(Collectors.joining(",")); } } rows.add(cells); @@ -83,7 +84,7 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=data.csv"); CSVPrinter csvPrinter = new CSVPrinter(response.getWriter(), CSVFormat.DEFAULT.withHeader(headers) - .withQuoteMode(QuoteMode.ALL)); + .withQuoteMode(QuoteMode.ALL)); for (String[] row : rows) csvPrinter.printRecords((Object) row); @@ -92,16 +93,4 @@ public static void prepareToDownload(HttpServletResponse response, DataColumn[] throw new UtmCsvException(msg); } } - - private static JsonElement getPath(String[] path, JsonObject jsonObject) { - if (jsonObject == null) - return null; - JsonElement obj = jsonObject; - for (String component : path) { - if (obj == null) - break; - obj = ((JsonObject) obj).get(component); - } - return obj; - } } diff --git a/backend/src/main/resources/config/liquibase/changelog/20231215001_updating_azure_filter.xml b/backend/src/main/resources/config/liquibase/changelog/20231215001_updating_azure_filter.xml new file mode 100644 index 000000000..0682f03d2 --- /dev/null +++ b/backend/src/main/resources/config/liquibase/changelog/20231215001_updating_azure_filter.xml @@ -0,0 +1,262 @@ + + + + + + + [ + "message", ''\"'', ''"'' + ] + } + +# Perform json transformation + json { + source => "message" + target => "azroot" + } +# Split fields in case of arrays +if ([azroot][records]) { + split { + field => "[azroot][records]" + target => "azroot" + } +} else if ([azroot]) { + split { + field => "azroot" + } +} +# Generating dataType and dataSource fields + if [@metadata][dataSource] { + mutate { + add_field => { + "dataType" => "azure" + } + #Add based on metadata + add_field => { + "dataSource" => "%{[@metadata][dataSource]}" + } + add_field => { + "[logx][tenant]" => "%{[@metadata][dataSource]}" + } + } + } + #Generating JSON structure of logx.azure + mutate { + #First, fields without fields inside, from the log example + rename => { "[azroot][id]" => "[logx][azure][id]" } + rename => { "[azroot][eventType]" => "[logx][azure][eventType]" } + rename => { "[azroot][subject]" => "[logx][azure][subject]" } + rename => { "[azroot][eventTime]" => "[logx][azure][eventTime]" } + rename => { "[azroot][topic]" => "[logx][azure][topic]" } + + #Then, fields inside [data] without fields inside, from the log example + rename => { "[azroot][data][tenantId]" => "[logx][azure][tenantId]" } + rename => { "[azroot][data][correlationId]" => "[logx][azure][correlationId]" } + rename => { "[azroot][data][resourceUri]" => "[logx][azure][resourceUri]" } + rename => { "[azroot][data][operationName]" => "[logx][azure][operationName]" } + rename => { "[azroot][data][operationVersion]" => "[logx][azure][operationVersion]" } + rename => { "[azroot][data][status]" => "[logx][azure][status]" } + rename => { "[azroot][data][subscriptionId]" => "[logx][azure][subscriptionId]" } + rename => { "[azroot][data][resourceProvider]" => "[logx][azure][resourceProvider]" } + + #Then fields in root level in the docs (first doc url), but not in the log examples, because operationName is inside [data] + # and in the docs are root level, we asume that the other must come in the same way + rename => { "[azroot][data][resourceId]" => "[logx][azure][resourceId]" } + rename => { "[azroot][data][category]" => "[logx][azure][category]" } + rename => { "[azroot][data][resultType]" => "[logx][azure][resultType]" } + rename => { "[azroot][data][resultSignature]" => "[logx][azure][resultSignature]" } + rename => { "[azroot][data][durationMs]" => "[logx][azure][durationMs]" } + rename => { "[azroot][data][callerIpAddress]" => "[logx][azure][callerIpAddress]" } + rename => { "[azroot][data][level]" => "[logx][azure][level]" } + rename => { "[azroot][data][location]" => "[logx][azure][location]" } + rename => { "[azroot][data][properties]" => "[logx][azure][properties]" } + + #Then fields in root level in the docs (second doc url), but not in the log examples, because operationName is inside [data] + # and in the docs are root level, we asume that the other must come in the same way + rename => { "[azroot][data][channels]" => "[logx][azure][channels]" } + rename => { "[azroot][data][description]" => "[logx][azure][description]" } + rename => { "[azroot][data][eventDataId]" => "[logx][azure][eventDataId]" } + rename => { "[azroot][data][eventName]" => "[logx][azure][eventName]" } + rename => { "[azroot][data][eventTimestamp]" => "[logx][azure][eventTimestamp]" } + rename => { "[azroot][data][operationId]" => "[logx][azure][operationId]" } + rename => { "[azroot][data][resourceGroupName]" => "[logx][azure][resourceGroupName]" } + rename => { "[azroot][data][resourceProviderName]" => "[logx][azure][resourceProviderName]" } + rename => { "[azroot][data][resourceType]" => "[logx][azure][resourceType]" } + rename => { "[azroot][data][subStatus]" => "[logx][azure][subStatus]" } + rename => { "[azroot][data][submissionTimestamp]" => "[logx][azure][submissionTimestamp]" } + rename => { "[azroot][data][relatedEvents]" => "[logx][azure][relatedEvents]" } + rename => { "[azroot][data][caller]" => "[logx][azure][caller]" } + + #Then, fields inside [data][authorization] without fields inside, from the log example + rename => { "[azroot][data][authorization][scope]" => "[logx][azure][auth_scope]" } + rename => { "[azroot][data][authorization][action]" => "[logx][azure][auth_action]" } + + #Then, fields inside [azroot][data][httpRequest] with fields inside, from the log example + rename => { "[azroot][data][httpRequest]" => "[logx][azure][httpRequest]" } + + #Then, fields inside [data][authorization][evidence], from the log example + rename => { "[azroot][data][authorization][evidence][role]" => "[logx][azure][auth_evidence_role]" } + rename => { "[azroot][data][authorization][evidence][roleAssignmentScope]" => "[logx][azure][auth_evidence_roleAssignmentScope]" } + rename => { "[azroot][data][authorization][evidence][roleAssignmentId]" => "[logx][azure][auth_evidence_roleAssignmentId]" } + rename => { "[azroot][data][authorization][evidence][principalId]" => "[logx][azure][auth_evidence_principalId]" } + rename => { "[azroot][data][authorization][evidence][principalType]" => "[logx][azure][auth_evidence_principalType]" } + rename => { "[azroot][data][authorization][evidence][roleDefinitionId]" => "[logx][azure][auth_evidence_roleDefinitionId]" } + + #Then, fields inside [data][claims], from the log example and match with docs at root level + rename => { "[azroot][data][claims][aud]" => "[logx][azure][claims_aud]" } + rename => { "[azroot][data][claims][iss]" => "[logx][azure][claims_iss]" } + rename => { "[azroot][data][claims][iat]" => "[logx][azure][claims_iat]" } + rename => { "[azroot][data][claims][nbf]" => "[logx][azure][claims_nbf]" } + rename => { "[azroot][data][claims][exp]" => "[logx][azure][claims_exp]" } + rename => { "[azroot][data][claims][ver]" => "[logx][azure][claims_ver]" } + rename => { "[azroot][data][claims][http://schemas.microsoft.com/identity/claims/tenantid]" => "[logx][azure][claims_tenantid]" } + rename => { "[azroot][data][claims][http://schemas.microsoft.com/claims/authnmethodsreferences]" => "[logx][azure][claims_authnmethodsreferences]" } + rename => { "[azroot][data][claims][http://schemas.microsoft.com/identity/claims/objectidentifier]" => "[logx][azure][claims_objectidentifier]" } + rename => { "[azroot][data][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn]" => "[logx][azure][claims_upn]" } + rename => { "[azroot][data][claims][puid]" => "[logx][azure][claims_puid]" } + rename => { "[azroot][data][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier]" => "[logx][azure][claims_nameidentifier]" } + rename => { "[azroot][data][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname]" => "[logx][azure][claims_givenname]" } + rename => { "[azroot][data][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname]" => "[logx][azure][claims_surname]" } + rename => { "[azroot][data][claims][name]" => "[logx][azure][claims_name]" } + rename => { "[azroot][data][claims][groups]" => "[logx][azure][claims_groups]" } + rename => { "[azroot][data][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name]" => "[logx][azure][claims_identity_name]" } + rename => { "[azroot][data][claims][appid]" => "[logx][azure][claims_appid]" } + rename => { "[azroot][data][claims][http://schemas.microsoft.com/identity/claims/scope]" => "[logx][azure][claims_scope]" } + rename => { "[azroot][data][claims][appidacr]" => "[logx][azure][claims_appidacr]" } + rename => { "[azroot][data][claims][http://schemas.microsoft.com/claims/authnclassreference]" => "[logx][azure][claims_authnclassreference]" } + + #Then, fields inside [data][claims] not in doc but in log examples provided + rename => { "[azroot][data][claims][ipaddr]" => "[logx][azure][src_ip]" } + rename => { "[azroot][data][claims][xms_tcdt]" => "[logx][azure][claims_xms_tcdt]" } + rename => { "[azroot][data][claims][rh]" => "[logx][azure][claims_rh]" } + rename => { "[azroot][data][claims][aio]" => "[logx][azure][claims_aio]" } + rename => { "[azroot][data][claims][uti]" => "[logx][azure][claims_uti]" } + } + #Generating JSON structure of logx.azure (Newer version 12-2023) + mutate { + + #Then, fields without fields inside, from the log example + rename => { "[azroot][properties]" => "[logx][azure][properties]" } + rename => { "[azroot][time]" => "[logx][azure][time]" } + rename => { "[azroot][identity]" => "[logx][azure][identity]" } + rename => { "[azroot][Level]" => "[logx][azure][Level]" } + rename => { "[azroot][operationVersion]" => "[logx][azure][operationVersion]" } + + rename => { "[azroot][tenantId]" => "[logx][azure][tenantId]" } + rename => { "[azroot][correlationId]" => "[logx][azure][correlationId]" } + rename => { "[azroot][resourceUri]" => "[logx][azure][resourceUri]" } + rename => { "[azroot][operationName]" => "[logx][azure][operationName]" } + rename => { "[azroot][status]" => "[logx][azure][status]" } + rename => { "[azroot][subscriptionId]" => "[logx][azure][subscriptionId]" } + rename => { "[azroot][resourceProvider]" => "[logx][azure][resourceProvider]" } + + #Then fields in root level in the docs (first doc url), but not in the log examples, because operationName is inside [data] + # and in the docs are root level, we asume that the other must come in the same way + rename => { "[azroot][resourceId]" => "[logx][azure][resourceId]" } + rename => { "[azroot][category]" => "[logx][azure][category]" } + rename => { "[azroot][resultType]" => "[logx][azure][resultType]" } + rename => { "[azroot][resultSignature]" => "[logx][azure][resultSignature]" } + rename => { "[azroot][durationMs]" => "[logx][azure][durationMs]" } + rename => { "[azroot][callerIpAddress]" => "[logx][azure][callerIpAddress]" } + rename => { "[azroot][level]" => "[logx][azure][level]" } + rename => { "[azroot][location]" => "[logx][azure][location]" } + rename => { "[azroot][properties]" => "[logx][azure][properties]" } + + #Then fields in root level in the docs (second doc url), but not in the log examples, because operationName is inside the root + rename => { "[azroot][channels]" => "[logx][azure][channels]" } + rename => { "[azroot][description]" => "[logx][azure][description]" } + rename => { "[azroot][eventDataId]" => "[logx][azure][eventDataId]" } + rename => { "[azroot][eventName]" => "[logx][azure][eventName]" } + rename => { "[azroot][eventTimestamp]" => "[logx][azure][eventTimestamp]" } + rename => { "[azroot][operationId]" => "[logx][azure][operationId]" } + rename => { "[azroot][resourceGroupName]" => "[logx][azure][resourceGroupName]" } + rename => { "[azroot][resourceProviderName]" => "[logx][azure][resourceProviderName]" } + rename => { "[azroot][resourceType]" => "[logx][azure][resourceType]" } + rename => { "[azroot][subStatus]" => "[logx][azure][subStatus]" } + rename => { "[azroot][submissionTimestamp]" => "[logx][azure][submissionTimestamp]" } + rename => { "[azroot][relatedEvents]" => "[logx][azure][relatedEvents]" } + rename => { "[azroot][caller]" => "[logx][azure][caller]" } + + #Then, fields inside [authorization] without fields inside, from the log example + rename => { "[azroot][authorization][scope]" => "[logx][azure][auth_scope]" } + rename => { "[azroot][authorization][action]" => "[logx][azure][auth_action]" } + + #Then, fields inside [azroot][httpRequest] with fields inside, from the log example + rename => { "[azroot][httpRequest]" => "[logx][azure][httpRequest]" } + + #Then, fields inside [authorization][evidence], from the log example + rename => { "[azroot][authorization][evidence][role]" => "[logx][azure][auth_evidence_role]" } + rename => { "[azroot][authorization][evidence][roleAssignmentScope]" => "[logx][azure][auth_evidence_roleAssignmentScope]" } + rename => { "[azroot][authorization][evidence][roleAssignmentId]" => "[logx][azure][auth_evidence_roleAssignmentId]" } + rename => { "[azroot][authorization][evidence][principalId]" => "[logx][azure][auth_evidence_principalId]" } + rename => { "[azroot][authorization][evidence][principalType]" => "[logx][azure][auth_evidence_principalType]" } + rename => { "[azroot][authorization][evidence][roleDefinitionId]" => "[logx][azure][auth_evidence_roleDefinitionId]" } + + #Then, fields inside [claims], from the log example and match with docs at root level + rename => { "[azroot][claims][aud]" => "[logx][azure][claims_aud]" } + rename => { "[azroot][claims][iss]" => "[logx][azure][claims_iss]" } + rename => { "[azroot][claims][iat]" => "[logx][azure][claims_iat]" } + rename => { "[azroot][claims][nbf]" => "[logx][azure][claims_nbf]" } + rename => { "[azroot][claims][exp]" => "[logx][azure][claims_exp]" } + rename => { "[azroot][claims][ver]" => "[logx][azure][claims_ver]" } + rename => { "[azroot][claims][http://schemas.microsoft.com/identity/claims/tenantid]" => "[logx][azure][claims_tenantid]" } + rename => { "[azroot][claims][http://schemas.microsoft.com/claims/authnmethodsreferences]" => "[logx][azure][claims_authnmethodsreferences]" } + rename => { "[azroot][claims][http://schemas.microsoft.com/identity/claims/objectidentifier]" => "[logx][azure][claims_objectidentifier]" } + rename => { "[azroot][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn]" => "[logx][azure][claims_upn]" } + rename => { "[azroot][claims][puid]" => "[logx][azure][claims_puid]" } + rename => { "[azroot][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier]" => "[logx][azure][claims_nameidentifier]" } + rename => { "[azroot][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname]" => "[logx][azure][claims_givenname]" } + rename => { "[azroot][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname]" => "[logx][azure][claims_surname]" } + rename => { "[azroot][claims][name]" => "[logx][azure][claims_name]" } + rename => { "[azroot][claims][groups]" => "[logx][azure][claims_groups]" } + rename => { "[azroot][claims][http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name]" => "[logx][azure][claims_identity_name]" } + rename => { "[azroot][claims][appid]" => "[logx][azure][claims_appid]" } + rename => { "[azroot][claims][http://schemas.microsoft.com/identity/claims/scope]" => "[logx][azure][claims_scope]" } + rename => { "[azroot][claims][appidacr]" => "[logx][azure][claims_appidacr]" } + rename => { "[azroot][claims][http://schemas.microsoft.com/claims/authnclassreference]" => "[logx][azure][claims_authnclassreference]" } + + #Then, fields inside [claims] not in doc but in log examples provided + rename => { "[azroot][claims][ipaddr]" => "[logx][azure][src_ip]" } + rename => { "[azroot][claims][xms_tcdt]" => "[logx][azure][claims_xms_tcdt]" } + rename => { "[azroot][claims][rh]" => "[logx][azure][claims_rh]" } + rename => { "[azroot][claims][aio]" => "[logx][azure][claims_aio]" } + rename => { "[azroot][claims][uti]" => "[logx][azure][claims_uti]" } + } + # Renaming message at the end + mutate { + rename => { "[message]" => "[logx][azure][message]" } + } + + #Finally remove unused fields + mutate { + remove_field => ["path","@version","dataVersion","[data][time]","metadataVersion","type","data","azroot","headers"] + } +} +#Also, remove unwanted fields if the message not match with conditions + mutate { + remove_field => ["@version","path","headers"] + } +} +' + WHERE id=201; + + ]]> + + + diff --git a/backend/src/main/resources/config/liquibase/changelog/20231229001_updating_syslog_json_generic_filters.xml b/backend/src/main/resources/config/liquibase/changelog/20231229001_updating_syslog_json_generic_filters.xml new file mode 100644 index 000000000..bb4e4b61d --- /dev/null +++ b/backend/src/main/resources/config/liquibase/changelog/20231229001_updating_syslog_json_generic_filters.xml @@ -0,0 +1,161 @@ + + + + + + + "message" + terminator => "" +} + +#Looking for datasource generated by an agent and parse original message +if [message]=~/\[utm_stack_agent_ds=(.+)\]-(.+)/ { + grok { + match => { + "message" => [ "\[utm_stack_agent_ds=%{DATA:dataSource}\]-%{GREEDYDATA:original_log_message}" ] + } + } +} +if [original_log_message] { + mutate { + update => { "message" => "%{[original_log_message]}" } + } +} +#......................................................................# +#Generating dataSource and dataType fields required by CurrelationRulesEngine +if ![dataSource] { + mutate { + add_field => { "dataSource" => "%{host}" } + } +} +if ![dataType] { + mutate { + add_field => {"dataType" => "generic"} + } +} +#......................................................................# +#Adding json support +if [message] =~/^\{/ { + json { + source => "message" + } +} + +#Remove unwanted fields if the message not match with conditions + mutate { + remove_field => ["@version","original_log_message","headers"] + } +} +',filter_version='1.0.1' + WHERE id=1521; + +-- Updating Syslog filter + UPDATE utm_logstash_filter + SET logstash_filter='filter { +# Syslog filter, version 1.0.1 + +split { + field => "message" + terminator => "" +} + +#Looking for datasource generated by an agent and parse original message +if [message]=~/\[utm_stack_agent_ds=(.+)\]-(.+)/ { + grok { + match => { + "message" => [ "\[utm_stack_agent_ds=%{DATA:dataSource}\]-%{GREEDYDATA:original_log_message}" ] + } + } +} +if [original_log_message] { + mutate { + update => { "message" => "%{[original_log_message]}" } + } +} +#......................................................................# +#Generating dataSource field required by CurrelationRulesEngine +if ![dataSource] { + mutate { + add_field => { "dataSource" => "%{host}" } + } +} +#......................................................................# +#Generating logx structure +if ![dataType] { + mutate { + add_field => {"dataType" => "syslog"} + rename => ["message", "[logx][syslog][message]"] + } +} +#Remove unwanted fields if the message not match with conditions + mutate { + remove_field => ["@version","original_log_message","headers"] + } +} +',filter_version='1.0.1' + WHERE id=1520; + +-- Updating json input filter + UPDATE utm_logstash_filter + SET logstash_filter='filter { +#Filter version 1.0.2 +#Used to format generic json files + + if [message] { + split { + field => "message" + terminator => "" + } + json { + source => "message" + target => "json_input" + } + + #Create logx structure + mutate { + rename => { "[message]" => "[logx][json_input][message]" } + rename => { "[json_input]" => "[logx][json_input]" } + } + + #Generating dataType and dataSource fields + if ![dataType] { + mutate { + add_field => { "dataType" => "json-input" } + } + } + if ![dataSource] { + if [logx][json_input][dataSource]{ + mutate { + rename => { "[logx][json_input][dataSource]" => "[dataSource]" } + } + } else { + mutate { + add_field => { "dataSource" => "%{host}" } + } + } + } + } + + #Finally remove unused fields + mutate { + remove_field => ["path","@version","host","headers"] + } +} +',filter_version='1.0.2' + WHERE id=1515; + + ]]> + + + diff --git a/backend/src/main/resources/config/liquibase/master.xml b/backend/src/main/resources/config/liquibase/master.xml index d78cb959a..c22d2aebb 100644 --- a/backend/src/main/resources/config/liquibase/master.xml +++ b/backend/src/main/resources/config/liquibase/master.xml @@ -24,4 +24,8 @@ + + + + diff --git a/filters/generic/generic.conf b/filters/generic/generic.conf index 3a6d89aa1..6b563e024 100644 --- a/filters/generic/generic.conf +++ b/filters/generic/generic.conf @@ -1,5 +1,5 @@ filter { -# Generic pipeline filter, version 1.0.0 +# Generic pipeline filter, version 1.0.1 # Supports plain logs and simple json logs split { @@ -27,10 +27,11 @@ if ![dataSource] { add_field => { "dataSource" => "%{host}" } } } +if ![dataType] { mutate { add_field => {"dataType" => "generic"} } - +} #......................................................................# #Adding json support if [message] =~/^\{/ { diff --git a/filters/json/json-input.conf b/filters/json/json-input.conf index 7dd4f83b5..a765843dd 100644 --- a/filters/json/json-input.conf +++ b/filters/json/json-input.conf @@ -1,5 +1,5 @@ filter { -#Filter version 1.0.1 +#Filter version 1.0.2 #Used to format generic json files if [message] { @@ -24,14 +24,16 @@ filter { add_field => { "dataType" => "json-input" } } } - if [logx][json_input][dataSource]{ + if ![dataSource] { + if [logx][json_input][dataSource]{ mutate { rename => { "[logx][json_input][dataSource]" => "[dataSource]" } } - } else { + } else { mutate { add_field => { "dataSource" => "%{host}" } } + } } } diff --git a/filters/privafy/privafy.conf b/filters/privafy/privafy.conf index 9ab93255e..1fc0a4796 100644 --- a/filters/privafy/privafy.conf +++ b/filters/privafy/privafy.conf @@ -1,6 +1,6 @@ filter { -# Privafy filter version 1.1.0 +# Privafy filter version 1.1.2 # Based on (User Doc) https://docs.progress.com/es-ES/bundle/loadmaster-technical-note-common-event-format-cef-logs-ga/page/Common-Event-Format-CEF-Logs.html (December, 2023) # and (User Doc) https://help.deepsecurity.trendmicro.com/20_0/on-premise/event-syslog-message-formats.html (December, 2023) # and example logs provided by user during POC @@ -28,10 +28,20 @@ filter { } } - if ![dataType] { +#......................................................................# +# Creating privafy message field from syslog message + if [logx][syslog][message] { + mutate { + add_field => { "prvf_message" => "%{[logx][syslog][message]}" } + } + } else { + mutate { + add_field => { "prvf_message" => "%{message}" } + } + } #......................................................................# # Privafy Entry point - if [message] and (("CEF:" in [message] or "LEEF:" in [message]) and [message] =~/\|(\w+)?(\s)?Privafy(\s)?(\w+)?\|/ ) { + if [prvf_message] and (("CEF:" in [prvf_message] or "LEEF:" in [prvf_message]) and [prvf_message] =~/\|(\w+)?(\s)?Privafy(\s)?(\w+)?\|/ ) { #......................................................................# #Generating dataSource field required by CurrelationRulesEngine #Checks if exists, if not evaluate to the host variable @@ -42,23 +52,29 @@ filter { } #......................................................................# #Generating dataType field required by CurrelationRulesEngine + if (![dataType]){ mutate { add_field => { "dataType" => "privafy" } } + } else { + mutate { + update => { "dataType" => "privafy" } + } + } #......................................................................# -#If CEF or LEEF formatted log do the parsing of the message mark as undefined syslog format - if ("CEF:" in [message] or "LEEF:" in [message] ) { +#If CEF or LEEF formatted log do the parsing of the prvf_message mark as undefined syslog format + if ("CEF:" in [prvf_message] or "LEEF:" in [prvf_message] ) { #......................................................................# -#Using grok to parse header of the message +#Using grok to parse header of the prvf_message grok { match => { - "message" => [ + "prvf_message" => [ "(%{INT:not_defined})?(\s)?(<%{NUMBER:priority}>)?(%{INT:syslog_version})?((\s)%{GREEDYDATA:syslog_date_host}(\s))?(?(CEF|LEEF)):(\s)?(?(%{INT}\.%{INT}|%{INT}))%{GREEDYDATA:cef_or_leef_msg_all}" ] } } } - if ("CEF:" in [message] ) { + if ("CEF:" in [prvf_message] ) { #......................................................................# #Using grok to parse components of the cef_or_leef_msg_all if [cef_or_leef_msg_all] { @@ -72,7 +88,7 @@ filter { } } } - } else if ("LEEF:" in [message] ) { + } else if ("LEEF:" in [prvf_message] ) { #......................................................................# #Using grok to parse components of the leef_message if [cef_or_leef_msg_all] { @@ -116,15 +132,15 @@ filter { #Using grok to parse kv issued fields grok { match => { - "cef_msg" => [ - "command_line=%{DATA:command_line} %{WORD}=(%{GREEDYDATA:irrelevant})?" + "cef_or_leef_msg" => [ + "command_line=%{DATA:command_line}\s(\b([a-zA-Z0-9_]+)\b)=(%{GREEDYDATA:irrelevant})?" ] } } grok { match => { - "cef_msg" => [ + "cef_or_leef_msg" => [ "username=%{DATA:src_user} %{WORD}=(%{GREEDYDATA:irrelevant})?" ] } @@ -132,7 +148,7 @@ filter { grok { match => { - "cef_msg" => [ + "cef_or_leef_msg" => [ "activity=%{DATA:activity} %{WORD}=(%{GREEDYDATA:irrelevant})?" ] } @@ -140,7 +156,7 @@ filter { grok { match => { - "cef_msg" => [ + "cef_or_leef_msg" => [ "description=%{DATA:description} %{WORD}=(%{GREEDYDATA:irrelevant})?" ] } @@ -148,7 +164,7 @@ filter { grok { match => { - "cef_msg" => [ + "cef_or_leef_msg" => [ "parent_path=%{DATA:parent_path} %{WORD}=(%{GREEDYDATA:irrelevant})?" ] } @@ -156,7 +172,7 @@ filter { grok { match => { - "cef_msg" => [ + "cef_or_leef_msg" => [ "path=%{DATA:path} %{WORD}=(%{GREEDYDATA:irrelevant})?" ] } @@ -176,7 +192,7 @@ filter { rename => { "[format_version]" => "[kv_field][format_version]" } rename => { "[format_type]" => "[kv_field][format_type]" } rename => { "[end_msg]" => "[kv_field][end_msg]" } - rename => { "[message]" => "[kv_field][message]" } + rename => { "[prvf_message]" => "[kv_field][message]" } #Generating other fields rename => { "[kv_field][srcIP]" => "[kv_field][src_ip]" } @@ -263,6 +279,10 @@ if [kv_field][severity]{ event.get("[kv_field]").each do |k, v| if (v == "X0X") event.set("[logx][privafy][#{k}]",nil) + elsif k.start_with?("-") + event.remove(k) + elsif k =~ /\W(.*)?/ + event.remove(k) elsif !(v.kind_of?(Array)) new_v = v.to_s.gsub(/\"/, "") new_v = new_v.gsub(/\'/, "") @@ -277,12 +297,10 @@ if [kv_field][severity]{ #......................................................................# #Finally, remove unnecessary fields mutate { - remove_field => ["@version","path","tags","type","syslog_version","kv_field", - "not_defined","cef_or_leef_msg_all","cef_or_leef_msg","syslog_date_host","irrelevant","init_msg"] + remove_field => ["@version","path","tags","type","syslog_version","kv_field","message","[logx][syslog]","not_defined","cef_or_leef_msg_all","cef_or_leef_msg","syslog_date_host","irrelevant","init_msg"] } } # End CEF entrypoint - } #Also, remove unwanted fields if the message not match with conditions mutate { diff --git a/filters/syslog/syslog-generic.conf b/filters/syslog/syslog-generic.conf index b33074ce1..6b25c72ec 100644 --- a/filters/syslog/syslog-generic.conf +++ b/filters/syslog/syslog-generic.conf @@ -1,5 +1,5 @@ filter { -# Syslog filter, version 1.0.0 +# Syslog filter, version 1.0.1 split { field => "message" @@ -28,11 +28,12 @@ if ![dataSource] { } #......................................................................# #Generating logx structure +if ![dataType] { mutate { add_field => {"dataType" => "syslog"} rename => ["message", "[logx][syslog][message]"] } - +} #Remove unwanted fields if the message not match with conditions mutate { remove_field => ["@version","original_log_message","headers"] diff --git a/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts b/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts index c0fc9aa2d..91c73584b 100644 --- a/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts +++ b/frontend/src/app/app-module/guides/guide-linux-agent/guide-linux-agent.component.ts @@ -49,8 +49,13 @@ export class GuideLinuxAgentComponent implements OnInit { `/opt/utmstack-linux-agent/utmstack_agent_installer && sudo /opt/utmstack-linux-agent/utmstack_agent_installer install ` + ip + ` ` + this.token + ` yes`; } getUninstallCommand(): string { - return `sudo /opt/utmstack-linux-agent/utmstack_agent_installer uninstall && echo "Removing UTMStack Agent dependencies..." ` + - `&& sleep 10 && sudo rm -rf "/opt/utmstack-linux-agent" && echo "UTMStack Agent dependencies removed successfully."`; + return `sudo /opt/utmstack-linux-agent/utmstack_agent_installer uninstall || true; sudo systemctl stop UTMStackAgent || true; ` + + `sudo systemctl disable UTMStackAgent || true; sudo rm /etc/systemd/system/UTMStackAgent.service || true; sudo systemctl stop UTMStackRedline || true; ` + + `sudo systemctl disable UTMStackRedline || true; sudo rm /etc/systemd/system/UTMStackRedline.service || true; ` + + `sudo systemctl stop UTMStackUpdater || true; sudo systemctl disable UTMStackUpdater || true; ` + + `sudo rm /etc/systemd/system/UTMStackUpdater.service || true; sudo systemctl stop UTMStackModulesLogsCollector || true; ` + + `sudo systemctl disable UTMStackModulesLogsCollector || true; sudo rm /etc/systemd/system/UTMStackModulesLogsCollector.service || true; ` + + `sudo systemctl daemon-reload || true; echo "Removing UTMStack Agent dependencies..." ` + + `&& sleep 10 && sudo rm -rf "/opt/utmstack-linux-agent" && echo "UTMStack Agent dependencies removed successfully."`; } - } diff --git a/frontend/src/app/app-module/guides/guide-winlogbeat/guide-winlogbeat.component.ts b/frontend/src/app/app-module/guides/guide-winlogbeat/guide-winlogbeat.component.ts index 77bee3ac2..8301c5a86 100644 --- a/frontend/src/app/app-module/guides/guide-winlogbeat/guide-winlogbeat.component.ts +++ b/frontend/src/app/app-module/guides/guide-winlogbeat/guide-winlogbeat.component.ts @@ -34,7 +34,7 @@ export class GuideWinlogbeatComponent implements OnInit { getCommand(): string { const ip = window.location.host.includes(':') ? window.location.host.split(':')[0] : window.location.host; return `New-Item -ItemType Directory -Force -Path "C:\\Program Files\\UTMStack\\UTMStack Agent"; ` + - `Invoke-WebRequest -Uri "https://cdn.utmstack.com/agent_updates/release/installer/v10.1.2/utmstack_agent_installer.exe" ` + + `Invoke-WebRequest -Uri "https://cdn.utmstack.com/agent_updates/release/installer/v10.2.0/utmstack_agent_installer.exe" ` + `-OutFile "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_installer.exe"; ` + `Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_installer.exe" ` + `-ArgumentList 'install', '` + ip + `', '` + this.token + `', 'yes' -NoNewWindow -Wait`; diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index 44db67ba0..64c4268f1 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -97,18 +97,6 @@

Getting alert detail

- -

Creating pdf, please wait

-
-
diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index c0b2c976d..a030c473c 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -1,5 +1,5 @@ import {Component, HostListener, OnInit, Renderer2} from '@angular/core'; -import {ActivatedRoute, NavigationEnd, Router} from '@angular/router'; +import {NavigationEnd, Router} from '@angular/router'; import {TranslateService} from '@ngx-translate/core'; import {NgxSpinnerService} from 'ngx-spinner'; import {UtmToastService} from './shared/alert/utm-toast.service'; @@ -12,8 +12,6 @@ import {UtmAppThemeService} from './shared/services/theme/utm-app-theme.service' import {retry} from "rxjs/operators"; import {ApiServiceCheckerService} from "./core/auth/api-checker-service"; import {TimezoneFormatService} from "./shared/services/utm-timezone.service"; -import {parseQueryParamsToFilter} from "./shared/util/query-params-to-filter.util"; -import {LoginService} from "./core/login/login.service"; @Component({ selector: 'app-root', @@ -40,9 +38,7 @@ export class AppComponent implements OnInit { private utmToastService: UtmToastService, private router: Router, private renderer: Renderer2, private apiServiceCheckerService: ApiServiceCheckerService, - private timezoneFormatService: TimezoneFormatService, - private activatedRoute: ActivatedRoute, - private loginService: LoginService) { + private timezoneFormatService: TimezoneFormatService) { this.translate.setDefaultLang('en'); this.menuBehavior.$menu.subscribe(men => { this.menu = men; diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index 21c5c3afa..7495cf977 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -13,4 +13,3 @@ export const SERVER_API_URL = environment.SERVER_API_URL + environment.SERVER_AP export const SERVER_API_CONTEXT = environment.SERVER_API_CONTEXT; export const WS_SERVER_API_URL = environment.WEBSOCKET_URL; export const BUILD_TIMESTAMP = environment.BUILD_TIMESTAMP; -export const ACCESS_KEY = 'Utm-Internal-Key'; diff --git a/frontend/src/app/assets-discover/shared/enums/asset-map-filter-field.enum.ts b/frontend/src/app/assets-discover/shared/enums/asset-map-filter-field.enum.ts index 080a49b14..5613c665f 100644 --- a/frontend/src/app/assets-discover/shared/enums/asset-map-filter-field.enum.ts +++ b/frontend/src/app/assets-discover/shared/enums/asset-map-filter-field.enum.ts @@ -1,5 +1,5 @@ /** - * Map filter with field + * Map filter with field, blame to leo to put another name on generic filter prop request param */ export enum AssetMapFilterFieldEnum { OS = 'os', diff --git a/frontend/src/app/blocks/interceptor/auth.interceptor.ts b/frontend/src/app/blocks/interceptor/auth.interceptor.ts index 65c7b11f5..2c85ca4fc 100644 --- a/frontend/src/app/blocks/interceptor/auth.interceptor.ts +++ b/frontend/src/app/blocks/interceptor/auth.interceptor.ts @@ -4,7 +4,7 @@ import {LocalStorageService, SessionStorageService} from 'ngx-webstorage'; import {Observable} from 'rxjs'; -import {ACCESS_KEY, SERVER_API_URL, SESSION_AUTH_TOKEN} from '../../app.constants'; +import {SERVER_API_URL, SESSION_AUTH_TOKEN} from '../../app.constants'; @Injectable() export class AuthInterceptor implements HttpInterceptor { @@ -19,11 +19,8 @@ export class AuthInterceptor implements HttpInterceptor { const sessionToken = this.sessionStorage.retrieve(SESSION_AUTH_TOKEN); const localStorageToken = this.localStorage.retrieve(SESSION_AUTH_TOKEN); const token = sessionToken || localStorageToken; - - const sessionKey = this.sessionStorage.retrieve(ACCESS_KEY); - const localStorageKey = this.localStorage.retrieve(ACCESS_KEY); - const key = sessionKey || localStorageKey; - + // const token = this.localStorage.retrieve(SESSION_AUTH_TOKEN); + // console.log(localStorageToken); if (!!token) { request = request.clone({ setHeaders: { @@ -31,14 +28,6 @@ export class AuthInterceptor implements HttpInterceptor { } }); } - - if (!!key) { - request = request.clone({ - setHeaders: { - 'Utm-Internal-Key': key - } - }); - } return next.handle(request); } } diff --git a/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.html b/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.html index f9fe94e34..a200c4c16 100644 --- a/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.html +++ b/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.html @@ -30,7 +30,8 @@
Back - {{pdfExport ? 'Generating...' : 'Save to PDF'}} diff --git a/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.ts b/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.ts index ae1fe26db..8a7fb4954 100644 --- a/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.ts +++ b/frontend/src/app/compliance/compliance-result-view/compliance-result-view.component.ts @@ -1,4 +1,4 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; import {CompactType, GridsterConfig, GridType} from 'angular-gridster2'; @@ -13,21 +13,13 @@ import {ComplianceTemplateService} from '../shared/services/compliance-template. import {CpReportsService} from '../shared/services/cp-reports.service'; import {ComplianceReportType} from '../shared/type/compliance-report.type'; import {HippaSignaturesType} from '../shared/type/hippa-signatures.type'; -import {ExportPdfService} from '../../shared/services/util/export-pdf.service'; -import {filtersToStringParam} from '../../shared/util/query-params-to-filter.util'; -import {rebuildVisualizationFilterTime} from '../../graphic-builder/shared/util/chart-filter/chart-filter.util'; -import {TimeFilterBehavior} from '../../shared/behaviors/time-filter.behavior'; -import {ElasticFilterType} from '../../shared/types/filter/elastic-filter.type'; -import {NgxSpinnerService} from 'ngx-spinner'; -import {Subject} from 'rxjs'; -import {takeUntil} from 'rxjs/operators'; @Component({ selector: 'app-compliance-result-view', templateUrl: './compliance-result-view.component.html', styleUrls: ['./compliance-result-view.component.scss'] }) -export class ComplianceResultViewComponent implements OnInit, OnDestroy { +export class ComplianceResultViewComponent implements OnInit { reportId: number; report: ComplianceReportType; signatures: HippaSignaturesType[] = []; @@ -64,8 +56,6 @@ export class ComplianceResultViewComponent implements OnInit, OnDestroy { standardId: number; sectionId: number; configSolution: string; - filtersValues: ElasticFilterType[] = []; - destroy$: Subject = new Subject(); constructor(private activeRoute: ActivatedRoute, private cpReportsService: CpReportsService, @@ -73,10 +63,7 @@ export class ComplianceResultViewComponent implements OnInit, OnDestroy { private utmToastService: UtmToastService, private modalService: NgbModal, private complianceTemplateService: ComplianceTemplateService, - private utmRenderVisualization: UtmRenderVisualization, - private timeFilterBehavior: TimeFilterBehavior, - private spinner: NgxSpinnerService, - private exportPdfService: ExportPdfService) { + private utmRenderVisualization: UtmRenderVisualization) { this.activeRoute.queryParams.subscribe((params) => { this.reportId = params[ComplianceParamsEnum.TEMPLATE]; @@ -87,16 +74,6 @@ export class ComplianceResultViewComponent implements OnInit, OnDestroy { ngOnInit() { this.getTemplate(); - - this.timeFilterBehavior.$time - .pipe(takeUntil(this.destroy$)) - .subscribe(time => { - if (time) { - rebuildVisualizationFilterTime({timeFrom: time.from, timeTo: time.to}, this.filtersValues).then(filters => { - this.filtersValues = filters; - }); - } - }); } /** @@ -126,27 +103,12 @@ export class ComplianceResultViewComponent implements OnInit, OnDestroy { }); } } - exportToPdf() { - filtersToStringParam(this.filtersValues).then(queryParams => { - this.spinner.show('buildPrintPDF'); - const params = queryParams !== '' ? '?' + queryParams : ''; - const url = '/dashboard/export-compliance/' + this.reportId + params; - const fileName = this.report.associatedDashboard.name.replace(/ /g, '_'); - this.exportPdfService.getPdf(url, fileName, 'PDF_TYPE_TOKEN').subscribe(response => { - this.spinner.hide('buildPrintPDF').then(() => - this.exportPdfService.handlePdfResponse(response)); - }, error => { - this.spinner.hide('buildPrintPDF').then(() => - this.utmToastService.showError('Error', 'An error occurred while creating a PDF.')); - }); - }); + + get exportToPdf() { + return '/dashboard/export-compliance/' + this.reportId; } + viewSolution(solution: string): void { this.configSolution = solution; } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } } diff --git a/frontend/src/app/compliance/compliance-routing.module.ts b/frontend/src/app/compliance/compliance-routing.module.ts index eee4c3646..84674b9d3 100644 --- a/frontend/src/app/compliance/compliance-routing.module.ts +++ b/frontend/src/app/compliance/compliance-routing.module.ts @@ -5,7 +5,6 @@ import {ADMIN_ROLE, USER_ROLE} from '../shared/constants/global.constant'; import {ComplianceCustomViewComponent} from './compliance-custom-view/compliance-custom-view.component'; import {CpStandardManagementComponent} from './compliance-management/cp-standard-management/cp-standard-management.component'; import {ComplianceResultViewComponent} from './compliance-result-view/compliance-result-view.component'; -import {ComplianceScheduleComponent} from './compliance-schedule/compliance-schedule.component'; import {ComplianceTemplatesComponent} from './compliance-templates/compliance-templates.component'; const routes: Routes = [ @@ -33,11 +32,6 @@ const routes: Routes = [ component: CpStandardManagementComponent, data: {authorities: [ADMIN_ROLE]} }, - { - path: 'schedule', - component: ComplianceScheduleComponent, - data: {authorities: [ADMIN_ROLE]} - }, ]; @NgModule({ diff --git a/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.html b/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.html deleted file mode 100644 index 42af537a7..000000000 --- a/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.html +++ /dev/null @@ -1,107 +0,0 @@ -
-
-
Schedules
-
- -
-
-
-
-
-
- - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
- Name  - - Schedule  - - Filters  - - Action  -
- - {{ schedule.compliance.associatedDashboard.name}} - - - - {{ getCronExpression(schedule.scheduleString) }} - - - - -
- - - -
-
- -
-
- - -
-
-
-
-
- - -
-
-
-
-
-
diff --git a/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.scss b/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.ts b/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.ts deleted file mode 100644 index 5e83886ec..000000000 --- a/frontend/src/app/compliance/compliance-schedule/compliance-schedule.component.ts +++ /dev/null @@ -1,167 +0,0 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; - -import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; -import {Observable, of, Subject} from 'rxjs'; -import {catchError, map, takeUntil, tap} from 'rxjs/operators'; -import {EventDataTypeEnum} from '../../data-management/alert-management/shared/enums/event-data-type.enum'; -import {UtmToastService} from '../../shared/alert/utm-toast.service'; -import {ADMIN_ROLE} from '../../shared/constants/global.constant'; -import {ITEMS_PER_PAGE} from '../../shared/constants/pagination.constants'; -import {SortEvent} from '../../shared/directives/sortable/type/sort-event'; -import {ElasticFilterType} from '../../shared/types/filter/elastic-filter.type'; -import {CpReportBehavior} from '../shared/behavior/cp-report.behavior'; -import {CpStandardBehavior} from '../shared/behavior/cp-standard.behavior'; -import { - UtmComplianceScheduleCreateComponent -} from '../shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component'; -import { - UtmComplianceScheduleDeleteComponent -} from '../shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component'; -import {ComplianceScheduleService} from '../shared/services/compliance-schedule.service'; -import {ComplianceScheduleFilterType} from '../shared/type/compliance-schedule-filter.type'; -import {ComplianceScheduleType} from '../shared/type/compliance-schedule.type'; -import {ComplianceStandardType} from '../shared/type/compliance-standard.type'; -import {CronDescriptionGeneratorService} from "../shared/services/cron-description-generator.service"; - - -@Component({ - selector: 'app-compliance-schedule', - templateUrl: './compliance-schedule.component.html', - styleUrls: ['./compliance-schedule.component.scss'] -}) -export class ComplianceScheduleComponent implements OnInit, OnDestroy { - standard: ComplianceStandardType; - admin = ADMIN_ROLE; - protected readonly ITEMS_PER_PAGE = ITEMS_PER_PAGE; - private requestParams: any; - private sortBy: SortEvent; - searching: any; - checkbox: any; - schedules: any[] = []; - loading = false; - totalItems: any; - page = 1; - itemsPerPage = ITEMS_PER_PAGE; - selected: number[] = []; - protected readonly EventDataTypeEnum = EventDataTypeEnum; - schedules$: Observable; - destroy$: Subject = new Subject(); - - constructor(private modalService: NgbModal, - private cpStandardBehavior: CpStandardBehavior, - private utmToastService: UtmToastService, - private cpReportBehavior: CpReportBehavior, - private complianceScheduleService: ComplianceScheduleService, - private cronDescriptionGeneratorService: CronDescriptionGeneratorService) { - } - - ngOnInit() { - this.requestParams = { - page: this.page - 1, - size: this.itemsPerPage, - sort: this.sortBy, - }; - this.getComplianceScheduleList(); - - this.cpReportBehavior.$reportUpdate - .pipe(takeUntil(this.destroy$)) - .subscribe(update => { - if (update) { - this.getComplianceScheduleList(); - } - }); - } - - newCompliance() { - this.modalService.open(UtmComplianceScheduleCreateComponent, { - centered: true, - size: 'lg', - windowClass: 'cp-schedule-report' - }); - } - - onSearch($event: string | number) { - this.searching = true; - - this.requestParams.page = 0; - this.requestParams['name.contains'] = $event; - this.getComplianceScheduleList(); - } - - getComplianceScheduleList() { - this.loading = true; - this.schedules$ = this.complianceScheduleService.query(this.requestParams) - .pipe( - tap((res) => { - this.totalItems = res.headers.get('X-Total-Count'); - this.schedules = res.body; - this.searching = false; - this.loading = false; - }), - map(response => response.body), - catchError(() => { - this.utmToastService.showError('Error', '"An error occurred while loading report schedules'); - return of([]); - } - )); - } - - loadPage(page: any) { - this.requestParams.page = page - 1; - this.getComplianceScheduleList(); - } - - private onError(res: any) { - this.utmToastService.showErrorResponse('Error', res); - } - - addToSelected(dashboard: any) { - } - - isSelected(schedule: any) { - return false; - } - - viewSchedule(schedule: any) { - } - - editSchedule(schedule: any) { - const modal = this.modalService.open(UtmComplianceScheduleCreateComponent, { - centered: true, - size: 'lg', - windowClass: 'cp-schedule-report' - }); - modal.componentInstance.report = schedule; - modal.componentInstance.reportUpdated.subscribe(updated => { - this.getComplianceScheduleList(); - }); - } - - deleteSchedule(schedule: any) { - const modal = this.modalService.open(UtmComplianceScheduleDeleteComponent, {centered: true}); - modal.componentInstance.complianceSchedule = schedule; - modal.componentInstance.complianceScheduleDeleted.subscribe(deleted => { - this.getComplianceScheduleList(); - }); - } - - getAllFilters(filters: ComplianceScheduleFilterType[]): ElasticFilterType[] { - return filters.reduce((allFilters: ElasticFilterType[], currentDef) => { - return allFilters.concat(currentDef.filterType); - }, []); - } - - getCronExpression(cron: string){ - return this.cronDescriptionGeneratorService.getDescription(cron); - } - - onSort($event: SortEvent) { - this.requestParams.sort = $event.column + ',' + $event.direction; - this.getComplianceScheduleList(); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } -} diff --git a/frontend/src/app/compliance/compliance.module.ts b/frontend/src/app/compliance/compliance.module.ts index 7b1797c64..2a01e6c10 100644 --- a/frontend/src/app/compliance/compliance.module.ts +++ b/frontend/src/app/compliance/compliance.module.ts @@ -18,12 +18,6 @@ import {ComplianceRoutingModule} from './compliance-routing.module'; import {ComplianceResultParamsComponent} from './compliance-templates/compliance-result-params/compliance-result-params.component'; import {ComplianceTemplatesComponent} from './compliance-templates/compliance-templates.component'; import {ComplianceSharedModule} from './shared/compliance-shared.module'; -import {ComplianceScheduleComponent} from "./compliance-schedule/compliance-schedule.component"; -import { - DashboardFilterCreateComponent -} from "../graphic-builder/dashboard-builder/dashboard-filter-create/dashboard-filter-create.component"; -import {DashboardBuilderModule} from "../graphic-builder/dashboard-builder/dashboard-builder.module"; -import {AlertManagementSharedModule} from "../data-management/alert-management/shared/alert-management-shared.module"; @NgModule({ declarations: [ @@ -31,31 +25,27 @@ import {AlertManagementSharedModule} from "../data-management/alert-management/s ComplianceTemplatesComponent, ComplianceResultParamsComponent, ComplianceCustomViewComponent, - ComplianceScheduleComponent ], - imports: [ - CommonModule, - ComplianceRoutingModule, - RouterModule, - UtmSharedModule, - InfiniteScrollModule, - NgSelectModule, - FormsModule, - LogAnalyzerModule, - NgbModule, - VisualizationSharedModule, - GraphicBuilderSharedModule, - ComplianceManagementModule, - ComplianceSharedModule, - UtmDashboardSharedModule, - DashboardBuilderModule, - NgbCollapseModule, - AlertManagementSharedModule - ], + imports: [ + CommonModule, + ComplianceRoutingModule, + RouterModule, + UtmSharedModule, + InfiniteScrollModule, + NgSelectModule, + FormsModule, + LogAnalyzerModule, + NgbModule, + VisualizationSharedModule, + GraphicBuilderSharedModule, + ComplianceManagementModule, + ComplianceSharedModule, + UtmDashboardSharedModule, + NgbCollapseModule + ], schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA], entryComponents: [ - ComplianceResultParamsComponent, - DashboardFilterCreateComponent], + ComplianceResultParamsComponent], exports: [] }) export class ComplianceModule { diff --git a/frontend/src/app/compliance/shared/compliance-shared.module.ts b/frontend/src/app/compliance/shared/compliance-shared.module.ts index 1e413646f..8084450bb 100644 --- a/frontend/src/app/compliance/shared/compliance-shared.module.ts +++ b/frontend/src/app/compliance/shared/compliance-shared.module.ts @@ -6,21 +6,12 @@ import {NgSelectModule} from '@ng-select/ng-select'; import {UtmDashboardSharedModule} from '../../dashboard/shared/utm-dashboard-shared.module'; import {UtmSharedModule} from '../../shared/utm-shared.module'; import {UtmComplianceCreateComponent} from './components/utm-compliance-create/utm-compliance-create.component'; -import {UtmCpCronEditorComponent} from './components/utm-cp-cron-editor/utm-cp-cron-editor.component'; import {UtmCpStSectionSelectComponent} from './components/utm-cp-st-section-select/utm-cp-st-section-select.component'; import {UtmCpStandardCreateComponent} from './components/utm-cp-standard-create/utm-cp-standard-create.component'; import {UtmCpStandardSectionCreateComponent} from './components/utm-cp-standard-section-create/utm-cp-standard-section-create.component'; import {UtmCpStandardSelectComponent} from './components/utm-cp-standard-select/utm-cp-standard-select.component'; import {UtmReportInfoViewComponent} from './components/utm-report-info-view/utm-report-info-view.component'; import {UtmSaveAsComplianceComponent} from './components/utm-save-as-compliance/utm-save-as-compliance.component'; -import { - UtmComplianceScheduleCreateComponent -} from "./components/utm-compliance-schedule-create/utm-compliance-schedule-create.component"; -import {UtmComplianceSelectComponent} from "./components/utm-compliance-select/utm-compliance-select.component"; -import { - UtmComplianceScheduleDeleteComponent -} from "./components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component"; - @NgModule({ declarations: [ @@ -30,11 +21,7 @@ import { UtmCpStandardCreateComponent, UtmCpStandardSectionCreateComponent, UtmReportInfoViewComponent, - UtmComplianceCreateComponent, - UtmComplianceScheduleCreateComponent, - UtmCpCronEditorComponent, - UtmComplianceSelectComponent, - UtmComplianceScheduleDeleteComponent + UtmComplianceCreateComponent ], imports: [ CommonModule, @@ -52,9 +39,7 @@ import { UtmCpStSectionSelectComponent, UtmCpStandardCreateComponent, UtmCpStandardSectionCreateComponent, - UtmComplianceCreateComponent, - UtmComplianceScheduleCreateComponent, - UtmComplianceScheduleDeleteComponent + UtmComplianceCreateComponent ], exports: [ UtmSaveAsComplianceComponent, @@ -62,9 +47,7 @@ import { UtmCpStSectionSelectComponent, UtmCpStandardCreateComponent, UtmCpStandardSectionCreateComponent, - UtmReportInfoViewComponent, - UtmComplianceScheduleCreateComponent, - UtmComplianceScheduleDeleteComponent + UtmReportInfoViewComponent ] }) export class ComplianceSharedModule { diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-create/utm-compliance-create.component.scss b/frontend/src/app/compliance/shared/components/utm-compliance-create/utm-compliance-create.component.scss index 94da32974..57f116164 100644 --- a/frontend/src/app/compliance/shared/components/utm-compliance-create/utm-compliance-create.component.scss +++ b/frontend/src/app/compliance/shared/components/utm-compliance-create/utm-compliance-create.component.scss @@ -4,7 +4,7 @@ .step-container { display: flex; align-items: center; - justify-content: space-between; + justify-content: space-around; width: 100%; position: relative; @@ -45,9 +45,8 @@ .step-link { height: 1px; background-color: #7777; - width: 72%; + width: 50%; top: 33px; - left: 16%; position: absolute; z-index: 0; } diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.html b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.html deleted file mode 100644 index 26ff082cc..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.html +++ /dev/null @@ -1,71 +0,0 @@ - -
-
-
-
- - Compliance report select - -
- -
-
- -
- - Schedule config - -
- -
-
-
-
-
- - -
-
-
-
-
-
- - - Dashbaoards filters - - -
-
-
- -
-
-
-
-
- - - - -
-
- diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.scss b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.scss deleted file mode 100644 index 94da32974..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.scss +++ /dev/null @@ -1,55 +0,0 @@ -@import "../../../../../assets/styles/theme"; -@import "../../../../../assets/styles/var"; - -.step-container { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - position: relative; - - .step { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - z-index: 1; - - .round-indicator { - width: 30px; - height: 30px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - color: #ffffff; - - i { - font-size: 11px; - } - } - - .step-active { - background-color: $blue-scroll; - } - - .step-inactive { - background-color: $grey-color; - } - - .step-success { - background-color: $success-color !important; - } - } - - .step-link { - height: 1px; - background-color: #7777; - width: 72%; - top: 33px; - left: 16%; - position: absolute; - z-index: 0; - } - -} diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.ts b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.ts deleted file mode 100644 index 917063e3c..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-create/utm-compliance-schedule-create.component.ts +++ /dev/null @@ -1,222 +0,0 @@ -import {Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core'; -import {NgbActiveModal, NgbModal} from '@ng-bootstrap/ng-bootstrap'; -import {Subject} from "rxjs"; -import {UtmToastService} from '../../../../shared/alert/utm-toast.service'; -import {DashboardBehavior} from '../../../../shared/behaviors/dashboard.behavior'; -import {UtmDashboardType} from '../../../../shared/chart/types/dashboard/utm-dashboard.type'; -import { - ElasticFilterDefaultTime -} from '../../../../shared/components/utm/filters/elastic-filter-time/elastic-filter-time.component'; -import {ChangeFilterValueService} from '../../../../shared/components/utm/filters/services/change-filter-value.service'; -import {FILTER_OPERATORS} from '../../../../shared/constants/filter-operators.const'; -import {ElasticOperatorsEnum} from '../../../../shared/enums/elastic-operators.enum'; -import {DataNatureTypeEnum, NatureDataPrefixEnum} from '../../../../shared/enums/nature-data.enum'; -import {DashboardFilterType} from '../../../../shared/types/filter/dashboard-filter.type'; -import {ElasticFilterType} from '../../../../shared/types/filter/elastic-filter.type'; -import {OperatorsType} from '../../../../shared/types/filter/operators.type'; -import {UtmIndexPattern} from '../../../../shared/types/index-pattern/utm-index-pattern'; -import {UtmFieldType} from '../../../../shared/types/table/utm-field.type'; -import {filtersWithPatternToStringParam -} from '../../../../shared/util/query-params-to-filter.util'; -import {CpReportBehavior} from '../../behavior/cp-report.behavior'; -import {ComplianceScheduleService} from '../../services/compliance-schedule.service'; -import {ComplianceReportType} from '../../type/compliance-report.type'; -import {ComplianceScheduleFilterType} from '../../type/compliance-schedule-filter.type'; -import {ComplianceScheduleType} from '../../type/compliance-schedule.type'; -import {takeUntil} from "rxjs/operators"; - -@Component({ - selector: 'app-utm-compliance-schedule-create', - templateUrl: './utm-compliance-schedule-create.component.html', - styleUrls: ['./utm-compliance-schedule-create.component.scss'] -}) -export class UtmComplianceScheduleCreateComponent implements OnInit, OnDestroy { - @Input() report: ComplianceScheduleType; - @Output() reportCreated = new EventEmitter(); - @Output() reportUpdated = new EventEmitter(); - dataNature: DataNatureTypeEnum = DataNatureTypeEnum.EVENT; - step = 1; - stepCompleted: number[] = []; - creating = false; - viewSection = false; - standardSectionId: number; - operators: OperatorsType[] = FILTER_OPERATORS; - operatorEnum = ElasticOperatorsEnum; - solution = ''; - cron = '* * * * * *'; - reportId: number; - filters: DashboardFilterType[]; - filtersTypes: ElasticFilterType[] = []; - page = 1; - private sortBy = NatureDataPrefixEnum.TIMESTAMP + ',' + 'desc'; - patterns: UtmIndexPattern[]; - defaultTime: ElasticFilterDefaultTime = new ElasticFilterDefaultTime('now-24h', 'now'); - pattern: UtmIndexPattern; - queryParams: any; - fields: UtmFieldType[] = []; - filterDef: ComplianceScheduleFilterType[]; - dashboard: UtmDashboardType; - onDestroy$: Subject = new Subject(); - - constructor(private complianceScheduleService: ComplianceScheduleService, - public activeModal: NgbActiveModal, - private cpReportBehavior: CpReportBehavior, - private utmToastService: UtmToastService, - private changeFilterValueService: ChangeFilterValueService, - private dashboardBehavior: DashboardBehavior, - public modalService: NgbModal) { - } - - ngOnInit() { - const req = { - page: 0, - size: 1000, - sort: 'id,asc', - 'isActive.equals': true, - }; - - if (this.report) { - this.solution = this.report.compliance.configSolution; - this.viewSection = true; - this.standardSectionId = this.report.compliance.standardSectionId; - this.reportId = this.report.id; - this.cron = this.report.scheduleString; - this.filterDef = this.report.filterDef; - this.filterDef.forEach( f => this.addFilterType({indexPattern: f.indexPattern, filter: f.filterType})); - } - - this.dashboardBehavior.$filterDashboard - .pipe(takeUntil(this.onDestroy$)) - .subscribe(data => { - if (data && this.step === 2) { - this.addFilterType(data); - } - }); - } - - backStep() { - this.step -= 1; - this.stepCompleted.pop(); - } - - nextStep() { - this.stepCompleted.push(this.step); - this.step += 1; - if (this.step === 2 && this.report) { - this.getAllFilters().forEach(f => { - this.changeFilterValueService.changeSelectedValue({field: f.field, value: f.value}) - }); - } - } - - isCompleted(step: number) { - return this.stepCompleted.findIndex(value => value === step) !== -1; - } - - createCompliance() { - filtersWithPatternToStringParam(this.filtersTypes).then(queryParams => { - this.creating = true; - const reportCompliance: ComplianceScheduleType = { - complianceId: this.reportId, - filterDef: this.convertToFilterDefs(), - scheduleString: this.cron, - urlWithParams: `/dashboard/export-compliance/${this.reportId}?${queryParams}` - }; - if (this.report) { - reportCompliance.id = this.report.id; - this.complianceScheduleService.update(reportCompliance) - .pipe(takeUntil(this.onDestroy$)) - .subscribe(() => { - this.utmToastService.showSuccessBottom('Compliance report edited successfully'); - this.filtersTypes = []; - this.activeModal.close(); - this.reportUpdated.emit('edited'); - }, error1 => { - this.creating = false; - this.utmToastService.showError('Error', 'Error editing compliance report'); - }); - } else { - this.complianceScheduleService.create(reportCompliance) - .pipe(takeUntil(this.onDestroy$)) - .subscribe(() => { - this.utmToastService.showSuccessBottom('Compliance report created successfully'); - this.filtersTypes = []; - this.activeModal.close(); - this.cpReportBehavior.$reportUpdate.next('update'); - this.reportCreated.emit('created'); - }, error1 => { - this.creating = false; - this.utmToastService.showError('Error', 'Error creating compliance report'); - }); - } - }); - } - - onDashboardSelected($event: ComplianceReportType) { - this.dashboard = $event.associatedDashboard; - this.filters = JSON.parse(this.dashboard.filters); - this.reportId = $event.id; - } - - private onError(res: any) { - this.utmToastService.showErrorResponse('Error', res); - } - - getAllFilters(): ElasticFilterType[] { - return this.report.filterDef.reduce((allFilters: ElasticFilterType[], currentDef) => { - return allFilters.concat(currentDef.filterType); - }, []); - } - - convertToFilterDefs() { - const filterDefs: ComplianceScheduleFilterType[] = []; - - this.filtersTypes.forEach(filterType => { - const existingFilterDef = filterDefs.find(def => def.indexPattern === filterType.pattern); - - if (existingFilterDef) { - existingFilterDef.filterType.push(filterType); - } else { - filterDefs.push({ - indexPattern: filterType.pattern, - filterType: [filterType] - }); - } - }); - - return filterDefs; - } - - addFilterType(filter: any) { - if (this.filtersTypes.length > 0) { - const filterType = this.filtersTypes.find(f => - f.field === filter.filter[0].field && - f.operator === filter.filter[0].operator && - f.pattern === filter.indexPattern && - f.value !== filter.filter[0].value); - - if (filterType) { - filterType.value = filter.filter[0].value; - } else { - this.filtersTypes.push({ - pattern: filter.indexPattern, - value: filter.filter[0].value, - operator: filter.filter[0].operator, - field: filter.filter[0].field - }); - } - } else { - this.filtersTypes.push({ - pattern: filter.indexPattern, - value: filter.filter[0].value, - operator: filter.filter[0].operator, - field: filter.filter[0].field - }); - } - } - - ngOnDestroy() { - this.onDestroy$.next(); - this.onDestroy$.complete(); - } -} diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.html b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.html deleted file mode 100644 index 1a5dc4581..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.html +++ /dev/null @@ -1,17 +0,0 @@ - -
-
- Are you sure that you want to delete this schedule to {{complianceSchedule.compliance.associatedDashboard.name}}.? -
-
- - -
-
diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.scss b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.ts b/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.ts deleted file mode 100644 index 74a6a89ad..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-schedule-delete/utm-compliance-schedule-delete.component.ts +++ /dev/null @@ -1,38 +0,0 @@ -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; -import {UtmToastService} from '../../../../shared/alert/utm-toast.service'; -import {NavBehavior} from '../../../../shared/behaviors/nav.behavior'; -import {ComplianceScheduleService} from '../../services/compliance-schedule.service'; - - -@Component({ - selector: 'app-dashboard-delete', - templateUrl: './utm-compliance-schedule-delete.component.html', - styleUrls: ['./utm-compliance-schedule-delete.component.scss'] -}) -export class UtmComplianceScheduleDeleteComponent implements OnInit { - @Input() complianceSchedule: any; - @Output() complianceScheduleDeleted = new EventEmitter(); - - constructor(public activeModal: NgbActiveModal, - private complianceScheduleService: ComplianceScheduleService, - private utmToastService: UtmToastService, - private navBehavior: NavBehavior) { - } - - ngOnInit() { - } - - deleteDashboard() { - this.complianceScheduleService.delete(this.complianceSchedule.id) - .subscribe(() => { - this.utmToastService.showSuccessBottom('Schedule Compliance deleted successfully'); - this.activeModal.close(); - this.navBehavior.$nav.next(true); - this.complianceScheduleDeleted.emit('deleted'); - }, () => { - this.utmToastService.showError('Error deleting schedule compliance', - 'Error deleting dashboard, please check your network and try again'); - }); - } -} diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.html b/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.html deleted file mode 100644 index 9447db4a3..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.html +++ /dev/null @@ -1,96 +0,0 @@ -
-
- - Selected:  - - {{report.associatedDashboard.name}} - - -
- - -
-
- - -
-
-
- - - - - - - - - - - - - - - - -
-
- - - {{report.associatedDashboard.name}} - - - - -
-
- -
-
- - -
-
-
-
-
- -
-
-
diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.scss b/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.ts b/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.ts deleted file mode 100644 index 5f91153e0..000000000 --- a/frontend/src/app/compliance/shared/components/utm-compliance-select/utm-compliance-select.component.ts +++ /dev/null @@ -1,137 +0,0 @@ -import {HttpResponse} from '@angular/common/http'; -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {UtmToastService} from '../../../../shared/alert/utm-toast.service'; -import {SortEvent} from '../../../../shared/directives/sortable/type/sort-event'; -import {ComplianceScheduleService} from '../../services/compliance-schedule.service'; -import {CpReportsService} from '../../services/cp-reports.service'; -import {CpStandardSectionService} from '../../services/cp-standard-section.service'; -import {CpStandardService} from '../../services/cp-standard.service'; -import {ComplianceReportType} from '../../type/compliance-report.type'; -import {ComplianceScheduleType} from '../../type/compliance-schedule.type'; -import {ComplianceStandardSectionType} from '../../type/compliance-standard-section.type'; -import {ComplianceStandardType} from '../../type/compliance-standard.type'; - -@Component({ - selector: 'app-utm-compliance-select', - templateUrl: './utm-compliance-select.component.html', - styleUrls: ['./utm-compliance-select.component.scss'] -}) -export class UtmComplianceSelectComponent implements OnInit { - @Input() idReport: number; - @Output() reportSelected = new EventEmitter(); - private requestParams: any; - private sortBy: SortEvent; - report: ComplianceReportType; - standards: ComplianceStandardType[] = []; - standard: number; - solution: string; - standardSections: ComplianceStandardSectionType[] = []; - section: number; - loading = true; - totalItems: any; - page = 1; - itemsPerPage = 10; - complianceReports: ComplianceReportType[] = []; - searching = false; - - constructor(private cpReportsService: CpReportsService, - private utmToastService: UtmToastService, - private cpStandardService: CpStandardService, - private cpStandardSectionService: CpStandardSectionService, - private complianceScheduleService: ComplianceScheduleService) {} - - ngOnInit() { - this.requestParams = { - page: this.page - 1, - size: this.itemsPerPage, - sort: this.sortBy, - 'name.contains': null - }; - this.getStandardList(); - } - - onSortBy($event) { - } - - getSelectedDashboard(id: number) { - this.complianceScheduleService.find(id).subscribe(response => { - const report: ComplianceScheduleType = response.body; - this.selectDashboard(response.body.compliance); - }); - } - - loadPage(page: any) { - this.requestParams.page = page - 1; - this.getDashboardList(); - } - - getDashboardList() { - const query = { - page: this.page - 1, - size: 1000, - sort: 'id,asc', - 'standardSectionId.equals': this.section, - 'configSolution.contains': this.solution - }; - this.cpReportsService.query(query).subscribe( - (res: HttpResponse) => this.onSuccess(res.body, res.headers), - (res: HttpResponse) => this.onError(res.body) - ); - } - - getSections() { - const query = { - page: this.page - 1, - size: 1000, - sort: 'id,asc', - 'standardId.equals': this.standard, - 'standardSectionName.contains': this.solution - }; - this.cpStandardSectionService.query(query).subscribe(response => { - this.standardSections = response.body; - this.section = this.standardSections[0].id; - this.getDashboardList(); - if (this.idReport) { - this.getSelectedDashboard(this.idReport); - } - }); - } - - getStandardList() { - this.cpStandardService.query({page: 0, size: 1000}).subscribe( - (res: HttpResponse) => { - this.standards = res.body; - this.standard = this.standards[0].id; - this.getSections(); - }, - (res: HttpResponse) => this.onError(res) - ); - } - - onSearchDashboard($event: string) { - this.searching = true; - this.solution = $event; - this.getDashboardList(); - } - - selectDashboard(report: ComplianceReportType) { - this.report = report; - this.idReport = report.id; - this.reportSelected.emit(report); - } - - private onSuccess(data, headers) { - this.totalItems = headers.get('X-Total-Count'); - this.complianceReports = data; - this.loading = false; - this.searching = false; - } - - private onError(res: any) { - this.utmToastService.showErrorResponse('Error', res); - } - - filterBySelect($event: {}, source: string) { - this.getSections(); - } -} diff --git a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/models/time-frequency.ts b/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/models/time-frequency.ts deleted file mode 100644 index 3b6fde147..000000000 --- a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/models/time-frequency.ts +++ /dev/null @@ -1,31 +0,0 @@ -export enum TimeFrequency { - Daily = 'Day', - Weekly = 'Week', - Monthly = 'Month', - Yearly = 'Year' -} - -export enum DaysOfWeek { - Sunday = 'SUN', - Monday = 'MON', - Tuesday = 'TUE', - Wednesday = 'WED', - Thursday = 'THU', - Friday = 'FRI', - Saturday = 'SAT', -} - -export enum MonthsOfYear { - January = '1', - February = '2', - March = '3', - April = '4', - May = '5', - June = '6', - July = '7', - August = '8', - September = '9', - October = '10', - November = '11', - December = '12' -} diff --git a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.html b/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.html deleted file mode 100644 index 0297ceb4a..000000000 --- a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.html +++ /dev/null @@ -1,67 +0,0 @@ - -
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - - -
-
-
- - -
-
- - {{day[0]}} - -
-
-
- - diff --git a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.scss b/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.scss deleted file mode 100644 index 0cfe0c7b8..000000000 --- a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.scss +++ /dev/null @@ -1,46 +0,0 @@ - -/*.margin-bottom{ - margin-bottom: 1.8em; -} - -@media (min-width: 576px) { - .flex-basics-30 { - flex-basis: 32%; - } - - .flex-basics-50 { - flex-basis: 48%; - } -}*/ - -.badge.badge-lg.badge-circle { - width: 2rem; - height: 2rem; -} -.badge.badge-lg { - min-width: 2rem; - font-size: 1rem; -} -.badge.badge-circle { - border-radius: 50%; - padding: 0; - min-width: unset; - width: 1.75rem; -} -.badge.badge-circle, .badge.badge-square { - display: inline-flex; - align-items: center; - justify-content: center; - height: 1.75rem; - min-width: 1.75rem; - padding: 0 0.1rem; - line-height: 0; -} -.badge-primary.badge-outline { - border: 1px solid #007bff; - color: #007bff; - background-color: transparent; -} -.gap-5 { - gap: 1.25rem !important; -} diff --git a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.ts b/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.ts deleted file mode 100644 index 4723811f0..000000000 --- a/frontend/src/app/compliance/shared/components/utm-cp-cron-editor/utm-cp-cron-editor.component.ts +++ /dev/null @@ -1,159 +0,0 @@ -import {Component, forwardRef} from '@angular/core'; -import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; -import {DaysOfWeek, MonthsOfYear, TimeFrequency} from './models/time-frequency'; - -const dailyFrequencies: number[] = Array.from({length: 29}, (_, index) => index + 1); -const monthlyFrequencies: number[] = Array.from({length: 12}, (_, index) => index + 1); - -export const CUSTOM_CONTROL_VALUE_ACCESSOR: any = { - provide: NG_VALUE_ACCESSOR, - useExisting: forwardRef(() => UtmCpCronEditorComponent), - multi: true, -}; - -@Component({ - selector: 'app-utm-cp-cron-editor', - templateUrl: './utm-cp-cron-editor.component.html', - styleUrls: ['./utm-cp-cron-editor.component.scss'], - providers: [CUSTOM_CONTROL_VALUE_ACCESSOR], -}) -export class UtmCpCronEditorComponent implements ControlValueAccessor { - - disabled = false; - - public readonly TimeFrequency = TimeFrequency; - public readonly DaysOfWeek = DaysOfWeek; - - months: { name: string, value: string }[] = Object.keys(MonthsOfYear).map(key => ({ - name: key, - value: MonthsOfYear[key as keyof typeof MonthsOfYear] - })); - - timeFrequency: TimeFrequency = TimeFrequency.Daily; - dailyFrequency = 1; - monthlyFrequency = 1; - yearlyFrequency = this.months[0].value; - - startDate = new Date(); - endDate: any; - time = {hour: 0, minute: 0}; - days: string[] = []; - cmdCron: string; - onChange: (value: string) => void = () => {}; - onTouched = () => {}; - - set cronSentence(cmd: string) { - this.cmdCron = cmd; - } - - get frequenciesByType() { - if (this.timeFrequency === TimeFrequency.Daily) { - return dailyFrequencies; - } - return monthlyFrequencies; - } - - get monthlyValue() { - if (this.timeFrequency === TimeFrequency.Yearly) { - return this.yearlyFrequency; - } else if (this.timeFrequency === TimeFrequency.Weekly || this.timeFrequency === TimeFrequency.Daily) { - return '*'; - } - return `*/${this.monthlyFrequency}`; - } - - getTimeEnumValues(obj: any): string[] { - return Object.values(obj) as string[]; - } - - getTime(position: number): string { - /*const formatTime = this.convertTo24Format(this.time);*/ - const time = position === 1 ? this.time.minute : this.time.hour; - return this.time.hour === 0 && this.time.minute === 0 ? '*' : time.toString(); - } - - getDay() { - return this.timeFrequency === TimeFrequency.Daily && this.dailyFrequency !== 0 ? `*/${this.dailyFrequency}` : '*'; - } - - getDays() { - return this.days.length > 0 ? this.days.join(',') : '*'; - } - - isSelected(day: string): boolean { - return this.days.includes(this.getIndexDay(day)); - } - - setDays(day: string) { - if (this.isSelected(day)) { - this.days.splice(this.days.indexOf(day), 1); - } else { - this.days.push(this.getIndexDay(day)); - } - this.emitChange(); - } - - onChangeFrequency() { - if (this.timeFrequency === TimeFrequency.Weekly) { - this.days = ['0']; - } - if (this.timeFrequency !== TimeFrequency.Weekly) { - this.days = []; - } - if (this.timeFrequency === TimeFrequency.Weekly || this.timeFrequency === TimeFrequency.Yearly) { - this.dailyFrequency = 0; - } - this.emitChange(); - } - registerOnChange(fn: any): void { - this.onChange = fn; - } - - registerOnTouched(fn: any): void { - this.onTouched = fn; - } - - writeValue(cron: string): void { - if (cron != null && cron !== '' && cron !== undefined) { - const cronParts = cron.split(' '); - if (cronParts[1] !== '*') { - this.time = { - hour: Number(cronParts[1]), - minute: Number(cronParts[2]) - }; - } - - if (cronParts[3] !== '*') { - this.timeFrequency = TimeFrequency.Daily; - this.dailyFrequency = Number(cronParts[3].split('*/')[1]); - } - - if (cronParts[4] !== '*') { - if (Number(cronParts[4])) { - this.timeFrequency = TimeFrequency.Yearly; - this.yearlyFrequency = this.months[Number(cronParts[4]) - 1].value; - } else { - this.timeFrequency = TimeFrequency.Monthly; - this.monthlyFrequency = Number(cronParts[4].split('*/')[1]); - } - } - - if (cronParts[5] !== '*') { - this.timeFrequency = TimeFrequency.Weekly; - this.days = []; - cronParts[5].split(',').forEach(value => { - this.days.push(value); - }); - } - - this.cronSentence = cron; - } - } - getIndexDay(day: string) { - return Object.values(DaysOfWeek).findIndex(value => value === day).toString(); - } - emitChange() { - this.cmdCron = `* ${this.getTime(1)} ${this.getTime(0)} ${this.getDay()} ${this.monthlyValue} ${this.getDays()}`; - this.onChange(this.cmdCron); - } -} diff --git a/frontend/src/app/compliance/shared/services/compliance-schedule.service.ts b/frontend/src/app/compliance/shared/services/compliance-schedule.service.ts deleted file mode 100644 index dc211786d..000000000 --- a/frontend/src/app/compliance/shared/services/compliance-schedule.service.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {HttpClient, HttpResponse} from '@angular/common/http'; -import {Injectable} from '@angular/core'; -import {Observable} from 'rxjs'; -import {SERVER_API_URL} from '../../../app.constants'; -import {createRequestOption} from '../../../shared/util/request-util'; -import {ComplianceScheduleType} from '../type/compliance-schedule.type'; - - -@Injectable({ - providedIn: 'root' -}) -export class ComplianceScheduleService { - public resourceUrl = SERVER_API_URL + 'api'; - - constructor(private http: HttpClient) { - } - - create(complianceSchedule: ComplianceScheduleType): Observable> { - return this.http.post(`${this.resourceUrl}/compliance-report-schedules`, - complianceSchedule, {observe: 'response'}); - } - - update(alert: ComplianceScheduleType): Observable> { - return this.http.put(`${this.resourceUrl}/compliance-report-schedules`, - alert, {observe: 'response'}); - } - - find(id: number): Observable> { - return this.http.get(`${this.resourceUrl}/compliance-report-schedules-by-id/${id}`, - {observe: 'response'}); - } - - query(req?: any): Observable> { - const options = createRequestOption(req); - return this.http.get(`${this.resourceUrl}/compliance-report-schedules-by-user`, { - params: options, observe: 'response' - }); - } - - delete(id: string): Observable> { - return this.http.delete(`${this.resourceUrl}/compliance-report-schedules/${id}`, - {observe: 'response'}); - } -} diff --git a/frontend/src/app/compliance/shared/services/cron-description-generator.service.ts b/frontend/src/app/compliance/shared/services/cron-description-generator.service.ts deleted file mode 100644 index c2454c285..000000000 --- a/frontend/src/app/compliance/shared/services/cron-description-generator.service.ts +++ /dev/null @@ -1,139 +0,0 @@ -import {Injectable} from '@angular/core'; -import {TimeFrequency} from '../components/utm-cp-cron-editor/models/time-frequency'; - -@Injectable({ - providedIn: 'root' -}) - -export class CronDescriptionGeneratorService { - - private static dayOfWeekMap: Record = { - '0': 'Sunday', - '1': 'Monday', - '2': 'Tuesday', - '3': 'Wednesday', - '4': 'Thursday', - '5': 'Friday', - '6': 'Saturday' - }; - - private static monthMap: Record = { - '1': 'January', - '2': 'February', - '3': 'March', - '4': 'April', - '5': 'May', - '6': 'June', - '7': 'July', - '8': 'August', - '9': 'September', - '10': 'October', - '11': 'November', - '12': 'December' - }; - - private cronFields: any; - private timeFrequency: TimeFrequency; - private frequency: string; - - - private mapDayOfWeek(dayOfWeek: string): string { - return CronDescriptionGeneratorService.dayOfWeekMap[dayOfWeek] || dayOfWeek; - } - - private mapMonth(month: string): string { - return CronDescriptionGeneratorService.monthMap[month] || month; - } - - private checkCronString(cronString: string) { - const fields = cronString.split(' '); - - if (fields.length !== 6) { - throw new Error('Invalid cron'); - } - - this.cronFields = { - seconds: fields[0], - minutes: fields[1], - hours: fields[2], - dayOfMonth: fields[3], - month: fields[4], - dayOfWeek: fields[5] - }; - - if (fields[3] !== '*') { - const day = fields[3].split('*/'); - if (Number(day[1])) { - this.timeFrequency = TimeFrequency.Daily; - this.frequency = day[1]; - } - } - - if (fields[4] !== '*') { - if (Number(fields[4])) { - this.timeFrequency = TimeFrequency.Yearly; - this.frequency = fields[4]; - } else { - const day = fields[4].split('*/'); - if (Number(day[1])) { - this.timeFrequency = TimeFrequency.Monthly; - this.frequency = day[1]; - } - } - } - - if (fields[5] !== '*') { - if (Number(fields[5]) || fields[5].split(',').length > 0) { - this.timeFrequency = TimeFrequency.Weekly; - } - } - - } - - public getDescription(cronString: string): string { - - this.checkCronString(cronString); - return this.getResults(); - - } - - getHour() { - if (this.cronFields.minutes === '*') { - return 'at every minute'; - } else if (Number(this.cronFields.minutes) && Number(this.cronFields.hours)) { - return `at ${this.cronFields.hours}:${this.cronFields.minutes}`; - } else { - return ''; - } - } - - getDaysOfWeek() { - if (this.cronFields.dayOfWeek === '*') { - return ''; - } else if (Number(this.cronFields.dayOfWeek)) { - return `on ${CronDescriptionGeneratorService.dayOfWeekMap[this.cronFields.dayOfWeek]}`; - } else { - const days = this.cronFields.dayOfWeek.split(','); - return `on ${days.map((day: string) => CronDescriptionGeneratorService.dayOfWeekMap[day]).join(',')}`; - } - } - private getResults() { - - let freq = this.timeFrequency.toLowerCase(); - const hours = this.getHour(); - - if (this.timeFrequency === TimeFrequency.Daily || this.timeFrequency === TimeFrequency.Monthly) { - if (Number(this.frequency) > 1) { - freq = this.timeFrequency.toLowerCase().concat('s'); - } - - return `Runs every ${this.frequency} ${freq} ${hours}`; - - } else if (this.timeFrequency === TimeFrequency.Weekly) { - return `Runs weekly ${this.getDaysOfWeek()} ${hours}`; - } else { - return `Runs yearly on ${CronDescriptionGeneratorService.monthMap[this.cronFields.month]} ${hours}`; - } - } - -} diff --git a/frontend/src/app/compliance/shared/type/compliance-schedule-filter.type.ts b/frontend/src/app/compliance/shared/type/compliance-schedule-filter.type.ts deleted file mode 100644 index 9b1ecd9bf..000000000 --- a/frontend/src/app/compliance/shared/type/compliance-schedule-filter.type.ts +++ /dev/null @@ -1,6 +0,0 @@ -import {ElasticFilterType} from '../../../shared/types/filter/elastic-filter.type'; - -export class ComplianceScheduleFilterType { - indexPattern: string; - filterType: ElasticFilterType[]; -} diff --git a/frontend/src/app/compliance/shared/type/compliance-schedule.type.ts b/frontend/src/app/compliance/shared/type/compliance-schedule.type.ts deleted file mode 100644 index e0ddbc63d..000000000 --- a/frontend/src/app/compliance/shared/type/compliance-schedule.type.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {ElasticFilterType} from '../../../shared/types/filter/elastic-filter.type'; -import {ComplianceReportType} from './compliance-report.type'; -import {ComplianceScheduleFilterType} from "./compliance-schedule-filter.type"; - -export class ComplianceScheduleType { - id?: number; - scheduleString: string; - urlWithParams?: string; - filters?: string; - filterDef: ComplianceScheduleFilterType[]; - compliance?: ComplianceReportType; - complianceId: number; -} diff --git a/frontend/src/app/core/auth/auth-jwt.service.ts b/frontend/src/app/core/auth/auth-jwt.service.ts index 1f0429b8f..7ffad1ece 100644 --- a/frontend/src/app/core/auth/auth-jwt.service.ts +++ b/frontend/src/app/core/auth/auth-jwt.service.ts @@ -5,7 +5,7 @@ import {LocalStorageService, SessionStorageService} from 'ngx-webstorage'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; -import {ACCESS_KEY, COOKIE_AUTH_TOKEN, SERVER_API_URL, SESSION_AUTH_TOKEN} from '../../app.constants'; +import {COOKIE_AUTH_TOKEN, SERVER_API_URL, SESSION_AUTH_TOKEN} from '../../app.constants'; import {UtmToastService} from '../../shared/alert/utm-toast.service'; import {CSRFService} from './csrf.service'; @@ -56,27 +56,12 @@ export class AuthServerProvider { } } - loginWithAccessKey(jwt, rememberMe) { - if (jwt) { - this.storeAccessKey(jwt); - return Promise.resolve(jwt); - } else { - return Promise.reject('auth-jwt-service Promise reject '); // Put appropriate error message here - } - } - storeAuthenticationToken(jwt) { this.$localStorage.store(SESSION_AUTH_TOKEN, jwt); this.$sessionStorage.store(SESSION_AUTH_TOKEN, jwt); this.$cookie.setCookie(COOKIE_AUTH_TOKEN, jwt); } - storeAccessKey(key) { - this.$localStorage.store(ACCESS_KEY, key); - this.$sessionStorage.store(ACCESS_KEY, key); - this.$cookie.setCookie(ACCESS_KEY, key); - } - logout(): Observable { return new Observable(observer => { this.$localStorage.clear(SESSION_AUTH_TOKEN); diff --git a/frontend/src/app/core/login/login.service.ts b/frontend/src/app/core/login/login.service.ts index b5a4bd7ad..084c7a5e6 100644 --- a/frontend/src/app/core/login/login.service.ts +++ b/frontend/src/app/core/login/login.service.ts @@ -33,10 +33,6 @@ export class LoginService { return this.authServerProvider.loginWithToken(jwt, rememberMe); } - loginWithKey(key, rememberMe) { - return this.authServerProvider.loginWithAccessKey(key, rememberMe); - } - logout() { this.authServerProvider.logout().subscribe(() => { this.accountService.authenticate(null); diff --git a/frontend/src/app/dashboard/compliance-export/compliance-export.component.ts b/frontend/src/app/dashboard/compliance-export/compliance-export.component.ts index e156714f9..69fb51c86 100644 --- a/frontend/src/app/dashboard/compliance-export/compliance-export.component.ts +++ b/frontend/src/app/dashboard/compliance-export/compliance-export.component.ts @@ -8,19 +8,11 @@ import {CpReportsService} from '../../compliance/shared/services/cp-reports.serv import {ComplianceReportType} from '../../compliance/shared/type/compliance-report.type'; import {AccountService} from '../../core/auth/account.service'; import {Account} from '../../core/user/account.model'; -import {DashboardBehavior} from '../../shared/behaviors/dashboard.behavior'; import {ThemeChangeBehavior} from '../../shared/behaviors/theme-change.behavior'; -import {TimeFilterBehavior} from '../../shared/behaviors/time-filter.behavior'; import {UtmDashboardVisualizationType} from '../../shared/chart/types/dashboard/utm-dashboard-visualization.type'; import {ChartTypeEnum} from '../../shared/enums/chart-type.enum'; -import {ElasticFilterType} from '../../shared/types/filter/elastic-filter.type'; -import { - parseQueryParamsToFilterWithPattern -} from '../../shared/util/query-params-to-filter.util'; -import {buildFormatInstantFromDate} from '../../shared/util/utm-time.util'; import {UtmRenderVisualization} from '../shared/services/utm-render-visualization.service'; - @Component({ selector: 'app-compliance-export', templateUrl: './compliance-export.component.html', @@ -62,8 +54,6 @@ export class ComplianceExportComponent implements OnInit, AfterViewInit { date = new Date(); preparingPrint = true; cover: string; - filters: ElasticFilterType[] = []; - filterTime: { from: string, to: string }; constructor(private activatedRoute: ActivatedRoute, private cpReportsService: CpReportsService, @@ -71,8 +61,6 @@ export class ComplianceExportComponent implements OnInit, AfterViewInit { private accountService: AccountService, private spinner: NgxSpinnerService, private themeChangeBehavior: ThemeChangeBehavior, - private dashboardBehavior: DashboardBehavior, - private timeFilterBehavior: TimeFilterBehavior, public sanitizer: DomSanitizer, private cdr: ChangeDetectorRef) { } @@ -104,37 +92,11 @@ export class ComplianceExportComponent implements OnInit, AfterViewInit { this.reportId = params.id; this.getTemplate(); }); - this.activatedRoute.queryParams.subscribe(params => { - const queryParams = Object.entries(params).length > 0 ? params : null; - if (queryParams) { - parseQueryParamsToFilterWithPattern(queryParams).then((filters) => { - this.filters = filters; - this.getTimeFilterValue(); - }); - } - }); this.accountService.identity().then(account => { this.account = account; }); } - getTimeFilterValue() { - this.filterTime = { - from: this.resolveFromDate(this.getTime()), - to: this.resolveToDate(this.getTime()), - }; - } - - getTime() { - const indexTime = this.filters.findIndex(value => value.field === '@timestamp'); - if (indexTime !== -1) { - return { - from: this.filters[indexTime].value[0], - to: this.filters[indexTime].value[1] - }; - } - } - /** * Return template */ @@ -163,59 +125,11 @@ export class ComplianceExportComponent implements OnInit, AfterViewInit { } } - resolveToDate(date: { from: any, to: any }): string { - if (!isNaN(Date.parse(date.to))) { - return date.to; - } else { - return new Date().toString(); - } - } - - setVisFilter(): Promise { - return new Promise(resolve => { - for (const dashFilter of this.getFilterByIndexPattern()) { - this.dashboardBehavior.$filterDashboard.next(dashFilter); - } - if (this.filterTime) { - this.timeFilterBehavior.$time.next(this.getTime()); - } - setTimeout(() => resolve(true), 5000); - }); - } - - getFilterByIndexPattern(): { filter: ElasticFilterType[], indexPattern: string }[] { - const filterDefs = []; - - this.filters.forEach(filterType => { - const existingFilterDef = filterDefs.find(def => def.indexPattern === filterType.pattern); - - if (existingFilterDef) { - existingFilterDef.filter.push(filterType); - } else { - filterDefs.push({ - indexPattern: filterType.pattern, - filter: [filterType] - }); - } - }); - return filterDefs; - } - onVisualizationLoaded() { - this.setVisFilter().then(() => { - this.spinner.hide('buildPrint').then(() => { + this.spinner.hide('buildPrint').then(() => { this.preparingPrint = false; this.print(); - }); }); } - resolveFromDate(date: { from: any, to: any }): string { - if (!isNaN(Date.parse(date.from))) { - return date.from; - } else { - return buildFormatInstantFromDate(date).timeFrom; - } - } - } diff --git a/frontend/src/app/dashboard/dashboard-export-pdf/dashboard-export-pdf.component.ts b/frontend/src/app/dashboard/dashboard-export-pdf/dashboard-export-pdf.component.ts index 118194adc..864625027 100644 --- a/frontend/src/app/dashboard/dashboard-export-pdf/dashboard-export-pdf.component.ts +++ b/frontend/src/app/dashboard/dashboard-export-pdf/dashboard-export-pdf.component.ts @@ -147,7 +147,7 @@ export class DashboardExportPdfComponent implements OnInit, AfterViewInit { this.setVisFilter().then(() => { this.spinner.hide('buildPrint').then(() => { this.preparingPrint = false; - // this.print(); + this.print(); }); }); } diff --git a/frontend/src/app/dashboard/dashboard-overview/dashboard-overview.component.ts b/frontend/src/app/dashboard/dashboard-overview/dashboard-overview.component.ts index 3ef9b5b5c..b4f47bf16 100644 --- a/frontend/src/app/dashboard/dashboard-overview/dashboard-overview.component.ts +++ b/frontend/src/app/dashboard/dashboard-overview/dashboard-overview.component.ts @@ -23,8 +23,6 @@ import {ElasticSearchIndexService} from '../../shared/services/elasticsearch/ela import {IndexPatternService} from '../../shared/services/elasticsearch/index-pattern.service'; import {LocalFieldService} from '../../shared/services/elasticsearch/local-field.service'; import {ChartSerieValueType} from '../../shared/types/chart-reponse/chart-serie-value.type'; -import {ActivatedRoute} from "@angular/router"; -import {LoginService} from "../../core/login/login.service"; @Component({ selector: 'app-dashboard-overview', @@ -82,8 +80,6 @@ export class DashboardOverviewComponent implements OnInit { private localFieldService: LocalFieldService, private indexPatternService: IndexPatternService, private indexPatternFieldService: ElasticSearchIndexService, - private activatedRoute: ActivatedRoute, - private loginService: LoginService, private accountService: AccountService, private modalService: NgbModal) { } @@ -110,6 +106,7 @@ export class DashboardOverviewComponent implements OnInit { * END */ + this.getDailyAlert(); /** * Show activate modules modal on constructor @@ -121,16 +118,6 @@ export class DashboardOverviewComponent implements OnInit { // } // }); - /* this.activatedRoute.queryParams.subscribe(params => { - const queryParams = Object.entries(params).length > 0 ? params : null; - if (queryParams.token) { - this.loginService.loginWithKey(queryParams.token, false); - } - this.getDailyAlert(); - });*/ - - this.getDailyAlert(); - setTimeout(() => { this.synchronizeFields(); }, 100000); @@ -146,8 +133,7 @@ export class DashboardOverviewComponent implements OnInit { this.overviewAlertDashboardService.getCardAlertTodayWeek().subscribe(response => { this.dailyAlert = response.body; this.loadingChartDailyAlert = false; - }, - error => console.log(error)); + }); } exportToPdf() { diff --git a/frontend/src/app/dashboard/dashboard-render/dashboard-render.component.ts b/frontend/src/app/dashboard/dashboard-render/dashboard-render.component.ts index 25782de1b..ed20f5005 100644 --- a/frontend/src/app/dashboard/dashboard-render/dashboard-render.component.ts +++ b/frontend/src/app/dashboard/dashboard-render/dashboard-render.component.ts @@ -18,8 +18,6 @@ import {filtersToStringParam} from '../../shared/util/query-params-to-filter.uti import {normalizeString} from '../../shared/util/string-util'; import {RenderLayoutService} from '../shared/services/render-layout.service'; import {UtmRenderVisualization} from '../shared/services/utm-render-visualization.service'; -import {ExportPdfService} from "../../shared/services/util/export-pdf.service"; -import {NgxSpinnerService} from "ngx-spinner"; @Component({ selector: 'app-dashboard-render', @@ -67,9 +65,7 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni private modalService: NgbModal, private dashboardBehavior: DashboardBehavior, private timeFilterBehavior: TimeFilterBehavior, - private utmRenderVisualization: UtmRenderVisualization, - private exportPdfService: ExportPdfService, - private spinner: NgxSpinnerService) { + private utmRenderVisualization: UtmRenderVisualization) { } ngOnInit() { @@ -163,16 +159,7 @@ export class DashboardRenderComponent implements OnInit, OnDestroy, AfterViewIni exportToPdf() { filtersToStringParam(this.filtersValues).then(queryParams => { - this.spinner.show('buildPrintPDF'); - const url = '/dashboard/export/' + this.dashboardId + '/' + normalizeString(this.dashboard.name) + '?' + queryParams; - // window.open('/dashboard/export/' + this.dashboardId + '/' + normalizeString(this.dashboard.name) + '?' + queryParams, '_blank'); - this.exportPdfService.getPdf(url, this.dashboard.name, 'PDF_TYPE_TOKEN').subscribe(response => { - this.spinner.hide('buildPrintPDF').then(() => - this.exportPdfService.handlePdfResponse(response)); - }, error => { - this.spinner.hide('buildPrintPDF'); - console.error('Error downloading PDF:', error); - }); + window.open('/dashboard/export/' + this.dashboardId + '/' + normalizeString(this.dashboard.name) + '?' + queryParams, '_blank'); }); } } diff --git a/frontend/src/app/data-management/alert-management/alert-tags/alert-tags-management.component.ts b/frontend/src/app/data-management/alert-management/alert-tags/alert-tags-management.component.ts index 43fa8c8c2..a876366b4 100644 --- a/frontend/src/app/data-management/alert-management/alert-tags/alert-tags-management.component.ts +++ b/frontend/src/app/data-management/alert-management/alert-tags/alert-tags-management.component.ts @@ -65,7 +65,7 @@ export class AlertTagsManagementComponent implements OnInit { openDeleteConfirmation(tag: any) { const deleteModalRef = this.modalService.open(ModalConfirmationComponent, {centered: true}); deleteModalRef.componentInstance.header = 'Confirm delete operation'; - deleteModalRef.componentInstance.message = 'Are you sure that you want to delete the tag: ' + tag.name; + deleteModalRef.componentInstance.message = 'Are you sure that you want to delete the tag: ' + tag.tagName; deleteModalRef.componentInstance.confirmBtnText = 'Delete'; deleteModalRef.componentInstance.confirmBtnIcon = 'icon-database-remove'; deleteModalRef.componentInstance.confirmBtnType = 'delete'; diff --git a/frontend/src/app/data-management/alert-management/shared/components/alert-actions/alert-apply-incident/alert-apply-incident.component.html b/frontend/src/app/data-management/alert-management/shared/components/alert-actions/alert-apply-incident/alert-apply-incident.component.html index a762ace60..24a7ad693 100644 --- a/frontend/src/app/data-management/alert-management/shared/components/alert-actions/alert-apply-incident/alert-apply-incident.component.html +++ b/frontend/src/app/data-management/alert-management/shared/components/alert-actions/alert-apply-incident/alert-apply-incident.component.html @@ -3,9 +3,9 @@ placement="top" container="body" tooltipClass="utm-tooltip-top"> -
-