diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go index 32dc2028..dbf1958e 100644 --- a/backend/go-app/docker.go +++ b/backend/go-app/docker.go @@ -842,7 +842,7 @@ func handleRemoteDownloadApp(resp http.ResponseWriter, ctx context.Context, user app := tmpapp{} err := json.Unmarshal(respBody, &app) if err != nil || app.Success == false || len(app.OpenAPI) == 0 { - log.Printf("[ERROR] Failed app unmarshal during auto-download. Success%#v. Applength: %d: %s", app.Success, len(app.OpenAPI), err) + log.Printf("[ERROR] Failed app unmarshal during auto-download. Success: %#v. Applength: %d: %s", app.Success, len(app.OpenAPI), err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "App doesn't exist"}`)) return @@ -960,37 +960,29 @@ func activateWorkflowAppDocker(resp http.ResponseWriter, request *http.Request) } } - if app.Sharing || app.Public { - org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id) - if err == nil { - added := false - if !shuffle.ArrayContains(org.ActiveApps, app.ID) { - org.ActiveApps = append(org.ActiveApps, app.ID) - added = true - } - - if added { - err = shuffle.SetOrg(ctx, *org, org.Id) - if err != nil { - log.Printf("[WARNING] Failed setting org when autoadding apps on save: %s", err) - } else { - log.Printf("[INFO] Added public app %s (%s) to org %s (%s)", app.Name, app.ID, user.ActiveOrg.Name, user.ActiveOrg.Id) - cacheKey := fmt.Sprintf("apps_%s", user.Id) - shuffle.DeleteCache(ctx, cacheKey) - } - } - } - } else { - log.Printf("[WARNING] User is trying to activate %s which is NOT public", app.Name) - resp.WriteHeader(401) - resp.Write([]byte(`{"success": false}`)) + // Just making sure it's being built properly + if app == nil { + log.Printf("[WARNING] App is nil. This shouldn't happen. Starting remote download(3)") + handleRemoteDownloadApp(resp, ctx, user, fileId) return } - log.Printf("[DEBUG] App %s (%s) activated for org %s by user %s", app.Name, app.ID, user.ActiveOrg.Id, user.Username) + // Check the app.. hmm + openApiApp, err := shuffle.GetOpenApiDatastore(ctx, app.ID) + if err != nil { + log.Printf("[WARNING] Error getting app %s (openapi config): %s", app.ID, err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false, "reason": "Couldn't find app OpenAPI"}`)) + return + } - // If onprem, it should autobuild the container(s) from here + log.Printf("[INFO] User %s (%s) is activating %s. Public: %t, Shared: %t", user.Username, user.Id, app.Name, app.Public, app.Sharing) + buildSwaggerApp(resp, []byte(openApiApp.Body), user, true) - resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) + //app.Active = true + //app.Generated = true + //app, err := shuffle.SetApp(ctx, app) + + //resp.WriteHeader(200) + //resp.Write([]byte(`{"success": true}`)) } diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 30ad9ebf..95ba41de 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -19,7 +19,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 - github.com/shuffle/shuffle-shared v0.4.1 + github.com/shuffle/shuffle-shared v0.4.2 golang.org/x/crypto v0.3.0 google.golang.org/api v0.103.0 google.golang.org/appengine v1.6.7 diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index aac4c7e8..37413896 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -1161,7 +1161,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) { } } - log.Printf("[INFO] Starting execution of %s!", fileId) + log.Printf("[AUDIT] Starting execution of workflow '%s' by user %s (%s)!", fileId, user.Username, user.Id) user.ActiveOrg.Users = []shuffle.UserMini{} workflow.ExecutingOrg = user.ActiveOrg diff --git a/frontend/src/components/ConfigureWorkflow.jsx b/frontend/src/components/ConfigureWorkflow.jsx index e7067da1..51baafdb 100644 --- a/frontend/src/components/ConfigureWorkflow.jsx +++ b/frontend/src/components/ConfigureWorkflow.jsx @@ -146,17 +146,18 @@ const ConfigureWorkflow = (props) => { app: {}, steps: [], show_steps: false, - }; + } - const app = apps.find( - (app) => - app.name === action.app_name && - (app.app_version === action.app_version || - (app.loop_versions !== null && - app.loop_versions.includes(action.app_version))) + //console.log("Action: ", key, keyval) + + const app = apps.find((app) => + app.id === action.app_id || + (app.name === action.app_name && + (app.app_version === action.app_version || (app.loop_versions !== null && app.loop_versions.includes(action.app_version)))) ) - //newaction.steps = wazuhSteps + //console.log("FOUND APP: ", app) + if (app === undefined || app === null) { const subapp = apps.find(app => app.name === action.app_name) if (subapp !== undefined && subapp !== null) { @@ -265,17 +266,14 @@ const ConfigureWorkflow = (props) => { if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length !== 0) { for (let [key,keyval] in Object.entries(workflow.workflow_variables)) { const variable = workflow.workflow_variables[key]; - if ( - variable.value === undefined || - variable.value === undefined || - variable.value.length < 2 - ) { + if (variable.value === undefined || variable.value === undefined || variable.value.length === 0) { variable.value = ""; - variable.index = key; requiredVariables.push(variable); } + + variable.index = key; } - } + } if (workflow.triggers !== undefined && workflow.triggers !== null && workflow.triggers.length !== 0) { for (let [key,keyval] in Object.entries(workflow.triggers)) { @@ -1015,7 +1013,7 @@ const ConfigureWorkflow = (props) => { {requiredActions.map((data, index) => { return ( -
+
{data.steps !== undefined && data.steps !== null && data.show_steps === true ? : diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index a5a22e58..e0f91e0e 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -1909,7 +1909,7 @@ const AngularWorkflow = (defaultprops) => { }; const getWorkflow = (workflow_id, sourcenode) => { - fetch(globalUrl + "/api/v1/workflows/" + workflow_id, { + fetch(`${globalUrl}/api/v1/workflows/${workflow_id}`, { method: "GET", headers: { "Content-Type": "application/json", @@ -1920,12 +1920,25 @@ const AngularWorkflow = (defaultprops) => { .then((response) => { if (response.status !== 200) { console.log("Status not 200 for workflows :O!"); - window.location.pathname = "/workflows"; + + if (response.status >= 500) { + alert.info("Something went wrong while loading the workflow. Please reload.") + } else { + alert.info("You don't access to this workflow or loading failed.") + window.location.pathname = "/workflows"; + } } + // Read text from stream + //return response.text(); return response.json(); }) .then((responseJson) => { + // Load as JSON + //console.log("Got workflow TXT: ", responseText) + //const responseJson = JSON.parse(responseText) + //console.log("Got workflow JSON: ", responseJson) + // Not sure why this is necessary. if (responseJson.isValid === undefined) { responseJson.isValid = true; @@ -2145,7 +2158,6 @@ const AngularWorkflow = (defaultprops) => { setWorkflowDone(true); // Add error checks - console.log("Workflow: ", responseJson); if (!responseJson.public) { if ( !responseJson.previously_saved || @@ -2517,8 +2529,6 @@ const AngularWorkflow = (defaultprops) => { cy.add(decoratorNode) } } else { - - // Readding the icon after moving the node if (!found) { const iconInfo = GetIconInfo(nodedata); @@ -3187,7 +3197,7 @@ const AngularWorkflow = (defaultprops) => { } const activateApp = (appid, refresh) => { - fetch(globalUrl + "/api/v1/apps/" + appid + "/activate", { + fetch(`${globalUrl}/api/v1/apps/${appid}/activate`, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -3204,11 +3214,10 @@ const AngularWorkflow = (defaultprops) => { }) .then((responseJson) => { if (responseJson.success === false) { - alert.error("Failed to activate the app") + alert.error("Failed to auto-activate the app. Go to /apps and activate it.") } else { - alert.success("App activated for your organization! Refresh the page to use the app.") - if (refresh === true) { + alert.success("App activated for your organization! Refresh the page to use the app.") getApps() } } @@ -3939,6 +3948,7 @@ const AngularWorkflow = (defaultprops) => { workflow.branches = workflow.branches.filter( (a) => a.id !== edge.data().id ); + setWorkflow(workflow); event.target.remove(); @@ -5591,7 +5601,9 @@ const AngularWorkflow = (defaultprops) => { display: "flex", }; - const VariablesView = () => { + const VariableItem = (props) => { + const { variable, index, type } = props; + const [open, setOpen] = React.useState(false); const [anchorEl, setAnchorEl] = React.useState(null); @@ -5600,29 +5612,148 @@ const AngularWorkflow = (defaultprops) => { setAnchorEl(event.currentTarget); }; - const deleteVariable = (variableIndex) => { - //console.log("Delete:", variableName); - if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length > variableIndex) { - workflow.workflow_variables.splice(variableIndex, 1) - } + const deleteVariable = (type, variableIndex) => { - //workflow.workflow_variables = workflow.workflow_variables.filter( - // (data) => data.name !== variableName - //); - setWorkflow(workflow); + console.log("Delete type: ", type, variableIndex) + + if (type === "normal") { + if (workflow.workflow_variables !== undefined && workflow.workflow_variables !== null && workflow.workflow_variables.length > variableIndex) { + var vars = JSON.parse(JSON.stringify(workflow.workflow_variables)) + vars.splice(variableIndex, 1) + workflow.workflow_variables = vars + + console.log("Workflow after del: ", workflow) + + setWorkflow(workflow); + setUpdate(Math.random()); + } + } else if (type === "exec") { + if (workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > variableIndex) { + var vars = JSON.parse(JSON.stringify(workflow.execution_variables)) + vars.splice(variableIndex, 1) + workflow.execution_variables = vars + + console.log("Workflow after del: ", workflow) + + setWorkflow(workflow); + setUpdate(Math.random()); + } + } }; - const deleteExecutionVariable = (variableIndex) => { - if (workflow.execution_variables !== undefined && workflow.execution_variables !== null && workflow.execution_variables.length > variableIndex) { - workflow.execution_variables.splice(variableIndex, 1) - } + return ( +
+ { }}> +
+
+
{ + setVariableInfo({ + "name": variable.name, + "description": variable.description, + "value": variable.value, + "index": index, + }) - //workflow.execution_variables = workflow.execution_variables.filter( - // (data) => data.name !== variableName - //); - setWorkflow(workflow); - }; + if (type === "normal") { + setVariablesModalOpen(true); + } else if (type === "exec") { + setExecutionVariablesModalOpen(true); + } else { + console.log("Unknown type: ", type) + } + }} + > + Name: {variable.name} +
+
+ + + + { + setOpen(false); + setAnchorEl(null); + }} + > + { + setOpen(false); + setVariableInfo({ + "name": variable.name, + "description": variable.description, + "value": variable.value, + "index": index, + }) + if (type === "normal") { + setVariablesModalOpen(true); + } else if (type === "exec") { + setExecutionVariablesModalOpen(true); + } else { + console.log("Unknown type: ", type) + } + }} + key={"Edit"} + > + {"Edit"} + + { + deleteVariable(type, index); + setOpen(false); + }} + key={"Delete"} + > + {"Delete"} + + +
+
+ +
+ ) + } + + const VariablesView = () => { const variableScrollStyle = { margin: 15, overflow: "scroll", @@ -5642,108 +5773,20 @@ const AngularWorkflow = (defaultprops) => { target="_blank" style={{ textDecoration: "none", color: "#f85a3e" }} > - WORKFLOW variables? + Workflow variables? {workflow.workflow_variables === null ? null - : workflow.workflow_variables.map((variable, index) => { + : workflow.workflow_variables.map((variable, varindex) => { return ( -
- { }}> -
-
-
{ - setVariableInfo({ - "name": variable.name, - "description": variable.description, - "value": variable.value, - "index": index, - }) - setVariablesModalOpen(true); - }} - > - Name: {variable.name} -
-
- - - - { - setOpen(false); - setAnchorEl(null); - }} - > - { - setOpen(false); - setVariableInfo({ - "name": variable.name, - "description": variable.description, - "value": variable.value, - "index": index, - }) - setVariablesModalOpen(true); - }} - key={"Edit"} - > - {"Edit"} - - { - deleteVariable(index); - setOpen(false); - }} - key={"Delete"} - > - {"Delete"} - - -
-
- -
+ ); - })} + })} +