Made major changes to import/export and workflow saving
This commit is contained in:
@@ -2447,7 +2447,7 @@ func handleLogin(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write([]byte(loginData))
|
||||
return
|
||||
} else {
|
||||
log.Printf("User session is empty - create one!")
|
||||
log.Printf("[INFO] User session is empty - create one!")
|
||||
|
||||
sessionToken := uuid.NewV4().String()
|
||||
expiration := time.Now().Add(3600 * time.Second)
|
||||
@@ -5797,7 +5797,7 @@ func handleCloudExecutionOnprem(workflowId, startNode, executionSource, executio
|
||||
var execution ExecutionRequest
|
||||
err = json.Unmarshal([]byte(parsedArgument), &execution)
|
||||
if err == nil {
|
||||
log.Printf("FOUND EXEC %#v", execution)
|
||||
//log.Printf("[INFO] FOUND EXEC %#v", execution)
|
||||
if len(execution.ExecutionArgument) > 0 {
|
||||
parsedArgument := strings.Replace(string(execution.ExecutionArgument), "\\\"", "\"", -1)
|
||||
log.Printf("New exec argument: %s", execution.ExecutionArgument)
|
||||
@@ -5822,7 +5822,7 @@ func handleCloudExecutionOnprem(workflowId, startNode, executionSource, executio
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println(string(b))
|
||||
//log.Println(string(b))
|
||||
newRequest := &http.Request{
|
||||
URL: &url.URL{},
|
||||
Method: "POST",
|
||||
@@ -5864,8 +5864,8 @@ func handleCloudJob(job CloudSyncJob) error {
|
||||
}
|
||||
|
||||
emails, err := getOutlookEmail(outlookClient, maildata)
|
||||
log.Printf("EMAILS: %d", len(emails))
|
||||
log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err)
|
||||
//log.Printf("EMAILS: %d", len(emails))
|
||||
//log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err)
|
||||
|
||||
//type FullEmail struct {
|
||||
email := FullEmail{}
|
||||
@@ -5879,7 +5879,7 @@ func handleCloudJob(job CloudSyncJob) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("Should handle webhook for workflow %s with start node %s and data %s", job.PrimaryItemId, job.SecondaryItem, job.ThirdItem)
|
||||
log.Printf("[INFO] Should handle outlook webhook for workflow %s with start node %s and data of length %d", job.PrimaryItemId, job.SecondaryItem, len(job.ThirdItem))
|
||||
err = handleCloudExecutionOnprem(job.PrimaryItemId, job.SecondaryItem, "outlook", string(emailBytes))
|
||||
if err != nil {
|
||||
log.Printf("Failed executing workflow from cloud outlook hook: %s", err)
|
||||
@@ -5889,7 +5889,7 @@ func handleCloudJob(job CloudSyncJob) error {
|
||||
}
|
||||
} else if job.Type == "webhook" {
|
||||
if job.Action == "execute" {
|
||||
log.Printf("Should handle webhook for workflow %s with start node %s and data %s", job.PrimaryItemId, job.SecondaryItem, job.ThirdItem)
|
||||
log.Printf("Should handle normal webhook for workflow %s with start node %s and data %s", job.PrimaryItemId, job.SecondaryItem, job.ThirdItem)
|
||||
err := handleCloudExecutionOnprem(job.PrimaryItemId, job.SecondaryItem, "webhook", job.ThirdItem)
|
||||
if err != nil {
|
||||
log.Printf("Failed executing workflow from cloud hook: %s", err)
|
||||
@@ -6053,7 +6053,7 @@ func remoteOrgJobController(org Org, body []byte) error {
|
||||
}
|
||||
|
||||
if len(responseData.Jobs) > 0 {
|
||||
log.Printf("[INFO] Remote JOB ret: %s", string(body))
|
||||
//log.Printf("[INFO] Remote JOB ret: %s", string(body))
|
||||
log.Printf("Got job with reason %s and %d job(s)", responseData.Reason, len(responseData.Jobs))
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -126,7 +126,7 @@ func getOutlookEmail(client *http.Client, maildata MailData) ([]FullEmail, error
|
||||
//messageId := email.Resourcedata.ID
|
||||
//requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/me/%s", messageId)
|
||||
requestUrl := fmt.Sprintf("https://graph.microsoft.com/v1.0/%s", email.Resource)
|
||||
log.Printf("URL: %#v", requestUrl)
|
||||
//log.Printf("Outlook email URL: %#v", requestUrl)
|
||||
|
||||
ret, err := client.Get(requestUrl)
|
||||
if err != nil {
|
||||
@@ -141,8 +141,8 @@ func getOutlookEmail(client *http.Client, maildata MailData) ([]FullEmail, error
|
||||
}
|
||||
|
||||
//type FullEmail struct {
|
||||
log.Printf("[INFO] EMAIL Body: %s", string(body))
|
||||
log.Printf("[INFO] Status email: %d", ret.StatusCode)
|
||||
//log.Printf("[INFO] EMAIL Body: %s", string(body))
|
||||
//log.Printf("[INFO] Status email: %d", ret.StatusCode)
|
||||
if ret.StatusCode != 200 {
|
||||
return []FullEmail{}, err
|
||||
}
|
||||
@@ -724,7 +724,7 @@ func createOutlookSub(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("Failed finding org %s: %s", org.Id, err)
|
||||
return
|
||||
}
|
||||
log.Printf("[INFO] Starting cloud configuration TO STOP trigger %s in org %s", trigger.Id, org.Id)
|
||||
log.Printf("[INFO] Starting cloud configuration TO START trigger %s in org %s for workflow %s", trigger.Id, org.Id, trigger.WorkflowId)
|
||||
|
||||
action := CloudSyncJob{
|
||||
Type: "outlook",
|
||||
@@ -732,7 +732,7 @@ func createOutlookSub(resp http.ResponseWriter, request *http.Request) {
|
||||
OrgId: org.Id,
|
||||
PrimaryItemId: trigger.Id,
|
||||
SecondaryItem: trigger.Start,
|
||||
ThirdItem: trigger.WorkflowId,
|
||||
ThirdItem: workflowId,
|
||||
}
|
||||
|
||||
err = executeCloudAction(action, org.SyncConfig.Apikey)
|
||||
@@ -982,8 +982,8 @@ func handleOutlookCallback(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
emails, err := getOutlookEmail(outlookClient, maildata)
|
||||
log.Printf("EMAILS: %d", len(emails))
|
||||
log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err)
|
||||
log.Printf("[INFO] EMAILS: %d. If this is more than 1, please contact frikky@shuffler.io", len(emails))
|
||||
//log.Printf("INSIDE GET OUTLOOK EMAIL!: %#v, %s", emails, err)
|
||||
|
||||
//type FullEmail struct {
|
||||
email := FullEmail{}
|
||||
@@ -1087,14 +1087,14 @@ func handleOutlookSubRemoval(ctx context.Context, user User, workflowId, trigger
|
||||
}
|
||||
|
||||
if runningEnvironment != "cloud" {
|
||||
log.Printf("[INFO] SHOULD STOP OUTLOOK SUB ONPREM SYNC WITH CLOUD")
|
||||
log.Printf("[INFO] SHOULD STOP OUTLOOK SUB ONPREM SYNC WITH CLOUD for workflow ID %s", workflowId)
|
||||
org, err := getOrg(ctx, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("[INFO] Failed finding org %s during outlook removal: %s", org.Id, err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Stopping cloud configuration for trigger %s in org %s", trigger.Id, org.Id)
|
||||
log.Printf("[INFO] Stopping cloud configuration for trigger %s in org %s for workflow %s", trigger.Id, org.Id, trigger.WorkflowId)
|
||||
action := CloudSyncJob{
|
||||
Type: "outlook",
|
||||
Action: "stop",
|
||||
@@ -1128,7 +1128,7 @@ func handleOutlookSubRemoval(ctx context.Context, user User, workflowId, trigger
|
||||
if err == nil {
|
||||
for _, sub := range curSubscriptions.Value {
|
||||
if sub.NotificationURL == notificationURL {
|
||||
log.Printf("[INFO] Removing subscription %s from o365", sub.Id)
|
||||
log.Printf("[INFO] Removing subscription %s from o365 for workflow %s", sub.Id, workflowId)
|
||||
removeOutlookSubscription(outlookClient, sub.Id)
|
||||
}
|
||||
}
|
||||
|
||||
+442
-400
@@ -424,7 +424,7 @@ type Workflow struct {
|
||||
Value string `json:"value" datastore:"value,noindex"`
|
||||
} `json:"execution_variables,omitempty" datastore:"execution_variables"`
|
||||
ExecutionEnvironment string `json:"execution_environment" datastore:"execution_environment"`
|
||||
PreviouslySaved bool `json:"first_save" datastore:"first_save"`
|
||||
PreviouslySaved bool `json:"previously_saved" datastore:"first_save"`
|
||||
Categories Categories `json:"categories" datastore:"categories"`
|
||||
ExampleArgument string `json:"example_argument" datastore:"example_argument,noindex"`
|
||||
}
|
||||
@@ -1810,7 +1810,7 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
action.IsValid = true
|
||||
}
|
||||
|
||||
action.LargeImage = ""
|
||||
//action.LargeImage = ""
|
||||
newActions = append(newActions, action)
|
||||
}
|
||||
|
||||
@@ -1962,7 +1962,7 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Saved new workflow %s with name %s", workflow.ID, workflow.Name)
|
||||
log.Printf("[INFO] Saved new workflow %s with name %s", workflow.ID, workflow.Name)
|
||||
//memcacheName := fmt.Sprintf("%s_workflows", user.Username)
|
||||
//memcache.Delete(ctx, memcacheName)
|
||||
|
||||
@@ -2047,7 +2047,7 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
// FIXME - maybe delete workflow executions
|
||||
log.Printf("Should delete workflow %s", fileId)
|
||||
log.Printf("[INFO] Should have deleted workflow %s", fileId)
|
||||
err = DeleteKey(ctx, "workflow", fileId)
|
||||
if err != nil {
|
||||
log.Printf("Failed deleting key %s", fileId)
|
||||
@@ -2244,6 +2244,8 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
//log.Printf("SAVED: %#v", workflow.PreviouslySaved)
|
||||
|
||||
// FIXME - auth and check if they should have access
|
||||
if fileId != workflow.ID {
|
||||
log.Printf("Path and request ID are not matching: %s:%s.", fileId, workflow.ID)
|
||||
@@ -2258,7 +2260,7 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
if len(workflow.ExecutingOrg.Id) == 0 {
|
||||
log.Printf("Setting executing org for workflow")
|
||||
log.Printf("[INFO] Setting executing org for workflow")
|
||||
user.ActiveOrg.Users = []User{}
|
||||
workflow.ExecutingOrg = user.ActiveOrg
|
||||
}
|
||||
@@ -2281,18 +2283,23 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
if action.Environment == "" {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "An environment for %s is required"}`, action.Label)))
|
||||
return
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "An environment for %s is required"}`, action.Label)))
|
||||
return
|
||||
}
|
||||
action.IsValid = true
|
||||
}
|
||||
|
||||
// FIXME: Have a good way of tracking errors. ID's or similar.
|
||||
if !action.IsValid && len(action.Errors) > 0 {
|
||||
log.Printf("Node %s is invalid and needs to be remade. Errors: %s", action.Label, strings.Join(action.Errors, "\n"))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Node %s is invalid and needs to be remade."}`, action.Label)))
|
||||
return
|
||||
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Node %s is invalid and needs to be remade."}`, action.Label)))
|
||||
return
|
||||
}
|
||||
action.IsValid = true
|
||||
action.Errors = []string{}
|
||||
}
|
||||
@@ -2301,7 +2308,418 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
newActions = append(newActions, action)
|
||||
}
|
||||
|
||||
log.Printf("PRE SAVECHECK")
|
||||
newTriggers := []Trigger{}
|
||||
for _, trigger := range workflow.Triggers {
|
||||
log.Printf("[INFO] Trigger %s: %s", trigger.TriggerType, trigger.Status)
|
||||
|
||||
// Check if it's actually running
|
||||
// FIXME: Do this for other triggers too
|
||||
if trigger.TriggerType == "SCHEDULE" && trigger.Status != "uninitialized" {
|
||||
schedule, err := getSchedule(ctx, trigger.ID)
|
||||
if err != nil {
|
||||
trigger.Status = "stopped"
|
||||
} else if schedule.Id == "" {
|
||||
trigger.Status = "stopped"
|
||||
}
|
||||
} else if trigger.TriggerType == "SUBFLOW" {
|
||||
for index, param := range trigger.Parameters {
|
||||
if len(param.Value) == 0 && param.Name != "argument" {
|
||||
//log.Printf("Param: %#v", param)
|
||||
if param.Name == "user_apikey" {
|
||||
apikey := ""
|
||||
if len(user.ApiKey) > 0 {
|
||||
apikey = user.ApiKey
|
||||
} else {
|
||||
user, err = generateApikey(ctx, user)
|
||||
if err != nil {
|
||||
workflow.IsValid = false
|
||||
workflow.Errors = []string{"Trigger is missing a parameter: %s", param.Name}
|
||||
|
||||
log.Printf("No type specified for user input node")
|
||||
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Trigger %s is missing the parameter %s"}`, trigger.Label, param.Name)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
apikey = user.ApiKey
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Set apikey in subflow trigger for user during save")
|
||||
trigger.Parameters[index].Value = apikey
|
||||
} else {
|
||||
|
||||
workflow.IsValid = false
|
||||
workflow.Errors = []string{"Trigger is missing a parameter: %s", param.Name}
|
||||
|
||||
log.Printf("No type specified for user input node")
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Trigger %s is missing the parameter %s"}`, trigger.Label, param.Name)))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if trigger.TriggerType == "WEBHOOK" && trigger.Status != "uninitialized" {
|
||||
hook, err := getHook(ctx, trigger.ID)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting webhook")
|
||||
trigger.Status = "stopped"
|
||||
} else if hook.Id == "" {
|
||||
trigger.Status = "stopped"
|
||||
}
|
||||
} else if trigger.TriggerType == "USERINPUT" {
|
||||
// E.g. check email
|
||||
sms := ""
|
||||
email := ""
|
||||
triggerType := ""
|
||||
triggerInformation := ""
|
||||
for _, item := range trigger.Parameters {
|
||||
if item.Name == "alertinfo" {
|
||||
triggerInformation = item.Value
|
||||
} else if item.Name == "type" {
|
||||
triggerType = item.Value
|
||||
} else if item.Name == "email" {
|
||||
email = item.Value
|
||||
} else if item.Name == "sms" {
|
||||
sms = item.Value
|
||||
}
|
||||
}
|
||||
|
||||
if len(triggerType) == 0 {
|
||||
log.Printf("No type specified for user input node")
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No contact option specified in user input"}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This is not the right time to send them, BUT it's well served for testing. Save -> send email / sms
|
||||
_ = triggerInformation
|
||||
if strings.Contains(triggerType, "email") {
|
||||
if email == "test@test.com" {
|
||||
log.Printf("Email isn't specified during save.")
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Email field in user input can't be empty"}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Should send email to %s during execution.", email)
|
||||
}
|
||||
if strings.Contains(triggerType, "sms") {
|
||||
if sms == "0000000" {
|
||||
log.Printf("Email isn't specified during save.")
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "SMS field in user input can't be empty"}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Should send SMS to %s during execution.", sms)
|
||||
}
|
||||
}
|
||||
|
||||
//log.Println("TRIGGERS")
|
||||
allNodes = append(allNodes, trigger.ID)
|
||||
newTriggers = append(newTriggers, trigger)
|
||||
}
|
||||
|
||||
workflow.Triggers = newTriggers
|
||||
|
||||
if len(workflow.Actions) == 0 {
|
||||
workflow.Actions = []Action{}
|
||||
}
|
||||
if len(workflow.Branches) == 0 {
|
||||
workflow.Branches = []Branch{}
|
||||
}
|
||||
if len(workflow.Triggers) == 0 {
|
||||
workflow.Triggers = []Trigger{}
|
||||
}
|
||||
if len(workflow.Errors) == 0 {
|
||||
workflow.Errors = []string{}
|
||||
}
|
||||
|
||||
//log.Printf("PRE VARIABLES")
|
||||
for _, variable := range workflow.WorkflowVariables {
|
||||
if len(variable.Value) == 0 {
|
||||
log.Printf("[WARNING] Variable %s is empty!", variable.Name)
|
||||
workflow.Errors = append(workflow.Errors, fmt.Sprintf("Variable %s is empty!", variable.Name))
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Variable %s can't be empty"}`, variable.Name)))
|
||||
//return
|
||||
}
|
||||
}
|
||||
|
||||
if len(workflow.ExecutionVariables) > 0 {
|
||||
log.Printf("[INFO] Found %d execution variable(s)", len(workflow.ExecutionVariables))
|
||||
}
|
||||
|
||||
if len(workflow.WorkflowVariables) > 0 {
|
||||
log.Printf("[INFO] Found %d workflow variable(s)", len(workflow.WorkflowVariables))
|
||||
}
|
||||
|
||||
// FIXME - do actual checks ROFL
|
||||
// FIXME - minor issues with e.g. hello world and self.console_logger
|
||||
// Nodechecks
|
||||
foundNodes := []string{}
|
||||
for _, node := range allNodes {
|
||||
for _, branch := range workflow.Branches {
|
||||
//log.Println("branch")
|
||||
//log.Println(node)
|
||||
//log.Println(branch.DestinationID)
|
||||
if node == branch.DestinationID || node == branch.SourceID {
|
||||
foundNodes = append(foundNodes, node)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - append all nodes (actions, triggers etc) to one single array here
|
||||
//log.Printf("PRE VARIABLES")
|
||||
if len(foundNodes) != len(allNodes) || len(workflow.Actions) <= 0 {
|
||||
// This shit takes a few seconds lol
|
||||
if !workflow.IsValid {
|
||||
oldworkflow, err := getWorkflow(ctx, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Workflow %s doesn't exist - oldworkflow.", fileId)
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Item already exists."}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
oldworkflow.IsValid = false
|
||||
err = setWorkflow(ctx, *oldworkflow, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Failed saving workflow to database: %s", err)
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - more checks here - force reload of data or something
|
||||
//if len(allNodes) == 0 {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "Please insert a node"}`))
|
||||
// return
|
||||
//}
|
||||
|
||||
// Allowed with only a start node
|
||||
//if len(allNodes) != 1 {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "There are nodes with no branches"}`))
|
||||
// return
|
||||
//}
|
||||
}
|
||||
|
||||
// FIXME - might be a sploit to run someone elses app if getAllWorkflowApps
|
||||
// doesn't check sharing=true
|
||||
// Have to do it like this to add the user's apps
|
||||
//log.Println("Apps set starting")
|
||||
//log.Printf("EXIT ON ERROR: %#v", workflow.Configuration.ExitOnError)
|
||||
//workflowapps, apperr := getAllWorkflowApps(ctx, 500)
|
||||
|
||||
// Started getting the single apps, but if it's weird, this is faster
|
||||
// 1. Check workflow.Start
|
||||
// 2. Check if any node has "isStartnode"
|
||||
if len(workflow.Actions) > 0 {
|
||||
index := -1
|
||||
for indexFound, action := range workflow.Actions {
|
||||
//log.Println("Apps set done")
|
||||
if workflow.Start == action.ID {
|
||||
index = indexFound
|
||||
}
|
||||
}
|
||||
|
||||
if index >= 0 {
|
||||
workflow.Actions[0].IsStartNode = true
|
||||
} else {
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "You need to set a startnode."}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allAuths, err := getAllWorkflowAppAuth(ctx, user.ActiveOrg.Id)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all apps: %s", userErr)
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Check every app action and param to see whether they exist
|
||||
//log.Printf("PRE ACTIONS 2")
|
||||
newActions = []Action{}
|
||||
for _, action := range workflow.Actions {
|
||||
reservedApps := []string{
|
||||
"0ca8887e-b4af-4e3e-887c-87e9d3bc3d3e",
|
||||
}
|
||||
|
||||
//log.Printf("%s Action execution var: %s", action.Label, action.ExecutionVariable.Name)
|
||||
|
||||
builtin := false
|
||||
for _, id := range reservedApps {
|
||||
if id == action.AppID {
|
||||
builtin = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check auth
|
||||
// 1. Find the auth in question
|
||||
// 2. Update the node and workflow info in the auth
|
||||
// 3. Get the values in the auth and add them to the action values
|
||||
if len(action.AuthenticationId) > 0 {
|
||||
authFound := false
|
||||
for _, auth := range allAuths {
|
||||
if auth.Id == action.AuthenticationId {
|
||||
authFound = true
|
||||
|
||||
// Updates the auth item itself IF necessary
|
||||
go updateAppAuth(auth, workflow.ID, action.ID, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !authFound {
|
||||
log.Printf("App auth %s doesn't exist. Setting error", action.AuthenticationId)
|
||||
workflow.Errors = append(workflow.Errors, fmt.Sprintf("App authentication for %s doesn't exist!", action.AppName))
|
||||
workflow.IsValid = false
|
||||
|
||||
action.Errors = append(action.Errors, "App authentication doesn't exist")
|
||||
action.IsValid = false
|
||||
action.AuthenticationId = ""
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "App auth %s doesn't exist"}`, action.AuthenticationId)))
|
||||
//return
|
||||
}
|
||||
}
|
||||
|
||||
if builtin {
|
||||
newActions = append(newActions, action)
|
||||
} else {
|
||||
curapp := WorkflowApp{}
|
||||
// FIXME - can this work with ONLY AppID?
|
||||
for _, app := range workflowapps {
|
||||
if app.ID == action.AppID {
|
||||
curapp = app
|
||||
break
|
||||
}
|
||||
|
||||
// Has to NOT be generated
|
||||
if app.Name == action.AppName && app.AppVersion == action.AppVersion {
|
||||
curapp = app
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the whole app is valid
|
||||
if curapp.Name != action.AppName {
|
||||
workflow.Errors = append(workflow.Errors, fmt.Sprintf("App %s doesn't exist", action.AppName))
|
||||
action.Errors = append(action.Errors, "This app doesn't exist.")
|
||||
action.IsValid = false
|
||||
workflow.IsValid = false
|
||||
|
||||
// Append with errors
|
||||
newActions = append(newActions, action)
|
||||
log.Printf("App %s doesn't exist. Adding as error.", action.AppName)
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "App %s doesn't exist"}`, action.AppName)))
|
||||
//return
|
||||
} else {
|
||||
// Check tosee if the appaction is valid
|
||||
curappaction := WorkflowAppAction{}
|
||||
for _, curAction := range curapp.Actions {
|
||||
if action.Name == curAction.Name {
|
||||
curappaction = curAction
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the action is valid
|
||||
if curappaction.Name != action.Name {
|
||||
log.Printf("[ERROR] Action %s in app %s doesn't exist.", action.Name, curapp.Name)
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Action %s in app %s doesn't exist"}`, action.Name, curapp.Name)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - check all parameters to see if they're valid
|
||||
// Includes checking required fields
|
||||
|
||||
newParams := []WorkflowAppActionParameter{}
|
||||
for _, param := range curappaction.Parameters {
|
||||
found := false
|
||||
|
||||
// Handles check for parameter exists + value not empty in used fields
|
||||
for _, actionParam := range action.Parameters {
|
||||
if actionParam.Name == param.Name {
|
||||
found = true
|
||||
|
||||
if actionParam.Value == "" && actionParam.Variant == "STATIC_VALUE" && actionParam.Required == true {
|
||||
log.Printf("[WARNING] Appaction %s with required param '%s' is empty. Can't save.", action.Name, param.Name)
|
||||
//if workflow.PreviouslySaved {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Appaction %s in app %s with required param '%s' is empty.", "node_id": "%s"}`, action.Name, action.AppName, param.Name, action.ID)))
|
||||
// return
|
||||
//} else {
|
||||
|
||||
thisError := fmt.Sprintf("Missing parameter %s", param.Name)
|
||||
action.Errors = append(action.Errors, thisError)
|
||||
workflow.Errors = append(workflow.Errors, thisError)
|
||||
action.IsValid = false
|
||||
}
|
||||
|
||||
if actionParam.Variant == "" {
|
||||
actionParam.Variant = "STATIC_VALUE"
|
||||
}
|
||||
|
||||
newParams = append(newParams, actionParam)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Handles check for required params
|
||||
if !found && param.Required {
|
||||
log.Printf("Appaction %s with required param %s doesn't exist.", action.Name, param.Name)
|
||||
thisError := fmt.Sprintf("Parameter %s is required", param.Name)
|
||||
action.Errors = append(action.Errors, thisError)
|
||||
|
||||
workflow.Errors = append(workflow.Errors, thisError)
|
||||
action.IsValid = false
|
||||
//newActions = append(newActions, action)
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Appaction %s with required param '%s' is empty."}`, action.Name, param.Name)))
|
||||
//return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
action.Parameters = newParams
|
||||
newActions = append(newActions, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//log.Printf("PRE SAVECHECK")
|
||||
if !workflow.PreviouslySaved {
|
||||
log.Printf("[WORKFLOW INIT] NOT PREVIOUSLY SAVED - SET ACTION AUTH!")
|
||||
//AuthenticationId string `json:"authentication_id,omitempty" datastore:"authentication_id"`
|
||||
@@ -2429,7 +2847,7 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
newActions = actionFixing
|
||||
} else {
|
||||
log.Printf("Err: %s - %s", err, apperr)
|
||||
log.Printf("FirstSave error: %s - %s", err, apperr)
|
||||
//workflowapps, apperr := getAllWorkflowApps(ctx, 100)
|
||||
//allAuths, err := getAllWorkflowAppAuth(ctx, user.ActiveOrg.Id)
|
||||
}
|
||||
@@ -2437,386 +2855,8 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
workflow.PreviouslySaved = true
|
||||
}
|
||||
|
||||
log.Printf("PRE TRIGGERS")
|
||||
workflow.Actions = newActions
|
||||
newTriggers := []Trigger{}
|
||||
for _, trigger := range workflow.Triggers {
|
||||
log.Printf("[INFO] Trigger %s: %s", trigger.TriggerType, trigger.Status)
|
||||
|
||||
// Check if it's actually running
|
||||
// FIXME: Do this for other triggers too
|
||||
if trigger.TriggerType == "SCHEDULE" && trigger.Status != "uninitialized" {
|
||||
schedule, err := getSchedule(ctx, trigger.ID)
|
||||
if err != nil {
|
||||
trigger.Status = "stopped"
|
||||
} else if schedule.Id == "" {
|
||||
trigger.Status = "stopped"
|
||||
}
|
||||
} else if trigger.TriggerType == "SUBFLOW" {
|
||||
for index, param := range trigger.Parameters {
|
||||
if len(param.Value) == 0 && param.Name != "argument" {
|
||||
log.Printf("Param: %#v", param)
|
||||
if param.Name == "user_apikey" {
|
||||
apikey := ""
|
||||
if len(user.ApiKey) > 0 {
|
||||
apikey = user.ApiKey
|
||||
} else {
|
||||
user, err = generateApikey(ctx, user)
|
||||
if err != nil {
|
||||
workflow.IsValid = false
|
||||
workflow.Errors = []string{"Trigger is missing a parameter: %s", param.Name}
|
||||
|
||||
log.Printf("No type specified for user input node")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Trigger %s is missing the parameter %s"}`, trigger.Label, param.Name)))
|
||||
return
|
||||
}
|
||||
|
||||
apikey = user.ApiKey
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Set apikey in subflow trigger for user during save")
|
||||
trigger.Parameters[index].Value = apikey
|
||||
} else {
|
||||
|
||||
workflow.IsValid = false
|
||||
workflow.Errors = []string{"Trigger is missing a parameter: %s", param.Name}
|
||||
|
||||
log.Printf("No type specified for user input node")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Trigger %s is missing the parameter %s"}`, trigger.Label, param.Name)))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if trigger.TriggerType == "WEBHOOK" && trigger.Status != "uninitialized" {
|
||||
hook, err := getHook(ctx, trigger.ID)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting webhook")
|
||||
trigger.Status = "stopped"
|
||||
} else if hook.Id == "" {
|
||||
trigger.Status = "stopped"
|
||||
}
|
||||
} else if trigger.TriggerType == "USERINPUT" {
|
||||
// E.g. check email
|
||||
sms := ""
|
||||
email := ""
|
||||
triggerType := ""
|
||||
triggerInformation := ""
|
||||
for _, item := range trigger.Parameters {
|
||||
if item.Name == "alertinfo" {
|
||||
triggerInformation = item.Value
|
||||
} else if item.Name == "type" {
|
||||
triggerType = item.Value
|
||||
} else if item.Name == "email" {
|
||||
email = item.Value
|
||||
} else if item.Name == "sms" {
|
||||
sms = item.Value
|
||||
}
|
||||
}
|
||||
|
||||
if len(triggerType) == 0 {
|
||||
log.Printf("No type specified for user input node")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "No contact option specified in user input"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: This is not the right time to send them, BUT it's well served for testing. Save -> send email / sms
|
||||
_ = triggerInformation
|
||||
if strings.Contains(triggerType, "email") {
|
||||
if email == "test@test.com" {
|
||||
log.Printf("Email isn't specified during save.")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Email field in user input can't be empty"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Should send email to %s during execution.", email)
|
||||
}
|
||||
if strings.Contains(triggerType, "sms") {
|
||||
if sms == "0000000" {
|
||||
log.Printf("Email isn't specified during save.")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "SMS field in user input can't be empty"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Should send SMS to %s during execution.", sms)
|
||||
}
|
||||
}
|
||||
|
||||
//log.Println("TRIGGERS")
|
||||
allNodes = append(allNodes, trigger.ID)
|
||||
newTriggers = append(newTriggers, trigger)
|
||||
}
|
||||
|
||||
workflow.Triggers = newTriggers
|
||||
|
||||
//log.Printf("PRE VARIABLES")
|
||||
for _, variable := range workflow.WorkflowVariables {
|
||||
if len(variable.Value) == 0 {
|
||||
log.Printf("Can't have an empty variable: %s", variable.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Variable %s can't be empty"}`, variable.Name)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if len(workflow.Actions) == 0 {
|
||||
workflow.Actions = []Action{}
|
||||
}
|
||||
if len(workflow.Branches) == 0 {
|
||||
workflow.Branches = []Branch{}
|
||||
}
|
||||
if len(workflow.Triggers) == 0 {
|
||||
workflow.Triggers = []Trigger{}
|
||||
}
|
||||
if len(workflow.Errors) == 0 {
|
||||
workflow.Errors = []string{}
|
||||
}
|
||||
|
||||
if len(workflow.ExecutionVariables) > 0 {
|
||||
log.Printf("[INFO] Found %d execution variable(s)", len(workflow.ExecutionVariables))
|
||||
}
|
||||
|
||||
if len(workflow.WorkflowVariables) > 0 {
|
||||
log.Printf("[INFO] Found %d workflow variable(s)", len(workflow.WorkflowVariables))
|
||||
}
|
||||
|
||||
// FIXME - do actual checks ROFL
|
||||
// FIXME - minor issues with e.g. hello world and self.console_logger
|
||||
// Nodechecks
|
||||
foundNodes := []string{}
|
||||
for _, node := range allNodes {
|
||||
for _, branch := range workflow.Branches {
|
||||
//log.Println("branch")
|
||||
//log.Println(node)
|
||||
//log.Println(branch.DestinationID)
|
||||
if node == branch.DestinationID || node == branch.SourceID {
|
||||
foundNodes = append(foundNodes, node)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - append all nodes (actions, triggers etc) to one single array here
|
||||
//log.Printf("PRE VARIABLES")
|
||||
if len(foundNodes) != len(allNodes) || len(workflow.Actions) <= 0 {
|
||||
// This shit takes a few seconds lol
|
||||
if !workflow.IsValid {
|
||||
oldworkflow, err := getWorkflow(ctx, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Workflow %s doesn't exist - oldworkflow.", fileId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Item already exists."}`))
|
||||
return
|
||||
}
|
||||
|
||||
oldworkflow.IsValid = false
|
||||
err = setWorkflow(ctx, *oldworkflow, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Failed saving workflow to database: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME - more checks here - force reload of data or something
|
||||
//if len(allNodes) == 0 {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "Please insert a node"}`))
|
||||
// return
|
||||
//}
|
||||
|
||||
// Allowed with only a start node
|
||||
//if len(allNodes) != 1 {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "There are nodes with no branches"}`))
|
||||
// return
|
||||
//}
|
||||
}
|
||||
|
||||
// FIXME - might be a sploit to run someone elses app if getAllWorkflowApps
|
||||
// doesn't check sharing=true
|
||||
// Have to do it like this to add the user's apps
|
||||
//log.Println("Apps set starting")
|
||||
//log.Printf("EXIT ON ERROR: %#v", workflow.Configuration.ExitOnError)
|
||||
//workflowapps, apperr := getAllWorkflowApps(ctx, 500)
|
||||
|
||||
// Started getting the single apps, but if it's weird, this is faster
|
||||
// 1. Check workflow.Start
|
||||
// 2. Check if any node has "isStartnode"
|
||||
if len(workflow.Actions) > 0 {
|
||||
index := -1
|
||||
for indexFound, action := range workflow.Actions {
|
||||
//log.Println("Apps set done")
|
||||
if workflow.Start == action.ID {
|
||||
index = indexFound
|
||||
}
|
||||
}
|
||||
|
||||
if index >= 0 {
|
||||
workflow.Actions[0].IsStartNode = true
|
||||
} else {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "You need to set a startnode."}`)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
allAuths, err := getAllWorkflowAppAuth(ctx, user.ActiveOrg.Id)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all apps: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Check every app action and param to see whether they exist
|
||||
//log.Printf("PRE ACTIONS 2")
|
||||
newActions = []Action{}
|
||||
for _, action := range workflow.Actions {
|
||||
reservedApps := []string{
|
||||
"0ca8887e-b4af-4e3e-887c-87e9d3bc3d3e",
|
||||
}
|
||||
|
||||
//log.Printf("%s Action execution var: %s", action.Label, action.ExecutionVariable.Name)
|
||||
|
||||
builtin := false
|
||||
for _, id := range reservedApps {
|
||||
if id == action.AppID {
|
||||
builtin = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check auth
|
||||
// 1. Find the auth in question
|
||||
// 2. Update the node and workflow info in the auth
|
||||
// 3. Get the values in the auth and add them to the action values
|
||||
if len(action.AuthenticationId) > 0 {
|
||||
authFound := false
|
||||
for _, auth := range allAuths {
|
||||
if auth.Id == action.AuthenticationId {
|
||||
authFound = true
|
||||
|
||||
// Updates the auth item itself IF necessary
|
||||
go updateAppAuth(auth, workflow.ID, action.ID, true)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !authFound {
|
||||
log.Printf("App auth %s doesn't exist. Setting error", action.AuthenticationId)
|
||||
workflow.Errors = append(workflow.Errors, fmt.Sprintf("App authentication for %s doesn't exist!", action.AppName))
|
||||
workflow.IsValid = false
|
||||
|
||||
action.Errors = append(action.Errors, "App authentication doesn't exist")
|
||||
action.IsValid = false
|
||||
action.AuthenticationId = ""
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "App auth %s doesn't exist"}`, action.AuthenticationId)))
|
||||
//return
|
||||
}
|
||||
}
|
||||
|
||||
if builtin {
|
||||
newActions = append(newActions, action)
|
||||
} else {
|
||||
curapp := WorkflowApp{}
|
||||
// FIXME - can this work with ONLY AppID?
|
||||
for _, app := range workflowapps {
|
||||
if app.ID == action.AppID {
|
||||
curapp = app
|
||||
break
|
||||
}
|
||||
|
||||
// Has to NOT be generated
|
||||
if app.Name == action.AppName && app.AppVersion == action.AppVersion {
|
||||
curapp = app
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the whole app is valid
|
||||
if curapp.Name != action.AppName {
|
||||
workflow.Errors = append(workflow.Errors, fmt.Sprintf("App %s doesn't exist", action.AppName))
|
||||
action.Errors = append(action.Errors, "This app doesn't exist.")
|
||||
action.IsValid = false
|
||||
workflow.IsValid = false
|
||||
|
||||
// Append with errors
|
||||
newActions = append(newActions, action)
|
||||
log.Printf("App %s doesn't exist. Adding as error.", action.AppName)
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "App %s doesn't exist"}`, action.AppName)))
|
||||
//return
|
||||
} else {
|
||||
// Check tosee if the appaction is valid
|
||||
curappaction := WorkflowAppAction{}
|
||||
for _, curAction := range curapp.Actions {
|
||||
if action.Name == curAction.Name {
|
||||
curappaction = curAction
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the action is valid
|
||||
if curappaction.Name != action.Name {
|
||||
log.Printf("[ERROR] Action %s in app %s doesn't exist.", action.Name, curapp.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Action %s in app %s doesn't exist"}`, action.Name, curapp.Name)))
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME - check all parameters to see if they're valid
|
||||
// Includes checking required fields
|
||||
|
||||
newParams := []WorkflowAppActionParameter{}
|
||||
for _, param := range curappaction.Parameters {
|
||||
found := false
|
||||
|
||||
// Handles check for parameter exists + value not empty in used fields
|
||||
for _, actionParam := range action.Parameters {
|
||||
if actionParam.Name == param.Name {
|
||||
found = true
|
||||
|
||||
if actionParam.Value == "" && actionParam.Variant == "STATIC_VALUE" && actionParam.Required == true {
|
||||
log.Printf("Appaction %s with required param '%s' is empty.", action.Name, param.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Appaction %s with required param '%s' is empty."}`, action.Name, param.Name)))
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
if actionParam.Variant == "" {
|
||||
actionParam.Variant = "STATIC_VALUE"
|
||||
}
|
||||
|
||||
newParams = append(newParams, actionParam)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Handles check for required params
|
||||
if !found && param.Required {
|
||||
log.Printf("Appaction %s with required param %s doesn't exist.", action.Name, param.Name)
|
||||
action.Errors = append(action.Errors, "Parameter %s is required", param.Name)
|
||||
//newActions = append(newActions, action)
|
||||
//resp.WriteHeader(401)
|
||||
//resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Appaction %s with required param '%s' is empty."}`, action.Name, param.Name)))
|
||||
//return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
action.Parameters = newParams
|
||||
newActions = append(newActions, action)
|
||||
}
|
||||
}
|
||||
}
|
||||
//log.Printf("PRE TRIGGERS")
|
||||
//workflow.Actions = newActions
|
||||
|
||||
workflow.Actions = newActions
|
||||
workflow.IsValid = true
|
||||
@@ -2834,9 +2874,11 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
err = setWorkflow(ctx, workflow, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Failed saving workflow to database: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
if workflow.PreviouslySaved {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
totalOldActions := len(tmpworkflow.Actions)
|
||||
@@ -3235,7 +3277,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
}
|
||||
|
||||
// This one doesn't really matter.
|
||||
log.Printf("[INFO] Running POST execution with body of length %d", len(string(body)))
|
||||
log.Printf("[INFO] Running POST execution with body of length %d for workflow %s", len(string(body)), workflowExecution.Workflow.ID)
|
||||
|
||||
if len(body) >= 4 {
|
||||
if body[0] == 34 && body[len(body)-1] == 34 {
|
||||
@@ -3446,7 +3488,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
log.Printf("[INFO] No execution source (trigger) specified. Setting to default")
|
||||
workflowExecution.ExecutionSource = "default"
|
||||
} else {
|
||||
log.Printf("[INFO] Execution source is %s for execution ID %s", workflowExecution.ExecutionSource, workflowExecution.ExecutionId)
|
||||
log.Printf("[INFO] Execution source is %s for execution ID %s in workflow %s", workflowExecution.ExecutionSource, workflowExecution.ExecutionId, workflowExecution.Workflow.ID)
|
||||
}
|
||||
|
||||
workflowExecution.ExecutionVariables = workflow.ExecutionVariables
|
||||
@@ -3648,7 +3690,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
|
||||
var allEnvs []Environment
|
||||
if len(workflowExecution.ExecutionOrg) > 0 {
|
||||
log.Printf("[INFO] Executing ORG: %s", workflowExecution.ExecutionOrg)
|
||||
//log.Printf("[INFO] Executing ORG: %s", workflowExecution.ExecutionOrg)
|
||||
|
||||
allEnvironments, err := getEnvironments(ctx, workflowExecution.ExecutionOrg)
|
||||
if err != nil {
|
||||
@@ -3751,7 +3793,7 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
// FIXME - tmp name based on future companyname-companyId
|
||||
// This leads to issues with overlaps. Should set limits and such instead
|
||||
for _, environment := range environments {
|
||||
log.Printf("[INFO] Execution: %s should execute onprem with execution environment \"%s\"", workflowExecution.ExecutionId, environment)
|
||||
log.Printf("[INFO] Execution: %s should execute onprem with execution environment \"%s\". Workflow: %s", workflowExecution.ExecutionId, environment, workflowExecution.Workflow.ID)
|
||||
|
||||
executionRequest := ExecutionRequest{
|
||||
ExecutionId: workflowExecution.ExecutionId,
|
||||
|
||||
@@ -780,6 +780,11 @@ const AngularWorkflow = (props) => {
|
||||
workflow.isValid = true
|
||||
}
|
||||
|
||||
for (var key in workflow.errors) {
|
||||
//console.log("Error: ", workflow.errors[key])
|
||||
alert.info(workflow.errors[key])
|
||||
}
|
||||
|
||||
setWorkflow(workflow)
|
||||
}
|
||||
//alert.success("Successfully saved workflow")
|
||||
@@ -5131,7 +5136,7 @@ const AngularWorkflow = (props) => {
|
||||
<div style={{marginTop: "20px", marginBottom: "7px", display: "flex"}}>
|
||||
<div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/>
|
||||
<div style={{flex: "10"}}>
|
||||
<b>Login to either: </b>
|
||||
<b>Login to either </b>
|
||||
</div>
|
||||
</div>
|
||||
{outlookButton}
|
||||
|
||||
@@ -12,6 +12,7 @@ import Dropzone from '../components/Dropzone';
|
||||
import {Link} from 'react-router-dom';
|
||||
import { useAlert } from "react-alert";
|
||||
import ChipInput from 'material-ui-chip-input'
|
||||
import uuid from "uuid"
|
||||
|
||||
const inputColor = "#383B40"
|
||||
const surfaceColor = "#27292D"
|
||||
@@ -92,31 +93,6 @@ const Workflows = (props) => {
|
||||
}
|
||||
})
|
||||
|
||||
// DEBUG HERE
|
||||
const handleClickLogout = () => {
|
||||
//console.log("Cookies: ", cookies)
|
||||
//console.log("SHOULD LOG OUT")
|
||||
//console.log(isLoggedIn)
|
||||
|
||||
// Don't really care about the logout
|
||||
//fetch(globalUrl+"/api/v1/logout", {
|
||||
// credentials: "include",
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// },
|
||||
//})
|
||||
//.then(() => {
|
||||
// // Log out anyway
|
||||
// removeCookie("session_token", {path: "/"})
|
||||
// //window.location = "/login"
|
||||
//})
|
||||
//.catch(error => {
|
||||
// console.log(error)
|
||||
// removeCookie("session_token", {path: "/"})
|
||||
//});
|
||||
}
|
||||
|
||||
const deleteModal = deleteModalOpen ?
|
||||
<Dialog
|
||||
open={deleteModalOpen}
|
||||
@@ -231,21 +207,21 @@ const Workflows = (props) => {
|
||||
setSelectedExecution({})
|
||||
setWorkflowExecutions([])
|
||||
|
||||
console.log(responseJson)
|
||||
|
||||
if (responseJson !== undefined) {
|
||||
setWorkflows(responseJson)
|
||||
setWorkflowDone(true)
|
||||
} else {
|
||||
if (isLoggedIn) {
|
||||
alert.error("An error occurred while loading workflows")
|
||||
} else {
|
||||
handleClickLogout()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (responseJson.length > 0){
|
||||
setSelectedWorkflow(responseJson[0])
|
||||
//setSelectedWorkflow(responseJson[0])
|
||||
//getWorkflowExecution(responseJson[0].id)
|
||||
}
|
||||
})
|
||||
@@ -417,12 +393,10 @@ const Workflows = (props) => {
|
||||
|
||||
const exportWorkflow = (data) => {
|
||||
console.log("export")
|
||||
let dataStr = JSON.stringify(data)
|
||||
|
||||
let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
|
||||
let exportFileDefaultName = data.name+'.json';
|
||||
|
||||
data["owner"] = ""
|
||||
console.log(data)
|
||||
if (data.triggers !== null && data.triggers !== undefined) {
|
||||
for (var key in data.triggers) {
|
||||
const trigger = data.triggers[key]
|
||||
@@ -435,6 +409,22 @@ const Workflows = (props) => {
|
||||
if (trigger.status == "running") {
|
||||
trigger.status = "stopped"
|
||||
}
|
||||
|
||||
const newId = uuid.v4()
|
||||
for (var branchkey in data.branches) {
|
||||
const branch = data.branches[branchkey]
|
||||
if (branch.source_id === trigger.id) {
|
||||
console.log("CHANGING SOURCE ID")
|
||||
branch.source_id = newId
|
||||
}
|
||||
|
||||
if (branch.destination_id === trigger.id) {
|
||||
console.log("CHANGING DESTINATION ID")
|
||||
branch.destination_id = newId
|
||||
}
|
||||
}
|
||||
|
||||
trigger.id = newId
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,9 +435,31 @@ const Workflows = (props) => {
|
||||
for (var subkey in data.actions[key].parameters) {
|
||||
const param = data.actions[key].parameters[subkey]
|
||||
if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret")) {
|
||||
param.value = ""
|
||||
// FIXME: This may be a vuln if api-keys are generated that start with $
|
||||
if (param.value.startsWith("$")) {
|
||||
console.log("Skipping field, as it's referencing a variable")
|
||||
} else {
|
||||
param.value = ""
|
||||
param.is_valid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newId = uuid.v4()
|
||||
for (var branchkey in data.branches) {
|
||||
const branch = data.branches[branchkey]
|
||||
if (branch.source_id === data.actions[key].id) {
|
||||
console.log("CHANGING SOURCE ID IN ACTION")
|
||||
branch.source_id = newId
|
||||
}
|
||||
|
||||
if (branch.destination_id === data.actions[key].id) {
|
||||
console.log("CHANGING DESTINATION ID IN ACTION")
|
||||
branch.destination_id = newId
|
||||
}
|
||||
}
|
||||
|
||||
data.actions[key].id = newId
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,6 +468,7 @@ const Workflows = (props) => {
|
||||
const param = data.workflow_variables[key]
|
||||
if (param.name.includes("key") || param.name.includes("user") || param.name.includes("pass") || param.name.includes("api") || param.name.includes("auth") || param.name.includes("secret")) {
|
||||
param.value = ""
|
||||
param.is_valid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,9 +478,16 @@ const Workflows = (props) => {
|
||||
|
||||
data["org"] = []
|
||||
data["org_id"] = ""
|
||||
data["execution_org"] = {}
|
||||
|
||||
// These are backwards.. True = saved before. Very confuse.
|
||||
data["previously_saved"] = false
|
||||
data["first_save"] = false
|
||||
data.execution_org = {"id": ""}
|
||||
console.log(data)
|
||||
|
||||
let dataStr = JSON.stringify(data)
|
||||
let dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
|
||||
let linkElement = document.createElement('a');
|
||||
linkElement.setAttribute('href', dataUri);
|
||||
linkElement.setAttribute('download', exportFileDefaultName);
|
||||
@@ -477,9 +497,9 @@ const Workflows = (props) => {
|
||||
const copyWorkflow = (data) => {
|
||||
data = JSON.parse(JSON.stringify(data))
|
||||
alert.success("Copying workflow "+data.name)
|
||||
console.log("data: ", data)
|
||||
data.id = ""
|
||||
data.name = data.name+"_copy"
|
||||
console.log("COPIED DATA: ", data)
|
||||
//return
|
||||
|
||||
fetch(globalUrl+"/api/v1/workflows", {
|
||||
@@ -503,7 +523,7 @@ const Workflows = (props) => {
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -571,6 +591,7 @@ const Workflows = (props) => {
|
||||
}
|
||||
|
||||
const imgSize = 25
|
||||
//console.log("TOP INFO: ", data)
|
||||
return (
|
||||
<Paper square style={paperAppStyle} onClick={(e) => {
|
||||
}}>
|
||||
@@ -580,7 +601,7 @@ const Workflows = (props) => {
|
||||
<Grid item style={{flex: 1, display: "flex"}}>
|
||||
<div style={{flex: "10",}} onClick={() => {
|
||||
if (selectedWorkflow.id !== data.id) {
|
||||
setSelectedWorkflow(data)
|
||||
//setSelectedWorkflow(data)
|
||||
//getWorkflowExecution(data.id)
|
||||
}
|
||||
}}>
|
||||
@@ -637,7 +658,7 @@ const Workflows = (props) => {
|
||||
</Grid>
|
||||
<div style={{display: "flex", flex: 1}} onClick={() => {
|
||||
if (selectedWorkflow.id !== data.id) {
|
||||
setSelectedWorkflow(data)
|
||||
//setSelectedWorkflow(data)
|
||||
//getWorkflowExecution(data.id)
|
||||
}
|
||||
}}>
|
||||
@@ -1064,6 +1085,9 @@ const Workflows = (props) => {
|
||||
if (response !== undefined) {
|
||||
// SET THE FULL THING
|
||||
data.id = response.id
|
||||
data.first_save = false
|
||||
data.previously_saved = false
|
||||
data.is_valid = false
|
||||
|
||||
// Actually create it
|
||||
const ret = setNewWorkflow(data.name, data.description, data.tags, data, false)
|
||||
|
||||
Reference in New Issue
Block a user