mirror of
https://github.com/correl/openapi-core.git
synced 2024-11-22 03:00:10 +00:00
Remove security on operation level fix
This commit is contained in:
parent
b6a745c7e9
commit
dcec29b1aa
6 changed files with 148 additions and 13 deletions
|
@ -42,12 +42,16 @@ class OperationsGenerator(object):
|
|||
tags_list = operation_deref.get('tags', [])
|
||||
summary = operation_deref.get('summary')
|
||||
description = operation_deref.get('description')
|
||||
security_spec = operation_deref.get('security', [])
|
||||
servers_spec = operation_deref.get('servers', [])
|
||||
|
||||
servers = self.servers_generator.generate(servers_spec)
|
||||
security = self.security_requirements_generator.generate(
|
||||
security_spec)
|
||||
|
||||
security = None
|
||||
if 'security' in operation_deref:
|
||||
security_spec = operation_deref.get('security')
|
||||
security = self.security_requirements_generator.generate(
|
||||
security_spec)
|
||||
|
||||
extensions = self.extensions_generator.generate(operation_deref)
|
||||
|
||||
external_docs = None
|
||||
|
@ -67,7 +71,7 @@ class OperationsGenerator(object):
|
|||
Operation(
|
||||
http_method, path_name, responses, list(parameters),
|
||||
summary=summary, description=description,
|
||||
external_docs=external_docs, security=list(security),
|
||||
external_docs=external_docs, security=security,
|
||||
request_body=request_body, deprecated=deprecated,
|
||||
operation_id=operation_id, tags=list(tags_list),
|
||||
servers=list(servers), extensions=extensions,
|
||||
|
|
|
@ -18,7 +18,7 @@ class Operation(object):
|
|||
self.summary = summary
|
||||
self.description = description
|
||||
self.external_docs = external_docs
|
||||
self.security = security
|
||||
self.security = security and list(security)
|
||||
self.request_body = request_body
|
||||
self.deprecated = deprecated
|
||||
self.operation_id = operation_id
|
||||
|
|
|
@ -87,7 +87,10 @@ class RequestValidator(BaseValidator):
|
|||
)
|
||||
|
||||
def _get_security(self, request, operation):
|
||||
security = operation.security or self.spec.security
|
||||
security = self.spec.security
|
||||
if operation.security is not None:
|
||||
security = operation.security
|
||||
|
||||
if not security:
|
||||
return {}
|
||||
|
||||
|
|
41
tests/integration/data/v3.0/security_override.yaml
Normal file
41
tests/integration/data/v3.0/security_override.yaml
Normal file
|
@ -0,0 +1,41 @@
|
|||
openapi: "3.0.0"
|
||||
info:
|
||||
title: Minimal OpenAPI specification with security override
|
||||
version: "0.1"
|
||||
security:
|
||||
- api_key: []
|
||||
paths:
|
||||
/resource/{resId}:
|
||||
parameters:
|
||||
- name: resId
|
||||
in: path
|
||||
required: true
|
||||
description: the ID of the resource to retrieve
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
responses:
|
||||
default:
|
||||
description: Default security.
|
||||
post:
|
||||
security:
|
||||
- petstore_auth:
|
||||
- write:pets
|
||||
- read:pets
|
||||
responses:
|
||||
default:
|
||||
description: Override security.
|
||||
put:
|
||||
security: []
|
||||
responses:
|
||||
default:
|
||||
description: Remove security.
|
||||
components:
|
||||
securitySchemes:
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: query
|
||||
petstore_auth:
|
||||
type: http
|
||||
scheme: basic
|
|
@ -152,14 +152,15 @@ class TestPetstore(object):
|
|||
assert variable.default == variable_spec['default']
|
||||
assert variable.enum == variable_spec.get('enum')
|
||||
|
||||
security_spec = operation_spec.get('security', [])
|
||||
for idx, security_req in enumerate(operation.security):
|
||||
assert type(security_req) == SecurityRequirement
|
||||
security_spec = operation_spec.get('security')
|
||||
if security_spec is not None:
|
||||
for idx, security_req in enumerate(operation.security):
|
||||
assert type(security_req) == SecurityRequirement
|
||||
|
||||
security_req_spec = security_spec[idx]
|
||||
for scheme_name in security_req:
|
||||
security_req[scheme_name] == security_req_spec[
|
||||
scheme_name]
|
||||
security_req_spec = security_spec[idx]
|
||||
for scheme_name in security_req:
|
||||
security_req[scheme_name] == security_req_spec[
|
||||
scheme_name]
|
||||
|
||||
responses_spec = operation_spec.get('responses')
|
||||
|
||||
|
|
86
tests/integration/validation/test_security_override.py
Normal file
86
tests/integration/validation/test_security_override.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
from base64 import b64encode
|
||||
|
||||
import pytest
|
||||
from six import text_type
|
||||
|
||||
from openapi_core.shortcuts import create_spec
|
||||
from openapi_core.validation.exceptions import InvalidSecurity
|
||||
from openapi_core.validation.request.validators import RequestValidator
|
||||
from openapi_core.testing import MockRequest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def request_validator(spec):
|
||||
return RequestValidator(spec)
|
||||
|
||||
|
||||
@pytest.fixture('class')
|
||||
def spec(factory):
|
||||
spec_dict = factory.spec_from_file("data/v3.0/security_override.yaml")
|
||||
return create_spec(spec_dict)
|
||||
|
||||
|
||||
class TestSecurityOverride(object):
|
||||
|
||||
host_url = 'http://petstore.swagger.io'
|
||||
|
||||
api_key = '12345'
|
||||
|
||||
@property
|
||||
def api_key_encoded(self):
|
||||
api_key_bytes = self.api_key.encode('utf8')
|
||||
api_key_bytes_enc = b64encode(api_key_bytes)
|
||||
return text_type(api_key_bytes_enc, 'utf8')
|
||||
|
||||
def test_default(self, request_validator):
|
||||
args = {'api_key': self.api_key}
|
||||
request = MockRequest(
|
||||
self.host_url, 'get', '/resource/one', args=args)
|
||||
|
||||
result = request_validator.validate(request)
|
||||
|
||||
assert not result.errors
|
||||
assert result.security == {
|
||||
'api_key': self.api_key,
|
||||
}
|
||||
|
||||
def test_default_invalid(self, request_validator):
|
||||
request = MockRequest(self.host_url, 'get', '/resource/one')
|
||||
|
||||
result = request_validator.validate(request)
|
||||
|
||||
assert type(result.errors[0]) == InvalidSecurity
|
||||
assert result.security is None
|
||||
|
||||
def test_override(self, request_validator):
|
||||
authorization = 'Basic ' + self.api_key_encoded
|
||||
headers = {
|
||||
'Authorization': authorization,
|
||||
}
|
||||
request = MockRequest(
|
||||
self.host_url, 'post', '/resource/one', headers=headers)
|
||||
|
||||
result = request_validator.validate(request)
|
||||
|
||||
assert not result.errors
|
||||
assert result.security == {
|
||||
'petstore_auth': self.api_key_encoded,
|
||||
}
|
||||
|
||||
def test_override_invalid(self, request_validator):
|
||||
request = MockRequest(
|
||||
self.host_url, 'post', '/resource/one')
|
||||
|
||||
result = request_validator.validate(request)
|
||||
|
||||
assert type(result.errors[0]) == InvalidSecurity
|
||||
assert result.security is None
|
||||
|
||||
def test_remove(self, request_validator):
|
||||
request = MockRequest(
|
||||
self.host_url, 'put', '/resource/one')
|
||||
|
||||
result = request_validator.validate(request)
|
||||
|
||||
assert not result.errors
|
||||
assert result.security == {}
|
Loading…
Reference in a new issue