From 5c1c92a0e6e25653fbfcdfae19a14e6fd854ca50 Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 21 Jul 2020 16:21:18 +0200 Subject: [PATCH 1/7] #105: Fixed app updates and cloud init --- backend/go-app/codegen.go | 2 +- backend/go-app/main.go | 14 ++- frontend/src/Admin.js | 151 ++++++++++++++++++++++++++++---- frontend/src/AngularWorkflow.js | 6 +- frontend/src/App.js | 7 +- frontend/src/Apps.js | 6 +- frontend/src/Header.js | 37 ++++++-- frontend/src/Workflows.js | 2 +- 8 files changed, 193 insertions(+), 32 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 0aa12fe4..f620cc7f 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -398,7 +398,7 @@ func makePythoncode(swagger *openapi3.Swagger, name, url, method string, paramet verifyAddin, ) - log.Printf("%s", data) + //log.Printf("%s", data) return functionname, data } diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 0b58ae5d..2f7e95d2 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -662,7 +662,7 @@ func handleApiAuthentication(resp http.ResponseWriter, request *http.Request) (U if len(Userdata.Username) > 0 { return Userdata, nil } else { - return Userdata, errors.New("User is invalid") + return Userdata, errors.New(fmt.Sprintf("User is invalid - no username found: %#v", Userdata)) } } @@ -1605,8 +1605,11 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { } // This is a long check to see if an inactive admin can access the site + parsedAdmin := "false" if !userInfo.Active { if userInfo.Role == "admin" { + parsedAdmin = "true" + ctx := context.Background() q := datastore.NewQuery("Users") var users []User @@ -1672,7 +1675,14 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) { Expires: expiration, }) - returnData := fmt.Sprintf(`{"success": true, "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}]}`, userInfo.Session, expiration.Unix()) + returnData := fmt.Sprintf(` + { + "success": true, + "admin": %s, + "orgs": [{"name": "Shuffle", "id": "123", "role": "admin"}], + "selected_org": {"name": "Shuffle", "id": "123", "role": "admin"}, + "cookies": [{"key": "session_token", "value": "%s", "expiration": %d}] + }`, parsedAdmin, userInfo.Session, expiration.Unix()) resp.WriteHeader(200) resp.Write([]byte(returnData)) diff --git a/frontend/src/Admin.js b/frontend/src/Admin.js index e60d14e0..f0aa92a5 100644 --- a/frontend/src/Admin.js +++ b/frontend/src/Admin.js @@ -2,6 +2,8 @@ import React, { useEffect} from 'react'; import {Link} from 'react-router-dom'; import Paper from '@material-ui/core/Paper'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Switch from '@material-ui/core/Switch'; import Select from '@material-ui/core/Select'; import MenuItem from '@material-ui/core/MenuItem'; import List from '@material-ui/core/List'; @@ -21,7 +23,13 @@ import DialogTitle from '@material-ui/core/DialogTitle'; import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; +import AccessibilityNewIcon from '@material-ui/icons/AccessibilityNew'; import CachedIcon from '@material-ui/icons/Cached'; +import LockIcon from '@material-ui/icons/Lock'; +import BusinessIcon from '@material-ui/icons/Business'; +import EcoIcon from '@material-ui/icons/Eco'; +import ScheduleIcon from '@material-ui/icons/Schedule'; +import CloudIcon from '@material-ui/icons/Cloud'; const surfaceColor = "#27292D" const inputColor = "#383B40" @@ -459,7 +467,7 @@ const Admin = (props) => { } const editAuthenticationModal = - {setSelectedAuthenticationModalOpen(false)}} PaperProps={{ @@ -523,7 +531,7 @@ const Admin = (props) => { const editUserModal = - {setSelectedUserModalOpen(false)}} PaperProps={{ @@ -587,7 +595,7 @@ const Admin = (props) => { const modalView = - {setModalOpen(false)}} PaperProps={{ @@ -600,7 +608,7 @@ const Admin = (props) => { }} > - {curTab === 0 ? "Add user" : "Add environment"} + {curTab === 0 ? "Add user" : curTab === 2 ? "Add environment" : "Add organization"} {curTab === 0 ? @@ -671,7 +679,30 @@ const Admin = (props) => { onChange={(event) => changeModalData("environment", event.target.value)} /> - : null } + : +
+ Org Name + changeModalData("organization", event.target.value)} + /> +
+ } {loginInfo}
@@ -731,7 +762,7 @@ const Admin = (props) => { {users === undefined ? null : users.map(data => { return ( - + { { style={{minWidth: 200, maxWidth: 200, overflow: "hidden"}} /> - + ) @@ -986,6 +1013,94 @@ const Admin = (props) => { : null + const organizationsTab = curTab === 5 ? +
+
+

Organizations

+ Global admin: control organizations +
+ + + + + + + + + + + + {console.log("INVERT")}} /> + style={{minWidth: 150, maxWidth: 150}} + /> + + +
+ : null + + const hybridTab = curTab === 4 ? +
+
+

Hybrid

+ +
+ + + + + + + + + + + {console.log("INVERT")}} /> + style={{minWidth: 150, maxWidth: 150}} + /> + + +
+ : null + // primary={environment.Registered ? "true" : "false"} const setConfig = (event, newValue) => { @@ -1001,20 +1116,22 @@ const Admin = (props) => { setCurTab(newValue) } + const iconStyle = {marginRight: 10} const data =
- - - - + Users /> + App Authentication/> + Environments/> + Schedules /> + {window.location.protocol == "http:" && window.location.port === "3000" ? Hybrid/> : null} + {window.location.protocol == "http:" && window.location.port === "3000" ? Organizations/> : null}
@@ -1022,6 +1139,8 @@ const Admin = (props) => { {usersView} {environmentView} {schedulesView} + {hybridTab} + {organizationsTab}
diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 31f792c4..4814c54a 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -950,6 +950,10 @@ const AngularWorkflow = (props) => { if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "") { curaction.selectedAuthentication = {} } + } else { + curaction.authentication = [] + curaction.authentication_id = "" + curaction.selectedAuthentication = {} } setSelectedApp(curapp) @@ -2998,7 +3002,7 @@ const AngularWorkflow = (props) => { paddingLeft: 10, minHeight: "100%", zIndex: 1000, - resize: "horizontal", + resize: "vertical", overflow: "auto", } diff --git a/frontend/src/App.js b/frontend/src/App.js index c162b774..42cd96ed 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -31,8 +31,8 @@ import LandingPageNew from "./LandingpageNew"; import LoginPage from "./LoginPage"; import SettingsPage from "./SettingsPage"; -import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; -import { createMuiTheme } from '@material-ui/core/styles'; +//import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; +import { createMuiTheme, ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles'; import AlertTemplate from "react-alert-template-basic"; import { positions, Provider } from "react-alert"; @@ -100,6 +100,7 @@ const App = (message, props) => { .then(response => response.json()) .then(responseJson => { if (responseJson.success === true) { + console.log(responseJson) setUserData(responseJson) setIsLoggedIn(true) @@ -127,7 +128,7 @@ const App = (message, props) => { } /> :
-
+
} /> } /> } /> diff --git a/frontend/src/Apps.js b/frontend/src/Apps.js index 0d1d7263..266a7d42 100644 --- a/frontend/src/Apps.js +++ b/frontend/src/Apps.js @@ -286,7 +286,7 @@ const Apps = (props) => { } return ( - { + { if (selectedApp.id !== data.id) { setSelectedApp(data) console.log(data) @@ -515,7 +515,7 @@ const Apps = (props) => { newActionname = newActionname.replace("_", " ") newActionname = newActionname.charAt(0).toUpperCase()+newActionname.substring(1) return ( - + {newActionname} @@ -540,7 +540,7 @@ const Apps = (props) => { const circleSize = 10 return ( - +
{data.name} diff --git a/frontend/src/Header.js b/frontend/src/Header.js index 7a01cb53..7a880bd5 100644 --- a/frontend/src/Header.js +++ b/frontend/src/Header.js @@ -6,6 +6,8 @@ import {Link} from 'react-router-dom'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import Button from '@material-ui/core/Button'; import HomeIcon from '@material-ui/icons/Home'; import PolymerIcon from '@material-ui/icons/Polymer'; @@ -17,7 +19,7 @@ const hoverColor = "#f85a3e" const hoverOutColor = "#e8eaf6" const Header = props => { - const { globalUrl, isLoggedIn, removeCookie, homePage, isLoaded } = props; + const { surfaceColor, inputColor, globalUrl, isLoggedIn, removeCookie, homePage, isLoaded, userdata} = props; const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor); const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor); @@ -100,7 +102,7 @@ const Header = props => { // Handle top bar or something - const loginTextBrowser = !isLoggedIn ? + const loginTextBrowser = !isLoggedIn ?
@@ -192,6 +194,31 @@ const Header = props => { + {userdata.orgs.length <= 1 ? null : + + + + }
@@ -272,10 +299,10 @@ const Header = props => { const loadedCheck = isLoaded ?
- {loginTextBrowser} + {loginTextBrowser} - {loginTextMobile} + {loginTextMobile}
: @@ -288,6 +315,6 @@ const Header = props => { {loadedCheck}
); -}; +} export default Header; diff --git a/frontend/src/Workflows.js b/frontend/src/Workflows.js index 407e6186..d5f07974 100644 --- a/frontend/src/Workflows.js +++ b/frontend/src/Workflows.js @@ -563,7 +563,7 @@ const Workflows = (props) => { } return ( - {}}> + {}}>
From 1ea4a233810509a0b7849ca9c5d988119952ba4e Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 21 Jul 2020 18:22:41 +0200 Subject: [PATCH 2/7] Fixed a bug that prevent orborus docker network passing --- backend/app_sdk/app_base.py | 2 +- functions/onprem/orborus/orborus.go | 28 +++++++++++++++------------- functions/onprem/worker/worker.go | 7 +++++++ 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 1a311ee7..7ef5bbeb 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -101,7 +101,7 @@ class AppBase: except requests.exceptions.ConnectionError as e: print("Connectionerror: %s" % e) - action_result["result"] = "Bad setup during startup: %d" % e + action_result["result"] = "Bad setup during startup: %s" % e self.send_result(action_result, headers, stream_path) return diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go index d86ba371..fbee4052 100644 --- a/functions/onprem/orborus/orborus.go +++ b/functions/onprem/orborus/orborus.go @@ -78,10 +78,11 @@ func init() { // Skip random containers. Only handle things related to Shuffle. for _, container := range containers { found := false - //log.Printf("Running? %#v", container) - if container.State != "running" { - continue - } + + // Bad states - it might just be created sometimes, leading to now netowkr + //if container.State == "restarting" || container.State == "paused" || container.State == "exited" || container.State == "dead" { + // continue + //} for _, name := range container.Names { if !strings.Contains(strings.ToLower(name), containerIdentifier) { @@ -120,17 +121,10 @@ func deployWorker(image string, identifier string, env []string) { }, } - // ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/ - config := &container.Config{ - Image: image, - Env: env, - } - // Look for Shuffle network and set it - - // FIXME: Move this out of here and have it be a global setting. During init? networkConfig := &network.NetworkingConfig{} if len(shuffleNetwork) > 0 { + log.Printf("Starting worker with network %s", shuffleNetwork) networkConfig = &network.NetworkingConfig{ EndpointsConfig: map[string]*network.EndpointSettings{ shuffleNetwork: { @@ -139,7 +133,15 @@ func deployWorker(image string, identifier string, env []string) { }, } - env = append(env, fmt.Sprintf("DOCKER_NETWORK", shuffleNetwork)) + env = append(env, fmt.Sprintf("DOCKER_NETWORK=%s", shuffleNetwork)) + } else { + log.Printf("Starting worker WITHOUT any specified network: %s", shuffleNetwork) + } + + // ROFL: https://docker-py.readthedocs.io/en/1.4.0/volumes/ + config := &container.Config{ + Image: image, + Env: env, } //test := &network.EndpointSettings{ diff --git a/functions/onprem/worker/worker.go b/functions/onprem/worker/worker.go index edb9c39c..48b11ebc 100644 --- a/functions/onprem/worker/worker.go +++ b/functions/onprem/worker/worker.go @@ -1107,6 +1107,13 @@ func main() { } } + shuffleNetwork := os.Getenv("DOCKER_NETWORK") + if len(shuffleNetwork) > 0 { + log.Printf("Running with Docker network %s", shuffleNetwork) + } else { + log.Printf("No docker network specified for Worker.") + } + // WORKER_TESTING_WORKFLOW should be a workflow ID authorization := "" executionId := "" From 8db710a5624affda653d22e86a09a1cbd57a73b0 Mon Sep 17 00:00:00 2001 From: frikky Date: Wed, 22 Jul 2020 16:58:54 +0200 Subject: [PATCH 3/7] Fixed optional force app update for all apps when running remote load --- backend/go-app/main.go | 4 ++-- backend/go-app/walkoff.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 2f7e95d2..7004a6b5 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -6144,7 +6144,7 @@ func handleAppHotload(location string) error { } //log.Printf("Reading app folder: %#v", dir) - err = iterateAppGithubFolders(fs, dir, "", "") + err = iterateAppGithubFolders(fs, dir, "", "", false) if err != nil { log.Printf("Err: %s", err) return err @@ -6355,7 +6355,7 @@ func runInit(ctx context.Context) { //iterateAppGithubFolders(fs, dir, "", "testing") // FIXME: Get all the apps? - iterateAppGithubFolders(fs, dir, "", "") + iterateAppGithubFolders(fs, dir, "", "", false) // Hotloads locally location := os.Getenv("APP_HOTLOAD_FOLDER") diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 037c8500..fcdef140 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -4265,7 +4265,7 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { log.Printf("FAiled reading folder: %s", err) } _ = r - iterateAppGithubFolders(fs, dir, "", "") + iterateAppGithubFolders(fs, dir, "", "", true) } else if strings.Contains(tmpBody.URL, "s3") { //https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ @@ -4490,7 +4490,7 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra } // Onlyname is used to -func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string) error { +func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string, forceUpdate bool) error { var err error for _, file := range dir { if len(onlyname) > 0 && file.Name() != onlyname { @@ -4508,7 +4508,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } // Go routine? Hmm, this can be super quick I guess - err = iterateAppGithubFolders(fs, dir, tmpExtra, "") + err = iterateAppGithubFolders(fs, dir, tmpExtra, "", forceUpdate) if err != nil { log.Printf("Error reading folder: %s", err) continue @@ -4617,7 +4617,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin } } - if skip { + if skip && !forceUpdate { continue } From 10ac88d30b624b96e3152fe01dfc7bef0d496bb8 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 23 Jul 2020 15:28:26 +0200 Subject: [PATCH 4/7] #107: Fixed double apps and general duplicates --- backend/go-app/walkoff.go | 35 ++++++++++++++++++++++++----------- frontend/src/Apps.js | 17 ++++++++++++----- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index fcdef140..66eb63f0 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -4221,9 +4221,10 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { // Field1 & 2 can be a lot of things.. type tmpStruct struct { - URL string `json:"url"` - Field1 string `json:"field_1"` - Field2 string `json:"field_2"` + URL string `json:"url"` + Field1 string `json:"field_1"` + Field2 string `json:"field_2"` + ForceUpdate bool `json:"force_update"` } //log.Printf("Body: %s", string(body)) @@ -4265,7 +4266,13 @@ func loadSpecificApps(resp http.ResponseWriter, request *http.Request) { log.Printf("FAiled reading folder: %s", err) } _ = r - iterateAppGithubFolders(fs, dir, "", "", true) + + if tmpBody.ForceUpdate { + log.Printf("Running with force update!") + } else { + log.Printf("Updating apps with updates") + } + iterateAppGithubFolders(fs, dir, "", "", tmpBody.ForceUpdate) } else if strings.Contains(tmpBody.URL, "s3") { //https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ @@ -4492,6 +4499,11 @@ func iterateWorkflowGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra // Onlyname is used to func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra string, onlyname string, forceUpdate bool) error { var err error + + allapps := []WorkflowApp{} + + // It's here to prevent getting them in every iteration + ctx := context.Background() for _, file := range dir { if len(onlyname) > 0 && file.Name() != onlyname { continue @@ -4591,12 +4603,12 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin fmt.Sprintf("%s:%s_%s", baseDockerName, newName, workflowapp.AppVersion), } - ctx := context.Background() - allapps, err := getAllWorkflowApps(ctx) - if err != nil { - log.Printf("Failed getting apps to verify: %s", err) - continue - //return err + if len(allapps) == 0 { + allapps, err = getAllWorkflowApps(ctx) + if err != nil { + log.Printf("Failed getting apps to verify: %s", err) + continue + } } // Make an option to override existing apps? @@ -4607,7 +4619,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin if app.Name == workflowapp.Name && app.AppVersion == workflowapp.AppVersion { // FIXME: Check if there's a new APP_SDK as well. // Skip this check if app_sdk is new. - if app.Hash == md5 && app.Hash != "" { + if app.Hash == md5 && app.Hash != "" && !forceUpdate { skip = true break } @@ -4677,6 +4689,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin if len(removeApps) > 0 { for _, item := range removeApps { + log.Printf("Removing duplicate: %s", item) err = DeleteKey(ctx, "workflowapp", item) if err != nil { log.Printf("Failed deleting %s", item) diff --git a/frontend/src/Apps.js b/frontend/src/Apps.js index 266a7d42..e482765d 100644 --- a/frontend/src/Apps.js +++ b/frontend/src/Apps.js @@ -743,7 +743,7 @@ const Apps = (props) => { null // Load data e.g. from github - const getSpecificApps = (url) => { + const getSpecificApps = (url, forceUpdate) => { setValidation(true) setIsLoading(true) @@ -761,6 +761,8 @@ const Apps = (props) => { parsedData["field_2"] = field2 } + parsedData["force_update"] = forceUpdate + alert.success("Getting specific apps from your URL.") var cors = "cors" fetch(globalUrl+"/api/v1/apps/get_existing", { @@ -977,8 +979,8 @@ const Apps = (props) => { window.location.href = "/apps/new?id="+appValidation } - const handleGithubValidation = () => { - getSpecificApps(openApi) + const handleGithubValidation = (forceUpdate) => { + getSpecificApps(openApi, forceUpdate) setLoadAppsModalOpen(false) } @@ -1034,7 +1036,7 @@ const Apps = (props) => { >
- Load from github repo + Load from github repo
@@ -1098,7 +1100,12 @@ const Apps = (props) => { Cancel + From d161b1ee99b2f03460ce0a87d0d81a572fc3e1c7 Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 23 Jul 2020 16:02:29 +0200 Subject: [PATCH 5/7] #102: Added general NOT feature to conditions --- backend/app_sdk/app_base.py | 12 +++++++++++- backend/go-app/walkoff.go | 1 + frontend/src/AngularWorkflow.js | 25 +++++++++++++------------ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 7ef5bbeb..1d148b9d 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -710,7 +710,17 @@ class AppBase: continue #print(destinationvalue) - if not run_validation(sourcevalue, condition["condition"]["value"], destinationvalue): + # NEGATE + validation = run_validation(sourcevalue, condition["condition"]["value"], destinationvalue) + + # Configuration = negated because of WorkflowAppActionParam.. + try: + if condition["condition"]["configuration"]: + validation = not validation + except KeyError: + pass + + if not validation: self.logger.info("Failed condition check for %s %s %s." % (sourcevalue, condition["condition"]["value"], destinationvalue)) return False, "Failed condition: %s %s %s" % (sourcevalue, condition["condition"]["value"], destinationvalue) diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 66eb63f0..da75a0be 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -94,6 +94,7 @@ type AuthenticationUsage struct { } // An app inside Shuffle +// Source string `json:"source" datastore:"soure" yaml:"source"` - downloadlocation type WorkflowApp struct { Name string `json:"name" yaml:"name" required:true datastore:"name"` IsValid bool `json:"is_valid" yaml:"is_valid" required:true datastore:"is_valid"` diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 4814c54a..0fb9249f 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -3517,14 +3517,6 @@ const AngularWorkflow = (props) => {
{data.name}
- -
{ - e.preventDefault() - changeActionParameterVariant("STATIC_VALUE") - }}> - -
-
{datafield} @@ -3557,11 +3549,21 @@ const AngularWorkflow = (props) => {
Condition
+ + +
-
- { setVariableAnchorEl(null) }} key={"less than"}>less than - -
+
From 1ec8bdebb6d9ad2a27328fbb269bbd4d392633a7 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 27 Jul 2020 11:45:12 +0200 Subject: [PATCH 6/7] Fixed app base --- backend/app_sdk/app_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 1d148b9d..ae57b0d2 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -288,7 +288,7 @@ class AppBase: # Do stuff here. innervalue = parse_nested_param(data, maxDepth(data)-0) outervalue = parse_nested_param(data, maxDepth(data)-1) - print("INNER: ", outervalue) + print("INNER: ", innervalue) print("OUTER: ", outervalue) if outervalue != innervalue: From b3c7c8c7e049d1be7f7e2b8c69923e7da83b7916 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 27 Jul 2020 12:05:18 +0200 Subject: [PATCH 7/7] An update which seems to have all the working components --- frontend/package-lock.json | 26 +-- frontend/src/App.js | 170 --------------- frontend/src/App.jsx | 161 ++++++++++++++ frontend/src/Flows.js | 25 --- frontend/src/Hookpost.js | 25 --- frontend/src/Schedulespost.js | 25 --- frontend/src/{ => __test__}/appdata.js | 0 .../src/{ => __test__}/environmentdata.js | 0 frontend/src/{ => __test__}/scheduledata.js | 0 frontend/src/{ => __test__}/webhookdata.js | 0 frontend/src/{ => __test__}/workflowdata.js | 0 frontend/src/{ => components}/AlertPopup.js | 0 .../src/{ => components}/AlertTemplate.js | 0 frontend/src/{ => components}/FooterNew.js | 0 frontend/src/{ => components}/Header.js | 2 +- frontend/src/{ => components}/LoginPopup.js | 0 .../src/{ => components}/SettingsPopup.js | 0 frontend/src/{About.js => views/About.jsx} | 12 +- frontend/src/{Admin.js => views/Admin.jsx} | 0 .../{AdminSetup.js => views/AdminSetup.jsx} | 0 .../AngularWorkflow.jsx} | 9 +- .../{AppCreator.js => views/AppCreator.jsx} | 0 frontend/src/{Apps.js => views/Apps.jsx} | 2 +- .../src/{Contact.js => views/Contact.jsx} | 196 +++++++++--------- .../src/{Dashboard.js => views/Dashboard.jsx} | 2 +- frontend/src/{Docs.js => views/Docs.jsx} | 0 .../EditSchedule.jsx} | 3 - .../{EditWebhook.js => views/EditWebhook.jsx} | 4 +- .../EditWorkflow.jsx} | 0 .../ForgotPassword.jsx} | 0 .../ForgotPasswordLink.jsx} | 0 .../{Landingpage.js => views/Landingpage.jsx} | 0 .../LandingpageLoggedin.jsx} | 0 .../LandingpageNew.jsx} | 0 .../src/{LoginPage.js => views/LoginPage.jsx} | 191 ++++++++--------- frontend/src/{Oauth2.js => views/Oauth2.jsx} | 0 frontend/src/{Post.js => views/Post.jsx} | 0 .../PrivacyPolicy.jsx} | 0 .../RegisterLink.jsx} | 0 .../RegisterPage.jsx} | 0 .../src/{Schedules.js => views/Schedules.jsx} | 0 .../SettingsPage.jsx} | 42 ++-- .../src/{Webhooks.js => views/Webhooks.jsx} | 4 +- .../src/{Workflows.js => views/Workflows.jsx} | 2 +- 44 files changed, 402 insertions(+), 499 deletions(-) delete mode 100644 frontend/src/App.js create mode 100644 frontend/src/App.jsx delete mode 100644 frontend/src/Flows.js delete mode 100644 frontend/src/Hookpost.js delete mode 100644 frontend/src/Schedulespost.js rename frontend/src/{ => __test__}/appdata.js (100%) rename frontend/src/{ => __test__}/environmentdata.js (100%) rename frontend/src/{ => __test__}/scheduledata.js (100%) rename frontend/src/{ => __test__}/webhookdata.js (100%) rename frontend/src/{ => __test__}/workflowdata.js (100%) rename frontend/src/{ => components}/AlertPopup.js (100%) rename frontend/src/{ => components}/AlertTemplate.js (100%) rename frontend/src/{ => components}/FooterNew.js (100%) rename frontend/src/{ => components}/Header.js (99%) rename frontend/src/{ => components}/LoginPopup.js (100%) rename frontend/src/{ => components}/SettingsPopup.js (100%) rename frontend/src/{About.js => views/About.jsx} (85%) rename frontend/src/{Admin.js => views/Admin.jsx} (100%) rename frontend/src/{AdminSetup.js => views/AdminSetup.jsx} (100%) rename frontend/src/{AngularWorkflow.js => views/AngularWorkflow.jsx} (99%) rename frontend/src/{AppCreator.js => views/AppCreator.jsx} (100%) rename frontend/src/{Apps.js => views/Apps.jsx} (99%) rename frontend/src/{Contact.js => views/Contact.jsx} (54%) rename frontend/src/{Dashboard.js => views/Dashboard.jsx} (99%) rename frontend/src/{Docs.js => views/Docs.jsx} (100%) rename frontend/src/{EditSchedule.js => views/EditSchedule.jsx} (99%) rename frontend/src/{EditWebhook.js => views/EditWebhook.jsx} (98%) rename frontend/src/{EditWorkflow.js => views/EditWorkflow.jsx} (100%) rename frontend/src/{ForgotPassword.js => views/ForgotPassword.jsx} (100%) rename frontend/src/{ForgotPasswordLink.js => views/ForgotPasswordLink.jsx} (100%) rename frontend/src/{Landingpage.js => views/Landingpage.jsx} (100%) rename frontend/src/{LandingpageLoggedin.js => views/LandingpageLoggedin.jsx} (100%) rename frontend/src/{LandingpageNew.js => views/LandingpageNew.jsx} (100%) rename frontend/src/{LoginPage.js => views/LoginPage.jsx} (55%) rename frontend/src/{Oauth2.js => views/Oauth2.jsx} (100%) rename frontend/src/{Post.js => views/Post.jsx} (100%) rename frontend/src/{PrivacyPolicy.js => views/PrivacyPolicy.jsx} (100%) rename frontend/src/{RegisterLink.js => views/RegisterLink.jsx} (100%) rename frontend/src/{RegisterPage.js => views/RegisterPage.jsx} (100%) rename frontend/src/{Schedules.js => views/Schedules.jsx} (100%) rename frontend/src/{SettingsPage.js => views/SettingsPage.jsx} (90%) rename frontend/src/{Webhooks.js => views/Webhooks.jsx} (98%) rename frontend/src/{Workflows.js => views/Workflows.jsx} (99%) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 276ecded..6f78e4b1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,6 +1,6 @@ { "name": "shuffler", - "version": "0.3.0", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3733,9 +3733,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "14.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", - "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==" + "version": "14.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.24.tgz", + "integrity": "sha512-btt/oNOiDWcSuI721MdL8VQGnjsKjlTMdrKyTcLCKeQp/n4AAMFJ961wMbp+09y8WuGPClDEv07RIItdXKIXAA==" }, "@types/object-assign": { "version": "4.0.30", @@ -3748,9 +3748,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prop-types": { - "version": "15.7.1", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", - "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==" + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/q": { "version": "1.5.4", @@ -3758,9 +3758,9 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/react": { - "version": "16.8.20", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.20.tgz", - "integrity": "sha512-ZLmI+ubSJpfUIlQuULDDrdyuFQORBuGOvNnMue8HeA0GVrAJbWtZQhcBvnBPNRBI/GrfSfrKPFhthzC2SLEtLQ==", + "version": "16.9.43", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz", + "integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==", "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" @@ -11944,9 +11944,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash._reinterpolate": { "version": "3.0.0", diff --git a/frontend/src/App.js b/frontend/src/App.js deleted file mode 100644 index 42cd96ed..00000000 --- a/frontend/src/App.js +++ /dev/null @@ -1,170 +0,0 @@ -import React, {useState, useEffect} from 'react'; - -import {Route} from 'react-router'; -import {BrowserRouter} from 'react-router-dom'; -import { CookiesProvider } from 'react-cookie'; -import { useCookies } from 'react-cookie'; - -import EditSchedule from "./EditSchedule"; -import Schedules from "./Schedules"; -import Webhooks from "./Webhooks"; -import Workflows from "./Workflows"; -import EditWebhook from "./EditWebhook"; -import AngularWorkflow from "./AngularWorkflow"; -import ForgotPassword from "./ForgotPassword"; -import ForgotPasswordLink from "./ForgotPasswordLink"; - -import Header from './Header'; -import Apps from './Apps'; -import AppCreator from './AppCreator'; -import Contact from './Contact'; -import Oauth2 from './Oauth2'; -import About from "./About"; -import Post from "./Post"; -import Dashboard from "./Dashboard"; -import AdminSetup from "./AdminSetup"; -import Admin from "./Admin"; -import Docs from "./Docs"; -import RegisterLink from "./RegisterLink"; -import LandingPage from "./Landingpage"; -import LandingPageNew from "./LandingpageNew"; -import LoginPage from "./LoginPage"; -import SettingsPage from "./SettingsPage"; - -//import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; -import { createMuiTheme, ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles'; - -import AlertTemplate from "react-alert-template-basic"; -import { positions, Provider } from "react-alert"; - -// Production - backend proxy forwarding in nginx -var globalUrl = window.location.origin - -// CORS used for testing purposes. Should only happen with specific port and http -if (window.location.protocol == "http:" && window.location.port === "3000") { - globalUrl = "http://localhost:5001" -} - -const surfaceColor = "#27292D" -const inputColor = "#383B40" - -const theme = createMuiTheme({ - palette: { - primary: { - main: "#f85a3e" - }, - secondary: { - main: '#e8eaf6', - }, - }, - typography: { - useNextVariants: true - }, - overrides: { - MuiMenu: { - list: { - backgroundColor: inputColor, - }, - }, - }, -}); - - -// FIXME - set client side cookies -const App = (message, props) => { - const [userdata, setUserData] = useState({}); - //const [homePage, ] = useState(true); - const [cookies, setCookie, removeCookie] = useCookies([]); - const [isLoggedIn, setIsLoggedIn] = useState(false); - const [dataset, setDataset] = useState(false); - const [isLoaded, setIsLoaded] = useState(false); - - useEffect(() => { - if (dataset === false) { - checkLogin() - setDataset(true) - }}) - - if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) { - window.location = "/login" - } - - const checkLogin = () => { - var baseurl = globalUrl - fetch(baseurl+"/api/v1/users/getinfo", { - credentials: "include", - headers: { - 'Content-Type': 'application/json', - }, - }) - .then(response => response.json()) - .then(responseJson => { - if (responseJson.success === true) { - console.log(responseJson) - setUserData(responseJson) - setIsLoggedIn(true) - - // Updating cookie every request - for (var key in responseJson["cookies"]) { - setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, {path: "/"}) - } - } - setIsLoaded(true) - }) - .catch(error => { - setIsLoaded(true) - }); - } - - // Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies) - - const options = { - timeout: 5000, - position: positions.BOTTOM_CENTER - }; - - const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ? -
- } /> -
: -
-
- } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - {window.location.pathname = "/docs/about"}} /> - {window.location.pathname = "/login"}} /> -
- - //
- // backgroundColor: "#213243", - // This is a mess hahahah - return ( - - - - - {includedData} - - - - - ); -}; - -export default App; - diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx new file mode 100644 index 00000000..f5214bab --- /dev/null +++ b/frontend/src/App.jsx @@ -0,0 +1,161 @@ +import React, { useState, useEffect } from 'react'; + +import { Route } from 'react-router'; +import { BrowserRouter } from 'react-router-dom'; +import { CookiesProvider } from 'react-cookie'; +import { useCookies } from 'react-cookie'; + +import EditSchedule from "./views/EditSchedule"; +import Schedules from "./views/Schedules"; +import Webhooks from "./views/Webhooks"; +import Workflows from "./views/Workflows"; +import EditWebhook from "./views/EditWebhook"; +import AngularWorkflow from "./views/AngularWorkflow"; + +import Header from './components/Header'; +import Apps from './views/Apps'; +import AppCreator from './views/AppCreator'; +import Contact from './views/Contact'; +import Oauth2 from './views/Oauth2'; +import Dashboard from "./views/Dashboard"; +import AdminSetup from "./views/AdminSetup"; +import Admin from "./views/Admin"; +import Docs from "./views/Docs"; +import LandingPageNew from "./views/LandingpageNew"; +import LoginPage from "./views/LoginPage"; +import SettingsPage from "./views/SettingsPage"; + +import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles'; + +import AlertTemplate from "react-alert-template-basic"; +import { positions, Provider } from "react-alert"; + +// Production - backend proxy forwarding in nginx +var globalUrl = window.location.origin + +// CORS used for testing purposes. Should only happen with specific port and http +if (window.location.protocol == "http:" && window.location.port === "3000") { + globalUrl = "http://localhost:5001" +} + +const theme = createMuiTheme({ + palette: { + primary: { + main: "#f85a3e" + }, + secondary: { + main: '#e8eaf6', + }, + surfaceColor: "#27292d", + inputColor: "#383B40" + }, + typography: { + useNextVariants: true + }, + overrides: { + MuiMenu: { + list: { + backgroundColor: "#383B40", + }, + }, + }, +}); + + +// FIXME - set client side cookies +const App = (message, props) => { + const [userdata, setUserData] = useState({}); + //const [homePage, ] = useState(true); + const [cookies, setCookie, removeCookie] = useCookies([]); + const [isLoggedIn, setIsLoggedIn] = useState(false); + const [dataset, setDataset] = useState(false); + const [isLoaded, setIsLoaded] = useState(false); + + useEffect(() => { + if (dataset === false) { + checkLogin() + setDataset(true) + } + }) + + if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) { + window.location = "/login" + } + + const checkLogin = () => { + var baseurl = globalUrl + fetch(baseurl + "/api/v1/users/getinfo", { + credentials: "include", + headers: { + 'Content-Type': 'application/json', + }, + }) + .then(response => response.json()) + .then(responseJson => { + if (responseJson.success === true) { + setUserData(responseJson) + setIsLoggedIn(true) + + // Updating cookie every request + for (var key in responseJson["cookies"]) { + setCookie(responseJson["cookies"][key].key, responseJson["cookies"][key].value, { path: "/" }) + } + } + setIsLoaded(true) + }) + .catch(error => { + setIsLoaded(true) + }); + } + + // Dumb for content load (per now), but good for making the site not suddenly reload parts (ajax thingies) + + const options = { + timeout: 5000, + position: positions.BOTTOM_CENTER + }; + + const includedData = window.location.pathname === "/home" || window.location.pathname === "/features" ? +
+ } /> +
: +
+
+ } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + { window.location.pathname = "/docs/about" }} /> + { window.location.pathname = "/login" }} /> +
+ + //
+ // backgroundColor: "#213243", + // This is a mess hahahah + return ( + + + + + {includedData} + + + + + ); +}; + +export default App; diff --git a/frontend/src/Flows.js b/frontend/src/Flows.js deleted file mode 100644 index aa1a35a3..00000000 --- a/frontend/src/Flows.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Flows = () => { - return ( -
-

Flows

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Flows; diff --git a/frontend/src/Hookpost.js b/frontend/src/Hookpost.js deleted file mode 100644 index 566a26d4..00000000 --- a/frontend/src/Hookpost.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Hooks = () => { - return ( -
-

Hooks

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Hooks; diff --git a/frontend/src/Schedulespost.js b/frontend/src/Schedulespost.js deleted file mode 100644 index 102144e7..00000000 --- a/frontend/src/Schedulespost.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -const Schedules = () => { - return ( -
-

Schedules

- -

- Built to suit any organization -

- -

- WAT -

- -

-

- -

- -
- ) -} - -export default Schedules; diff --git a/frontend/src/appdata.js b/frontend/src/__test__/appdata.js similarity index 100% rename from frontend/src/appdata.js rename to frontend/src/__test__/appdata.js diff --git a/frontend/src/environmentdata.js b/frontend/src/__test__/environmentdata.js similarity index 100% rename from frontend/src/environmentdata.js rename to frontend/src/__test__/environmentdata.js diff --git a/frontend/src/scheduledata.js b/frontend/src/__test__/scheduledata.js similarity index 100% rename from frontend/src/scheduledata.js rename to frontend/src/__test__/scheduledata.js diff --git a/frontend/src/webhookdata.js b/frontend/src/__test__/webhookdata.js similarity index 100% rename from frontend/src/webhookdata.js rename to frontend/src/__test__/webhookdata.js diff --git a/frontend/src/workflowdata.js b/frontend/src/__test__/workflowdata.js similarity index 100% rename from frontend/src/workflowdata.js rename to frontend/src/__test__/workflowdata.js diff --git a/frontend/src/AlertPopup.js b/frontend/src/components/AlertPopup.js similarity index 100% rename from frontend/src/AlertPopup.js rename to frontend/src/components/AlertPopup.js diff --git a/frontend/src/AlertTemplate.js b/frontend/src/components/AlertTemplate.js similarity index 100% rename from frontend/src/AlertTemplate.js rename to frontend/src/components/AlertTemplate.js diff --git a/frontend/src/FooterNew.js b/frontend/src/components/FooterNew.js similarity index 100% rename from frontend/src/FooterNew.js rename to frontend/src/components/FooterNew.js diff --git a/frontend/src/Header.js b/frontend/src/components/Header.js similarity index 99% rename from frontend/src/Header.js rename to frontend/src/components/Header.js index 7a880bd5..54dfafc2 100644 --- a/frontend/src/Header.js +++ b/frontend/src/components/Header.js @@ -194,7 +194,7 @@ const Header = props => { - {userdata.orgs.length <= 1 ? null : + {userdata === undefined || userdata.orgs.length <= 1 ? null :