From b75541af6136dfba6ab04c5e6bd247e1684849ee Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Tue, 24 Feb 2026 14:41:25 +0300 Subject: [PATCH] feat: logic for scripts and webhooks --- internal/actions/scripts.go | 23 +++++++++++++++ internal/actions/webhooks.go | 57 ++++++++++++++++++++++++++++++++++++ internal/config/types.go | 1 + 3 files changed, 81 insertions(+) diff --git a/internal/actions/scripts.go b/internal/actions/scripts.go index fe0b693..d57d504 100644 --- a/internal/actions/scripts.go +++ b/internal/actions/scripts.go @@ -1,9 +1,32 @@ package actions import ( + "fmt" + "os/exec" + "github.com/d3m0k1d/BanForge/internal/config" ) func RunScript(action config.Action) error { + if !action.Enabled { + return nil + } + if action.Script == "" { + return fmt.Errorf("script on config is empty") + } + if action.Interpretator == "" { + // #nosec G204 - managed by system adminstartor + cmd := exec.Command(action.Script) + err := cmd.Run() + if err != nil { + return fmt.Errorf("run script: %w", err) + } + } + // #nosec G204 - managed by system adminstartor + cmd := exec.Command(action.Interpretator, action.Script) + err := cmd.Run() + if err != nil { + return fmt.Errorf("run script: %w", err) + } return nil } diff --git a/internal/actions/webhooks.go b/internal/actions/webhooks.go index 6b579b0..e5ddf26 100644 --- a/internal/actions/webhooks.go +++ b/internal/actions/webhooks.go @@ -1,9 +1,66 @@ package actions import ( + "fmt" + "io" + "net/http" + "strings" + "time" + "github.com/d3m0k1d/BanForge/internal/config" ) +var defaultClient = &http.Client{ + Timeout: 10 * time.Second, + Transport: &http.Transport{ + MaxIdleConns: 100, + MaxIdleConnsPerHost: 10, + IdleConnTimeout: 90 * time.Second, + }, +} + func SendWebhook(action config.Action) error { + if !action.Enabled { + return nil + } + if action.URL == "" { + return fmt.Errorf("URL on config is empty") + } + + method := action.Method + if method == "" { + method = "POST" + } + + var bodyReader io.Reader + if action.Body != "" { + bodyReader = strings.NewReader(action.Body) + if action.Headers["Content-Type"] == "" && action.Headers["content-type"] == "" { + action.Headers["Content-Type"] = "application/json" + } + } + + req, err := http.NewRequest(method, action.URL, bodyReader) + if err != nil { + return fmt.Errorf("create request: %w", err) + } + + for key, value := range action.Headers { + req.Header.Add(key, value) + } + + // #nosec G704 - HTTP request validation by system administrators + resp, err := defaultClient.Do(req) + if err != nil { + return fmt.Errorf("execute request: %w", err) + } + defer func() { + _ = resp.Body.Close() + }() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("webhook returned status %d", resp.StatusCode) + } + return nil } diff --git a/internal/config/types.go b/internal/config/types.go index 828fb3c..240e2c4 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -44,6 +44,7 @@ type Action struct { Type string `toml:"type"` Enabled bool `toml:"enabled"` URL string `toml:"url"` + Method string `toml:"method"` Headers map[string]string `toml:"headers"` Body string `toml:"body"` Email string `toml:"email"`