diff --git a/backend/go-app/main.go b/backend/go-app/main.go
index d2110f56..0b2b47cd 100644
--- a/backend/go-app/main.go
+++ b/backend/go-app/main.go
@@ -842,7 +842,7 @@ func handleSetEnvironments(resp http.ResponseWriter, request *http.Request) {
resp.Write([]byte(`{"success": true}`))
}
-func createNewUser(username, password, role, apikey string, org shuffle.Org) error {
+func createNewUser(username, password, role, apikey string, org shuffle.OrgMini) error {
// Returns false if there is an issue
// Use this for register
err := shuffle.CheckPasswordStrength(password)
@@ -893,7 +893,10 @@ func createNewUser(username, password, role, apikey string, org shuffle.Org) err
newUser.Roles = []string{"user"}
}
- newUser.ActiveOrg = org
+ newUser.ActiveOrg = shuffle.OrgMini{
+ Id: org.Id,
+ Name: org.Name,
+ }
if len(apikey) > 0 {
newUser.ApiKey = apikey
@@ -1000,7 +1003,10 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
_, err = dbclient.GetAll(ctx, q, &orgs)
if err == nil && len(orgs) == 1 {
log.Printf("No org exists in auth. Setting to default (first one)")
- currentOrg = orgs[0]
+ currentOrg = shuffle.OrgMini{
+ Id: orgs[0].Id,
+ Name: orgs[0].Name,
+ }
}
}
@@ -1274,7 +1280,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
}
if len(newOrgs) > 0 {
- userInfo.ActiveOrg = newOrgs[0]
+ userInfo.ActiveOrg = shuffle.OrgMini{
+ Id: newOrgs[0].Id,
+ Name: newOrgs[0].Name,
+ }
+
userInfo.Orgs = newStringOrgs
err = shuffle.SetUser(ctx, &userInfo)
@@ -1291,7 +1301,7 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
} else {
// 1. Check if the org exists by ID
// 2. if it does, overwrite user
- userInfo.ActiveOrg = shuffle.Org{
+ userInfo.ActiveOrg = shuffle.OrgMini{
Id: userInfo.Orgs[0],
}
err = shuffle.SetUser(ctx, &userInfo)
@@ -1304,12 +1314,15 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
// FIXME: Remove this dependency by updating users' orgs when org itself is updated
org, err := shuffle.GetOrg(ctx, userInfo.ActiveOrg.Id)
if err == nil {
- userInfo.ActiveOrg = *org
- userInfo.ActiveOrg.Users = []shuffle.User{}
+ userInfo.ActiveOrg = shuffle.OrgMini{
+ Id: org.Id,
+ Name: org.Name,
+ }
+
+ userInfo.ActiveOrg.Users = []shuffle.UserMini{}
}
- userInfo.ActiveOrg.Users = []shuffle.User{}
- userInfo.ActiveOrg.SyncConfig = shuffle.SyncConfig{}
+ userInfo.ActiveOrg.Users = []shuffle.UserMini{}
currentOrg, err := json.Marshal(userInfo.ActiveOrg)
if err != nil {
currentOrg = []byte("{}")
@@ -4988,6 +5001,39 @@ func runInit(ctx context.Context) {
}
} else {
log.Printf("There are %d org(s).", len(activeOrgs))
+
+ if len(activeOrgs) == 1 {
+ if len(activeOrgs[0].Users) == 0 {
+ log.Printf("ORG doesn't have any users??")
+
+ q := datastore.NewQuery("Users")
+ var users []shuffle.User
+ _, err = dbclient.GetAll(ctx, q, &users)
+ if err != nil && len(users) == 0 {
+ log.Printf("Failed getting users in org fix")
+ } else {
+ // Remapping everyone to admin. This should never happen.
+
+ for _, user := range users {
+ user.ActiveOrg = shuffle.OrgMini{
+ Id: activeOrgs[0].Id,
+ Name: activeOrgs[0].Name,
+ Role: "admin",
+ }
+
+ activeOrgs[0].Users = append(activeOrgs[0].Users, user)
+ }
+
+ err = shuffle.SetOrg(ctx, activeOrgs[0], activeOrgs[0].Id)
+ if err != nil {
+ log.Printf("Failed setting org: %s", err)
+ } else {
+ log.Printf("Successfully updated org to have users!")
+ }
+ }
+
+ }
+ }
}
}
@@ -5004,7 +5050,7 @@ func runInit(ctx context.Context) {
newUser := shuffle.User{
Username: user.Username,
Id: user.Id,
- ActiveOrg: shuffle.Org{
+ ActiveOrg: shuffle.OrgMini{
Id: activeOrg.Id,
},
Orgs: []string{activeOrg.Id},
@@ -5050,7 +5096,7 @@ func runInit(ctx context.Context) {
q := datastore.NewQuery("Users").Filter("active =", true)
var activeusers []shuffle.User
_, err = dbclient.GetAll(ctx, q, &activeusers)
- if err != nil {
+ if err != nil && len(activeusers) == 0 {
log.Printf("Error getting users during init: %s", err)
} else {
q := datastore.NewQuery("Users")
@@ -5074,9 +5120,9 @@ func runInit(ctx context.Context) {
if len(user.Orgs) == 0 {
defaultName := "default"
user.Orgs = []string{defaultName}
- user.ActiveOrg = shuffle.Org{
+ user.ActiveOrg = shuffle.OrgMini{
Name: defaultName,
- Role: "user",
+ Role: "admin",
}
}
@@ -5101,9 +5147,10 @@ func runInit(ctx context.Context) {
} else {
apikey := os.Getenv("SHUFFLE_DEFAULT_APIKEY")
- tmpOrg := shuffle.Org{
+ tmpOrg := shuffle.OrgMini{
Name: "default",
}
+
err = createNewUser(username, password, "admin", apikey, tmpOrg)
if err != nil {
log.Printf("Failed to create default user %s: %s", username, err)
@@ -5123,7 +5170,11 @@ func runInit(ctx context.Context) {
if len(activeOrgs) == 1 && len(users) > 0 {
for _, user := range users {
if user.ActiveOrg.Id == "" && len(user.Username) > 0 {
- user.ActiveOrg = activeOrgs[0]
+ user.ActiveOrg = shuffle.OrgMini{
+ Id: activeOrgs[0].Id,
+ Name: activeOrgs[0].Name,
+ }
+
err = shuffle.SetUser(ctx, &user)
if err != nil {
log.Printf("Failed updating user %s with org", user.Username)
@@ -5178,7 +5229,7 @@ func runInit(ctx context.Context) {
q := datastore.NewQuery("workflow").Limit(35)
var workflows []shuffle.Workflow
_, err = dbclient.GetAll(ctx, q, &workflows)
- if err != nil {
+ if err != nil && len(workflows) == 0 {
log.Printf("Error getting workflows in runinit: %s", err)
} else {
updated := 0
@@ -5187,7 +5238,11 @@ func runInit(ctx context.Context) {
setLocal := false
if workflow.ExecutingOrg.Id == "" || len(workflow.OrgId) == 0 {
workflow.OrgId = activeOrgs[0].Id
- workflow.ExecutingOrg = activeOrgs[0]
+ workflow.ExecutingOrg = shuffle.OrgMini{
+ Id: activeOrgs[0].Id,
+ Name: activeOrgs[0].Name,
+ }
+
setLocal = true
} else if workflow.Edited == 0 {
workflow.Edited = timeNow
@@ -5475,7 +5530,7 @@ func runInit(ctx context.Context) {
q := datastore.NewQuery("workflow").Limit(35)
var workflows []shuffle.Workflow
_, err = dbclient.GetAll(ctx, q, &workflows)
- if err != nil {
+ if err != nil && len(workflows) == 0 {
log.Printf("Error getting workflows: %s", err)
} else {
if len(workflows) == 0 {
@@ -6041,7 +6096,15 @@ func makeWorkflowPublic(resp http.ResponseWriter, request *http.Request) {
FifthItem: user.Id,
}
- err = executeCloudAction(action, user.ActiveOrg.SyncConfig.Apikey)
+ org, err := shuffle.GetOrg(ctx, user.ActiveOrg.Id)
+ if err != nil {
+ log.Printf("[WARNING] Failed setting getting org during cloud job setting: %s", err)
+ resp.WriteHeader(401)
+ resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
+ return
+ }
+
+ err = executeCloudAction(action, org.SyncConfig.Apikey)
if err != nil {
log.Printf("[WARNING] Failed cloud PUBLISH: %s", err)
resp.WriteHeader(401)
@@ -6160,7 +6223,7 @@ func initHandlers() {
r.HandleFunc("/api/v1/workflows/{key}/schedule/{schedule}", stopSchedule).Methods("DELETE", "OPTIONS")
r.HandleFunc("/api/v1/workflows/{key}/outlook", createOutlookSub).Methods("POST", "OPTIONS")
r.HandleFunc("/api/v1/workflows/{key}/outlook/{triggerId}", handleDeleteOutlookSub).Methods("DELETE", "OPTIONS")
- r.HandleFunc("/api/v1/workflows/{key}/executions", getWorkflowExecutions).Methods("GET", "OPTIONS")
+ r.HandleFunc("/api/v1/workflows/{key}/executions", shuffle.GetWorkflowExecutions).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/workflows/{key}/executions/{key}/abort", shuffle.AbortExecution).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/workflows/{key}", deleteWorkflow).Methods("DELETE", "OPTIONS")
diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go
index c694fd82..935e989e 100644
--- a/backend/go-app/walkoff.go
+++ b/backend/go-app/walkoff.go
@@ -642,7 +642,7 @@ func createSchedule(ctx context.Context, scheduleId, workflowId, name, startNode
Body: ioutil.NopCloser(strings.NewReader(bodyWrapper)),
}
- _, _, err := handleExecution(workflowId, shuffle.Workflow{ExecutingOrg: shuffle.Org{Id: orgId}}, request)
+ _, _, err := handleExecution(workflowId, shuffle.Workflow{ExecutingOrg: shuffle.OrgMini{Id: orgId}}, request)
if err != nil {
log.Printf("Failed to execute %s: %s", workflowId, err)
}
@@ -2513,10 +2513,10 @@ func handleExecution(id string, workflow shuffle.Workflow, request *http.Request
// //workflowExecution.ExecutionOrg.SyncFeatures = Org{}
//}
- workflowExecution.Workflow.ExecutingOrg = shuffle.Org{
+ workflowExecution.Workflow.ExecutingOrg = shuffle.OrgMini{
Id: workflowExecution.Workflow.ExecutingOrg.Id,
}
- workflowExecution.Workflow.Org = []shuffle.Org{
+ workflowExecution.Workflow.Org = []shuffle.OrgMini{
workflowExecution.Workflow.ExecutingOrg,
}
@@ -2698,8 +2698,8 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
//memcacheName := fmt.Sprintf("%s_%s", user.Username, fileId)
ctx := context.Background()
workflow, err := shuffle.GetWorkflow(ctx, fileId)
- if err != nil {
- log.Printf("Failed getting the workflow locally (execute workflow): %s", err)
+ if err != nil && workflow.ID == "" {
+ log.Printf("[WARNING] Failed getting the workflow locally (execute workflow): %s", err)
resp.WriteHeader(401)
resp.Write([]byte(`{"success": false}`))
return
@@ -2716,7 +2716,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
log.Printf("[INFO] Starting execution of %s!", fileId)
- user.ActiveOrg.Users = []shuffle.User{}
+ user.ActiveOrg.Users = []shuffle.UserMini{}
workflow.ExecutingOrg = user.ActiveOrg
workflowExecution, executionResp, err := handleExecution(fileId, *workflow, request)
@@ -4502,11 +4502,11 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra
workflow.ID = uuid.NewV4().String()
workflow.OrgId = orgId
- workflow.ExecutingOrg = shuffle.Org{
+ workflow.ExecutingOrg = shuffle.OrgMini{
Id: orgId,
}
- workflow.Org = append(workflow.Org, shuffle.Org{
+ workflow.Org = append(workflow.Org, shuffle.OrgMini{
Id: orgId,
})
workflow.IsValid = false
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx
index 6201fdf8..b73af2fb 100644
--- a/frontend/src/views/Admin.jsx
+++ b/frontend/src/views/Admin.jsx
@@ -2043,7 +2043,7 @@ const Admin = (props) => {
/>
{
return (
{
if (nodedata.app_name == "Shuffle Tools" || nodedata.app_name == "Testing") {
//console.log("NODE: ",
//selector: `node[app_name="Shuffle Tools"]`,
- console.log(event.target)
+ //console.log(event.target)
// 1. Find location of node
// 2. Check if it's within view of another node (inside)
@@ -1387,6 +1387,42 @@ const AngularWorkflow = (props) => {
const onEdgeAdded = (event) => {
setLastSaved(false)
const edge = event.target.data()
+ var targetnode = workflow.triggers.findIndex(data => data.id === edge.target)
+ if (targetnode !== -1) {
+ console.log("TARGETNODE: ", targetnode)
+ if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow") {
+ } else {
+ alert.error("Can't have triggers as target of branch")
+ event.target.remove()
+ }
+ }
+
+ targetnode = -1
+ var sourcenode = workflow.triggers.findIndex(data => data.id === edge.source)
+ //console.log("SOURCENODE: ", sourcenode)
+ if (sourcenode !== -1) {
+ if (workflow.triggers[sourcenode].app_name === "User Input" || workflow.triggers[sourcenode].app_name === "Shuffle Workflow") {
+ //console.log("NORMAL TRIGGER")
+ } else {
+ var currentnode = cy.getElementById(workflow.triggers[sourcenode].id)
+ if (currentnode !== null && currentnode !== undefined) {
+ console.log("SHOULD CHECK IF TRIGGER HAS MULTIPLE EDGES: ", currentnode)
+ // https://js.cytoscape.org/#edges.connectedNodes
+ //console.log("CURRENTNODE: ", currentnode)
+ //console.log("EDGES: ", currentnode.connectedEdges(`node[id=${workflow.triggers[sourcenode].id}]`))
+ //console.log("EDGES2: ", currentnode.connectedEdges())
+ //currentnode.connectedEdges().animate({style: {lineColor: "red"}})
+ //console.log("OUTGOERS: ", currentnode.outgoers())
+
+ //console.log("LEN2: ", currentnode.edges().length)
+ //if (currentnode.connectedNodes().length > 0) {
+ // alert.error("Can't have multiple branches from this trigger")
+ // event.target.remove()
+ //}
+ }
+ }
+ }
+
//console.log(workflow.branches)
// Check if:
@@ -1407,7 +1443,7 @@ const AngularWorkflow = (props) => {
found = true
break
} else if (edge.target === workflow.start) {
- var targetnode = workflow.triggers.findIndex(data => data.id === edge.source)
+ targetnode = workflow.triggers.findIndex(data => data.id === edge.source)
if (targetnode === -1) {
alert.error("Can't make arrow to starting node")
event.target.remove()
@@ -1428,10 +1464,14 @@ const AngularWorkflow = (props) => {
// break
// }
} else {
+ console.log("INSIDE LAST CHECK: ", edge)
+
// Find the targetnode and check if its a trigger
// FIXME - do this for both actions and other types?
+ /*
targetnode = workflow.triggers.findIndex(data => data.id === edge.target)
if (targetnode !== -1) {
+ console.log("TARGETNODE: ", targetnode)
if (workflow.triggers[targetnode].app_name === "User Input" || workflow.triggers[targetnode].app_name === "Shuffle Workflow") {
} else {
alert.error("Can't have triggers as target of branch")
@@ -1440,6 +1480,9 @@ const AngularWorkflow = (props) => {
break
}
}
+ */
+
+
}
}
@@ -1491,6 +1534,7 @@ const AngularWorkflow = (props) => {
workflow.branches = workflow.branches.filter(a => a.id !== edge.data().id)
setWorkflow(workflow)
+ event.target.remove()
// trigger as source check
const indexcheck = workflow.triggers.findIndex(data => edge.data()["source"] === data.id)
@@ -6811,6 +6855,9 @@ const AngularWorkflow = (props) => {
theme="solarized"
collapsed={true}
displayDataTypes={false}
+ enableClipboard={(copy) => {
+ handleReactJsonClipboard(copy)
+ }}
onSelect={(select) => {
HandleJsonCopy(showResult, select, "exec")
console.log("SELECTED!: ", select)
@@ -6858,6 +6905,22 @@ const AngularWorkflow = (props) => {
)
}
+ const handleReactJsonClipboard = (copy) => {
+ console.log("COPY: ", copy)
+
+ const elementName = "copy_element_shuffle"
+ var copyText = document.getElementById(elementName);
+ if (copyText !== null && copyText !== undefined) {
+ navigator.clipboard.writeText(JSON.stringify(copy))
+ copyText.select();
+ copyText.setSelectionRange(0, 99999); /* For mobile devices */
+
+ /* Copy the text inside the text field */
+ document.execCommand("copy");
+ alert.success("Copied data")
+ }
+ }
+
const HandleJsonCopy = (base, copy, base_node_name) => {
console.log("COPY: ", copy)
var newitem = JSON.parse(base)
@@ -7204,10 +7267,14 @@ const AngularWorkflow = (props) => {
{data.status}
- {validate.valid ?
+ {
+ handleReactJsonClipboard(copy)
+ }}
displayDataTypes={false}
onSelect={(select) => {
HandleJsonCopy(showResult, select, data.action.label)
@@ -7394,6 +7461,9 @@ const AngularWorkflow = (props) => {
theme="solarized"
collapsed={false}
displayDataTypes={false}
+ enableClipboard={(copy) => {
+ handleReactJsonClipboard(copy)
+ }}
onSelect={(select) => {
HandleJsonCopy(JSON.stringify(validate.result), select, selectedResult.action.label)
}}
diff --git a/functions/onprem/worker/worker.go b/functions/onprem/worker/worker.go
index cc981636..642af1bc 100644
--- a/functions/onprem/worker/worker.go
+++ b/functions/onprem/worker/worker.go
@@ -24,7 +24,7 @@ import (
//"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
dockerclient "github.com/docker/docker/client"
- "github.com/satori/go.uuid"
+ //"github.com/satori/go.uuid"
"github.com/gorilla/mux"
"github.com/patrickmn/go-cache"
@@ -857,17 +857,25 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
}
// Added UUID to identifier just in case
- identifier := fmt.Sprintf("%s_%s_%s_%s_%s", appname, appversion, action.ID, workflowExecution.ExecutionId, uuid.NewV4())
+ //identifier := fmt.Sprintf("%s_%s_%s_%s_%s", appname, appversion, action.ID, workflowExecution.ExecutionId, uuid.NewV4())
+ identifier := fmt.Sprintf("%s_%s_%s_%s", appname, appversion, action.ID, workflowExecution.ExecutionId)
if strings.Contains(identifier, " ") {
identifier = strings.ReplaceAll(identifier, " ", "-")
}
+ //if arrayContains(executed, action.ID) || arrayContains(visited, action.ID) {
+ // log.Printf("[WARNING] Action %s is already executed")
+ // continue
+ //}
+ //visited = append(visited, action.ID)
+ //executed = append(executed, action.ID)
+
// FIXME - check whether it's running locally yet too
dockercli, err := dockerclient.NewEnvClient()
if err != nil {
log.Printf("[ERROR] Unable to create docker client (2): %s", err)
//return err
- return
+ continue
}
stats, err := dockercli.ContainerInspect(context.Background(), identifier)
@@ -1309,6 +1317,7 @@ func arrayContains(visited []string, id string) bool {
for _, item := range visited {
if item == id {
found = true
+ break
}
}
@@ -2094,7 +2103,7 @@ func sendResult(workflowExecution shuffle.WorkflowExecution, data []byte) {
}
body, err := ioutil.ReadAll(newresp.Body)
- log.Printf("[INFO] BACKEND STATUS: %d", newresp.StatusCode)
+ //log.Printf("[INFO] BACKEND STATUS: %d", newresp.StatusCode)
if err != nil {
log.Printf("[ERROR] Failed reading body: %s", err)
} else {