From 4e10981db53a9f8d790781819a8070b8f9b0fb75 Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 1 Jun 2020 10:05:20 +0200 Subject: [PATCH] Fixed body and header issues with app creator --- backend/go-app/codegen.go | 65 +++++++------------------- backend/go-app/main.go | 34 ++++++++------ backend/go-app/walkoff.go | 3 ++ frontend/src/AppCreator.js | 96 +++++++++++++++++++++++++++----------- 4 files changed, 109 insertions(+), 89 deletions(-) diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index f39ba2fd..0a6a9811 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -16,7 +16,7 @@ import ( "cloud.google.com/go/storage" "github.com/getkin/kin-openapi/openapi3" - "github.com/satori/go.uuid" + //"github.com/satori/go.uuid" "gopkg.in/yaml.v2" ) @@ -347,7 +347,11 @@ func generateYaml(swagger *openapi3.Swagger, newmd5 string) (WorkflowApp, []stri api.Name = swagger.Info.Title api.Description = swagger.Info.Description - api.ID = uuid.NewV4().String() + + // FIXME: Versioning issue? + api.ID = newmd5 + //uuid.NewV4().String() + api.IsValid = true api.Link = swagger.Servers[0].URL // host doesnt exist lol if strings.HasSuffix(api.Link, "/") { @@ -722,7 +726,7 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ optionalParameters := []WorkflowAppActionParameter{} if len(path.Connect.Parameters) > 0 { for _, param := range path.Connect.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } curParam := WorkflowAppActionParameter{ @@ -828,8 +832,7 @@ func handleGet(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor optionalParameters := []WorkflowAppActionParameter{} if len(path.Get.Parameters) > 0 { for _, param := range path.Get.Parameters { - //log.Printf("TYPE: %#v", param.Value.Schema) - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } @@ -933,7 +936,7 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo optionalParameters := []WorkflowAppActionParameter{} if len(path.Head.Parameters) > 0 { for _, param := range path.Head.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } curParam := WorkflowAppActionParameter{ @@ -1036,7 +1039,7 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] optionalParameters := []WorkflowAppActionParameter{} if len(path.Delete.Parameters) > 0 { for _, param := range path.Delete.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } curParam := WorkflowAppActionParameter{ @@ -1140,26 +1143,13 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} - /* - WorkflowAppActionParameter{ - Name: "body", - Description: "The body to use", - Multiline: true, - Required: false, - Example: `{"username": "test"}`, - Schema: SchemaDefinition{ - Type: "string", - }, - }, - } - */ + if len(path.Post.Parameters) > 0 { for _, param := range path.Post.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } - log.Printf("PARAM: %#v", param.Value) curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -1257,21 +1247,10 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W firstQuery = true optionalQueries := []string{} parameters := []string{} - optionalParameters := []WorkflowAppActionParameter{ - WorkflowAppActionParameter{ - Name: "body", - Description: "The body to use", - Multiline: true, - Required: false, - Example: `{"username": "test"}`, - Schema: SchemaDefinition{ - Type: "string", - }, - }, - } + optionalParameters := []WorkflowAppActionParameter{} if len(path.Patch.Parameters) > 0 { for _, param := range path.Patch.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } curParam := WorkflowAppActionParameter{ @@ -1372,22 +1351,10 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor optionalQueries := []string{} parameters := []string{} optionalParameters := []WorkflowAppActionParameter{} - /* - WorkflowAppActionParameter{ - Name: "body", - Description: "The body to use", - Multiline: true, - Required: false, - Example: `{"username": "test"}`, - Schema: SchemaDefinition{ - Type: "string", - }, - }, - } - */ + if len(path.Put.Parameters) > 0 { for _, param := range path.Put.Parameters { - if param.Value.Schema == nil { + if param.Value.Schema == nil || param.Value.In == "header" { continue } curParam := WorkflowAppActionParameter{ diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 356e0e4a..bfb523e8 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -2112,7 +2112,6 @@ func SetSession(ctx context.Context, Userdata User, value string) error { func setOpenApiDatastore(ctx context.Context, id string, data ParsedOpenApi) error { k := datastore.NameKey("openapi3", id, nil) if _, err := dbclient.Put(ctx, k, &data); err != nil { - log.Println(err) return err } @@ -5075,6 +5074,8 @@ func getOpenapi(resp http.ResponseWriter, request *http.Request) { return } + log.Printf("API LENGTH GET: %d, ID: %s", len(parsedApi.Body), id) + parsedApi.Success = true data, err := json.Marshal(parsedApi) if err != nil { @@ -5505,13 +5506,6 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { // Test = client side with fetch? ctx := context.Background() - //client, err := storage.NewClient(ctx) - //if err != nil { - // log.Printf("Failed to create client (storage): %v", err) - // resp.WriteHeader(401) - // resp.Write([]byte(`{"success": false, "reason": "Failed creating client"}`)) - // return - //} swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(body) if err != nil { @@ -5542,6 +5536,9 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { return } + log.Printf("PATHS: %#v", swagger.Paths["/comments/put"]) + log.Printf("Functions: %d", len(swagger.Paths)) + log.Printf("Actions: %d", len(api.Actions)) api.Owner = user.Id err = dumpApi(basePath, api) @@ -5680,24 +5677,35 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { return } + log.Printf("DO I REACH HERE WHEN SAVING?") parsed := ParsedOpenApi{ - ID: api.ID, + ID: newmd5, Body: string(body), } - setOpenApiDatastore(ctx, api.ID, parsed) - err = increaseStatisticsField(ctx, "total_apps_created", api.ID, 1) + log.Printf("API LENGTH: %d, ID: %s", len(parsed.Body), newmd5) + // FIXME: Might cause versioning issues if we re-use the same!! + // FIXME: Need a way to track different versions of the same app properly. + // Hint: Save API.id somewhere, and use newmd5 to save latest version + err = setOpenApiDatastore(ctx, newmd5, parsed) + if err != nil { + log.Printf("Failed saving to datastore: %s", err) + resp.WriteHeader(500) + resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%"}`, err))) + } + + err = increaseStatisticsField(ctx, "total_apps_created", newmd5, 1) if err != nil { log.Printf("Failed to increase success execution stats: %s", err) } - err = increaseStatisticsField(ctx, "openapi_apps_created", api.ID, 1) + err = increaseStatisticsField(ctx, "openapi_apps_created", newmd5, 1) if err != nil { log.Printf("Failed to increase success execution stats: %s", err) } resp.WriteHeader(200) - resp.Write([]byte(`{"success": true}`)) + resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, api.ID))) } func healthCheckHandler(resp http.ResponseWriter, request *http.Request) { diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index af100687..b09713c7 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -2745,6 +2745,9 @@ func getWorkflowAppConfig(resp http.ResponseWriter, request *http.Request) { return } + //log.Printf("%#v", parsedApi) + log.Printf("API LEN: %d, ID: %s", len(parsedApi.Body), fileId) + //log.Printf("Parsed API: %#v", parsedApi) if len(parsedApi.ID) > 0 { parsedApi.Success = true diff --git a/frontend/src/AppCreator.js b/frontend/src/AppCreator.js index db545fed..c8b99057 100644 --- a/frontend/src/AppCreator.js +++ b/frontend/src/AppCreator.js @@ -60,7 +60,7 @@ const useStyles = makeStyles({ }) -function rewrite(args) { +const rewrite = (args) => { return args.reduce(function(args, a){ if (0 == a.indexOf('-X')) { args.push('-X') @@ -73,14 +73,15 @@ function rewrite(args) { }, []) } -function parseField(s) { +const parseField = (s) => { return s.split(/: (.+)/) } -function isURL(s) { +const isURL = (s) => { return /^https?:\/\//.test(s) } +// Parses CURL to a real request const parseCurl = (s) => { //console.log("CURL: ", s) @@ -230,16 +231,16 @@ const AppCreator = (props) => { const [currentActionMethod, setCurrentActionMethod] = useState(actionNonBodyRequest[0]) const [currentAction, setCurrentAction] = useState({ - "name": "", - "description": "", - "url": "", - "headers": "", - "paths": [], - "queries": [], - "body": "", - "errors": [], - "method": actionNonBodyRequest[0], - }); + "name": "", + "description": "", + "url": "", + "headers": "", + "paths": [], + "queries": [], + "body": "", + "errors": [], + "method": actionNonBodyRequest[0], + }); @@ -429,6 +430,16 @@ const AppCreator = (props) => { } else if (parameter.in === "path") { // FIXME - parse this to the URL too newaction.paths.push(parameter.name) + + // FIXME: This doesn't follow OpenAPI3 exactly. + // https://swagger.io/docs/specification/describing-request-body/ + // https://swagger.io/docs/specification/describing-parameters/ + // Need to split the data. + } else if (parameter.in === "body") { + console.log("BODY: ", parameter) + newaction.body = parameter.example + } else if (parameter.in === "header") { + newaction.headers += `${parameter.name}=${parameter.example}\n` } } @@ -579,10 +590,42 @@ const AppCreator = (props) => { }, } - console.log(data.paths[item.url][item.method.toLowerCase()]) - data.paths[item.url][item.method.toLowerCase()].parameters.push(newitem) } + + if (item.headers.length > 0) { + const required = false + + const headersSplit = item.headers.split("\n") + for (var key in headersSplit) { + const header = headersSplit[key] + var key = "" + var value = "" + if (header.length > 0 && header.includes("=")) { + const headersplit = header.split("=") + key = headersplit[0] + value = headersplit[1] + } else { + continue + } + + if (key.length > 0 && value.length > 0) { + newitem = { + "in": "header", + "name": key, + "multiline": false, + "description": "Header generated by shuffler.io OpenAPI", + "required": false, + "example": value, + "schema": { + "type": "string", + }, + } + + data.paths[item.url][item.method.toLowerCase()].parameters.push(newitem) + } + } + } } if (authenticationOption === "API key") { @@ -604,6 +647,8 @@ const AppCreator = (props) => { } } + console.log("ACTIONS: ", data.paths) + fetch(globalUrl+"/api/v1/verify_openapi", { method: 'POST', headers: { @@ -627,7 +672,11 @@ const AppCreator = (props) => { alert.error("Failed to verify: ") } else { alert.success("Successfully uploaded openapi") - //window.location = "/apps" + if (window.location.pathname.includes("/new")) { + if (responseJson.id !== undefined && responseJson.id !== null) { + window.location = `/apps/edit/${responseJson.id}` + } + } } }) .catch(error => { @@ -891,7 +940,7 @@ const AppCreator = (props) => { const bodyInfo = actionBodyRequest.includes(currentActionMethod) ?
- Body + Body - used as example in action argument { currentAction.queries = urlPathQueries setUrlPathQueries([]) - console.log(actions) - console.log(currentAction.name) const actionIndex = actions.findIndex(data => data.name === currentAction.name) - console.log(actionIndex) if (actionIndex < 0) { actions.push(currentAction) } else { @@ -953,9 +999,6 @@ const AppCreator = (props) => { errormessage.push("All queries must have a value") } - console.log(urlPathParameters) - // const [urlPathParameters, setUrlPathParameters] = useState([]); - return errormessage } @@ -1039,7 +1082,6 @@ const AppCreator = (props) => { setActionField("paths", paths) } - console.log("QUERIES: ", queries) var tmpQueries = [] // No overlapping of names @@ -1204,7 +1246,7 @@ const AppCreator = (props) => { } if (request.header !== undefined && request.header !== null) { - var headers = "" + var headers = [] for (let [key, value] of Object.entries(request.header)) { headers += key+"="+value+"\n" } @@ -1249,7 +1291,7 @@ const AppCreator = (props) => { addPathQuery() }}>New query
- Headers + Headers - static for the action { "errors": [], "method": actionNonBodyRequest[0], }) - setCurrentActionMethod(actionNonBodyRequest[0]) + setCurrentActionMethod(actionNonBodyRequest[0]) setActionsModalOpen(true) }}>New action