More Shuffle-Hybrid migration
This commit is contained in:
+34
-806
@@ -665,90 +665,6 @@ func parseLoginParameters(resp http.ResponseWriter, request *http.Request) (logi
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func deleteUser(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
userInfo, userErr := shuffle.HandleApiAuthentication(resp, request)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in edit workflow: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if userInfo.Role != "admin" {
|
||||
log.Printf("Wrong user (%s) when deleting - must be admin", userInfo.Username)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Must be admin"}`))
|
||||
return
|
||||
}
|
||||
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
var userId string
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
userId = location[4]
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
foundUser, err := shuffle.GetUser(ctx, userId)
|
||||
if err != nil {
|
||||
log.Printf("Can't find user %s (delete user): %s", userId, err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false}`)))
|
||||
return
|
||||
}
|
||||
|
||||
orgFound := false
|
||||
if userInfo.ActiveOrg.Id == foundUser.ActiveOrg.Id {
|
||||
orgFound = true
|
||||
} else {
|
||||
log.Printf("FoundUser: %#v", foundUser.Orgs)
|
||||
for _, item := range foundUser.Orgs {
|
||||
if item == userInfo.ActiveOrg.Id {
|
||||
orgFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !orgFound {
|
||||
log.Printf("User %s is admin, but can't delete users outside their own org.", userInfo.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Can't change users outside your org."}`)))
|
||||
return
|
||||
}
|
||||
|
||||
// Invert. No user deletion.
|
||||
if foundUser.Active {
|
||||
|
||||
foundUser.Active = false
|
||||
} else {
|
||||
foundUser.Active = true
|
||||
}
|
||||
|
||||
err = shuffle.SetUser(ctx, foundUser)
|
||||
if err != nil {
|
||||
log.Printf("Failed swapping active for user %s (%s)", foundUser.Username, foundUser.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false}`)))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Successfully inverted %s", foundUser.Username)
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
}
|
||||
|
||||
// No more emails :)
|
||||
func checkUsername(Username string) error {
|
||||
// Stupid first check of email loool
|
||||
@@ -1390,6 +1306,8 @@ func handleInfo(resp http.ResponseWriter, request *http.Request) {
|
||||
userInfo.ActiveOrg.Users = []shuffle.User{}
|
||||
}
|
||||
|
||||
userInfo.ActiveOrg.Users = []shuffle.User{}
|
||||
userInfo.ActiveOrg.SyncConfig = shuffle.SyncConfig{}
|
||||
currentOrg, err := json.Marshal(userInfo.ActiveOrg)
|
||||
if err != nil {
|
||||
currentOrg = []byte("{}")
|
||||
@@ -1616,163 +1534,6 @@ func handleGetSchedules(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write(newjson)
|
||||
}
|
||||
|
||||
func handleGetEnvironments(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := shuffle.HandleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in set new workflowhandler: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
var environments []shuffle.Environment
|
||||
q := datastore.NewQuery("Environments").Filter("org_id =", user.ActiveOrg.Id)
|
||||
_, err = dbclient.GetAll(ctx, q, &environments)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Can't get environments"}`))
|
||||
return
|
||||
}
|
||||
|
||||
newjson, err := json.Marshal(environments)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshal: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking environments"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
//log.Printf("Existing environments: %s", string(newjson))
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write(newjson)
|
||||
}
|
||||
|
||||
func handleGetOrg(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("Path too short: %d", len(location))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
user, err := shuffle.HandleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in set new workflowhandler: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
org, err := shuffle.GetOrg(ctx, fileId)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Failed getting org users"}`))
|
||||
return
|
||||
}
|
||||
|
||||
//FIXME : cleanup org before marshal
|
||||
userFound := false
|
||||
for _, foundUser := range org.Users {
|
||||
if foundUser.Id == user.Id {
|
||||
userFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !userFound {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Use doesn't have access to org"}`))
|
||||
return
|
||||
}
|
||||
|
||||
org.Users = []shuffle.User{}
|
||||
org.SyncConfig.Apikey = ""
|
||||
newjson, err := json.Marshal(org)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshal of org: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write(newjson)
|
||||
}
|
||||
|
||||
func handleGetOrgs(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := shuffle.HandleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in set new workflowhandler: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Role != "global_admin" {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
var orgs []shuffle.Org
|
||||
q := datastore.NewQuery("Organizations")
|
||||
_, err = dbclient.GetAll(ctx, q, &orgs)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Can't get users"}`))
|
||||
return
|
||||
}
|
||||
|
||||
//newUsers := []User{}
|
||||
//for _, item := range users {
|
||||
// if len(item.Username) == 0 {
|
||||
// continue
|
||||
// }
|
||||
|
||||
// item.Password = ""
|
||||
// item.Session = ""
|
||||
// item.VerificationToken = ""
|
||||
|
||||
// newUsers = append(newUsers, item)
|
||||
//}
|
||||
|
||||
newjson, err := json.Marshal(orgs)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshal: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed unpacking"}`)))
|
||||
return
|
||||
}
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write(newjson)
|
||||
}
|
||||
|
||||
func checkAdminLogin(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -4698,7 +4459,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// FIXME: CHECK IF SAME NAME AS NORMAL APP
|
||||
// Can't overwrite existing normal app
|
||||
workflowApps, err := shuffle.GetAllWorkflowApps(ctx, 500)
|
||||
workflowApps, err := shuffle.GetPrioritizedApps(ctx, user)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting all workflow apps from database to verify: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
@@ -4875,20 +4636,23 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) {
|
||||
// Backup every single one
|
||||
setOpenApiDatastore(ctx, api.ID, parsed)
|
||||
|
||||
err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed to increase success execution stats: %s", err)
|
||||
}
|
||||
/*
|
||||
err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed to increase success execution stats: %s", err)
|
||||
}
|
||||
|
||||
err = increaseStatisticsField(ctx, "openapi_apps_created", newmd5, 1, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed to increase success execution stats: %s", err)
|
||||
}
|
||||
err = increaseStatisticsField(ctx, "openapi_apps_created", newmd5, 1, user.ActiveOrg.Id)
|
||||
if err != nil {
|
||||
log.Printf("Failed to increase success execution stats: %s", err)
|
||||
}
|
||||
*/
|
||||
|
||||
cacheKey := fmt.Sprintf("workflowapps-sorted-100")
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
cacheKey = fmt.Sprintf("workflowapps-sorted-500")
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
shuffle.DeleteCache(ctx, fmt.Sprintf("apps_%s", user.Id))
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, api.ID)))
|
||||
@@ -4984,6 +4748,7 @@ func handleAppHotload(ctx context.Context, location string, forceUpdate bool) er
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
cacheKey = fmt.Sprintf("workflowapps-sorted-500")
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
shuffle.DeleteCache(ctx, fmt.Sprintf("apps_%s", user.Id))
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -5797,11 +5562,10 @@ func runInit(ctx context.Context) {
|
||||
|
||||
// Getting apps to see if we should initialize a test
|
||||
log.Printf("Getting remote workflow apps")
|
||||
workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 500)
|
||||
workflowapps, err := shuffle.GetPrioritizedApps(ctx, user)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting apps (runInit): %s", err)
|
||||
} else if err == nil && len(workflowapps) > 0 {
|
||||
//shuffle.GetAllWorkflowApps(ctx context.Context) ([]WorkflowApp, error) {
|
||||
var allworkflowapps []shuffle.WorkflowApp
|
||||
q := datastore.NewQuery("workflowapp")
|
||||
_, err := dbclient.GetAll(ctx, q, &allworkflowapps)
|
||||
@@ -5860,7 +5624,11 @@ func runInit(ctx context.Context) {
|
||||
//iterateAppGithubFolders(fs, dir, "", "testing")
|
||||
|
||||
// FIXME: Get all the apps?
|
||||
iterateAppGithubFolders(fs, dir, "", "", forceUpdate)
|
||||
_, _, err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Error from app load in init: %s", err)
|
||||
}
|
||||
//_, _, err = iterateAppGithubFolders(fs, dir, "", "", forceUpdate)
|
||||
|
||||
// Hotloads locally
|
||||
location := os.Getenv("SHUFFLE_APP_HOTLOAD_FOLDER")
|
||||
@@ -6060,368 +5828,6 @@ func handleStopCloudSync(syncUrl string, org shuffle.Org) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleKeyValueCheck(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(request.Body)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Append: Checks if the value should be appended
|
||||
// WorkflowCheck: Checks if the value should only check for workflow in org, or entire org
|
||||
// Authorization: the Authorization to use
|
||||
// ExecutionRef: Ref for the execution
|
||||
// Values: The values to use
|
||||
type DataValues struct {
|
||||
App string
|
||||
Actions string
|
||||
ParameterNames []string
|
||||
ParameterValues []string
|
||||
}
|
||||
|
||||
type ReturnData struct {
|
||||
Append bool `json:"append"`
|
||||
WorkflowCheck bool `json:"workflow_check"`
|
||||
Authorization string `json:"authorization"`
|
||||
ExecutionRef string `json:"execution_ref"`
|
||||
OrgId string `json:"org_id"`
|
||||
Values []DataValues `json:"values"`
|
||||
}
|
||||
|
||||
//for key, value := range data.Apps {
|
||||
var fileId string
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
log.Printf("Path too short: %d", len(location))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
var tmpData ReturnData
|
||||
err = json.Unmarshal(body, &tmpData)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshalling test: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if tmpData.OrgId != fileId {
|
||||
log.Printf("[INFO] OrgId %s and %s don't match", tmpData.OrgId, fileId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "Organization ID's don't match"}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
org, err := shuffle.GetOrg(ctx, tmpData.OrgId)
|
||||
if err != nil {
|
||||
log.Printf("[INFO] Organization doesn't exist: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
workflowExecution, err := shuffle.GetWorkflowExecution(ctx, tmpData.ExecutionRef)
|
||||
if err != nil {
|
||||
log.Printf("[INFO] User can't edit the org")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "No permission to get execution"}`))
|
||||
return
|
||||
}
|
||||
|
||||
if workflowExecution.Authorization != tmpData.Authorization {
|
||||
log.Printf("[INFO] Execution auth %s and %s don't match", workflowExecution.Authorization, tmpData.Authorization)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "Auth doesn't match"}`))
|
||||
return
|
||||
}
|
||||
|
||||
if workflowExecution.Status != "EXECUTING" {
|
||||
log.Printf("[INFO] Workflow isn't executing and shouldn't be searching", workflowExecution.ExecutionId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "Workflow isn't executing"}`))
|
||||
return
|
||||
}
|
||||
|
||||
if workflowExecution.ExecutionOrg != org.Id {
|
||||
log.Printf("[INFO] Org %s wasn't used to execute %s", org.Id, workflowExecution.ExecutionId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "Bad organization specified"}`))
|
||||
return
|
||||
}
|
||||
|
||||
// Prepared for the future~
|
||||
if len(tmpData.Values) != 1 {
|
||||
log.Printf("[INFO] Filter data can only hande 1 value right now, not %d", len(tmpData.Values))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "Can't handle multiple apps yet, just one"}`))
|
||||
return
|
||||
}
|
||||
|
||||
value := tmpData.Values[0]
|
||||
|
||||
// FIXME: Alphabetically sort the parameternames
|
||||
// FIXME: Add organization wide search, not just workflow based
|
||||
|
||||
found := []string{}
|
||||
notFound := []string{}
|
||||
|
||||
dbKey := fmt.Sprintf("app_execution_values")
|
||||
parameterNames := fmt.Sprintf("%s_%s", value.App, strings.Join(value.ParameterNames, "_"))
|
||||
log.Printf("[INFO] PARAMNAME: %s", parameterNames)
|
||||
if tmpData.WorkflowCheck {
|
||||
//for _, item := range tmpData.Values {
|
||||
// log.Printf("[INFO] Should validate if values %#v in app parameter %#v exists WITH WORKFLOW %s", item.ParameterValues, item.ParameterNames, workflowExecution.Workflow.ID)
|
||||
|
||||
// FIXME: Make this alphabetical
|
||||
|
||||
for _, value := range value.ParameterValues {
|
||||
if len(value) == 0 {
|
||||
log.Printf("Shouldn't have value of length 0!")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Looking for value %s in Workflow %s of ORG %s", value, workflowExecution.Workflow.ID, org.Id)
|
||||
|
||||
q := datastore.NewQuery(dbKey).Filter("org_id =", org.Id).Filter("workflow_id =", workflowExecution.Workflow.ID).Filter("parameter_name =", parameterNames).Filter("value =", value)
|
||||
foundCount, err := dbclient.Count(ctx, q)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed getting key %s: %s", dbKey, err)
|
||||
notFound = append(notFound, value)
|
||||
//found = append(found, value)
|
||||
continue
|
||||
}
|
||||
|
||||
if foundCount > 0 {
|
||||
found = append(found, value)
|
||||
} else {
|
||||
log.Printf("[INFO] Found for %s: %d", dbKey, foundCount)
|
||||
notFound = append(notFound, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//log.Printf("[INFO] Should validate if value %s in app %s exists WITH ORG %s", workflowExecution.Workflow.ID)
|
||||
|
||||
for _, value := range value.ParameterValues {
|
||||
if len(value) == 0 {
|
||||
log.Printf("Shouldn't have value of length 0!")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("[INFO] Looking for value %s in ORG %s", value, org.Id)
|
||||
|
||||
q := datastore.NewQuery(dbKey).Filter("org_id =", org.Id).Filter("workflow_id =", "").Filter("parameter_name =", parameterNames).Filter("value =", value)
|
||||
foundCount, err := dbclient.Count(ctx, q)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed getting key %s: %s", dbKey, err)
|
||||
notFound = append(notFound, value)
|
||||
//found = append(found, value)
|
||||
continue
|
||||
}
|
||||
|
||||
if foundCount > 0 {
|
||||
found = append(found, value)
|
||||
} else {
|
||||
log.Printf("[INFO] Found for %s: %d", dbKey, foundCount)
|
||||
notFound = append(notFound, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//App string
|
||||
//Actions string
|
||||
//ParameterNames string
|
||||
//ParamererValues []string
|
||||
|
||||
appended := 0
|
||||
if tmpData.Append {
|
||||
log.Printf("[INFO] Should append %d values!", len(notFound))
|
||||
dbKey := fmt.Sprintf("app_execution_values")
|
||||
|
||||
//q := datastore.NewQuery(dbKey).Filter("org_id =", org.Id).Filter("workflow_id", workflowExecution.Workflow.ID).Filter("app_name =", parameterNames).Filter("value =", value)
|
||||
key := datastore.NameKey(dbKey, "", nil)
|
||||
type NewValue struct {
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||
WorkflowExecutionId string `json:"workflow_execution_id" datastore:"workflow_execution_id"`
|
||||
ParameterName string `json:"parameter_name" datastore:"parameter_name"`
|
||||
Value string `json:"value" datastore:"value"`
|
||||
}
|
||||
|
||||
//parameterNames := strings.Join(value.ParameterNames, "_")
|
||||
for _, notFoundValue := range notFound {
|
||||
newRequest := NewValue{
|
||||
OrgId: org.Id,
|
||||
WorkflowExecutionId: workflowExecution.ExecutionId,
|
||||
ParameterName: parameterNames,
|
||||
Value: notFoundValue,
|
||||
}
|
||||
|
||||
if tmpData.WorkflowCheck {
|
||||
newRequest.WorkflowId = workflowExecution.Workflow.ID
|
||||
}
|
||||
|
||||
if _, err := dbclient.Put(ctx, key, &newRequest); err != nil {
|
||||
log.Printf("Error adding %s to appvalue: %s", notFoundValue, err)
|
||||
continue
|
||||
}
|
||||
|
||||
appended += 1
|
||||
log.Printf("[INFO] Added %s as new appvalue to datastore", notFoundValue)
|
||||
}
|
||||
}
|
||||
|
||||
type returnStruct struct {
|
||||
Success bool `json:"success"`
|
||||
Appended int `json:"appended"`
|
||||
Found []string `json:"found"`
|
||||
}
|
||||
|
||||
returnData := returnStruct{
|
||||
Success: true,
|
||||
Appended: appended,
|
||||
Found: found,
|
||||
}
|
||||
|
||||
b, _ := json.Marshal(returnData)
|
||||
resp.WriteHeader(200)
|
||||
resp.Write(b)
|
||||
}
|
||||
|
||||
func handleEditOrg(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := shuffle.HandleApiAuthentication(resp, request)
|
||||
if err != nil {
|
||||
log.Printf("Api authentication failed in cloud setup: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Role != "admin" {
|
||||
log.Printf("Not admin.")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(request.Body)
|
||||
if err != nil {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`))
|
||||
return
|
||||
}
|
||||
|
||||
type ReturnData struct {
|
||||
Image string `json:"image" datastore:"image"`
|
||||
Name string `json:"name" datastore:"name"`
|
||||
Description string `json:"description" datastore:"description"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
Defaults shuffle.Defaults `json:"defaults" datastore:"defaults"`
|
||||
}
|
||||
|
||||
var tmpData ReturnData
|
||||
err = json.Unmarshal(body, &tmpData)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshalling test: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
var fileId string
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
log.Printf("Path too short: %d", len(location))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
if tmpData.OrgId != user.ActiveOrg.Id || fileId != user.ActiveOrg.Id {
|
||||
log.Printf("User can't edit the org")
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "No permission to edit this org"}`))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
org, err := shuffle.GetOrg(ctx, tmpData.OrgId)
|
||||
if err != nil {
|
||||
log.Printf("Organization doesn't exist: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
admin := false
|
||||
userFound := false
|
||||
for _, inneruser := range org.Users {
|
||||
if inneruser.Id == user.Id {
|
||||
userFound = true
|
||||
if inneruser.Role == "admin" {
|
||||
admin = true
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !userFound {
|
||||
log.Printf("User %s doesn't exist in organization for edit %s", user.Id, org.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if !admin {
|
||||
log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
org.Image = tmpData.Image
|
||||
org.Name = tmpData.Name
|
||||
org.Description = tmpData.Description
|
||||
org.Defaults = tmpData.Defaults
|
||||
|
||||
//log.Printf("Org: %#v", org)
|
||||
err = setOrg(ctx, *org, org.Id)
|
||||
if err != nil {
|
||||
log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("SUCCESSFULLY UPDATED ORG")
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Successfully updated org"}`)))
|
||||
|
||||
}
|
||||
|
||||
// INFO: https://docs.google.com/drawings/d/1JJebpPeEVEbmH_qsAC6zf9Noygp7PytvesrkhE19QrY/edit
|
||||
/*
|
||||
This is here to both enable and disable cloud sync features for an organization
|
||||
@@ -6707,182 +6113,6 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write(respBody)
|
||||
}
|
||||
|
||||
//func handleEditOrg(resp http.ResponseWriter, request *http.Request) {
|
||||
// cors := handleCors(resp, request)
|
||||
// if cors {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// user, err := shuffle.HandleApiAuthentication(resp, request)
|
||||
// if err != nil {
|
||||
// log.Printf("Api authentication failed in cloud setup: %s", err)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// ctx := context.Background()
|
||||
// if user.Role != "admin" {
|
||||
// /*
|
||||
// log.Printf("User: %s", user.Role)
|
||||
// dbclient, err := getDatastoreClient(ctx, gceProject)
|
||||
// if err != nil {
|
||||
// log.Printf("Err1: %s", err)
|
||||
// }
|
||||
//
|
||||
// user.Role = "admin"
|
||||
// key := datastore.NameKey("Users", strings.ToLower(user.Username), nil)
|
||||
// if _, err := dbclient.Put(ctx, key, &user); err != nil {
|
||||
// log.Printf("Err2: %s", err)
|
||||
// }
|
||||
// */
|
||||
//
|
||||
// log.Printf("Not admin, can't edit org.")
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "Not admin"}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// body, err := ioutil.ReadAll(request.Body)
|
||||
// if err != nil {
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// type ReturnData struct {
|
||||
// Image string `json:"image" datastore:"image"`
|
||||
// Name string `json:"name" datastore:"name"`
|
||||
// Description string `json:"description" datastore:"description"`
|
||||
// OrgId string `json:"org_id" datastore:"org_id"`
|
||||
// SubscriptionId string `json:"subscription_id" datastore:"subscription_id"`
|
||||
// Action string `json:"action" datastore:"action"`
|
||||
// }
|
||||
//
|
||||
// var tmpData ReturnData
|
||||
// err = json.Unmarshal(body, &tmpData)
|
||||
// if err != nil {
|
||||
// log.Printf("Failed unmarshalling test: %s", err)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// var fileId string
|
||||
// location := strings.Split(request.URL.String(), "/")
|
||||
// if location[1] == "api" {
|
||||
// if len(location) <= 4 {
|
||||
// log.Printf("Path too short: %d", len(location))
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// fileId = location[4]
|
||||
// }
|
||||
//
|
||||
// if tmpData.OrgId != user.ActiveOrg.Id || fileId != user.ActiveOrg.Id {
|
||||
// log.Printf("User can't edit the org. Not part of ORG: %s vs %s", tmpData.OrgId, user.ActiveOrg.Id)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false, "No permission to edit this org"}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// org, err := shuffle.GetOrg(ctx, tmpData.OrgId)
|
||||
// if err != nil {
|
||||
// log.Printf("Organization doesn't exist: %s", err)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// admin := false
|
||||
// userFound := false
|
||||
// for _, inneruser := range org.Users {
|
||||
// if inneruser.Id == user.Id {
|
||||
// userFound = true
|
||||
// if inneruser.Role == "admin" {
|
||||
// admin = true
|
||||
// }
|
||||
//
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if !userFound {
|
||||
// log.Printf("User %s doesn't exist in organization for edit %s", user.Id, org.Id)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if !admin {
|
||||
// log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if tmpData.Image != org.Image {
|
||||
// org.Image = tmpData.Image
|
||||
// }
|
||||
//
|
||||
// if tmpData.Name != org.Name {
|
||||
// org.Name = tmpData.Name
|
||||
// }
|
||||
//
|
||||
// if tmpData.Description != org.Description {
|
||||
// org.Description = tmpData.Description
|
||||
// }
|
||||
//
|
||||
// if len(tmpData.SubscriptionId) > 0 {
|
||||
// log.Printf("Should update subscription %s with action %s if it exists", tmpData.SubscriptionId, tmpData.Action)
|
||||
// found := false
|
||||
// foundIndex := 0
|
||||
// for index, sub := range org.Subscriptions {
|
||||
// if tmpData.SubscriptionId == sub.Reference {
|
||||
// found = true
|
||||
// foundIndex = index
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if !found {
|
||||
// log.Printf("Couldn't find sub %s in org %s", tmpData.SubscriptionId, tmpData.OrgId)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if tmpData.Action == "cancel" {
|
||||
// _, err := sub.Cancel(tmpData.SubscriptionId, nil)
|
||||
// //log.Printf("Ret: %#v", subReturn)
|
||||
// if err != nil {
|
||||
// log.Printf("Failed canceling sub %s.", tmpData.SubscriptionId)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// } else {
|
||||
// log.Printf("Successfully canceled sub %s in org %s", tmpData.SubscriptionId, tmpData.OrgId)
|
||||
// timeNow := time.Now().Unix()
|
||||
// org.Subscriptions[foundIndex].Active = false
|
||||
// org.Subscriptions[foundIndex].CancellationDate = timeNow
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //log.Printf("Org: %#v", org)
|
||||
// err = setOrg(ctx, *org, org.Id)
|
||||
// if err != nil {
|
||||
// log.Printf("User %s doesn't have edit rights to %s", user.Id, org.Id)
|
||||
// resp.WriteHeader(401)
|
||||
// resp.Write([]byte(`{"success": false}`))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// resp.WriteHeader(200)
|
||||
// resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "Successfully updated org"}`)))
|
||||
//}
|
||||
|
||||
func initHandlers() {
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
@@ -6919,7 +6149,7 @@ func initHandlers() {
|
||||
r.HandleFunc("/api/v1/users/getsettings", shuffle.HandleSettings).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users/getusers", shuffle.HandleGetUsers).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users/updateuser", handleUpdateUser).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users/{user}", deleteUser).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users/{user}", shuffle.DeleteUser).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users/passwordchange", shuffle.HandlePasswordChange).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/users", shuffle.HandleGetUsers).Methods("GET", "OPTIONS")
|
||||
|
||||
@@ -6934,8 +6164,8 @@ func initHandlers() {
|
||||
r.HandleFunc("/api/v1/generateapikey", shuffle.HandleApiGeneration).Methods("GET", "POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/passwordchange", shuffle.HandlePasswordChange).Methods("POST", "OPTIONS")
|
||||
|
||||
r.HandleFunc("/api/v1/getenvironments", handleGetEnvironments).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/setenvironments", handleSetEnvironments).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/getenvironments", shuffle.HandleGetEnvironments).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/setenvironments", shuffle.HandleSetEnvironments).Methods("PUT", "OPTIONS")
|
||||
|
||||
r.HandleFunc("/api/v1/docs", getDocList).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/docs/{key}", getDocs).Methods("GET", "OPTIONS")
|
||||
@@ -6953,12 +6183,12 @@ func initHandlers() {
|
||||
|
||||
// App specific
|
||||
// From here down isnt checked for org specific
|
||||
r.HandleFunc("/api/v1/apps/{appId}", shuffle.UpdateWorkflowAppConfig).Methods("PATCH", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/{appId}", shuffle.DeleteWorkflowApp).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/run_hotload", handleAppHotloadRequest).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/get_existing", loadSpecificApps).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/download_remote", loadSpecificApps).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/{appId}", updateWorkflowAppConfig).Methods("PATCH", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/validate", validateAppInput).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/{appId}", deleteWorkflowApp).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps/{appId}/config", getWorkflowAppConfig).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps", getWorkflowApps).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/apps", setNewWorkflowApp).Methods("PUT", "OPTIONS")
|
||||
@@ -6980,6 +6210,8 @@ func initHandlers() {
|
||||
/* Everything below here increases the counters*/
|
||||
r.HandleFunc("/api/v1/workflows", shuffle.GetWorkflows).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows", shuffle.SetNewWorkflow).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}", shuffle.GetSpecificWorkflow).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}", shuffle.SaveWorkflow).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/schedules", handleGetSchedules).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}/schedule", scheduleWorkflow).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/download_remote", loadSpecificWorkflows).Methods("POST", "OPTIONS")
|
||||
@@ -6989,8 +6221,6 @@ func initHandlers() {
|
||||
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/{key}/abort", abortExecution).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}", shuffle.GetSpecificWorkflow).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}", shuffle.SaveWorkflow).Methods("PUT", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/workflows/{key}", deleteWorkflow).Methods("DELETE", "OPTIONS")
|
||||
|
||||
// Triggers
|
||||
@@ -7007,16 +6237,14 @@ func initHandlers() {
|
||||
|
||||
// NEW for 0.8.0
|
||||
r.HandleFunc("/api/v1/cloud/setup", handleCloudSetup).Methods("POST", "OPTIONS")
|
||||
|
||||
// Orgs
|
||||
r.HandleFunc("/api/v1/orgs", handleGetOrgs).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/", handleGetOrgs).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", handleGetOrg).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS")
|
||||
|
||||
r.HandleFunc("/api/v1/orgs", shuffle.HandleGetOrgs).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/", shuffle.HandleGetOrgs).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleGetOrg).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleEditOrg).Methods("POST", "OPTIONS")
|
||||
// This is a new API that validates if a key has been seen before.
|
||||
// Not sure what the best course of action is for it.
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}/validate_app_values", handleKeyValueCheck).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}/validate_app_values", shuffle.HandleKeyValueCheck).Methods("POST", "OPTIONS")
|
||||
|
||||
//r.HandleFunc("/api/v1/orgs/{orgId}", handleEditOrg).Methods("POST", "OPTIONS")
|
||||
|
||||
// Docker orborus specific
|
||||
|
||||
+33
-119
@@ -1802,7 +1802,7 @@ func deleteWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
if user.Id != workflow.Owner && user.Role != "admin" {
|
||||
if user.Id != workflow.Owner {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -1956,7 +1956,7 @@ func abortExecution(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
if user.Id != workflowExecution.Workflow.Owner && user.Role != "admin" {
|
||||
if user.Id != workflowExecution.Workflow.Owner {
|
||||
log.Printf("[INFO] Wrong user (%s) for workflowexecution workflow %s", user.Username, workflowExecution.Workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -2912,7 +2912,7 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
// FIXME - admin check like this? idk
|
||||
if user.Id != workflow.Owner && user.Role != "admin" && user.Role != "scheduler" && user.Role != fmt.Sprintf("workflow_%s", fileId) {
|
||||
if user.Id != workflow.Owner && user.Role != "scheduler" && user.Role != fmt.Sprintf("workflow_%s", fileId) {
|
||||
log.Printf("Wrong user (%s) for workflow %s (execute)", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -2987,7 +2987,7 @@ func stopSchedule(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
// FIXME - admin check like this? idk
|
||||
if user.Id != workflow.Owner && user.Role != "admin" && user.Role != "scheduler" {
|
||||
if user.Id != workflow.Owner && user.Role != "scheduler" {
|
||||
log.Printf("[WARNING] Wrong user (%s) for workflow %s (stop schedule)", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -3116,7 +3116,7 @@ func stopScheduleGCP(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
// FIXME - admin check like this? idk
|
||||
if user.Id != workflow.Owner && user.Role != "admin" && user.Role != "scheduler" {
|
||||
if user.Id != workflow.Owner && user.Role != "scheduler" {
|
||||
log.Printf("Wrong user (%s) for workflow %s (stop schedule)", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -3237,7 +3237,7 @@ func scheduleWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
// FIXME - admin check like this? idk
|
||||
if user.Id != workflow.Owner && user.Role != "admin" && user.Role != "scheduler" {
|
||||
if user.Id != workflow.Owner && user.Role != "scheduler" {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -3478,14 +3478,14 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
// FIXME - actually delete other than private apps too..
|
||||
private := false
|
||||
if app.Downloaded && user.Role == "admin" {
|
||||
log.Printf("Deleting downloaded app (authenticated users can do this)")
|
||||
} else if user.Id != app.Owner && user.Role != "admin" {
|
||||
log.Printf("Wrong user (%s) for app %s (delete)", user.Username, app.Name)
|
||||
log.Printf("[INFO] Deleting downloaded app (authenticated users can do this)")
|
||||
} else if user.Id != app.Owner {
|
||||
log.Printf("[WARNING] Wrong user (%s) for app %s (delete)", user.Username, app.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
} else {
|
||||
log.Printf("App to be deleted is private")
|
||||
log.Printf("[WARNING] App to be deleted is private")
|
||||
private = true
|
||||
}
|
||||
|
||||
@@ -3494,7 +3494,7 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
var workflows []shuffle.Workflow
|
||||
_, err = dbclient.GetAll(ctx, q, &workflows)
|
||||
if err != nil {
|
||||
log.Printf("Failed getting related workflows for the app: %s", err)
|
||||
log.Printf("[WARNING] Failed getting related workflows for the app: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
@@ -3671,7 +3671,7 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != app.Owner && user.Role != "admin" {
|
||||
if user.Id != app.Owner {
|
||||
log.Printf("[WARNING] Wrong user (%s) for app %s", user.Username, app.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -3705,96 +3705,6 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write(data)
|
||||
}
|
||||
|
||||
func updateWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
return
|
||||
}
|
||||
|
||||
user, userErr := shuffle.HandleApiAuthentication(resp, request)
|
||||
if userErr != nil {
|
||||
log.Printf("Api authentication failed in get all apps: %s", userErr)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
location := strings.Split(request.URL.String(), "/")
|
||||
var fileId string
|
||||
if location[1] == "api" {
|
||||
if len(location) <= 4 {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
fileId = location[4]
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
app, err := shuffle.GetApp(ctx, fileId)
|
||||
if err != nil {
|
||||
log.Printf("Error getting app (update app): %s", fileId)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != app.Owner && user.Role != "admin" {
|
||||
log.Printf("Wrong user (%s) for app %s in update app", user.Username, app.Name)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(request.Body)
|
||||
if err != nil {
|
||||
log.Printf("Error with body read in update app: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
type updatefields struct {
|
||||
Sharing bool `json:"sharing"`
|
||||
SharingConfig string `json:"sharing_config"`
|
||||
}
|
||||
|
||||
var tmpfields updatefields
|
||||
err = json.Unmarshal(body, &tmpfields)
|
||||
if err != nil {
|
||||
log.Printf("Error with unmarshal body in update app: %s\n%s", err, string(body))
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
if tmpfields.Sharing != app.Sharing {
|
||||
app.Sharing = tmpfields.Sharing
|
||||
}
|
||||
|
||||
if tmpfields.SharingConfig != app.SharingConfig {
|
||||
app.SharingConfig = tmpfields.SharingConfig
|
||||
}
|
||||
|
||||
err = shuffle.SetWorkflowAppDatastore(ctx, *app, app.ID)
|
||||
if err != nil {
|
||||
log.Printf("Failed patching workflowapp: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
return
|
||||
}
|
||||
|
||||
cacheKey := fmt.Sprintf("workflowapps-sorted-100")
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
cacheKey = fmt.Sprintf("workflowapps-sorted-500")
|
||||
shuffle.DeleteCache(ctx, cacheKey)
|
||||
|
||||
log.Printf("Changed workflow app %s", app.ID)
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
|
||||
}
|
||||
|
||||
func getWorkflowApps(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -4432,9 +4342,9 @@ func handleAppHotloadRequest(resp http.ResponseWriter, request *http.Request) {
|
||||
log.Printf("[INFO] Starting hotloading from %s", location)
|
||||
err = handleAppHotload(ctx, location, true)
|
||||
if err != nil {
|
||||
log.Printf("Failed app hotload: %s", err)
|
||||
log.Printf("[WARNING] Failed app hotload: %s", err)
|
||||
resp.WriteHeader(500)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed loading apps: %s"}`, err)))
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4625,7 +4535,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
|
||||
}
|
||||
|
||||
if contOuter {
|
||||
log.Printf("Skipping %s", filename)
|
||||
//log.Printf("Skipping %s", filename)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -4859,12 +4769,10 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
"YARA",
|
||||
}
|
||||
|
||||
// It's here to prevent getting them in every iteration
|
||||
buildLaterFirst := []buildLaterStruct{}
|
||||
buildLaterList := []buildLaterStruct{}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// It's here to prevent getting them in every iteration
|
||||
for _, file := range dir {
|
||||
if len(onlyname) > 0 && file.Name() != onlyname {
|
||||
continue
|
||||
@@ -4882,10 +4790,6 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
|
||||
// Go routine? Hmm, this can be super quick I guess
|
||||
buildFirst, buildLast, err := iterateAppGithubFolders(fs, dir, tmpExtra, "", forceUpdate)
|
||||
if err != nil {
|
||||
log.Printf("Error reading folder: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, item := range buildFirst {
|
||||
buildLaterFirst = append(buildLaterFirst, item)
|
||||
@@ -4895,6 +4799,15 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
buildLaterList = append(buildLaterList, item)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Error reading folder: %s", err)
|
||||
//buildFirst, buildLast, err := iterateAppGithubFolders(fs, dir, tmpExtra, "", forceUpdate)
|
||||
|
||||
if !forceUpdate {
|
||||
return buildLaterFirst, buildLaterList, err
|
||||
}
|
||||
}
|
||||
|
||||
case mode.IsRegular():
|
||||
// Check the file
|
||||
filename := file.Name()
|
||||
@@ -4964,8 +4877,9 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
var workflowapp shuffle.WorkflowApp
|
||||
err = gyaml.Unmarshal(appfileData, &workflowapp)
|
||||
if err != nil {
|
||||
log.Printf("Failed unmarshaling workflowapp %s: %s", fullPath, err)
|
||||
continue
|
||||
log.Printf("[WARNING] Failed building workflowapp %s: %s", extra, err)
|
||||
return buildLaterFirst, buildLaterList, errors.New(fmt.Sprintf("Failed building %s: %s", extra, err))
|
||||
//continue
|
||||
}
|
||||
|
||||
newName := workflowapp.Name
|
||||
@@ -5007,7 +4921,7 @@ func iterateAppGithubFolders(fs billy.Filesystem, dir []os.FileInfo, extra strin
|
||||
|
||||
// Fixes (appends) authentication parameters if they're required
|
||||
if workflowapp.Authentication.Required {
|
||||
log.Printf("Checking authentication fields and appending for %s!", workflowapp.Name)
|
||||
log.Printf("[INFO] Checking authentication fields and appending for %s!", workflowapp.Name)
|
||||
// FIXME:
|
||||
// Might require reflection into the python code to append the fields as well
|
||||
for index, action := range workflowapp.Actions {
|
||||
@@ -5305,7 +5219,7 @@ func getWorkflowExecutions(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
// FIXME - have a check for org etc too..
|
||||
if user.Id != workflow.Owner && user.Role != "admin" {
|
||||
if user.Id != workflow.Owner {
|
||||
log.Printf("Wrong user (%s) for workflow %s (get execution)", user.Username, workflow.ID)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -5637,7 +5551,7 @@ func handleStopHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != hook.Owner && user.Role != "admin" {
|
||||
if user.Id != hook.Owner {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -5720,7 +5634,7 @@ func handleDeleteHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != hook.Owner && user.Role != "admin" && user.ActiveOrg.Id != hook.OrgId {
|
||||
if user.Id != hook.Owner && user.ActiveOrg.Id != hook.OrgId {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
@@ -5861,7 +5775,7 @@ func handleStartHook(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id != hook.Owner && user.Role != "admin" {
|
||||
if user.Id != hook.Owner {
|
||||
log.Printf("Wrong user (%s) for workflow %s", user.Username, hook.Id)
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false}`))
|
||||
|
||||
@@ -348,7 +348,9 @@ const Admin = (props) => {
|
||||
|
||||
const deleteUser = (data) => {
|
||||
// Just use this one?
|
||||
const url = globalUrl + '/api/v1/users/' + data.id
|
||||
const userId = isCloud ? data.username : data.id
|
||||
|
||||
const url = globalUrl + '/api/v1/users/' + userId
|
||||
fetch(url, {
|
||||
method: 'DELETE',
|
||||
credentials: "include",
|
||||
@@ -1038,7 +1040,8 @@ const Admin = (props) => {
|
||||
|
||||
|
||||
|
||||
const generateApikey = (userId) => {
|
||||
const generateApikey = (user) => {
|
||||
const userId = isCloud ? user.username : user.id
|
||||
const data = { "user_id": userId }
|
||||
|
||||
fetch(globalUrl + "/api/v1/generateapikey", {
|
||||
@@ -1209,7 +1212,7 @@ const Admin = (props) => {
|
||||
style={{}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => generateApikey(selectedUser.id)}
|
||||
onClick={() => generateApikey(selectedUser)}
|
||||
>
|
||||
Get new API key
|
||||
</Button>
|
||||
@@ -1748,12 +1751,12 @@ const Admin = (props) => {
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Username"
|
||||
style={{ minWidth: 200, maxWidth: 200 }}
|
||||
style={{ minWidth: 300, maxWidth: 300}}
|
||||
/>
|
||||
|
||||
<ListItemText
|
||||
primary="API key"
|
||||
style={{ minWidth: 360, maxWidth: 360, overflow: "hidden" }}
|
||||
style={{ minWidth: 100, maxWidth: 100, overflow: "hidden" }}
|
||||
/>
|
||||
|
||||
<ListItemText
|
||||
@@ -1779,42 +1782,61 @@ const Admin = (props) => {
|
||||
<ListItem key={index} style={{backgroundColor: bgColor}}>
|
||||
<ListItemText
|
||||
primary={data.username}
|
||||
style={{ minWidth: 200, maxWidth: 200 }}
|
||||
style={{ minWidth: 300, maxWidth: 300, overflow: "hidden",}}
|
||||
/>
|
||||
|
||||
<ListItemText
|
||||
primary={data.apikey === undefined || data.apikey.length === 0 ? "" : data.apikey}
|
||||
style={{ maxWidth: 360, minWidth: 360, }}
|
||||
/>
|
||||
style={{ maxWidth: 100, minWidth: 100, }}
|
||||
primary={data.apikey === undefined || data.apikey.length === 0 ? "" :
|
||||
<Tooltip title={"Copy Api Key"} style={{}} aria-label={"Copy APIkey"}>
|
||||
<IconButton style={{}} onClick={() => {
|
||||
const elementName = "copy_element_shuffle"
|
||||
var copyText = document.getElementById(elementName);
|
||||
if (copyText !== null && copyText !== undefined) {
|
||||
navigator.clipboard.writeText(data.apikey)
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999); /* For mobile devices */
|
||||
|
||||
/* Copy the text inside the text field */
|
||||
document.execCommand("copy");
|
||||
|
||||
alert.info("Apikey copied to clipboard")
|
||||
}
|
||||
}}>
|
||||
<FileCopyIcon style={{color: "rgba(255,255,255,0.8)"}}/>
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
}/>
|
||||
|
||||
<ListItemText
|
||||
primary=
|
||||
{<Select
|
||||
SelectDisplayProps={{
|
||||
style: {
|
||||
marginLeft: 10,
|
||||
{<Select
|
||||
SelectDisplayProps={{
|
||||
style: {
|
||||
marginLeft: 10,
|
||||
}
|
||||
}}
|
||||
value={data.role}
|
||||
fullWidth
|
||||
onChange={(e) => {
|
||||
console.log("VALUE: ", e.target.value)
|
||||
|
||||
if (isCloud) {
|
||||
setUser(data.username, "role", e.target.value)
|
||||
} else {
|
||||
setUser(data.id, "role", e.target.value)
|
||||
}
|
||||
}}
|
||||
value={data.role}
|
||||
fullWidth
|
||||
onChange={(e) => {
|
||||
console.log("VALUE: ", e.target.value)
|
||||
|
||||
if (isCloud) {
|
||||
setUser(data.username, "role", e.target.value)
|
||||
} else {
|
||||
setUser(data.id, "role", e.target.value)
|
||||
}
|
||||
}}
|
||||
style={{ backgroundColor: theme.palette.surfaceColor, color: "white", height: "50px" }}
|
||||
>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"admin"}>
|
||||
Admin
|
||||
</MenuItem>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"user"}>
|
||||
User
|
||||
</MenuItem>
|
||||
</Select>}
|
||||
>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"admin"}>
|
||||
Admin
|
||||
</MenuItem>
|
||||
<MenuItem style={{ backgroundColor: theme.palette.inputColor, color: "white" }} value={"user"}>
|
||||
User
|
||||
</MenuItem>
|
||||
</Select>
|
||||
}
|
||||
style ={{ minWidth: 135, maxWidth: 135, marginRight: 15,}}
|
||||
/>
|
||||
<ListItemText
|
||||
@@ -1831,7 +1853,9 @@ const Admin = (props) => {
|
||||
<EditIcon color="primary"/>
|
||||
</IconButton>
|
||||
<Button
|
||||
onClick={() => generateApikey(data.id)}
|
||||
onClick={() => {
|
||||
generateApikey(data)
|
||||
}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
>
|
||||
@@ -1932,7 +1956,7 @@ const Admin = (props) => {
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Status"
|
||||
style={{minWidth: 75, maxWidth: 75}}
|
||||
style={{minWidth: 75, maxWidth: 75, marginLeft: 10,}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Filesize"
|
||||
@@ -1984,7 +2008,7 @@ const Admin = (props) => {
|
||||
/>
|
||||
<ListItemText
|
||||
primary={file.status}
|
||||
style={{minWidth: 75, maxWidth: 75, overflow: "hidden"}}
|
||||
style={{minWidth: 75, maxWidth: 75, overflow: "hidden", marginLeft: 10,}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={file.filesize}
|
||||
@@ -2221,7 +2245,7 @@ const Admin = (props) => {
|
||||
/>
|
||||
<ListItemText
|
||||
primary="App Name"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
style={{minWidth: 175, maxWidth: 175, marginLeft: 10,}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Ready"
|
||||
@@ -2257,15 +2281,15 @@ const Admin = (props) => {
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.label}
|
||||
style={{minWidth: 225, maxWidth: 225}}
|
||||
style={{minWidth: 225, maxWidth: 225, overflow: "hidden",}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.app.name}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
style={{minWidth: 175, maxWidth: 175, marginLeft: 10}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.defined === false ? "No" : "Yes"}
|
||||
style={{minWidth: 100, maxWidth: 100}}
|
||||
style={{minWidth: 100, maxWidth: 100, marginLeft: 10,}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.workflow_count === null ? 0 : data.workflow_count}
|
||||
|
||||
@@ -88,7 +88,7 @@ const AngularWorkflow = (props) => {
|
||||
const { globalUrl, isLoggedIn, isLoaded, userdata } = props;
|
||||
const referenceUrl = globalUrl+"/api/v1/hooks/"
|
||||
const alert = useAlert()
|
||||
const borderRadius = 3
|
||||
const borderRadius = 5
|
||||
const theme = useTheme();
|
||||
|
||||
const [bodyWidth, bodyHeight] = useWindowSize();
|
||||
@@ -883,6 +883,19 @@ const AngularWorkflow = (props) => {
|
||||
setExecutionRequestStarted(false)
|
||||
}
|
||||
|
||||
if (responseJson.execution_id === "" || responseJson.execution_id === undefined || responseJson.authorization === "" || responseJson.authorization === undefined ) {
|
||||
alert.error("Something went wrong during execution startup")
|
||||
console.log("BAD RESPONSE FOR EXECUTION: ", responseJson)
|
||||
setExecutionRunning(false)
|
||||
setExecutionRequestStarted(false)
|
||||
stop()
|
||||
|
||||
for (var i = 0; i < curelements.length; i++) {
|
||||
curelements[i].removeClass("not-executing-highlight")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
setExecutionRequest({
|
||||
"execution_id": responseJson.execution_id,
|
||||
"authorization": responseJson.authorization,
|
||||
@@ -1021,7 +1034,7 @@ const AngularWorkflow = (props) => {
|
||||
|
||||
|
||||
const getApps = () => {
|
||||
fetch(globalUrl+"/api/v1/workflows/apps", {
|
||||
fetch(globalUrl+"/api/v1/apps", {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -1042,11 +1055,16 @@ const AngularWorkflow = (props) => {
|
||||
//var tmpapps = []
|
||||
//tmpapps = tmpapps.concat(getExtraApps())
|
||||
//tmpapps = tmpapps.concat(responseJson)
|
||||
console.log("APPS: ", responseJson)
|
||||
setApps(responseJson)
|
||||
//getAppAuthentication()
|
||||
|
||||
setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated)))
|
||||
setPrioritizedApps(responseJson.filter(app => internalIds.includes(app.name)))
|
||||
if (isCloud) {
|
||||
setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name)))
|
||||
setPrioritizedApps(responseJson.filter(app => internalIds.includes(app.name)))
|
||||
} else {
|
||||
setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated)))
|
||||
setPrioritizedApps(responseJson.filter(app => internalIds.includes(app.name)))
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert.error(error.toString())
|
||||
@@ -1172,6 +1190,12 @@ const AngularWorkflow = (props) => {
|
||||
const onNodeSelect = (event, newAppAuth) => {
|
||||
const data = event.target.data()
|
||||
setLastSaved(false)
|
||||
|
||||
const node = cy.getElementById(data.id)
|
||||
if (node.length > 0) {
|
||||
node.addClass('shuffle-hover-highlight')
|
||||
}
|
||||
|
||||
//const branch = workflow.branches.filter(branch => branch.source_id === data.id || branch.destination_id === data.id)
|
||||
console.log("NODE: ", data)
|
||||
//console.log("BRANCHES: ", branch)
|
||||
@@ -2757,6 +2781,7 @@ const AngularWorkflow = (props) => {
|
||||
//setSelectedActionEnvironment(env)
|
||||
|
||||
setSelectedAction(selectedAction)
|
||||
setUpdate(Math.random())
|
||||
}
|
||||
|
||||
// APPSELECT at top
|
||||
@@ -2996,6 +3021,7 @@ const AngularWorkflow = (props) => {
|
||||
selectedActionParameters[count]["value_replace"] = paramcheck
|
||||
selectedAction.parameters[count]["value_replace"] = paramcheck
|
||||
setSelectedAction(selectedAction)
|
||||
//setUpdate(Math.random())
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -3088,6 +3114,7 @@ const AngularWorkflow = (props) => {
|
||||
selectedActionParameters[count].value = event.target.value
|
||||
selectedAction.parameters[count].value = event.target.value
|
||||
setSelectedAction(selectedAction)
|
||||
//setUpdate(Math.random())
|
||||
//setUpdate(event.target.value)
|
||||
}
|
||||
|
||||
@@ -3125,7 +3152,7 @@ const AngularWorkflow = (props) => {
|
||||
setSelectedApp(selectedApp)
|
||||
|
||||
setSelectedAction(selectedAction)
|
||||
setUpdate(fieldvalue)
|
||||
setUpdate(Math.random())
|
||||
}
|
||||
|
||||
const changeActionParameterVariant = (data, count) => {
|
||||
@@ -3157,6 +3184,7 @@ const AngularWorkflow = (props) => {
|
||||
// Set value
|
||||
setSelectedApp(selectedApp)
|
||||
setSelectedAction(selectedAction)
|
||||
setUpdate(Math.random())
|
||||
}
|
||||
|
||||
// FIXME: Issue #40 - selectedActionParameters not reset
|
||||
@@ -3177,6 +3205,7 @@ const AngularWorkflow = (props) => {
|
||||
selectedActionParameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
|
||||
selectedAction.parameters[count].value = selectedAction.selectedAuthentication.fields[data.name]
|
||||
setSelectedAction(selectedAction)
|
||||
//setUpdate(Math.random())
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -2502,7 +2502,9 @@ const AppCreator = (props) => {
|
||||
}}>
|
||||
{appBuilding ? <CircularProgress /> : "Save"}
|
||||
</Button>
|
||||
{errorCode.length > 0 ? `Error: ${errorCode}` : null}
|
||||
<Typography style={{marginTop: 5}}>
|
||||
{errorCode.length > 0 ? `Error: ${errorCode}` : null}
|
||||
</Typography>
|
||||
</Paper>
|
||||
</div>
|
||||
|
||||
|
||||
+25
-11
@@ -195,6 +195,10 @@ const Apps = (props) => {
|
||||
setIsLoading(false)
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for apps :O!")
|
||||
|
||||
if (isCloud) {
|
||||
window.location.pathname = "/search"
|
||||
}
|
||||
}
|
||||
|
||||
return response.json()
|
||||
@@ -648,11 +652,17 @@ const Apps = (props) => {
|
||||
<Select
|
||||
value={sharingConfiguration}
|
||||
onChange={(event) => {
|
||||
setSharingConfiguration(event.target.value)
|
||||
alert.info("Changed sharing to "+event.target.value)
|
||||
alert.info("Changing sharing to "+event.target.value)
|
||||
|
||||
updateAppField(selectedApp.id, "sharing", !selectedApp.sharing)
|
||||
//setSelectedAction(event.target.value)
|
||||
setSharingConfiguration(event.target.value)
|
||||
|
||||
if (event.target.value === "you") {
|
||||
updateAppField(selectedApp.id, "sharing", false)
|
||||
} else if (event.target.value === "everyone") {
|
||||
updateAppField(selectedApp.id, "sharing", true)
|
||||
} else {
|
||||
console.log("Can't handle value for sharing: ", event.target.value)
|
||||
}
|
||||
}}
|
||||
style={{width: 150, backgroundColor: theme.palette.surfaceColor, backgroundColor: inputColor, color: "white", height: 35, marginleft: 10,}}
|
||||
SelectDisplayProps={{
|
||||
@@ -910,9 +920,8 @@ const Apps = (props) => {
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
{isCloud ? null :
|
||||
<TextField
|
||||
style={{backgroundColor: inputColor}}
|
||||
style={{backgroundColor: inputColor, borderRadius: 5,}}
|
||||
InputProps={{
|
||||
style:{
|
||||
color: "white",
|
||||
@@ -920,6 +929,7 @@ const Apps = (props) => {
|
||||
marginLeft: "5px",
|
||||
maxWidth: "95%",
|
||||
fontSize: "1em",
|
||||
borderRadius: 5,
|
||||
},
|
||||
}}
|
||||
fullWidth
|
||||
@@ -930,7 +940,6 @@ const Apps = (props) => {
|
||||
setCursearch(event.target.value)
|
||||
}}
|
||||
/>
|
||||
}
|
||||
<div style={{marginTop: 15}}>
|
||||
{apps.length > 0 ?
|
||||
filteredApps.length > 0 ?
|
||||
@@ -1057,8 +1066,11 @@ const Apps = (props) => {
|
||||
return response.json()
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (responseJson.reason !== undefined && responseJson.reason.length > 0) {
|
||||
alert.info("Hotloading: ", responseJson.reason)
|
||||
if (responseJson.success === true) {
|
||||
alert.info("Successfully finished hotload")
|
||||
} else {
|
||||
alert.error("Failed hotload: ", responseJson.reason)
|
||||
//(responseJson.reason !== undefined && responseJson.reason.length > 0) {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -1116,6 +1128,8 @@ const Apps = (props) => {
|
||||
const data = {}
|
||||
data[fieldname] = fieldvalue
|
||||
|
||||
console.log("DATA: ", data)
|
||||
|
||||
fetch(globalUrl+"/api/v1/apps/"+app_id, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
@@ -1132,9 +1146,9 @@ const Apps = (props) => {
|
||||
//console.log(responseJson)
|
||||
//alert.info(responseJson)
|
||||
if (responseJson.success) {
|
||||
alert.info("Success")
|
||||
alert.success("Successfully updated app configuration")
|
||||
} else {
|
||||
alert.error("Error updating app")
|
||||
alert.error("Error updating app configuration")
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
@@ -527,7 +527,6 @@ const Workflows = (props) => {
|
||||
|
||||
|
||||
const deleteWorkflow = (id) => {
|
||||
alert.success("Deleted workflow "+id)
|
||||
fetch(globalUrl+"/api/v1/workflows/"+id, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
@@ -539,6 +538,9 @@ const Workflows = (props) => {
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for setting workflows :O!")
|
||||
alert.error("Failed deleting workflow")
|
||||
} else {
|
||||
alert.success("Deleted workflow "+id)
|
||||
}
|
||||
|
||||
return response.json()
|
||||
|
||||
Reference in New Issue
Block a user