Skip to content

Commit cc92660

Browse files
committed
Made Orborus able to create notifications
1 parent 07c4434 commit cc92660

File tree

4 files changed

+171
-90
lines changed

4 files changed

+171
-90
lines changed

cloudSync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ func SetGitWorkflow(ctx context.Context, workflow Workflow, org *Org) error {
857857

858858

859859
if org.Defaults.WorkflowUploadRepo == "" || org.Defaults.WorkflowUploadToken == "" {
860-
log.Printf("[DEBUG] Missing Repo/Token during Workflow backup upload for org %s (%s)", org.Name, org.Id)
860+
//log.Printf("[DEBUG] Missing Repo/Token during Workflow backup upload for org %s (%s)", org.Name, org.Id)
861861
//return errors.New("Missing repo or token")
862862
return nil
863863
}

detection.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,10 @@ func HandleDetectionAutoConnect(resp http.ResponseWriter, request *http.Request)
641641
detectionType := strings.ToLower(location[4])
642642
log.Printf("[DEBUG] Validating if the org %s (%s) has a %s sandbox handling workflow/system", user.ActiveOrg.Name, user.ActiveOrg.Id, detectionType)
643643

644+
log.Printf("[AUDIT] User '%s' (%s) is trying to detection-connect to %s", user.Username, user.Id, strings.ToUpper(detectionType))
645+
644646
workflow := Workflow{}
645647
if detectionType == "siem" {
646-
log.Printf("[AUDIT] User '%s' (%s) is trying to connect to SIEM", user.Username, user.Id)
647648

648649
ctx := GetContext(request)
649650
execType := "START_TENZIR"

notifications.go

Lines changed: 163 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ func sendToNotificationWorkflow(ctx context.Context, notification Notification,
523523
_ = respBody
524524

525525
//log.Printf("[DEBUG] Finished notification request to %s with status %d. Data: %s", executionUrl, newresp.StatusCode, string(respBody))
526-
log.Printf("[DEBUG] Finished notification request to %s with status %d", executionUrl, newresp.StatusCode)
526+
log.Printf("[DEBUG] Finished notification request to %s with status %d. If status is not 200, an error is created.", executionUrl, newresp.StatusCode)
527527
if newresp.StatusCode != 200 {
528528
return errors.New(fmt.Sprintf("Got status code %d when sending notification for org %s", newresp.StatusCode, notification.OrgId))
529529
}
@@ -532,30 +532,41 @@ func sendToNotificationWorkflow(ctx context.Context, notification Notification,
532532
}
533533

534534
func forwardNotificationRequest(ctx context.Context, title, description, referenceUrl, orgId string) error {
535-
if !strings.Contains(referenceUrl, "execution_id") {
536-
log.Printf("[DEBUG] Notification doesn't contain execution ID. Skipping (1)")
535+
if !strings.Contains(referenceUrl, "execution_id") && !strings.Contains(referenceUrl, "detection") {
536+
log.Printf("[DEBUG] Notification doesn't contain execution ID and detection. Skipping (1)")
537537
return nil
538538
}
539539

540540
// Find execution id
541-
executionId := strings.Split(referenceUrl, "execution_id=")[1]
542-
if len(executionId) == 0 {
543-
log.Printf("[DEBUG] Notification doesn't contain execution ID. Skipping (2)")
544-
return nil
545-
}
541+
executionId := ""
542+
userApikey := ""
543+
if strings.Contains(referenceUrl, "execution_id") {
544+
executionId = strings.Split(referenceUrl, "execution_id=")[1]
545+
if len(executionId) == 0 {
546+
log.Printf("[DEBUG] Notification doesn't contain execution ID. Skipping (2)")
547+
return nil
548+
}
546549

547-
if strings.Contains(executionId, "&") {
548-
executionId = strings.Split(executionId, "&")[0]
549-
}
550+
if strings.Contains(executionId, "&") {
551+
executionId = strings.Split(executionId, "&")[0]
552+
}
550553

551-
// Get the execution
552-
exec, err := GetWorkflowExecution(ctx, executionId)
553-
if err != nil {
554-
log.Printf("[DEBUG] Failed getting execution from notification %s: %s", executionId, err)
555-
return err
554+
// Get the execution
555+
exec, err := GetWorkflowExecution(ctx, executionId)
556+
if err != nil {
557+
log.Printf("[DEBUG] Failed getting execution from notification %s: %s", executionId, err)
558+
return err
559+
}
560+
561+
userApikey = exec.Authorization
556562
}
557563

558-
userApikey := exec.Authorization
564+
if len(userApikey) == 0 {
565+
auth := os.Getenv("AUTH")
566+
if len(auth) > 0 {
567+
userApikey = auth
568+
}
569+
}
559570

560571
notification := Notification{
561572
Title: title,
@@ -593,8 +604,14 @@ func forwardNotificationRequest(ctx context.Context, title, description, referen
593604
bytes.NewBuffer(b),
594605
)
595606

607+
// Environment auth if possible.
596608
req.Header.Add("Authorization", fmt.Sprintf(`Bearer %s`, userApikey))
609+
envName := os.Getenv("ENVIRONMENT_NAME")
597610
req.Header.Add("Org-Id", notification.OrgId)
611+
if len(envName) > 0 {
612+
req.Header.Add("ENVIRONMENT_NAME", envName)
613+
}
614+
598615
newresp, err := client.Do(req)
599616
if err != nil {
600617
log.Printf("[ERROR] Failed sending notification to backend: %s", err)
@@ -621,7 +638,16 @@ func CreateOrgNotification(ctx context.Context, title, description, referenceUrl
621638

622639
if project.Environment == "" {
623640
log.Printf("\n\n\n[ERROR] Not generating notification, as no environment has been detected: %#v", project.Environment)
624-
return nil
641+
642+
auth := os.Getenv("AUTH")
643+
org := os.Getenv("ORG")
644+
environment := os.Getenv("ENVIRONMENT_NAME")
645+
if len(auth) == 0 || len(org) == 0 || len(environment) == 0 {
646+
return nil
647+
}
648+
649+
// Overriding it for Orborus to ensure we have a way to manage
650+
project.Environment = "worker"
625651
}
626652

627653
// Check if the referenceUrl is already in cache or not
@@ -633,7 +659,7 @@ func CreateOrgNotification(ctx context.Context, title, description, referenceUrl
633659
if err == nil {
634660
// Avoiding duplicates for the same workflow+execution
635661
if project.Environment != "cloud" {
636-
log.Printf("[DEBUG] Found cached notification for %s", referenceUrl)
662+
//log.Printf("[DEBUG] Found cached notification for %s", referenceUrl)
637663
}
638664

639665
return nil
@@ -925,82 +951,136 @@ func HandleCreateNotification(resp http.ResponseWriter, request *http.Request) {
925951
ctx := GetContext(request)
926952
user, err := HandleApiAuthentication(resp, request)
927953
if err != nil {
928-
//log.Printf("[AUDIT] INITIAL Api authentication failed in Create notification api: %s", err)
929-
930-
// Allows for execution authorization
931-
if len(notification.ExecutionId) == 0 {
932-
log.Printf("[INFO] User tried to create notification for execution %s with org id %s, but notification org id is %s", notification.ExecutionId, orgId,notification.OrgId)
933-
resp.WriteHeader(403)
934-
resp.Write([]byte(`{"success": false}`))
935-
return
954+
log.Printf("[AUDIT] INITIAL Api authentication failed in Create notification api: %s", err)
955+
956+
// Environmentauth
957+
// Why don't we have a function for this?
958+
newOrgId := request.Header.Get("Org-Id")
959+
environment := request.Header.Get("ENVIRONMENT_NAME")
960+
apikey := request.Header.Get("Authorization")
961+
if len(newOrgId) > 0 {
962+
orgId = newOrgId
936963
}
937964

938-
exec, err := GetWorkflowExecution(ctx, notification.ExecutionId)
939-
if err != nil {
940-
log.Printf("[ERROR] Failed getting execution %s in create notification api: %s", notification.ExecutionId, err)
941-
resp.WriteHeader(400)
942-
resp.Write([]byte(`{"success": false}`))
943-
return
944-
}
965+
if len(orgId) > 0 && len(environment) > 0 && len(apikey) > 0 {
966+
log.Printf("[DEBUG] HANDLING ENVIRONMENT AUTH")
945967

946-
// Check if user has access. Parse out authorization header with "Bearer X"
947-
authHeader := request.Header.Get("Authorization")
948-
if len(authHeader) == 0 {
949-
log.Printf("[INFO] No authorization header in create notification api")
950-
resp.WriteHeader(401)
951-
resp.Write([]byte(`{"success": false}`))
952-
return
953-
}
968+
authHeaderParts := strings.Split(apikey, " ")
969+
if len(authHeaderParts) != 2 {
970+
log.Printf("[INFO] Invalid authorization header in create notification api")
971+
resp.WriteHeader(401)
972+
resp.Write([]byte(`{"success": false}`))
973+
return
974+
}
954975

955-
authHeaderParts := strings.Split(authHeader, " ")
956-
if len(authHeaderParts) != 2 {
957-
log.Printf("[INFO] Invalid authorization header in create notification api")
958-
resp.WriteHeader(401)
959-
resp.Write([]byte(`{"success": false}`))
960-
return
961-
}
976+
if authHeaderParts[0] != "Bearer" {
977+
log.Printf("[INFO] Invalid authorization header in create notification api")
978+
resp.WriteHeader(401)
979+
resp.Write([]byte(`{"success": false}`))
980+
return
981+
}
962982

963-
if authHeaderParts[0] != "Bearer" {
964-
log.Printf("[INFO] Invalid authorization header in create notification api")
965-
resp.WriteHeader(401)
966-
resp.Write([]byte(`{"success": false}`))
967-
return
968-
}
983+
authKey := authHeaderParts[1]
984+
environments, err := GetEnvironments(ctx, orgId)
985+
if err != nil {
986+
resp.WriteHeader(400)
987+
resp.Write([]byte(`{"success": false, "reason": "Failed getting environments"}`))
988+
return
989+
}
969990

970-
// Check if user has access to execution
971-
if authHeaderParts[1] != exec.Authorization {
972-
log.Printf("[INFO] User tried to create notification for execution %s without authorization", exec.ExecutionId)
973-
resp.WriteHeader(403)
974-
resp.Write([]byte(`{"success": false}`))
975-
return
976-
}
991+
found := false
992+
for _, env := range environments {
993+
if env.Name == environment && env.Auth == authKey {
994+
found = true
995+
break
996+
}
997+
}
977998

978-
// Check if exec org id is same
979-
if exec.OrgId != notification.OrgId {
980-
log.Printf("[WARNING] User tried to create notification for execution %s with org id %s, but notification org id is %s", exec.ExecutionId, exec.OrgId, notification.OrgId)
981-
}
999+
if !found {
1000+
log.Printf("[AUDIT] Invalid authorization header in create notification api for Orborus request")
1001+
resp.WriteHeader(403)
1002+
resp.Write([]byte(`{"success": false, "reason": "Invalid authorization config for Environment auth"}`))
1003+
return
1004+
}
9821005

983-
skipUserCheck = true
984-
user.Role = "admin"
985-
user.Username = fmt.Sprintf("execution %s", exec.ExecutionId)
1006+
log.Printf("[AUDIT] Environment auth successful for environment %s", environment)
9861007

987-
if len(exec.ExecutionOrg) > 0 {
988-
orgId = exec.ExecutionOrg
989-
}
1008+
} else {
1009+
// Allows for execution authorization
1010+
if len(notification.ExecutionId) == 0 {
1011+
log.Printf("[INFO] User tried to create notification without an execution ID present", notification.ExecutionId, orgId, notification.OrgId)
1012+
resp.WriteHeader(403)
1013+
resp.Write([]byte(`{"success": false}`))
1014+
return
1015+
}
9901016

991-
if len(orgId) == 0 && len(exec.OrgId) > 0 {
992-
orgId = exec.OrgId
993-
}
1017+
exec, err := GetWorkflowExecution(ctx, notification.ExecutionId)
1018+
if err != nil {
1019+
log.Printf("[ERROR] Failed getting execution %s in create notification api: %s", notification.ExecutionId, err)
1020+
resp.WriteHeader(400)
1021+
resp.Write([]byte(`{"success": false}`))
1022+
return
1023+
}
9941024

995-
if len(orgId) == 0 && len(exec.Workflow.OrgId) > 0 {
996-
orgId = exec.Workflow.OrgId
997-
}
1025+
// Check if user has access. Parse out authorization header with "Bearer X"
1026+
authHeader := request.Header.Get("Authorization")
1027+
if len(authHeader) == 0 {
1028+
log.Printf("[INFO] No authorization header in create notification api")
1029+
resp.WriteHeader(401)
1030+
resp.Write([]byte(`{"success": false}`))
1031+
return
1032+
}
9981033

999-
if len(orgId) == 0 {
1000-
log.Printf("[ERROR] No org id found in create notification api from worker(?)")
1001-
resp.WriteHeader(400)
1002-
resp.Write([]byte(`{"success": false}`))
1003-
return
1034+
authHeaderParts := strings.Split(authHeader, " ")
1035+
if len(authHeaderParts) != 2 {
1036+
log.Printf("[INFO] Invalid authorization header in create notification api")
1037+
resp.WriteHeader(401)
1038+
resp.Write([]byte(`{"success": false}`))
1039+
return
1040+
}
1041+
1042+
if authHeaderParts[0] != "Bearer" {
1043+
log.Printf("[INFO] Invalid authorization header in create notification api")
1044+
resp.WriteHeader(401)
1045+
resp.Write([]byte(`{"success": false}`))
1046+
return
1047+
}
1048+
1049+
// Check if user has access to execution
1050+
if authHeaderParts[1] != exec.Authorization {
1051+
log.Printf("[INFO] User tried to create notification for execution %s without authorization", exec.ExecutionId)
1052+
resp.WriteHeader(403)
1053+
resp.Write([]byte(`{"success": false}`))
1054+
return
1055+
}
1056+
1057+
// Check if exec org id is same
1058+
if exec.OrgId != notification.OrgId {
1059+
log.Printf("[WARNING] User tried to create notification for execution %s with org id %s, but notification org id is %s", exec.ExecutionId, exec.OrgId, notification.OrgId)
1060+
}
1061+
1062+
skipUserCheck = true
1063+
user.Role = "admin"
1064+
user.Username = fmt.Sprintf("execution %s", exec.ExecutionId)
1065+
1066+
if len(exec.ExecutionOrg) > 0 {
1067+
orgId = exec.ExecutionOrg
1068+
}
1069+
1070+
if len(orgId) == 0 && len(exec.OrgId) > 0 {
1071+
orgId = exec.OrgId
1072+
}
1073+
1074+
if len(orgId) == 0 && len(exec.Workflow.OrgId) > 0 {
1075+
orgId = exec.Workflow.OrgId
1076+
}
1077+
1078+
if len(orgId) == 0 {
1079+
log.Printf("[ERROR] No org id found in create notification api from worker(?)")
1080+
resp.WriteHeader(400)
1081+
resp.Write([]byte(`{"success": false}`))
1082+
return
1083+
}
10041084
}
10051085

10061086
user.ActiveOrg.Id = orgId

shared.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5942,6 +5942,7 @@ func hasActionChanged(newAction Action, oldAction Action) (string, bool) {
59425942
return "", false
59435943
}
59445944

5945+
// Diffs workflows with Child workflows and updates them
59455946
func diffWorkflowWrapper(newWorkflow Workflow) Workflow {
59465947
// Actually load the child workflows directly from DB
59475948
ctx := context.Background()
@@ -5950,8 +5951,6 @@ func diffWorkflowWrapper(newWorkflow Workflow) Workflow {
59505951
return newWorkflow
59515952
}
59525953

5953-
//log.Printf("\n\n\nCHILD WORKFLOWS (1): %d\n\n\n", len(childWorkflows))
5954-
59555954
// Taking care of dedup in case there is a reduction in orgs
59565955
newChildWorkflows := []Workflow{}
59575956
for _, childWorkflow := range childWorkflows {
@@ -5963,8 +5962,6 @@ func diffWorkflowWrapper(newWorkflow Workflow) Workflow {
59635962
}
59645963

59655964
childWorkflows = newChildWorkflows
5966-
//log.Printf("\n\n\nCHILD WORKFLOWS (2): %d\n\n\n", len(childWorkflows))
5967-
59685965
if len(childWorkflows) < len(newWorkflow.SuborgDistribution) {
59695966
for _, suborgId := range newWorkflow.SuborgDistribution {
59705967
found := false
@@ -6012,7 +6009,6 @@ func diffWorkflowWrapper(newWorkflow Workflow) Workflow {
60126009
continue
60136010
}
60146011

6015-
//diffWorkflows(childWorkflow, newWorkflow, true)
60166012
waitgroup.Add(1)
60176013
go func(childWorkflow Workflow, newWorkflow Workflow, update bool) {
60186014
diffWorkflows(childWorkflow, newWorkflow, update)
@@ -6072,6 +6068,10 @@ func diffWorkflows(oldWorkflow Workflow, newWorkflow Workflow, update bool) {
60726068

60736069
// Child workflow env & auth id mapping
60746070
newWorkflowEnvironment := "cloud"
6071+
if project.Environment != "cloud" {
6072+
newWorkflowEnvironment = "Shuffle"
6073+
}
6074+
60756075
for actionIndex, action := range newWorkflow.Actions {
60766076
if len(action.Environment) > 0 {
60776077
discoveredEnvironment = action.Environment

0 commit comments

Comments
 (0)