diff --git a/mock/mock_engine.go b/mock/mock_engine.go index 4219531..06f8faf 100644 --- a/mock/mock_engine.go +++ b/mock/mock_engine.go @@ -51,17 +51,6 @@ func (rme *ResponseMockEngine) ValidateSecurity(request *http.Request, operation mustApply := make(map[string][]string) - // global security - if len(rme.doc.Security) > 0 { - for _, securityRequirement := range rme.doc.Security { - for securityPairs := securityRequirement.Requirements.First(); securityPairs != nil; securityPairs = securityPairs.Next() { - key := securityPairs.Key() - scopes := securityPairs.Value() - mustApply[key] = scopes - } - } - } - // operation security if len(operation.Security) > 0 { for _, securityRequirement := range operation.Security { @@ -79,6 +68,17 @@ func (rme *ResponseMockEngine) ValidateSecurity(request *http.Request, operation } } + // global security if no local security found. + if len(mustApply) <= 0 && len(rme.doc.Security) > 0 { + for _, securityRequirement := range rme.doc.Security { + for securityPairs := securityRequirement.Requirements.First(); securityPairs != nil; securityPairs = securityPairs.Next() { + key := securityPairs.Key() + scopes := securityPairs.Value() + mustApply[key] = scopes + } + } + } + // check if we have any security requirements to apply. if len(mustApply) > 0 { // locate the security schemes components from the document. @@ -95,7 +95,8 @@ func (rme *ResponseMockEngine) ValidateSecurity(request *http.Request, operation if securityComponent.Scheme == "bearer" || securityComponent.Scheme == "basic" { // check if we have a bearer token. if request.Header.Get("Authorization") == "" { - return fmt.Errorf("bearer token not found, no `Authorization` header found in request") + return fmt.Errorf("%s authentication failed: bearer token not found, "+ + "no `Authorization` header found in request", securityComponent.Scheme) } } @@ -347,6 +348,9 @@ func (rme *ResponseMockEngine) lookForResponseCodes( responseBody = resp.Content.GetOrZero("application/json") return responseBody, false } + } else { + // no content, so try and extract a default JSON response + return nil, false } } diff --git a/mock/mock_engine_test.go b/mock/mock_engine_test.go index d802568..b4e5087 100644 --- a/mock/mock_engine_test.go +++ b/mock/mock_engine_test.go @@ -445,3 +445,98 @@ components: err := me.ValidateSecurity(request, operation) assert.NoError(t, err) } + +// https://github.com/pb33f/wiretap/issues/78 +func TestNewMockEngine_Fragment(t *testing.T) { + + spec := `openapi: 3.1.0 +info: + title: Test + version: 0.1.0 +security: + - apiKeyAuth: [] +paths: + /auth#basicAuth: + post: + operationId: basicAuth + security: + - basicAuth: [] + servers: + - url: http://localhost:35456 + requestBody: + content: + application/json: + schemas: + type: object + required: true + responses: + "200": + description: OK +components: + securitySchemes: + basicAuth: + type: http + scheme: basic` + + d, _ := libopenapi.NewDocument([]byte(spec)) + doc, _ := d.BuildV3Model() + + me := NewMockEngine(&doc.Model, false) + + request, _ := http.NewRequest(http.MethodPost, "https://api.pb33f.io/auth", nil) + request.Header.Set(helpers.ContentTypeHeader, "application/json") + path, _ := me.findPath(request) + operation := me.findOperation(request, path) + + err := me.ValidateSecurity(request, operation) + assert.Error(t, err) + assert.Equal(t, "basic authentication failed: bearer token not found, "+ + "no `Authorization` header found in request", err.Error()) +} + +// https://github.com/pb33f/wiretap/issues/79 +func TestNewMockEngine_ContentType(t *testing.T) { + + spec := `openapi: 3.1.0 +info: + title: Test + version: 0.1.0 +paths: + /auth: + post: + operationId: basicAuth + security: + - basicAuth: [] + servers: + - url: http://localhost:35456 + requestBody: + content: + application/json: + schemas: + type: object + required: true + responses: + "200": + description: OK +components: + securitySchemes: + basicAuth: + type: http + scheme: basic` + + d, _ := libopenapi.NewDocument([]byte(spec)) + doc, _ := d.BuildV3Model() + + me := NewMockEngine(&doc.Model, false) + + payload := `{"basicAuth":{"password":"testPass","username":"testUser"}}` + buf := bytes.NewBuffer([]byte(payload)) + request, _ := http.NewRequest(http.MethodPost, "https://api.pb33f.io/auth", buf) + request.Header.Set(helpers.ContentTypeHeader, "application/json") + request.Header.Set(helpers.AuthorizationHeader, "the science man") + + b, status, err := me.GenerateResponse(request) + assert.NoError(t, err) + assert.Equal(t, 200, status) + assert.Equal(t, "", string(b)) +}