From d58ad9cb977b6d1e2f8dfbe021bb12a6cbfed752 Mon Sep 17 00:00:00 2001 From: Matthias Ramsauer Date: Tue, 2 Oct 2018 15:23:52 +0200 Subject: [PATCH 1/5] Fix for Issue #8766 --- .../src/main/resources/go/client.mustache | 14 +++++++-- .../petstore/go/go-petstore/api/swagger.yaml | 30 +++++++++---------- .../client/petstore/go/go-petstore/client.go | 14 +++++++-- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/go/client.mustache b/modules/swagger-codegen/src/main/resources/go/client.mustache index d243a859571..900e3f5ad1a 100644 --- a/modules/swagger-codegen/src/main/resources/go/client.mustache +++ b/modules/swagger-codegen/src/main/resources/go/client.mustache @@ -185,7 +185,7 @@ func (c *APIClient) prepareRequest( } // add form parameters and file if available. - if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { if body != nil { return nil, errors.New("Cannot specify postBody and multipart form at the same time.") } @@ -224,6 +224,16 @@ func (c *APIClient) prepareRequest( w.Close() } + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + // Setup path and query parameters url, err := url.Parse(path) if err != nil { @@ -465,4 +475,4 @@ func (e GenericSwaggerError) Body() []byte { // Model returns the unpacked model of the error func (e GenericSwaggerError) Model() interface{} { return e.model -} \ No newline at end of file +} diff --git a/samples/client/petstore/go/go-petstore/api/swagger.yaml b/samples/client/petstore/go/go-petstore/api/swagger.yaml index 54961e0aa7c..d8749671bcb 100644 --- a/samples/client/petstore/go/go-petstore/api/swagger.yaml +++ b/samples/client/petstore/go/go-petstore/api/swagger.yaml @@ -492,8 +492,6 @@ paths: responses: 200: description: "successful operation" - schema: - type: "string" headers: X-Rate-Limit: type: "integer" @@ -503,6 +501,8 @@ paths: type: "string" format: "date-time" description: "date in UTC when token expires" + schema: + type: "string" 400: description: "Invalid username/password supplied" /user/logout: @@ -1105,6 +1105,8 @@ definitions: complete: type: "boolean" default: false + xml: + name: "Order" example: petId: 6 quantity: 1 @@ -1112,8 +1114,6 @@ definitions: shipDate: "2000-01-23T04:56:07.000+00:00" complete: false status: "placed" - xml: - name: "Order" Category: type: "object" properties: @@ -1122,11 +1122,11 @@ definitions: format: "int64" name: type: "string" + xml: + name: "Category" example: name: "name" id: 6 - xml: - name: "Category" User: type: "object" properties: @@ -1150,6 +1150,8 @@ definitions: type: "integer" format: "int32" description: "User Status" + xml: + name: "User" example: firstName: "firstName" lastName: "lastName" @@ -1159,8 +1161,6 @@ definitions: id: 0 email: "email" username: "username" - xml: - name: "User" Tag: type: "object" properties: @@ -1169,11 +1169,11 @@ definitions: format: "int64" name: type: "string" + xml: + name: "Tag" example: name: "name" id: 1 - xml: - name: "Tag" Pet: type: "object" required: @@ -1210,6 +1210,8 @@ definitions: - "available" - "pending" - "sold" + xml: + name: "Pet" example: photoUrls: - "photoUrls" @@ -1225,8 +1227,6 @@ definitions: - name: "name" id: 1 status: "available" - xml: - name: "Pet" ApiResponse: type: "object" properties: @@ -1253,9 +1253,9 @@ definitions: return: type: "integer" format: "int32" - description: "Model for testing reserved words" xml: name: "Return" + description: "Model for testing reserved words" Name: required: - "name" @@ -1272,9 +1272,9 @@ definitions: 123Number: type: "integer" readOnly: true - description: "Model for testing model name same as property name" xml: name: "Name" + description: "Model for testing model name same as property name" 200_response: properties: name: @@ -1282,9 +1282,9 @@ definitions: format: "int32" class: type: "string" - description: "Model for testing model name starting with number" xml: name: "Name" + description: "Model for testing model name starting with number" ClassModel: properties: _class: diff --git a/samples/client/petstore/go/go-petstore/client.go b/samples/client/petstore/go/go-petstore/client.go index 3c9aacc301c..52b150cfc51 100644 --- a/samples/client/petstore/go/go-petstore/client.go +++ b/samples/client/petstore/go/go-petstore/client.go @@ -197,7 +197,7 @@ func (c *APIClient) prepareRequest( } // add form parameters and file if available. - if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { if body != nil { return nil, errors.New("Cannot specify postBody and multipart form at the same time.") } @@ -236,6 +236,16 @@ func (c *APIClient) prepareRequest( w.Close() } + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + // Setup path and query parameters url, err := url.Parse(path) if err != nil { @@ -477,4 +487,4 @@ func (e GenericSwaggerError) Body() []byte { // Model returns the unpacked model of the error func (e GenericSwaggerError) Model() interface{} { return e.model -} \ No newline at end of file +} From be8a5d44b898ae043444f6a78792e96dbde6fe8b Mon Sep 17 00:00:00 2001 From: Matthias Ramsauer Date: Tue, 2 Oct 2018 16:25:24 +0200 Subject: [PATCH 2/5] Fix Test: The obove test sets the status to available so in the next test the expected value should be available --- .../go/.swagger-codegen/VERSION | 2 +- .../petstore-security-test/go/README.md | 34 +- .../go/api/swagger.yaml | 72 +++ .../petstore-security-test/go/api_fake.go | 105 ++++ .../petstore-security-test/go/client.go | 475 ++++++++++++++++++ .../petstore-security-test/go/docs/FakeApi.md | 8 +- .../petstore-security-test/go/response.go | 44 ++ samples/client/petstore/go/pet_api_test.go | 2 +- 8 files changed, 719 insertions(+), 23 deletions(-) create mode 100644 samples/client/petstore-security-test/go/api/swagger.yaml create mode 100644 samples/client/petstore-security-test/go/api_fake.go create mode 100644 samples/client/petstore-security-test/go/client.go create mode 100644 samples/client/petstore-security-test/go/response.go diff --git a/samples/client/petstore-security-test/go/.swagger-codegen/VERSION b/samples/client/petstore-security-test/go/.swagger-codegen/VERSION index f9f7450d135..855ff9501eb 100644 --- a/samples/client/petstore-security-test/go/.swagger-codegen/VERSION +++ b/samples/client/petstore-security-test/go/.swagger-codegen/VERSION @@ -1 +1 @@ -2.3.0-SNAPSHOT \ No newline at end of file +2.4.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore-security-test/go/README.md b/samples/client/petstore-security-test/go/README.md index d092ab5477f..2380cd4510f 100644 --- a/samples/client/petstore-security-test/go/README.md +++ b/samples/client/petstore-security-test/go/README.md @@ -11,8 +11,8 @@ This API client was generated by the [swagger-codegen](https://github.com/swagge ## Installation Put the package under your project folder and add the following in import: -``` - "./swagger" +```golang +import "./swagger" ``` ## Documentation for API Endpoints @@ -35,12 +35,12 @@ Class | Method | HTTP request | Description - **Type**: API key Example -``` - auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{ - Key: "APIKEY", - Prefix: "Bearer", // Omit if not necessary. - }) - r, err := client.Service.Operation(auth, args) +```golang +auth := context.WithValue(context.Background(), sw.ContextAPIKey, sw.APIKey{ + Key: "APIKEY", + Prefix: "Bearer", // Omit if not necessary. +}) +r, err := client.Service.Operation(auth, args) ``` ## petstore_auth - **Type**: OAuth @@ -51,20 +51,20 @@ Example - **read:pets**: read your pets *_/ ' \" =end -- \\r\\n \\n \\r Example -``` - auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING") - r, err := client.Service.Operation(auth, args) +```golang +auth := context.WithValue(context.Background(), sw.ContextAccessToken, "ACCESSTOKENSTRING") +r, err := client.Service.Operation(auth, args) ``` Or via OAuth2 module to automatically refresh tokens and perform user authentication. -``` - import "golang.org/x/oauth2" +```golang +import "golang.org/x/oauth2" - / .. Perform OAuth2 round trip request and obtain a token .. // +/* Perform OAuth2 round trip request and obtain a token */ - tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token) - auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource) - r, err := client.Service.Operation(auth, args) +tokenSource := oauth2cfg.TokenSource(createContext(httpClient), &token) +auth := context.WithValue(oauth2.NoContext, sw.ContextOAuth2, tokenSource) +r, err := client.Service.Operation(auth, args) ``` ## Author diff --git a/samples/client/petstore-security-test/go/api/swagger.yaml b/samples/client/petstore-security-test/go/api/swagger.yaml new file mode 100644 index 00000000000..51679506dae --- /dev/null +++ b/samples/client/petstore-security-test/go/api/swagger.yaml @@ -0,0 +1,72 @@ +--- +swagger: "2.0" +info: + description: "This spec is mainly for testing Petstore server and contains fake\ + \ endpoints, models. Please do not use this for any other purpose. Special characters:\ + \ \" \\ */ ' \" =end -- \r\n \n \r" + version: "1.0.0 */ ' \" =end -- \\r\\n \\n \\r" + title: "Swagger Petstore */ ' \" =end -- \\r\\n \\n \\r" + termsOfService: "http://swagger.io/terms/ */ ' \" =end -- \\r\\n \\n \\r" + contact: + email: "apiteam@swagger.io */ ' \" =end -- \\r\\n \\n \\r" + license: + name: "Apache-2.0 */ ' \" =end -- \\r\\n \\n \\r" + url: "http://www.apache.org/licenses/LICENSE-2.0.html */ ' \" =end -- \\r\\n \\\ + n \\r" +host: "petstore.swagger.io */ ' \" =end -- \\r\\n \\n \\r" +basePath: "/v2 */ ' \" =end -- \\r\\n \\n \\r" +tags: +- name: "fake" + description: "Everything about your Pets */ ' \" =end -- \\r\\n \\n \\r" + externalDocs: + description: "Find out more */ ' \" =end -- \\r\\n \\n \\r" + url: "http://swagger.io" +paths: + /fake: + put: + tags: + - "fake" + summary: "To test code injection */ ' \" =end -- \\r\\n \\n \\r" + operationId: "testCodeInject */ ' \" =end -- \\r\\n \\n \\r" + consumes: + - "application/json" + - "*/ ' \" =end -- \r\n \n \r" + produces: + - "application/json" + - "*/ ' \" =end -- \r\n \n \r" + parameters: + - name: "test code inject */ ' \" =end -- \\r\\n \\n \\r" + in: "formData" + description: "To test code injection */ ' \" =end -- \\r\\n \\n \\r" + required: false + type: "string" + x-exportParamName: "TestCodeInjectEndRnNR" + x-optionalDataType: "String" + responses: + 400: + description: "To test code injection */ ' \" =end -- \\r\\n \\n \\r" +securityDefinitions: + petstore_auth: + type: "oauth2" + authorizationUrl: "http://petstore.swagger.io/api/oauth/dialog" + flow: "implicit" + scopes: + write:pets: "modify pets in your account */ ' \" =end -- \\r\\n \\n \\r" + read:pets: "read your pets */ ' \" =end -- \\r\\n \\n \\r" + api_key: + type: "apiKey" + name: "api_key */ ' \" =end -- \\r\\n \\n \\r" + in: "header" +definitions: + Return: + properties: + return: + type: "integer" + format: "int32" + description: "property description */ ' \" =end -- \\r\\n \\n \\r" + xml: + name: "Return" + description: "Model for testing reserved words */ ' \" =end -- \\r\\n \\n \\r" +externalDocs: + description: "Find out more about Swagger */ ' \" =end -- \\r\\n \\n \\r" + url: "http://swagger.io" diff --git a/samples/client/petstore-security-test/go/api_fake.go b/samples/client/petstore-security-test/go/api_fake.go new file mode 100644 index 00000000000..a19200a1fac --- /dev/null +++ b/samples/client/petstore-security-test/go/api_fake.go @@ -0,0 +1,105 @@ +/* + * Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: apiteam@swagger.io *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package swagger + +import ( + "context" + "io/ioutil" + "net/http" + "net/url" + "strings" + "github.com/antihax/optional" +) + +// Linger please +var ( + _ context.Context +) + +type FakeApiService service + +/* +FakeApiService To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *TestCodeInjectEndRnNROpts - Optional Parameters: + * @param "TestCodeInjectEndRnNR" (optional.String) - To test code injection *_/ ' \" =end -- \\r\\n \\n \\r + + +*/ + +type TestCodeInjectEndRnNROpts struct { + TestCodeInjectEndRnNR optional.String +} + +func (a *FakeApiService) TestCodeInjectEndRnNR(ctx context.Context, localVarOptionals *TestCodeInjectEndRnNROpts) (*http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Put") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/fake" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json", "*_/ ' =end -- "} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json", "*_/ ' =end -- "} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + if localVarOptionals != nil && localVarOptionals.TestCodeInjectEndRnNR.IsSet() { + localVarFormParams.Add("test code inject */ ' " =end -- \r\n \n \r", parameterToString(localVarOptionals.TestCodeInjectEndRnNR.Value(), "")) + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarHttpResponse, err + } + + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + + return localVarHttpResponse, newErr + } + + return localVarHttpResponse, nil +} diff --git a/samples/client/petstore-security-test/go/client.go b/samples/client/petstore-security-test/go/client.go new file mode 100644 index 00000000000..ceacaa4445a --- /dev/null +++ b/samples/client/petstore-security-test/go/client.go @@ -0,0 +1,475 @@ +/* + * Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: apiteam@swagger.io *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package swagger + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" + + "golang.org/x/oauth2" +) + +var ( + jsonCheck = regexp.MustCompile("(?i:[application|text]/json)") + xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)") +) + +// APIClient manages communication with the Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r API v1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + FakeApi *FakeApiService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.FakeApi = (*FakeApiService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insenstive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.ToLower(a) == strings.ToLower(needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("Expected %s to be of type %s but received %s.", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +// parameterToString convert interface{} parameters to string, using a delimiter if format is provided. +func parameterToString(obj interface{}, collectionFormat string) string { + var delimiter string + + switch collectionFormat { + case "pipes": + delimiter = "|" + case "ssv": + delimiter = " " + case "tsv": + delimiter = "\t" + case "csv": + delimiter = "," + } + + if reflect.TypeOf(obj).Kind() == reflect.Slice { + return strings.Trim(strings.Replace(fmt.Sprint(obj), " ", delimiter, -1), "[]") + } + + return fmt.Sprintf("%v", obj) +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + return c.cfg.HTTPClient.Do(request) +} + +// Change base path to allow switching to mocks +func (c *APIClient) ChangeBasePath(path string) { + c.cfg.BasePath = path +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + fileName string, + fileBytes []byte) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + if len(fileBytes) > 0 && fileName != "" { + w.Boundary() + //_, fileNm := filepath.Split(fileName) + part, err := w.CreateFormFile("file", filepath.Base(fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(fileBytes) + if err != nil { + return nil, err + } + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + } + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = query.Encode() + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers.Set(h, v) + } + localVarRequest.Header = headers + } + + // Override request host, if applicable + if c.cfg.Host != "" { + localVarRequest.Host = c.cfg.Host + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + // OAuth2 authentication + if tok, ok := ctx.Value(ContextOAuth2).(oauth2.TokenSource); ok { + // We were able to grab an oauth2 token from the context + var latestToken *oauth2.Token + if latestToken, err = tok.Token(); err != nil { + return nil, err + } + + latestToken.SetAuthHeader(localVarRequest) + } + + // Basic HTTP Authentication + if auth, ok := ctx.Value(ContextBasicAuth).(BasicAuth); ok { + localVarRequest.SetBasicAuth(auth.UserName, auth.Password) + } + + // AccessToken Authentication + if auth, ok := ctx.Value(ContextAccessToken).(string); ok { + localVarRequest.Header.Add("Authorization", "Bearer "+auth) + } + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if strings.Contains(contentType, "application/xml") { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } else if strings.Contains(contentType, "application/json") { + if err = json.Unmarshal(b, v); err != nil { + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + xml.NewEncoder(bodyBuf).Encode(body) + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("Invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } + expires = now.Add(lifetime) + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericSwaggerError Provides access to the body, error and model on returned errors. +type GenericSwaggerError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericSwaggerError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericSwaggerError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericSwaggerError) Model() interface{} { + return e.model +} diff --git a/samples/client/petstore-security-test/go/docs/FakeApi.md b/samples/client/petstore-security-test/go/docs/FakeApi.md index f855aef7bc3..1cf144bcd33 100644 --- a/samples/client/petstore-security-test/go/docs/FakeApi.md +++ b/samples/client/petstore-security-test/go/docs/FakeApi.md @@ -15,15 +15,15 @@ To test code injection *_/ ' \" =end -- \\r\\n \\n \\r Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **ctx** | **context.Context** | context for logging, tracing, authentication, etc. - **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **optional** | ***TestCodeInjectEndRnNROpts** | optional parameters | nil if no parameters ### Optional Parameters -Optional parameters are passed through a map[string]interface{}. +Optional parameters are passed through a pointer to a TestCodeInjectEndRnNROpts struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **testCodeInjectEndRnNR** | **string**| To test code injection *_/ ' \" =end -- \\r\\n \\n \\r | + **testCodeInjectEndRnNR** | **optional.String**| To test code injection *_/ ' \" =end -- \\r\\n \\n \\r | ### Return type diff --git a/samples/client/petstore-security-test/go/response.go b/samples/client/petstore-security-test/go/response.go new file mode 100644 index 00000000000..05fd1dc4e90 --- /dev/null +++ b/samples/client/petstore-security-test/go/response.go @@ -0,0 +1,44 @@ +/* + * Swagger Petstore *_/ ' \" =end -- \\r\\n \\n \\r + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ *_/ ' \" =end -- + * + * API version: 1.0.0 *_/ ' \" =end -- \\r\\n \\n \\r + * Contact: apiteam@swagger.io *_/ ' \" =end -- \\r\\n \\n \\r + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package swagger + +import ( + "net/http" +) + +type APIResponse struct { + *http.Response `json:"-"` + Message string `json:"message,omitempty"` + // Operation is the name of the swagger operation. + Operation string `json:"operation,omitempty"` + // RequestURL is the request URL. This value is always available, even if the + // embedded *http.Response is nil. + RequestURL string `json:"url,omitempty"` + // Method is the HTTP method used for the request. This value is always + // available, even if the embedded *http.Response is nil. + Method string `json:"method,omitempty"` + // Payload holds the contents of the response body (which may be nil or empty). + // This is provided here as the raw response.Body() reader will have already + // been drained. + Payload []byte `json:"-"` +} + +func NewAPIResponse(r *http.Response) *APIResponse { + + response := &APIResponse{Response: r} + return response +} + +func NewAPIResponseWithError(errorMessage string) *APIResponse { + + response := &APIResponse{Message: errorMessage} + return response +} diff --git a/samples/client/petstore/go/pet_api_test.go b/samples/client/petstore/go/pet_api_test.go index aa16a8b8acc..03f243602f1 100644 --- a/samples/client/petstore/go/pet_api_test.go +++ b/samples/client/petstore/go/pet_api_test.go @@ -104,7 +104,7 @@ func TestFindPetsByTag(t *testing.T) { assert := assert.New(t) for i := 0; i < len(resp); i++ { if resp[i].Id == 12830 { - assert.Equal(resp[i].Status, "pending", "Pet status should be `pending`") + assert.Equal(resp[i].Status, "available", "Pet status should be `available`") found = true } } From 07a81e7ac8932adddaeabe9b917dc1f5a9f74ac9 Mon Sep 17 00:00:00 2001 From: HugoMario Date: Fri, 27 Mar 2020 00:26:01 -0500 Subject: [PATCH 3/5] removed git conflict text --- .../client/petstore-security-test/go/.swagger-codegen/VERSION | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/client/petstore-security-test/go/.swagger-codegen/VERSION b/samples/client/petstore-security-test/go/.swagger-codegen/VERSION index 9243dcf2da8..a6254504e40 100644 --- a/samples/client/petstore-security-test/go/.swagger-codegen/VERSION +++ b/samples/client/petstore-security-test/go/.swagger-codegen/VERSION @@ -1,2 +1 @@ -<<<<<<< HEAD 2.3.1 \ No newline at end of file From c2a3252dc65f345414a71dbac3b7b2b6cb48ba03 Mon Sep 17 00:00:00 2001 From: HugoMario Date: Fri, 27 Mar 2020 00:26:32 -0500 Subject: [PATCH 4/5] updated sample --- .../go/go-petstore/.swagger-codegen/VERSION | 2 +- .../petstore/go/go-petstore/api/swagger.yaml | 96 +++++++++---------- .../client/petstore/go/go-petstore/api_pet.go | 2 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/samples/client/petstore/go/go-petstore/.swagger-codegen/VERSION b/samples/client/petstore/go/go-petstore/.swagger-codegen/VERSION index 6cecc1a68f3..be9d3ebd547 100644 --- a/samples/client/petstore/go/go-petstore/.swagger-codegen/VERSION +++ b/samples/client/petstore/go/go-petstore/.swagger-codegen/VERSION @@ -1 +1 @@ -2.4.6-SNAPSHOT \ No newline at end of file +2.4.13-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/go/go-petstore/api/swagger.yaml b/samples/client/petstore/go/go-petstore/api/swagger.yaml index d8749671bcb..35a55274005 100644 --- a/samples/client/petstore/go/go-petstore/api/swagger.yaml +++ b/samples/client/petstore/go/go-petstore/api/swagger.yaml @@ -52,7 +52,7 @@ paths: $ref: "#/definitions/Pet" x-exportParamName: "Body" responses: - 405: + "405": description: "Invalid input" security: - petstore_auth: @@ -79,11 +79,11 @@ paths: $ref: "#/definitions/Pet" x-exportParamName: "Body" responses: - 400: + "400": description: "Invalid ID supplied" - 404: + "404": description: "Pet not found" - 405: + "405": description: "Validation exception" security: - petstore_auth: @@ -115,13 +115,13 @@ paths: collectionFormat: "csv" x-exportParamName: "Status" responses: - 200: + "200": description: "successful operation" schema: type: "array" items: $ref: "#/definitions/Pet" - 400: + "400": description: "Invalid status value" security: - petstore_auth: @@ -149,13 +149,13 @@ paths: collectionFormat: "csv" x-exportParamName: "Tags" responses: - 200: + "200": description: "successful operation" schema: type: "array" items: $ref: "#/definitions/Pet" - 400: + "400": description: "Invalid tag value" security: - petstore_auth: @@ -181,13 +181,13 @@ paths: format: "int64" x-exportParamName: "PetId" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Pet" - 400: + "400": description: "Invalid ID supplied" - 404: + "404": description: "Pet not found" security: - api_key: [] @@ -225,7 +225,7 @@ paths: x-exportParamName: "Status" x-optionalDataType: "String" responses: - 405: + "405": description: "Invalid input" security: - petstore_auth: @@ -255,7 +255,7 @@ paths: format: "int64" x-exportParamName: "PetId" responses: - 400: + "400": description: "Invalid pet value" security: - petstore_auth: @@ -294,7 +294,7 @@ paths: type: "file" x-exportParamName: "File" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/ApiResponse" @@ -313,7 +313,7 @@ paths: - "application/json" parameters: [] responses: - 200: + "200": description: "successful operation" schema: type: "object" @@ -341,11 +341,11 @@ paths: $ref: "#/definitions/Order" x-exportParamName: "Body" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Order" - 400: + "400": description: "Invalid Order" /store/order/{order_id}: get: @@ -369,13 +369,13 @@ paths: format: "int64" x-exportParamName: "OrderId" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Order" - 400: + "400": description: "Invalid ID supplied" - 404: + "404": description: "Order not found" delete: tags: @@ -395,9 +395,9 @@ paths: type: "string" x-exportParamName: "OrderId" responses: - 400: + "400": description: "Invalid ID supplied" - 404: + "404": description: "Order not found" /user: post: @@ -490,7 +490,7 @@ paths: type: "string" x-exportParamName: "Password" responses: - 200: + "200": description: "successful operation" headers: X-Rate-Limit: @@ -503,7 +503,7 @@ paths: description: "date in UTC when token expires" schema: type: "string" - 400: + "400": description: "Invalid username/password supplied" /user/logout: get: @@ -537,13 +537,13 @@ paths: type: "string" x-exportParamName: "Username" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/User" - 400: + "400": description: "Invalid username supplied" - 404: + "404": description: "User not found" put: tags: @@ -569,9 +569,9 @@ paths: $ref: "#/definitions/User" x-exportParamName: "Body" responses: - 400: + "400": description: "Invalid user supplied" - 404: + "404": description: "User not found" delete: tags: @@ -590,9 +590,9 @@ paths: type: "string" x-exportParamName: "Username" responses: - 400: + "400": description: "Invalid username supplied" - 404: + "404": description: "User not found" /fake_classname_test: patch: @@ -614,7 +614,7 @@ paths: $ref: "#/definitions/Client" x-exportParamName: "Body" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Client" @@ -727,9 +727,9 @@ paths: x-exportParamName: "EnumQueryDouble" x-optionalDataType: "Float64" responses: - 400: + "400": description: "Invalid request" - 404: + "404": description: "Not found" post: tags: @@ -863,9 +863,9 @@ paths: x-exportParamName: "Callback" x-optionalDataType: "String" responses: - 400: + "400": description: "Invalid username supplied" - 404: + "404": description: "User not found" security: - http_basic_test: [] @@ -888,7 +888,7 @@ paths: $ref: "#/definitions/Client" x-exportParamName: "Body" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Client" @@ -907,7 +907,7 @@ paths: $ref: "#/definitions/OuterNumber" x-exportParamName: "Body" responses: - 200: + "200": description: "Output number" schema: $ref: "#/definitions/OuterNumber" @@ -926,7 +926,7 @@ paths: $ref: "#/definitions/OuterString" x-exportParamName: "Body" responses: - 200: + "200": description: "Output string" schema: $ref: "#/definitions/OuterString" @@ -945,7 +945,7 @@ paths: $ref: "#/definitions/OuterBoolean" x-exportParamName: "Body" responses: - 200: + "200": description: "Output boolean" schema: $ref: "#/definitions/OuterBoolean" @@ -964,7 +964,7 @@ paths: $ref: "#/definitions/OuterComposite" x-exportParamName: "Body" responses: - 200: + "200": description: "Output composite" schema: $ref: "#/definitions/OuterComposite" @@ -991,7 +991,7 @@ paths: type: "string" x-exportParamName: "Param2" responses: - 200: + "200": description: "successful operation" /fake/inline-additionalProperties: post: @@ -1013,7 +1013,7 @@ paths: type: "string" x-exportParamName: "Param" responses: - 200: + "200": description: "successful operation" /fake/body-with-query-params: put: @@ -1035,7 +1035,7 @@ paths: type: "string" x-exportParamName: "Query" responses: - 200: + "200": description: "Success" /another-fake/dummy: patch: @@ -1057,7 +1057,7 @@ paths: $ref: "#/definitions/Client" x-exportParamName: "Body" responses: - 200: + "200": description: "successful operation" schema: $ref: "#/definitions/Client" @@ -1269,13 +1269,13 @@ definitions: readOnly: true property: type: "string" - 123Number: + "123Number": type: "integer" readOnly: true xml: name: "Name" description: "Model for testing model name same as property name" - 200_response: + "200_response": properties: name: type: "integer" @@ -1444,7 +1444,7 @@ definitions: List: type: "object" properties: - 123-list: + "123-list": type: "string" Client: type: "object" diff --git a/samples/client/petstore/go/go-petstore/api_pet.go b/samples/client/petstore/go/go-petstore/api_pet.go index 631ad3eaccf..960a5f994e3 100644 --- a/samples/client/petstore/go/go-petstore/api_pet.go +++ b/samples/client/petstore/go/go-petstore/api_pet.go @@ -674,7 +674,7 @@ func (a *PetApiService) UploadFile(ctx context.Context, petId int64, localVarOpt if localVarOptionals != nil && localVarOptionals.AdditionalMetadata.IsSet() { localVarFormParams.Add("additionalMetadata", parameterToString(localVarOptionals.AdditionalMetadata.Value(), "")) } - var localVarFile *os.File + var localVarFile *os.File if localVarOptionals != nil && localVarOptionals.File.IsSet() { localVarFileOk := false localVarFile, localVarFileOk = localVarOptionals.File.Value().(*os.File) From 8859a05672286e41aba17c3fbf278fce006723a3 Mon Sep 17 00:00:00 2001 From: HugoMario Date: Fri, 27 Mar 2020 00:33:41 -0500 Subject: [PATCH 5/5] removed conflict text on api file --- samples/client/petstore-security-test/go/api/swagger.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/samples/client/petstore-security-test/go/api/swagger.yaml b/samples/client/petstore-security-test/go/api/swagger.yaml index 8170c09ca78..81d2ac1b8bb 100644 --- a/samples/client/petstore-security-test/go/api/swagger.yaml +++ b/samples/client/petstore-security-test/go/api/swagger.yaml @@ -63,15 +63,10 @@ definitions: type: "integer" format: "int32" description: "property description */ ' \" =end -- \\r\\n \\n \\r" -<<<<<<< HEAD description: "Model for testing reserved words */ ' \" =end -- \\r\\n \\n \\r" xml: name: "Return" -======= - xml: - name: "Return" - description: "Model for testing reserved words */ ' \" =end -- \\r\\n \\n \\r" ->>>>>>> be8a5d44b898ae043444f6a78792e96dbde6fe8b + externalDocs: description: "Find out more about Swagger */ ' \" =end -- \\r\\n \\n \\r" url: "http://swagger.io"