From d225ddd74c312d7eea59484678a4742023c3fc65 Mon Sep 17 00:00:00 2001 From: JP <37535226+RabbITCybErSeC@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:00:30 +0100 Subject: [PATCH 1/2] fix providerlink requirement even if auth is disabled (#74) * fix providerlink requirement even if auth is disabled * feedback fix maarten --- routes/routes.go | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/routes/routes.go b/routes/routes.go index 9e95898..ec6cc84 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -15,6 +15,8 @@ import ( "github.com/gin-gonic/gin" ) +const requiredGroupPermission = "soarca_admin" + func Setup(app *gin.Engine) { app.GET("/404-page", handlers.ErrorPage) app.NoRoute(func(ctx *gin.Context) { @@ -22,24 +24,28 @@ func Setup(app *gin.Engine) { }) authEnabled, _ := strconv.ParseBool(utils.GetEnv("AUTH_ENABLED", "false")) - reporter := soarca.NewReport(utils.GetEnv("SOARCA_URI", "http://localhost:8080"), &http.Client{}, authEnabled) status := soarca.NewStatus(utils.GetEnv("SOARCA_URI", "http://localhost:8080"), &http.Client{}, authEnabled) - auth, err := gauth.New(gauth.OIDCRedirectConfig()) - authHandler := handlers.NewOIDCAuthHandler(auth) - if err != nil { - log.Fatal("could not configure oidc redirect config: ", err) - } + var auth *gauth.Authenticator + var authHandler *handlers.OIDCAuthHandler + var err error + publicRoutes := app.Group("/") protectedRoutes := app.Group("/") - protectedRoutes.Use(auth.LoadAuthContext()) - PublicRoutes(publicRoutes, authEnabled, authHandler) + if authEnabled { + auth, err = gauth.New(gauth.OIDCRedirectConfig()) + if err != nil { + log.Fatal("could not configure oidc redirect config: ", err) + } + authHandler = handlers.NewOIDCAuthHandler(auth) + PublicRoutes(publicRoutes, authEnabled, authHandler) + protectedRoutes.Use(auth.LoadAuthContext()) + protectedRoutes.Use(auth.Middleware([]string{requiredGroupPermission})) + } - protectedRoutes.Use(auth.Middleware([]string{"soarca_admin"})) DashboardRoutes(protectedRoutes, authHandler) - ReportingRoutes(reporter, protectedRoutes, authEnabled) StatusRoutes(status, protectedRoutes, authEnabled) SettingsRoutes(protectedRoutes) From ba2be14f6a199359f5eea57cbff43c1aeeaa0606 Mon Sep 17 00:00:00 2001 From: JP Date: Thu, 19 Dec 2024 16:26:40 +0100 Subject: [PATCH 2/2] wip on manual step integration --- backend/soarca/helper.go | 35 +++++++++++++++++++++++ backend/soarca/manual.go | 61 ++++++++++++++++++++++++++++++++++++++++ models/manual/manual.go | 22 +++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 backend/soarca/manual.go create mode 100644 models/manual/manual.go diff --git a/backend/soarca/helper.go b/backend/soarca/helper.go index c472871..ab8fcc3 100644 --- a/backend/soarca/helper.go +++ b/backend/soarca/helper.go @@ -1,6 +1,7 @@ package soarca import ( + "bytes" "context" "encoding/json" "fmt" @@ -61,3 +62,37 @@ func fetch(ctx context.Context, client *http.Client, url string, modifyRequest f return body, nil } + +func postJson(client *http.Client, url string, payload interface{}) error { + ctx, cancel := context.WithTimeout(context.Background(), timeout*time.Millisecond) + defer cancel() + + return postJsonWithContext(ctx, client, url, payload) +} + +func postJsonWithContext(ctx context.Context, client *http.Client, url string, payload interface{}) error { + jsonData, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("failed to marshal payload: %w", err) + } + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(jsonData)) + if err != nil { + return fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("Content-Type", "application/json") + + response, err := client.Do(req) + if err != nil { + return fmt.Errorf("failed to make POST request: %w", err) + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + body, _ := io.ReadAll(response.Body) + return fmt.Errorf("unexpected status code: %d, body: %s", response.StatusCode, string(body)) + } + + return nil +} diff --git a/backend/soarca/manual.go b/backend/soarca/manual.go new file mode 100644 index 0000000..6021f86 --- /dev/null +++ b/backend/soarca/manual.go @@ -0,0 +1,61 @@ +package soarca + +import ( + "encoding/json" + "fmt" + "net/http" + models "soarca-gui/models/manual" +) + +const ( + manualPath = "/manual" +) + +type Manual struct { + Host string + client *http.Client +} + +func NewManual(host string, client *http.Client) *Manual { + return &Manual{Host: host, client: client} +} + +func (m *Manual) GetManualActions() ([]models.ManualAction, error) { + url := fmt.Sprintf("%s%s", m.Host, manualPath) + var actions []models.ManualAction + err := fetchToJson(m.client, url, &actions) + if err != nil { + return nil, fmt.Errorf("failed to fetch manual actions: %w", err) + } + return actions, nil +} + +func (m *Manual) GetManualActionByIDs(executionID, stepID string) (*models.ManualAction, error) { + url := fmt.Sprintf("%s%s/%s/%s", m.Host, manualPath, executionID, stepID) + var action models.ManualAction + err := fetchToJson(m.client, url, &action) + if err != nil { + return nil, fmt.Errorf("failed to fetch manual action: %w", err) + } + return &action, nil +} + +func (m *Manual) ContinueManualAction(request models.ManualContinueRequest) error { + url := fmt.Sprintf("%s%s/continue", m.Host, manualPath) + + jsonData, err := json.Marshal(request) + if err != nil { + return fmt.Errorf("failed to marshal continue request: %w", err) + } + + err = postJson(url, &request) + if err != nil { + return nil, fmt.Errorf("failed to fetch manual action: %w", err) + } + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + return nil +} diff --git a/models/manual/manual.go b/models/manual/manual.go new file mode 100644 index 0000000..87478e0 --- /dev/null +++ b/models/manual/manual.go @@ -0,0 +1,22 @@ +package manual + +type ManualAction struct { + ExecutionStatus string `json:"execution-status"` + ExecutionID string `json:"execution_id"` + PlaybookID string `json:"playbook_id"` + StepID string `json:"step_id"` + Description string `json:"description"` + Command string `json:"command"` + CommandIsBase64 bool `json:"command_is_base64"` + Targets map[string]interface{} `json:"targets"` + OutArgs map[string]interface{} `json:"out_args"` +} + +type ManualContinueRequest struct { + ExecutionStatus string `json:"execution-status"` + ExecutionID string `json:"execution_id"` + PlaybookID string `json:"playbook_id"` + StepID string `json:"step_id"` + ResponseStatus string `json:"response_status"` + ResponseOutArgs map[string]interface{} `json:"response_out_args"` +}