11"""OpenAPI core validation request validators module"""
2- import base64
3- import binascii
42from itertools import chain
53from six import iteritems
6- import warnings
74
85from openapi_core .casting .schemas .exceptions import CastError
96from openapi_core .deserializing .exceptions import DeserializeError
1411)
1512from openapi_core .schema .paths .exceptions import InvalidPath
1613from openapi_core .schema .request_bodies .exceptions import MissingRequestBody
17- from openapi_core .schema .security_schemes .enums import SecuritySchemeType
1814from openapi_core .schema .servers .exceptions import InvalidServer
15+ from openapi_core .security .exceptions import SecurityError
1916from openapi_core .unmarshalling .schemas .exceptions import (
2017 UnmarshalError , ValidateError ,
2118)
19+ from openapi_core .validation .exceptions import InvalidSecurity
2220from openapi_core .validation .request .datatypes import (
2321 RequestParameters , RequestValidationResult ,
2422)
@@ -45,8 +43,7 @@ def validate(self, request):
4543
4644 try :
4745 security = self ._get_security (request , operation )
48- # TODO narrow exceptions
49- except Exception as exc :
46+ except InvalidSecurity as exc :
5047 return RequestValidationResult ([exc , ], None , None , None )
5148
5249 params , params_errors = self ._get_parameters (
@@ -108,14 +105,16 @@ def _get_security(self, request, operation):
108105 return {}
109106
110107 for security_requirement in security :
111- data = {
112- security_requirement .name : self ._get_security_value (
113- security_requirement .name , request )
114- }
115- if all (value for value in data .values ()):
116- return data
108+ try :
109+ return {
110+ scheme_name : self ._get_security_value (
111+ scheme_name , request )
112+ for scheme_name in security_requirement
113+ }
114+ except SecurityError :
115+ continue
117116
118- return {}
117+ raise InvalidSecurity ()
119118
120119 def _get_parameters (self , request , params ):
121120 errors = []
@@ -196,27 +195,10 @@ def _get_security_value(self, scheme_name, request):
196195 if not scheme :
197196 return
198197
199- if scheme .type == SecuritySchemeType .API_KEY :
200- source = getattr (request .parameters , scheme .apikey_in .value )
201- return source .get (scheme .name )
202- elif scheme .type == SecuritySchemeType .HTTP :
203- auth_header = request .parameters .header .get ('Authorization' )
204- try :
205- auth_type , encoded_credentials = auth_header .split (' ' , 1 )
206- except ValueError :
207- raise ValueError ('Could not parse authorization header.' )
208-
209- if auth_type .lower () != scheme .scheme .value :
210- raise ValueError (
211- 'Unknown authorization method %s' % auth_type )
212- try :
213- return base64 .b64decode (
214- encoded_credentials .encode ('ascii' ), validate = True
215- ).decode ('latin1' )
216- except binascii .Error :
217- raise ValueError ('Invalid base64 encoding.' )
218-
219- warnings .warn ("Only api key security scheme type supported" )
198+ from openapi_core .security .factories import SecurityProviderFactory
199+ security_provider_factory = SecurityProviderFactory ()
200+ security_provider = security_provider_factory .create (scheme )
201+ return security_provider (request )
220202
221203 def _get_parameter_value (self , param , request ):
222204 location = request .parameters [param .location .value ]
0 commit comments