diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index ca5039cb..7663a299 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -830,21 +830,40 @@ class AppBase: def get_files(full_execution, value): org_id = full_execution["workflow"]["execution_org"]["id"] print("SHOULD GET FILES BASED ON ORG %s, workflow %s and value(s) %s" % (org_id, full_execution["workflow"]["id"], value)) - get_path = "/api/v1/files/%s/content?execution_id=%s" % (value, full_execution["execution_id"]) - print("PATH: %s" % get_path) + get_path = "/api/v1/files/%s?execution_id=%s" % (value, full_execution["execution_id"]) headers = { "Content-Type": "application/json", "Authorization": "Bearer %s" % self.authorization } - ret = requests.get("%s%s" % (self.url, get_path), headers=headers) - if ret.status_code == 200: - return ret.text - print("ERROR GETTING FILE: ") - print("FILE RET CONTENT: %s" % ret.text) - print("FILE RET CODE FILE: %d" % ret.status_code) - return "Error getting file(s). Status code %d" % ret.status_code + ret1 = requests.get("%s%s" % (self.url, get_path), headers=headers) + print("RET1: %s" % ret1.text) + if ret1.status_code != 200: + return { + "filename": "", + "data": "", + "success": False, + } + + content_path = "/api/v1/files/%s/content?execution_id=%s" % (value, full_execution["execution_id"]) + ret2 = requests.get("%s%s" % (self.url, content_path), headers=headers) + print("Ret2: %s" % ret2.text) + if ret2.status_code == 200: + tmpdata = ret1.json() + returndata = { + "success": True, + "filename": tmpdata["filename"], + "data": ret2.text, + } + + return returndata + + return { + "success": False, + "filename": "", + "data": "", + } # Sets files in the backend def set_files(full_execution, infiles): @@ -1094,7 +1113,7 @@ class AppBase: # This code handles files. try: - if parameter["schema"]["type"] == "file": + if parameter["schema"]["type"] == "file" and len(value) > 0: print("SHOULD HANDLE FILE. Get based on value %s" % parameter["value"]) file_value = get_files(fullexecution, value) print("FILE VALUE: %s" % file_value) diff --git a/backend/go-app/files.go b/backend/go-app/files.go index 16e238a7..d7ab890f 100644 --- a/backend/go-app/files.go +++ b/backend/go-app/files.go @@ -92,6 +92,91 @@ func fileExists(filename string) bool { return !info.IsDir() } +func handleGetFileMeta(resp http.ResponseWriter, request *http.Request) { + cors := handleCors(resp, request) + if cors { + return + } + + var fileId string + location := strings.Split(request.URL.String(), "/") + if location[1] == "api" { + if len(location) <= 4 { + log.Printf("[INFO] Path too short: %d", len(location)) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + fileId = location[4] + } + + if strings.Contains(fileId, "?") { + fileId = strings.Split(fileId, "?")[0] + } + + log.Printf("\n\n[INFO] User is trying to delete file %s\n\n", fileId) + + // 1. Check user directly + // 2. Check workflow execution authorization + user, err := handleApiAuthentication(resp, request) + if err != nil { + log.Printf("[INFO] INITIAL Api authentication failed in file deletion: %s", err) + + orgId, err := fileAuthentication(request) + if err != nil { + log.Printf("[ERROR] Bad file authentication in get: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + user.ActiveOrg.Id = orgId + user.Username = "Execution File API" + } + + // 1. Verify if the user has access to the file: org_id and workflow + log.Printf("[INFO] Should DELETE file %s if user has access", fileId) + ctx := context.Background() + file, err := getFile(ctx, fileId) + if err != nil { + log.Printf("[INFO] File %s not found: %s", fileId, err) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + found := false + if file.OrgId == user.ActiveOrg.Id { + found = true + } else { + for _, item := range user.Orgs { + if item == file.OrgId { + found = true + break + } + } + } + + if !found { + log.Printf("[INFO] User %s doesn't have access to %s", user.Username, fileId) + resp.WriteHeader(401) + resp.Write([]byte(`{"success": false}`)) + return + } + + newBody, err := json.Marshal(file) + if err != nil { + resp.WriteHeader(500) + resp.Write([]byte(`{"success": false, "reason": "Failed to marshal filedata"}`)) + return + } + + log.Printf("[INFO] Successfully deleted file %s", fileId) + resp.WriteHeader(200) + resp.Write([]byte(newBody)) +} + func handleDeleteFile(resp http.ResponseWriter, request *http.Request) { cors := handleCors(resp, request) if cors { diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 796e9ea7..07d6e047 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -8048,7 +8048,7 @@ func initHandlers() { r.HandleFunc("/api/v1/files/{fileId}", handleDeleteFile).Methods("DELETE", "OPTIONS") r.HandleFunc("/api/v1/files/create", handleCreateFile).Methods("POST", "OPTIONS") r.HandleFunc("/api/v1/files/{fileId}/upload", handleUploadFile).Methods("POST", "OPTIONS") - //r.HandleFunc("/api/v1/files/{fileId}", handleGetFile).Methods("GET", "OPTIONS") + r.HandleFunc("/api/v1/files/{fileId}", handleGetFileMeta).Methods("GET", "OPTIONS") http.Handle("/", r) } diff --git a/docker-compose.yml b/docker-compose.yml index 855a06b5..11a7fe29 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: frontend: build: ./frontend - image: ghcr.io/frikky/shuffle-frontend:0.8.1 + image: ghcr.io/frikky/shuffle-frontend:0.8.0 container_name: shuffle-frontend hostname: shuffle-frontend ports: diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 485ff4cb..e2c57f3e 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -899,6 +899,41 @@ const AngularWorkflow = (props) => { const onUnselect = (event) => { console.time("UNSELECT") + // Attempt at rewrite of name in other actions in following nodes. + // Should probably be done in the onBlur for the textfield instead + /* + if (event.target.data().type === "ACTION") { + const nodeaction = event.target.data() + const curaction = workflow.actions.find(a => a.id === nodeaction.id) + console.log("workflowaction: ", curaction) + console.log("nodeaction: ", nodeaction) + if (nodeaction.label !== curaction.label) { + console.log("BEACH!") + + var params = [] + const fixedName = "$"+curaction.label.toLowerCase().replace(" ", "_") + for (var actionkey in workflow.actions) { + if (workflow.actions[actionkey].id === curaction.id) { + continue + } + + for (var paramkey in workflow.actions[actionkey].parameters) { + const param = workflow.actions[actionkey].parameters[paramkey] + if (param.value === null || param.value === undefined || !param.value.includes("$")) { + continue + } + + const innername = param.value.toLowerCase().replace(" ", "_") + if (innername.includes(fixedName)) { + //workflow.actions[actionkey].parameters[paramkey].replace( + //console.log("FOUND!: ", innername) + } + } + } + } + } + */ + // FIXME - check if they have value before overriding like this for no reason. // Would save a lot of time (400~ ms -> 30ms) //console.log("ACTION: ", selectedAction) @@ -1009,8 +1044,29 @@ const AngularWorkflow = (props) => { } setSelectedActionName(curaction.name) - setSelectedAction(curaction) + + /* + var params = [] + const fixedName = "$"+curaction.label.toLowerCase().replace(" ", "_") + for (var actionkey in workflow.actions) { + if (workflow.actions[actionkey].id === curaction.id) { + continue + } + + for (var paramkey in workflow.actions[actionkey].parameters) { + const param = workflow.actions[actionkey].parameters[paramkey] + if (param.value === null || param.value === undefined || !param.value.includes("$")) { + continue + } + + const innername = param.value.toLowerCase().replace(" ", "_") + if (innername.includes(fixedName)) { + console.log("FOUND!: ", innername) + } + } + } + */ } else if (data.type === "TRIGGER") { //console.log("Should handle trigger "+data.triggertype) //console.log(data) @@ -2419,14 +2475,43 @@ const AngularWorkflow = (props) => { // ACTION select // const selectedNameChange = (event) => { + console.log("OLDNAME: ", selectedActionName) event.target.value = event.target.value.replace("(", "") event.target.value = event.target.value.replace(")", "") event.target.value = event.target.value.replace("$", "") event.target.value = event.target.value.replace("#", "") event.target.value = event.target.value.replace(".", "") event.target.value = event.target.value.replace(",", "") + event.target.value = event.target.value.replace(" ", "_") selectedAction.label = event.target.value setSelectedAction(selectedAction) + + /* + if (nodeaction.label !== curaction.label) { + console.log("BEACH!") + + var params = [] + const fixedName = "$"+curaction.label.toLowerCase().replace(" ", "_") + for (var actionkey in workflow.actions) { + if (workflow.actions[actionkey].id === curaction.id) { + continue + } + + for (var paramkey in workflow.actions[actionkey].parameters) { + const param = workflow.actions[actionkey].parameters[paramkey] + if (param.value === null || param.value === undefined || !param.value.includes("$")) { + continue + } + + const innername = param.value.toLowerCase().replace(" ", "_") + if (innername.includes(fixedName)) { + //workflow.actions[actionkey].parameters[paramkey].replace( + //console.log("FOUND!: ", innername) + } + } + } + } + */ } const selectedTriggerChange = (event) => { @@ -2836,7 +2921,6 @@ const AngularWorkflow = (props) => { }} /> - console.log(selectedActionParameters[count]) if (selectedActionParameters[count].schema !== undefined && selectedActionParameters[count].schema !== null && selectedActionParameters[count].schema.type === "file") { datafield =