|
|
|
@@ -6,6 +6,7 @@ import (
|
|
|
|
|
"crypto/tls"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
"math/rand"
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
@@ -38,77 +39,6 @@ type SwaggerRequest struct {
|
|
|
|
|
var accessibleEndpoints []string
|
|
|
|
|
var specJSON string
|
|
|
|
|
|
|
|
|
|
func CheckAndConfigureProxy() (client http.Client) {
|
|
|
|
|
var proxyUrl *url.URL
|
|
|
|
|
|
|
|
|
|
transport := &http.Transport{}
|
|
|
|
|
|
|
|
|
|
if insecure {
|
|
|
|
|
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if proxy != "NOPROXY" {
|
|
|
|
|
proxyUrl, _ = url.Parse(proxy)
|
|
|
|
|
transport.Proxy = http.ProxyURL(proxyUrl)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client = http.Client{
|
|
|
|
|
Transport: transport,
|
|
|
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
|
|
|
return http.ErrUseLastResponse
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return client
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ExtractSpecFromJS(bodyBytes []byte) []byte {
|
|
|
|
|
var openApiIndex int
|
|
|
|
|
var specClose int
|
|
|
|
|
var bodyString, spec string
|
|
|
|
|
|
|
|
|
|
bodyString = string(bodyBytes)
|
|
|
|
|
spec = strings.ReplaceAll(bodyString, "\n", "")
|
|
|
|
|
spec = strings.ReplaceAll(spec, "\t", "")
|
|
|
|
|
spec = strings.ReplaceAll(spec, " ", "")
|
|
|
|
|
|
|
|
|
|
if strings.Contains(strings.ReplaceAll(bodyString, " ", ""), `"swagger":"2.0"`) {
|
|
|
|
|
openApiIndex = strings.Index(spec, `"swagger":`) - 1
|
|
|
|
|
specClose = strings.LastIndex(spec, "]}") + 2
|
|
|
|
|
|
|
|
|
|
var doc2 openapi2.T
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc2)
|
|
|
|
|
if !strings.Contains(doc2.Swagger, "2") {
|
|
|
|
|
specClose = strings.LastIndex(spec, "}") + 1
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc2)
|
|
|
|
|
if !strings.Contains(doc2.Swagger, "2") {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if strings.Contains(strings.ReplaceAll(bodyString, " ", ""), `"openapi":"3`) {
|
|
|
|
|
openApiIndex = strings.Index(spec, `"openapi":`) - 1
|
|
|
|
|
|
|
|
|
|
specClose = strings.LastIndex(spec, "]}") + 2
|
|
|
|
|
|
|
|
|
|
var doc3 openapi3.T
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
if !strings.Contains(doc3.OpenAPI, "3") {
|
|
|
|
|
specClose = strings.LastIndex(spec, "}") + 1
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
if !strings.Contains(doc3.OpenAPI, "3") {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bodyBytes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GenerateRequests(bodyBytes []byte, client http.Client) []string {
|
|
|
|
|
|
|
|
|
|
var s SwaggerRequest
|
|
|
|
@@ -117,8 +47,6 @@ func GenerateRequests(bodyBytes []byte, client http.Client) []string {
|
|
|
|
|
u, _ := url.Parse(swaggerURL)
|
|
|
|
|
s.URL = *u
|
|
|
|
|
|
|
|
|
|
// BuildObjectsFromSchemaDefinitions(*newDoc) TODO
|
|
|
|
|
|
|
|
|
|
if os.Args[1] != "endpoints" {
|
|
|
|
|
// Prints Title/Description values if they exist
|
|
|
|
|
PrintSpecInfo(*s.Def.Info)
|
|
|
|
@@ -134,11 +62,13 @@ func GenerateRequests(bodyBytes []byte, client http.Client) []string {
|
|
|
|
|
|
|
|
|
|
if len(s.Def.Servers) > 1 {
|
|
|
|
|
if !quiet && (os.Args[1] != "endpoints") {
|
|
|
|
|
log.Warn("Multiple servers detected in documentation. You can manually set a server to test with the -T flag.\nThe detected servers are as follows:")
|
|
|
|
|
for i, server := range s.Def.Servers {
|
|
|
|
|
fmt.Printf("Server %d: %s\n", i+1, server.URL)
|
|
|
|
|
if apiTarget == "" {
|
|
|
|
|
log.Warn("Multiple servers detected in documentation. You can manually set a server to test with the -T flag.\nThe detected servers are as follows:")
|
|
|
|
|
for i, server := range s.Def.Servers {
|
|
|
|
|
fmt.Printf("Server %d: %s\n", i+1, server.URL)
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
}
|
|
|
|
|
fmt.Println()
|
|
|
|
|
}
|
|
|
|
|
if len(s.Def.Servers) > 1 && apiTarget == "" {
|
|
|
|
|
for _, server := range s.Def.Servers {
|
|
|
|
@@ -218,6 +148,7 @@ func (s SwaggerRequest) IterateOverPaths(client http.Client) SwaggerRequest {
|
|
|
|
|
|
|
|
|
|
for method, op := range operations {
|
|
|
|
|
// Do all the things here :D
|
|
|
|
|
s.BodyData = nil
|
|
|
|
|
if op != nil {
|
|
|
|
|
s.URL.Path = s.Path + path
|
|
|
|
|
s = s.BuildDefinedRequests(client, method, pathItem, op)
|
|
|
|
@@ -335,17 +266,32 @@ func (s SwaggerRequest) BuildDefinedRequests(client http.Client, method string,
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This whole function needs to be refactored/cleaned up a bit
|
|
|
|
|
func (s SwaggerRequest) AddParametersToRequest(op *openapi3.Operation) SwaggerRequest {
|
|
|
|
|
for _, param := range op.Parameters {
|
|
|
|
|
if param.Ref != "" || param.Value == nil {
|
|
|
|
|
if param.Value == nil && param.Value.Schema.Ref == "" {
|
|
|
|
|
continue
|
|
|
|
|
} else if param.Value.In == "path" {
|
|
|
|
|
s.Path = strings.ReplaceAll(s.Path, "{"+param.Value.Name+"}", "test")
|
|
|
|
|
if param.Value.Schema.Ref != "" {
|
|
|
|
|
s.SetParametersFromSchema(param, "path", param.Value.Schema.Ref, nil)
|
|
|
|
|
} else if param.Value.Schema.Value.Type != "" && param.Value.Schema.Value.Type == "string" {
|
|
|
|
|
if strings.Contains(s.URL.Path, param.Value.Name) {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+param.Value.Name+"}", "test")
|
|
|
|
|
} else {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+strings.ToLower(param.Value.Name)+"}", "test")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if strings.Contains(s.URL.Path, param.Value.Name) {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+param.Value.Name+"}", "1")
|
|
|
|
|
} else {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+strings.ToLower(param.Value.Name)+"}", "1")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if param.Value.In == "query" {
|
|
|
|
|
if param.Value.Schema.Ref != "" {
|
|
|
|
|
s.Query.Add(param.Value.Name, "test") // TODO: Implement actual definition/schema
|
|
|
|
|
s.SetParametersFromSchema(param, "query", param.Value.Schema.Ref, nil)
|
|
|
|
|
} else {
|
|
|
|
|
if param.Value.Schema.Value.Type == "string" {
|
|
|
|
|
if param.Value.Schema.Value.Type != "" && param.Value.Schema.Value.Type == "string" {
|
|
|
|
|
s.Query.Add(param.Value.Name, "test")
|
|
|
|
|
} else {
|
|
|
|
|
s.Query.Add(param.Value.Name, "1")
|
|
|
|
@@ -354,20 +300,104 @@ func (s SwaggerRequest) AddParametersToRequest(op *openapi3.Operation) SwaggerRe
|
|
|
|
|
} else if param.Value.In == "header" && param.Value.Required {
|
|
|
|
|
Headers = append(Headers, fmt.Sprintf("%s: %s", param.Value.Name, "1"))
|
|
|
|
|
} else if param.Value.In == "body" {
|
|
|
|
|
if param.Value.Schema.Ref != "" {
|
|
|
|
|
s.SetParametersFromSchema(param, "body", param.Value.Schema.Ref, nil)
|
|
|
|
|
}
|
|
|
|
|
if param.Value.Schema.Value.Type == "string" {
|
|
|
|
|
s.Body[param.Value.Name] = "test"
|
|
|
|
|
} else {
|
|
|
|
|
s.Body[param.Value.Name] = 1
|
|
|
|
|
}
|
|
|
|
|
s.BodyData, _ = json.Marshal(s.Body)
|
|
|
|
|
var data []string
|
|
|
|
|
for k, v := range s.Body {
|
|
|
|
|
data = append(data, fmt.Sprintf("%s=%s", k, v))
|
|
|
|
|
}
|
|
|
|
|
s.BodyData = []byte(strings.Join(data, "&"))
|
|
|
|
|
} else {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if op.RequestBody != nil {
|
|
|
|
|
s.Body["test"] = "test"
|
|
|
|
|
s.BodyData, _ = json.Marshal(s.Body)
|
|
|
|
|
if op.RequestBody.Value.Content != nil {
|
|
|
|
|
for i := range op.RequestBody.Value.Content {
|
|
|
|
|
if contentType == "" && Headers != nil && strings.Contains(strings.ToLower(strings.Join(Headers, ",")), "content-type") {
|
|
|
|
|
headerString := strings.Join(Headers, ",")
|
|
|
|
|
Headers = nil
|
|
|
|
|
ctIndex := strings.Index(strings.ToLower(headerString), "content-type:") + 14
|
|
|
|
|
headerString = headerString[ctIndex:]
|
|
|
|
|
if strings.Contains(headerString, ",") {
|
|
|
|
|
headerString = strings.TrimPrefix(headerString, ",")
|
|
|
|
|
ctEndIndex := strings.Index(headerString[ctIndex:], ",") + 1
|
|
|
|
|
headerString = headerString[:ctEndIndex]
|
|
|
|
|
} else if !strings.Contains(strings.ToLower(headerString), "content-type") && (strings.Contains(strings.ToLower(headerString), "application/x-www-form-urlencoded") || strings.Contains(strings.ToLower(headerString), "application/json")) {
|
|
|
|
|
headerString = ""
|
|
|
|
|
}
|
|
|
|
|
if headerString != "" {
|
|
|
|
|
Headers = append(Headers, strings.Split(headerString, ",")...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if op.RequestBody.Value.Content.Get(i).Schema.Value == nil {
|
|
|
|
|
s.SetParametersFromSchema(nil, "body", op.RequestBody.Value.Content.Get(i).Schema.Ref, op.RequestBody)
|
|
|
|
|
if strings.Contains(i, "json") {
|
|
|
|
|
s.BodyData, _ = json.Marshal(s.Body)
|
|
|
|
|
}
|
|
|
|
|
} else if i == "application/x-www-form-urlencoded" {
|
|
|
|
|
if contentType == "" && !strings.Contains(strings.ToLower(strings.Join(Headers, "")), "content-type") {
|
|
|
|
|
Headers = append(Headers, "Content-Type: application/x-www-form-urlencoded")
|
|
|
|
|
}
|
|
|
|
|
var formData []string
|
|
|
|
|
for j := range op.RequestBody.Value.Content.Get(i).Schema.Value.Properties {
|
|
|
|
|
if op.RequestBody.Value.Content.Get(i).Schema.Value.Properties[j].Value != nil {
|
|
|
|
|
var valueType string = op.RequestBody.Value.Content.Get(i).Schema.Value.Properties[j].Value.Type
|
|
|
|
|
if valueType == "string" {
|
|
|
|
|
s.Body[j] = "test"
|
|
|
|
|
} else if valueType == "boolean" {
|
|
|
|
|
s.Body[j] = false
|
|
|
|
|
} else if valueType == "integer" || valueType == "number" {
|
|
|
|
|
s.Body[j] = 1
|
|
|
|
|
} else {
|
|
|
|
|
s.Body[j] = "unknown_type_populate_manually"
|
|
|
|
|
}
|
|
|
|
|
formData = append(formData, fmt.Sprintf("%s=%s", j, fmt.Sprint(s.Body[j])))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s.BodyData = []byte(strings.Join(formData, "&"))
|
|
|
|
|
} else if strings.Contains(i, "json") {
|
|
|
|
|
if contentType == "" && !strings.Contains(strings.ToLower(strings.Join(Headers, "")), "content-type") {
|
|
|
|
|
Headers = append(Headers, "Content-Type: application/json")
|
|
|
|
|
}
|
|
|
|
|
for j := range op.RequestBody.Value.Content.Get(i).Schema.Value.Properties {
|
|
|
|
|
if op.RequestBody.Value.Content.Get(i).Schema.Value.Properties[j].Value != nil {
|
|
|
|
|
var valueType string = op.RequestBody.Value.Content.Get(i).Schema.Value.Properties[j].Value.Type
|
|
|
|
|
if valueType == "string" {
|
|
|
|
|
s.Body[j] = "test"
|
|
|
|
|
} else if valueType == "boolean" {
|
|
|
|
|
s.Body[j] = false
|
|
|
|
|
} else if valueType == "integer" || valueType == "number" {
|
|
|
|
|
s.Body[j] = 1
|
|
|
|
|
} else {
|
|
|
|
|
s.Body[j] = "unknown_type_populate_manually"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s.BodyData, _ = json.Marshal(s.Body)
|
|
|
|
|
} else if strings.Contains(i, "multipart/form-data") {
|
|
|
|
|
//TODO
|
|
|
|
|
s.Body["MULTIPART_FORM_DATA"] = "TEST_MANUALLY"
|
|
|
|
|
s.BodyData = []byte("MULTIPART_FORM_DATA=TEST_MANUALLY")
|
|
|
|
|
} else if strings.Contains(i, "xml") {
|
|
|
|
|
//TODO
|
|
|
|
|
s.Body["XML"] = "TEST_MANUALLY"
|
|
|
|
|
s.BodyData = []byte("XML=TEST_MANUALLY")
|
|
|
|
|
} else {
|
|
|
|
|
fmt.Println(i)
|
|
|
|
|
s.Body["test"] = "test"
|
|
|
|
|
s.BodyData = []byte("test=test")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if s.ApiInQuery && s.ApiKey != "" {
|
|
|
|
@@ -376,13 +406,91 @@ func (s SwaggerRequest) AddParametersToRequest(op *openapi3.Operation) SwaggerRe
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s SwaggerRequest) GetBasePath() string {
|
|
|
|
|
if strings.Contains(s.URL.Host, ":") {
|
|
|
|
|
hostPortStart := strings.Index(s.URL.Host, ":")
|
|
|
|
|
s.URL.Host = s.URL.Host[0:hostPortStart]
|
|
|
|
|
func (s SwaggerRequest) SetParametersFromSchema(param *openapi3.ParameterRef, location, schemaRef string, req *openapi3.RequestBodyRef) {
|
|
|
|
|
if param != nil {
|
|
|
|
|
name := strings.TrimPrefix(schemaRef, "#/components/schemas/")
|
|
|
|
|
if s.Def.Components.Schemas[name] != nil {
|
|
|
|
|
schema := s.Def.Components.Schemas[name]
|
|
|
|
|
if schema.Value.Properties != nil {
|
|
|
|
|
for property := range schema.Value.Properties {
|
|
|
|
|
if schema.Value.Properties[property].Value.Type == "string" {
|
|
|
|
|
if location == "path" {
|
|
|
|
|
if strings.Contains(s.URL.Path, param.Value.Name) {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+param.Value.Name+"}", "test")
|
|
|
|
|
} else {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+strings.ToLower(param.Value.Name)+"}", "test")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if strings.Contains(s.URL.Path, param.Value.Name) {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+param.Value.Name+"}", "1")
|
|
|
|
|
} else {
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+strings.ToLower(param.Value.Name)+"}", "1")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if location == "query" {
|
|
|
|
|
if schema.Value.Properties[property].Value.Type == "string" {
|
|
|
|
|
s.Query.Add(param.Value.Name, "test")
|
|
|
|
|
} else {
|
|
|
|
|
s.Query.Add(param.Value.Name, "1")
|
|
|
|
|
}
|
|
|
|
|
} else if location == "body" {
|
|
|
|
|
if schema.Value.Properties[property].Value.Type == "string" {
|
|
|
|
|
s.Body[param.Value.Name] = "test"
|
|
|
|
|
} else {
|
|
|
|
|
s.Body[param.Value.Name] = 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if schema.Value.Enum != nil {
|
|
|
|
|
if location == "path" {
|
|
|
|
|
value := schema.Value.Enum[rand.Intn(len(schema.Value.Enum))]
|
|
|
|
|
s.URL.Path = strings.ReplaceAll(s.URL.Path, "{"+param.Value.Name+"}", fmt.Sprint(value))
|
|
|
|
|
} else if location == "query" {
|
|
|
|
|
value := schema.Value.Enum[rand.Intn(len(schema.Value.Enum))]
|
|
|
|
|
s.Query.Add(param.Value.Name, fmt.Sprint(value))
|
|
|
|
|
} else if location == "body" {
|
|
|
|
|
value := schema.Value.Enum[rand.Intn(len(schema.Value.Enum))]
|
|
|
|
|
s.Body[param.Value.Name] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
name := strings.TrimPrefix(schemaRef, "#/components/schemas/")
|
|
|
|
|
if s.Def.Components.Schemas[name] != nil {
|
|
|
|
|
schema := s.Def.Components.Schemas[name]
|
|
|
|
|
if schema.Value.Properties != nil {
|
|
|
|
|
for property := range schema.Value.Properties {
|
|
|
|
|
if schema.Value.Properties[property].Ref != "" {
|
|
|
|
|
s.SetParametersFromSchema(nil, "body", schema.Value.Properties[property].Ref, req)
|
|
|
|
|
} else {
|
|
|
|
|
if schema.Value.Properties[property].Value.Type == "string" {
|
|
|
|
|
s.Body[property] = "test"
|
|
|
|
|
} else {
|
|
|
|
|
s.Body[property] = 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if schema.Value.Enum != nil {
|
|
|
|
|
value := schema.Value.Enum[rand.Intn(len(schema.Value.Enum))]
|
|
|
|
|
s.Body[schema.Value.Title] = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s SwaggerRequest) GetBasePath() string {
|
|
|
|
|
if basePath == "" {
|
|
|
|
|
if s.Def.Servers != nil {
|
|
|
|
|
if strings.Contains(s.Def.Servers[0].URL, ":") {
|
|
|
|
|
var schemeIndex int
|
|
|
|
|
if strings.Contains(s.Def.Servers[0].URL, "://") {
|
|
|
|
|
schemeIndex = strings.Index(s.Def.Servers[0].URL, "://") + 3
|
|
|
|
|
} else {
|
|
|
|
|
schemeIndex = 0
|
|
|
|
|
}
|
|
|
|
|
s.URL.Host = s.Def.Servers[0].URL[schemeIndex:]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if s.Def.Servers[0].URL == "/" {
|
|
|
|
|
basePath = "/"
|
|
|
|
|
} else if strings.Contains(s.Def.Servers[0].URL, "http") && !strings.Contains(s.Def.Servers[0].URL, s.URL.Host) { // Check to see if the server object being used for the base path contains a different host than the target
|
|
|
|
@@ -469,14 +577,9 @@ func UnmarshalSpec(bodyBytes []byte) (newDoc *openapi3.T) {
|
|
|
|
|
_ = yaml.Unmarshal(bodyBytes, &doc)
|
|
|
|
|
_ = yaml.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
}
|
|
|
|
|
err := json.Unmarshal(bodyBytes, &doc)
|
|
|
|
|
if err != nil {
|
|
|
|
|
err = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("Error unmarshalling API definitions: %s\n", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
err = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc)
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
|
|
|
|
|
if strings.HasPrefix(doc3.OpenAPI, "3") {
|
|
|
|
|
newDoc := &doc3
|
|
|
|
@@ -491,7 +594,7 @@ func UnmarshalSpec(bodyBytes []byte) (newDoc *openapi3.T) {
|
|
|
|
|
var noDoc openapi3.T
|
|
|
|
|
return &noDoc
|
|
|
|
|
} else {
|
|
|
|
|
log.Fatalf("Error parsing definition file: %s\n", doc3.OpenAPI)
|
|
|
|
|
log.Fatal("Error parsing definition file.")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -540,3 +643,74 @@ func WriteJSONFile(result string, end bool) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ExtractSpecFromJS(bodyBytes []byte) []byte {
|
|
|
|
|
var openApiIndex int
|
|
|
|
|
var specClose int
|
|
|
|
|
var bodyString, spec string
|
|
|
|
|
|
|
|
|
|
bodyString = string(bodyBytes)
|
|
|
|
|
spec = strings.ReplaceAll(bodyString, "\n", "")
|
|
|
|
|
spec = strings.ReplaceAll(spec, "\t", "")
|
|
|
|
|
spec = strings.ReplaceAll(spec, " ", "")
|
|
|
|
|
|
|
|
|
|
if strings.Contains(strings.ReplaceAll(bodyString, " ", ""), `"swagger":"2.0"`) {
|
|
|
|
|
openApiIndex = strings.Index(spec, `"swagger":`) - 1
|
|
|
|
|
specClose = strings.LastIndex(spec, "]}") + 2
|
|
|
|
|
|
|
|
|
|
var doc2 openapi2.T
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc2)
|
|
|
|
|
if !strings.Contains(doc2.Swagger, "2") {
|
|
|
|
|
specClose = strings.LastIndex(spec, "}") + 1
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc2)
|
|
|
|
|
if !strings.Contains(doc2.Swagger, "2") {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if strings.Contains(strings.ReplaceAll(bodyString, " ", ""), `"openapi":"3`) {
|
|
|
|
|
openApiIndex = strings.Index(spec, `"openapi":`) - 1
|
|
|
|
|
|
|
|
|
|
specClose = strings.LastIndex(spec, "]}") + 2
|
|
|
|
|
|
|
|
|
|
var doc3 openapi3.T
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
if !strings.Contains(doc3.OpenAPI, "3") {
|
|
|
|
|
specClose = strings.LastIndex(spec, "}") + 1
|
|
|
|
|
bodyBytes = []byte(spec[openApiIndex:specClose])
|
|
|
|
|
_ = json.Unmarshal(bodyBytes, &doc3)
|
|
|
|
|
if !strings.Contains(doc3.OpenAPI, "3") {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
log.Error("Error parsing JavaScript file for spec. Try saving the object as a JSON file and reference it locally.")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bodyBytes
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func CheckAndConfigureProxy() (client http.Client) {
|
|
|
|
|
var proxyUrl *url.URL
|
|
|
|
|
|
|
|
|
|
transport := &http.Transport{}
|
|
|
|
|
|
|
|
|
|
if insecure {
|
|
|
|
|
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if proxy != "NOPROXY" {
|
|
|
|
|
proxyUrl, _ = url.Parse(proxy)
|
|
|
|
|
transport.Proxy = http.ProxyURL(proxyUrl)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
client = http.Client{
|
|
|
|
|
Transport: transport,
|
|
|
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
|
|
|
return http.ErrUseLastResponse
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return client
|
|
|
|
|
}
|