From f77c1c56ce7ea962d2c4610072e70a4472d91f81 Mon Sep 17 00:00:00 2001 From: Sreedeep CV Date: Tue, 28 May 2024 00:15:38 +0530 Subject: [PATCH] adressing the code repetetion issues --- cmdgen/cmdgen.cli.go | 14 ++++ cmdgen/cmdgen.go | 12 +-- cmdgen/cmdgen.wasm.go | 82 +------------------- codegen/codegen.cli.go | 13 ---- codegen/codegen.wasm.go | 140 ---------------------------------- controller/controller.cli.go | 75 +++++++++--------- controller/controller.go | 139 +++++++++++++++++++++++++++++++++ controller/controller.wasm.go | 88 ++++++++++----------- preprocess/preprocess.go | 2 - 9 files changed, 237 insertions(+), 328 deletions(-) create mode 100644 cmdgen/cmdgen.cli.go delete mode 100644 codegen/codegen.cli.go delete mode 100644 codegen/codegen.wasm.go diff --git a/cmdgen/cmdgen.cli.go b/cmdgen/cmdgen.cli.go new file mode 100644 index 00000000..6f391103 --- /dev/null +++ b/cmdgen/cmdgen.cli.go @@ -0,0 +1,14 @@ +//go:build cli + +package cmdgen + +import ( + "github.com/HexmosTech/gabs/v2" + "github.com/HexmosTech/lama2/lama2cmd" +) + +func ConstructCommand(parsedInput *gabs.Container, o *lama2cmd.Opts) ([]string, string) { + httpv, url, jsonObj, headers, multipartBool, formBool := ConstructCommandHelper(parsedInput) + res, stdinBody := assembleCmdString(httpv, url, jsonObj, headers, multipartBool, formBool, o) + return res, stdinBody +} diff --git a/cmdgen/cmdgen.go b/cmdgen/cmdgen.go index 04af3ac6..ec98bfaa 100644 --- a/cmdgen/cmdgen.go +++ b/cmdgen/cmdgen.go @@ -1,5 +1,3 @@ -//go:build cli - // Package `cmdgen` provides an API to generate // API request commands (by default based on HTTPie) // based on the parsed API file contents and the `l2` @@ -14,7 +12,6 @@ import ( "github.com/HexmosTech/gabs/v2" "github.com/HexmosTech/lama2/lama2cmd" - "github.com/rs/zerolog/log" ) func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, headers *gabs.Container, multipart bool, form bool, o *lama2cmd.Opts) ([]string, string) { @@ -90,20 +87,17 @@ func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, header // API file inputs, figures out the type of target command // and finally generates a string representing the generated // command -func ConstructCommand(parsedInput *gabs.Container, o *lama2cmd.Opts) ([]string, string) { - log.Info().Str("ParsedInput", parsedInput.String()).Msg("") +func ConstructCommandHelper(parsedInput *gabs.Container) (string, string, *gabs.Container, *gabs.Container, bool, bool) { httpv := parsedInput.S("verb", "value") url := parsedInput.S("url", "value") jsonObj := parsedInput.S("details", "ip_data") headers := parsedInput.S("details", "headers") multipart := parsedInput.S("multipart", "value") + form := parsedInput.S("form", "value") multipartBool := false if multipart != nil { multipartBool = true } - form := parsedInput.S("form", "value") formBool := form != nil - - res, stdinBody := assembleCmdString(httpv.Data().(string), url.Data().(string), jsonObj, headers, multipartBool, formBool, o) - return res, stdinBody + return httpv.Data().(string), url.Data().(string), jsonObj, headers, multipartBool, formBool } diff --git a/cmdgen/cmdgen.wasm.go b/cmdgen/cmdgen.wasm.go index 1c03e986..9e6e0844 100644 --- a/cmdgen/cmdgen.wasm.go +++ b/cmdgen/cmdgen.wasm.go @@ -3,89 +3,11 @@ package cmdgen import ( - "bytes" - "encoding/json" - "fmt" - "strings" - "github.com/HexmosTech/gabs/v2" ) -func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, headers *gabs.Container, multipart bool, form bool) ([]string, string) { - command := make([]string, 0) - var files *gabs.Container - if multipart { - if jsonObj.ExistsP("@files") { - files = jsonObj.S("@files") - jsonObj.Delete("@files") - } - } - - jsonStr := "" - if jsonObj != nil && !multipart && !form { - dst := &bytes.Buffer{} - if err := json.Compact(dst, []byte(jsonObj.String())); err != nil { - } - jsonStr = dst.String() - } - - command = append(command, "ht ") - if multipart || form { - command = append(command, "--ignore-stdin", "--form") - } - - command = append(command, httpv+" ") - command = append(command, url+" ") - - if multipart { - for key, val := range jsonObj.Data().(*gabs.Container).ChildrenMap() { - command = append(command, "'"+key+"'='"+val.Data().(string)+"' ") - } - for key, val := range files.ChildrenMap() { - command = append(command, key+"@"+val.Data().(string)) - } - } - - if form { - for key, val := range jsonObj.Data().(*gabs.Container).ChildrenMap() { - keyValuePair := fmt.Sprintf("'%s'='%s' ", key, val.Data().(string)) - command = append(command, keyValuePair) - } - } - - if headers != nil { - for key, val := range headers.Data().(*gabs.Container).ChildrenMap() { - command = append(command, key+":"+val.Data().(*gabs.Container).Data().(string)) - } - } - cleanCommand := make([]string, 0) - for _, c := range command { - cleanC := strings.TrimSpace(c) - cleanCommand = append(cleanCommand, cleanC) - } - if multipart || form { - return cleanCommand, "" - } - return cleanCommand, jsonStr -} - -// func assembleCmdString(httpv string, url string, jsonObj *gabs.Container, headers *gabs.Container, multipart bool, form bool, o *lama2cmd.Opts) ([]string, string) { -// return assembleCmdStringHelper(httpv, url, jsonObj, headers, multipart, form, o.Nocolor) -// } - func ConstructCommand(parsedInput *gabs.Container) ([]string, string) { - httpv := parsedInput.S("verb", "value") - url := parsedInput.S("url", "value") - jsonObj := parsedInput.S("details", "ip_data") - headers := parsedInput.S("details", "headers") - multipart := parsedInput.S("multipart", "value") - multipartBool := false - if multipart != nil { - multipartBool = true - } - form := parsedInput.S("form", "value") - formBool := form != nil - - res, stdinBody := assembleCmdString(httpv.Data().(string), url.Data().(string), jsonObj, headers, multipartBool, formBool) + httpv, url, jsonObj, headers, multipartBool, formBool := ConstructCommandHelper(parsedInput) + res, stdinBody := assembleCmdString(httpv, url, jsonObj, headers, multipartBool, formBool, nil) return res, stdinBody } diff --git a/codegen/codegen.cli.go b/codegen/codegen.cli.go deleted file mode 100644 index 1076938f..00000000 --- a/codegen/codegen.cli.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:wasm cli - -package codegen - -import ( - _ "embed" - - "github.com/HexmosTech/lama2/cmdexec" -) - -func initialize() { - globalVM = cmdexec.GetJSVm() -} diff --git a/codegen/codegen.wasm.go b/codegen/codegen.wasm.go deleted file mode 100644 index 004db850..00000000 --- a/codegen/codegen.wasm.go +++ /dev/null @@ -1,140 +0,0 @@ -//go:build wasm - -package codegen - -import ( - "bytes" - _ "embed" - "fmt" - "strings" - "syscall/js" - "text/template" - - "github.com/HexmosTech/gabs/v2" - "github.com/HexmosTech/lama2/preprocess" -) - -var snippetcore string - -type SnippetArgs struct { - Language string - Library string - HARRequest string - SnippetCore string -} - -// takes in the headers in L2 format, and generates -// HAR compatible -func GetHARHeadersCookies(headers *gabs.Container) (*gabs.Container, *gabs.Container) { - headersData := gabs.New() - headersData.Array() - - cookiesData := gabs.New() - cookiesData.Array() - for key, val := range headers.Data().(*gabs.Container).ChildrenMap() { - if strings.ToLower(key) == "cookie" { - cookieList := strings.Split(val.Data().(*gabs.Container).Data().(string), ";") - for _, c := range cookieList { - r := strings.Split(c, "=") - ck := r[0] - cv := r[1] - cookie := gabs.New() - cookie.Set(ck, "name") - cookie.Set(cv, "value") - cookiesData.ArrayAppend(cookie) - } - continue - } - header := gabs.New() - header.Set(key, "name") - header.Set(val, "value") - headersData.ArrayAppend(header) - } - - cookiesData.Array() - for key, val := range headers.Data().(*gabs.Container).ChildrenMap() { - if strings.ToLower(key) == "cookie" { - cookieList := strings.Split(val.Data().(*gabs.Container).Data().(string), ";") - for _, c := range cookieList { - r := strings.Split(c, "=") - ck := r[0] - cv := r[1] - cookie := gabs.New() - cookie.Set(ck, "name") - cookie.Set(cv, "value") - cookiesData.ArrayAppend(cookie) - } - continue - } - header := gabs.New() - header.Set(key, "name") - header.Set(val, "value") - headersData.ArrayAppend(header) - } - return headersData, cookiesData -} - -func GetRequestHARString(block *gabs.Container) string { - preprocess.ProcessVarsInBlock(block) - httpv := block.S("verb", "value") - url := block.S("url", "value") - jsonObj := block.S("details", "ip_data") - headers := block.S("details", "headers") - /* - TODO: Handle multipart case - multipart := block.S("multipart", "value") - multipartBool := false - if multipart != nil { - multipartBool = true - } - */ - harObj := gabs.New() - - if jsonObj != nil { - postData := gabs.New() - postData.Set("application/json", "mimeType") - postData.Set(jsonObj.String(), "text") - harObj.Set(postData, "postData") - } - - if headers != nil { - headersData, cookiesData := GetHARHeadersCookies(headers) - if cookiesData.String() != "[]" { - harObj.Set(cookiesData, "cookies") - } - harObj.Set(headersData, "headers") - } - - harObj.Set(httpv, "method") - harObj.Set(url, "url") - - res := harObj.String() - return res -} - -func GenerateTargetCode(targetLangLib string, parsedAPI *gabs.Container) { - parsedAPIblocks := parsedAPI.S("value").Data().(*gabs.Container).Children() - convertedSnippetList := make([]string, 0) - - for i, block := range parsedAPIblocks { - blockType := block.S("type").Data().(string) - if blockType == "processor" { - snippet := block.S("value").Data().(*gabs.Container).Data().(string) - convertedSnippetList = append(convertedSnippetList, snippet) - } else if blockType == "Lama2File" { - harRequest := GetRequestHARString(block) - snippetArgs := SnippetArgs{} - lang, lib := SplitLangLib(targetLangLib) - snippetArgs.Language = lang - snippetArgs.Library = lib - snippetArgs.HARRequest = harRequest - snippetArgs.SnippetCore = snippetcore - httpsnippetCode := PrepareHTTPSnippetGenerator(snippetArgs) - js.Global().Call("eval", httpsnippetCode) - convertedSnippet := js.Global().Get("convertedSnippet").String() - convertedSnippetList = append(convertedSnippetList, convertedSnippet) - } - } - convertedSnippetFinal := strings.Join(convertedSnippetList, "\n") - fmt.Println(convertedSnippetFinal) -} diff --git a/controller/controller.cli.go b/controller/controller.cli.go index 722848f3..30f3a89c 100644 --- a/controller/controller.cli.go +++ b/controller/controller.cli.go @@ -11,11 +11,8 @@ import ( "github.com/HexmosTech/gabs/v2" "github.com/HexmosTech/httpie-go" - "github.com/HexmosTech/lama2/cmdexec" - "github.com/HexmosTech/lama2/cmdgen" "github.com/HexmosTech/lama2/codegen" "github.com/HexmosTech/lama2/lama2cmd" - outputmanager "github.com/HexmosTech/lama2/outputManager" "github.com/HexmosTech/lama2/parser" "github.com/HexmosTech/lama2/preprocess" "github.com/HexmosTech/lama2/prettify" @@ -24,48 +21,50 @@ import ( "github.com/rs/zerolog/log" ) - func ExecuteProcessorBlock(block *gabs.Container, vm *goja.Runtime) { - b := block.S("value").Data().(*gabs.Container) - log.Debug().Str("Processor block incoming block", block.String()).Msg("") - script := b.Data().(string) - cmdexec.RunVMCode(script, vm) + // b := block.S("value").Data().(*gabs.Container) + // log.Debug().Str("Processor block incoming block", block.String()).Msg("") + // script := b.Data().(string) + // cmdexec.RunVMCode(script, vm) + ExecuteProcessorBlockHelper(block, vm...) } func ExecuteRequestorBlock(block *gabs.Container, vm *goja.Runtime, opts *lama2cmd.Opts, dir string) httpie.ExResponse { - preprocess.ProcessVarsInBlock(block, vm) - // TODO - replace stuff in headers, and varjson and json as well - cmd, stdinBody := cmdgen.ConstructCommand(block, opts) - log.Debug().Str("Stdin Body to be passed into httpie", stdinBody).Msg("") - resp, e1 := cmdexec.ExecCommand(cmd, stdinBody, dir) - log.Debug().Str("Response from ExecCommand", resp.Body).Msg("") - if e1 == nil { - chainCode := cmdexec.GenerateChainCode(resp.Body) - cmdexec.RunVMCode(chainCode, vm) - } else { - log.Fatal().Str("Error from ExecCommand", e1.Error()) - os.Exit(1) - } - return resp + // preprocess.ProcessVarsInBlock(block, vm) + // // TODO - replace stuff in headers, and varjson and json as well + // cmd, stdinBody := cmdgen.ConstructCommand(block, opts) + // log.Debug().Str("Stdin Body to be passed into httpie", stdinBody).Msg("") + // resp, e1 := cmdexec.ExecCommand(cmd, stdinBody, dir) + // log.Debug().Str("Response from ExecCommand", resp.Body).Msg("") + // if e1 == nil { + // chainCode := cmdexec.GenerateChainCode(resp.Body) + // cmdexec.RunVMCode(chainCode, vm) + // } else { + // log.Fatal().Str("Error from ExecCommand", e1.Error()) + // os.Exit(1) + // } + // return resp + return ExecuteRequestorBlockHelper(block, vm, opts, dir) } func HandleParsedFile(parsedAPI *gabs.Container, o *lama2cmd.Opts, dir string) { - parsedAPIblocks := GetParsedAPIBlocks(parsedAPI) - vm := cmdexec.GetJSVm() - var resp httpie.ExResponse - for i, block := range parsedAPIblocks { - log.Debug().Int("Block num", i).Msg("") - log.Debug().Str("Block getting processed", block.String()).Msg("") - blockType := block.S("type").Data().(string) - if blockType == "processor" { - ExecuteProcessorBlock(block, vm) - } else if blockType == "Lama2File" { - resp = ExecuteRequestorBlock(block, vm, o, dir) - } - } - if o.Output != "" { - outputmanager.WriteJSONOutput(resp, o.Output) - } + // parsedAPIblocks := GetParsedAPIBlocks(parsedAPI) + // vm := cmdexec.GetJSVm() + // var resp httpie.ExResponse + // for i, block := range parsedAPIblocks { + // log.Debug().Int("Block num", i).Msg("") + // log.Debug().Str("Block getting processed", block.String()).Msg("") + // blockType := block.S("type").Data().(string) + // if blockType == "processor" { + // ExecuteProcessorBlock(block, vm) + // } else if blockType == "Lama2File" { + // resp = ExecuteRequestorBlock(block, vm, o, dir) + // } + // } + // if o.Output != "" { + // outputmanager.WriteJSONOutput(resp, o.Output) + // } + return HandleParsedFileHelper(parsedAPI, O, dir) } // Process initiates the following tasks in the given order: diff --git a/controller/controller.go b/controller/controller.go index c3727343..d7cddf5a 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -5,10 +5,149 @@ package contoller import ( + "fmt" + "log" + "os" + "strings" + "syscall/js" + "github.com/HexmosTech/gabs/v2" + "github.com/HexmosTech/httpie-go" + "github.com/HexmosTech/lama2/cmdexec" + "github.com/HexmosTech/lama2/cmdgen" + "github.com/HexmosTech/lama2/preprocess" + "github.com/dop251/goja" ) func GetParsedAPIBlocks(parsedAPI *gabs.Container) []*gabs.Container { return parsedAPI.S("value").Data().(*gabs.Container).Children() } +func HandleParsedFileHelper(parsedAPI *gabs.Container, args ...interface{}) ExResponse { + parsedAPIblocks := GetParsedAPIBlocks(parsedAPI) + var resp ExResponse + var vm *goja.Runtime + var o *Opts + var dir string + + if len(args) > 0 { + for _, arg := range args { + switch v := arg.(type) { + case *goja.Runtime: + vm = v + case *Opts: + o = v + case string: + dir = v + } + } + } + + for i, block := range parsedAPIblocks { + log.Println("Block num", i) + log.Println("Block getting processed", block.String()) + blockType := block.S("type").Data().(string) + if blockType == "processor" { + if vm != nil { + ExecuteProcessorBlock(block, vm) + } else { + ExecuteProcessorBlock(block) + } + } else if blockType == "Lama2File" { + if vm != nil && o != nil && dir != "" { + resp = ExecuteRequestorBlock(block, vm, o, dir) + } else { + resp = ExecuteRequestorBlock(block) + } + } + } + + if o != nil && o.Output != "" { + outputmanager{}.WriteJSONOutput(resp, o.Output) + } + + return resp +} + +func ExecuteProcessorBlockHelper(block *gabs.Container, vm ...*goja.Runtime) { + b := block.S("value").Data().(*gabs.Container) + script := b.Data().(string) + + // Check if vm is provided + if len(vm) > 0 && vm[0] != nil { + log.Println("Executing with VM") + cmdexec.RunVMCode(script, vm[0]) + } else { + log.Println("Executing without VM") + js.Global().Call("eval", script) + } +} + +func ExecuteRequestorBlockHelper(block *gabs.Container, args ...interface{}) httpie.ExResponse { + var vm *goja.Runtime + var opts *Opts + var dir string + + if len(args) > 0 { + for _, arg := range args { + switch v := arg.(type) { + case *goja.Runtime: + vm = v + case *Opts: + opts = v + case string: + dir = v + } + } + } + + if vm != nil { + preprocess.ProcessVarsInBlock(block, vm) + } else { + preprocess.ProcessVarsInBlock(block) + } + + var cmd, stdinBody string + if opts != nil { + cmd, stdinBody = cmdgen.ConstructCommand(block, opts) + } else { + cmd, stdinBody = cmdgen.ConstructCommand(block) + } + + var resp ExResponse + var e1 error + if dir != "" { + resp, e1 = cmdexec.ExecCommand(cmd, stdinBody, dir) + } else { + resp, e1 = cmdexec.ExecCommand(cmd, stdinBody) + } + + headers := resp.Headers + var headersString string + for key, value := range headers { + headersString += fmt.Sprintf("%s: %s\n", key, value) + } + + targetHeader := "text/html" + isTextHTMLPresent := strings.Contains(headersString, targetHeader) + + if isTextHTMLPresent { + fmt.Printf("'%s' is present in the headers.\n", targetHeader) + return resp + } else { + fmt.Printf("'%s' is not present in the headers.\n", targetHeader) + if e1 == nil { + chainCode := cmdexec.GenerateChainCode(resp.Body) + if vm != nil { + cmdexec.RunVMCode(chainCode, vm) + } else { + js.Global().Call("eval", chainCode) + } + } else { + log.Fatal("Error from ExecCommand", e1) + os.Exit(1) + } + } + + return resp +} diff --git a/controller/controller.wasm.go b/controller/controller.wasm.go index b5a037f0..99ef4140 100644 --- a/controller/controller.wasm.go +++ b/controller/controller.wasm.go @@ -4,69 +4,65 @@ package contoller import ( "fmt" - "os" - "strings" "github.com/HexmosTech/gabs/v2" "github.com/HexmosTech/httpie-go" - "github.com/HexmosTech/lama2/cmdexec" - "github.com/HexmosTech/lama2/cmdgen" "github.com/HexmosTech/lama2/parser" - "github.com/HexmosTech/lama2/preprocess" - - "syscall/js" ) func ExecuteProcessorBlock(block *gabs.Container) { - b := block.S("value").Data().(*gabs.Container) - script := b.Data().(string) - js.Global().Call("eval", script) + // b := block.S("value").Data().(*gabs.Container) + // script := b.Data().(string) + // js.Global().Call("eval", script) + ExecuteProcessorBlockHelper(block) } func ExecuteRequestorBlock(block *gabs.Container) httpie.ExResponse { - preprocess.ProcessVarsInBlock(block) - // TODO - replace stuff in headers, and varjson and json as well - cmd, stdinBody := cmdgen.ConstructCommand(block) - resp, e1 := cmdexec.ExecCommand(cmd, stdinBody) - headers := resp.Headers - var headersString string - for key, value := range headers { - headersString += fmt.Sprintf("%s: %s\n", key, value) - } + // preprocess.ProcessVarsInBlock(block) + // // TODO - replace stuff in headers, and varjson and json as well + // cmd, stdinBody := cmdgen.ConstructCommand(block) + // resp, e1 := cmdexec.ExecCommand(cmd, stdinBody) + // headers := resp.Headers + // var headersString string + // for key, value := range headers { + // headersString += fmt.Sprintf("%s: %s\n", key, value) + // } - targetHeader := "text/html" - isTextHTMLPresent := strings.Contains(headersString, targetHeader) + // targetHeader := "text/html" + // isTextHTMLPresent := strings.Contains(headersString, targetHeader) - if isTextHTMLPresent { - fmt.Printf("'%s' is present in the headers.\n", targetHeader) - return resp - } else { - fmt.Printf("'%s' is not present in the headers.\n", targetHeader) - if e1 == nil { - chainCode := cmdexec.GenerateChainCode(resp.Body) - js.Global().Call("eval", chainCode) - } else { - os.Exit(1) - } - } + // if isTextHTMLPresent { + // fmt.Printf("'%s' is present in the headers.\n", targetHeader) + // return resp + // } else { + // fmt.Printf("'%s' is not present in the headers.\n", targetHeader) + // if e1 == nil { + // chainCode := cmdexec.GenerateChainCode(resp.Body) + // js.Global().Call("eval", chainCode) + // } else { + // os.Exit(1) + // } + // } - return resp + // return resp + return ExecuteRequestorBlockHelper(block) } func HandleParsedFile(parsedAPI *gabs.Container) httpie.ExResponse { - parsedAPIblocks := GetParsedAPIBlocks(parsedAPI) - var resp httpie.ExResponse - for i, block := range parsedAPIblocks { - fmt.Println(i) - blockType := block.S("type").Data().(string) - if blockType == "processor" { - ExecuteProcessorBlock(block) - } else if blockType == "Lama2File" { - resp = ExecuteRequestorBlock(block) - } - } - return resp + // parsedAPIblocks := GetParsedAPIBlocks(parsedAPI) + // var resp httpie.ExResponse + // for i, block := range parsedAPIblocks { + // fmt.Println(i) + // blockType := block.S("type").Data().(string) + // if blockType == "processor" { + // ExecuteProcessorBlock(block) + // } else if blockType == "Lama2File" { + // resp = ExecuteRequestorBlock(block) + // } + // } + // return resp + HandleParsedFileHelper(parsedAPI) } func ProcessWasmInput(data string) httpie.ExResponse { diff --git a/preprocess/preprocess.go b/preprocess/preprocess.go index dc48570b..4f641797 100644 --- a/preprocess/preprocess.go +++ b/preprocess/preprocess.go @@ -1,5 +1,3 @@ -//go:build cli - // Package preprocess provides facilities to expand // environment variables in `.l2` API files and return // the contents