From f84607707122a9bf42a4955c8ce2492a74a80625 Mon Sep 17 00:00:00 2001 From: Michael Farrell Date: Thu, 20 Feb 2025 17:26:39 +1000 Subject: [PATCH] Add `ca_cert_data` parameter to Python client. This lets a client validate a server's CA certificate chain using a variable/constant containing PEM (`str`) or DER (`bytes`) data, rather than needing to reference a file on disk. --- .../src/main/resources/python/asyncio/rest.mustache | 3 ++- .../src/main/resources/python/configuration.mustache | 7 +++++++ .../src/main/resources/python/rest.mustache | 1 + .../openapi_client/configuration.py | 7 +++++++ .../openapi_client/rest.py | 1 + .../client/echo_api/python/openapi_client/configuration.py | 7 +++++++ samples/client/echo_api/python/openapi_client/rest.py | 1 + .../petstore/python-aiohttp/petstore_api/configuration.py | 7 +++++++ .../client/petstore/python-aiohttp/petstore_api/rest.py | 3 ++- .../client/petstore/python/petstore_api/configuration.py | 7 +++++++ .../openapi3/client/petstore/python/petstore_api/rest.py | 1 + 11 files changed, 43 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache index 3b201d99ba9b2..937e76ed5a4c2 100644 --- a/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/asyncio/rest.mustache @@ -47,7 +47,8 @@ class RESTClientObject: self.maxsize = configuration.connection_pool_maxsize self.ssl_context = ssl.create_default_context( - cafile=configuration.ssl_ca_cert + cafile=configuration.ssl_ca_cert, + cadata=configuration.ca_cert_data, ) if configuration.cert_file: self.ssl_context.load_cert_chain( diff --git a/modules/openapi-generator/src/main/resources/python/configuration.mustache b/modules/openapi-generator/src/main/resources/python/configuration.mustache index 667a5c88fc930..de8ab2cae070d 100644 --- a/modules/openapi-generator/src/main/resources/python/configuration.mustache +++ b/modules/openapi-generator/src/main/resources/python/configuration.mustache @@ -183,6 +183,8 @@ class Configuration: :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. :param retries: Number of retries for API requests. + :param ca_cert_data: str|bytes - verify the peer using concatenated CA + certificate data in PEM (str) or DER (bytes) format. {{#hasAuthMethods}} :Example: @@ -289,6 +291,7 @@ conf = {{{packageName}}}.Configuration( ignore_operation_servers: bool=False, ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, + ca_cert_data: Optional[str | bytes] = None, *, debug: Optional[bool] = None, ) -> None: @@ -373,6 +376,10 @@ conf = {{{packageName}}}.Configuration( self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ self.cert_file = None """client certificate file """ diff --git a/modules/openapi-generator/src/main/resources/python/rest.mustache b/modules/openapi-generator/src/main/resources/python/rest.mustache index fc71a59cf4048..f545066bb6776 100644 --- a/modules/openapi-generator/src/main/resources/python/rest.mustache +++ b/modules/openapi-generator/src/main/resources/python/rest.mustache @@ -66,6 +66,7 @@ class RESTClientObject: "ca_certs": configuration.ssl_ca_cert, "cert_file": configuration.cert_file, "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, } if configuration.assert_hostname is not None: pool_args['assert_hostname'] = ( diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/configuration.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/configuration.py index e48902fd8ede2..ce10b7eb4af65 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/configuration.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/configuration.py @@ -163,6 +163,8 @@ class Configuration: :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. :param retries: Number of retries for API requests. + :param ca_cert_data: str|bytes - verify the peer using concatenated CA + certificate data in PEM (str) or DER (bytes) format. :Example: @@ -200,6 +202,7 @@ def __init__( ignore_operation_servers: bool=False, ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, + ca_cert_data: Optional[str | bytes] = None, *, debug: Optional[bool] = None, ) -> None: @@ -277,6 +280,10 @@ def __init__( self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ self.cert_file = None """client certificate file """ diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py index 91fb8eb029dc8..89600d574a46a 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/rest.py @@ -77,6 +77,7 @@ def __init__(self, configuration) -> None: "ca_certs": configuration.ssl_ca_cert, "cert_file": configuration.cert_file, "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, } if configuration.assert_hostname is not None: pool_args['assert_hostname'] = ( diff --git a/samples/client/echo_api/python/openapi_client/configuration.py b/samples/client/echo_api/python/openapi_client/configuration.py index e48902fd8ede2..ce10b7eb4af65 100644 --- a/samples/client/echo_api/python/openapi_client/configuration.py +++ b/samples/client/echo_api/python/openapi_client/configuration.py @@ -163,6 +163,8 @@ class Configuration: :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. :param retries: Number of retries for API requests. + :param ca_cert_data: str|bytes - verify the peer using concatenated CA + certificate data in PEM (str) or DER (bytes) format. :Example: @@ -200,6 +202,7 @@ def __init__( ignore_operation_servers: bool=False, ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, + ca_cert_data: Optional[str | bytes] = None, *, debug: Optional[bool] = None, ) -> None: @@ -277,6 +280,10 @@ def __init__( self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ self.cert_file = None """client certificate file """ diff --git a/samples/client/echo_api/python/openapi_client/rest.py b/samples/client/echo_api/python/openapi_client/rest.py index b97741ddfce4d..d2bd065dc08fc 100644 --- a/samples/client/echo_api/python/openapi_client/rest.py +++ b/samples/client/echo_api/python/openapi_client/rest.py @@ -77,6 +77,7 @@ def __init__(self, configuration) -> None: "ca_certs": configuration.ssl_ca_cert, "cert_file": configuration.cert_file, "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, } if configuration.assert_hostname is not None: pool_args['assert_hostname'] = ( diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/configuration.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/configuration.py index 0282a0aa460ba..3ddcd1cafd8d3 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/configuration.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/configuration.py @@ -168,6 +168,8 @@ class Configuration: :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. :param retries: Number of retries for API requests. + :param ca_cert_data: str|bytes - verify the peer using concatenated CA + certificate data in PEM (str) or DER (bytes) format. :Example: @@ -264,6 +266,7 @@ def __init__( ignore_operation_servers: bool=False, ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, + ca_cert_data: Optional[str | bytes] = None, *, debug: Optional[bool] = None, ) -> None: @@ -346,6 +349,10 @@ def __init__( self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ self.cert_file = None """client certificate file """ diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py index ec1da5adf9e3d..5ee6cd4b2df8f 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/rest.py @@ -57,7 +57,8 @@ def __init__(self, configuration) -> None: self.maxsize = configuration.connection_pool_maxsize self.ssl_context = ssl.create_default_context( - cafile=configuration.ssl_ca_cert + cafile=configuration.ssl_ca_cert, + cadata=configuration.ca_cert_data, ) if configuration.cert_file: self.ssl_context.load_cert_chain( diff --git a/samples/openapi3/client/petstore/python/petstore_api/configuration.py b/samples/openapi3/client/petstore/python/petstore_api/configuration.py index f374b0bc53d41..a78b6698ea914 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/configuration.py +++ b/samples/openapi3/client/petstore/python/petstore_api/configuration.py @@ -169,6 +169,8 @@ class Configuration: :param ssl_ca_cert: str - the path to a file of concatenated CA certificates in PEM format. :param retries: Number of retries for API requests. + :param ca_cert_data: str|bytes - verify the peer using concatenated CA + certificate data in PEM (str) or DER (bytes) format. :Example: @@ -265,6 +267,7 @@ def __init__( ignore_operation_servers: bool=False, ssl_ca_cert: Optional[str]=None, retries: Optional[int] = None, + ca_cert_data: Optional[str | bytes] = None, *, debug: Optional[bool] = None, ) -> None: @@ -347,6 +350,10 @@ def __init__( self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ + self.ca_cert_data = ca_cert_data + """Set this to verify the peer using PEM (str) or DER (bytes) + certificate data. + """ self.cert_file = None """client certificate file """ diff --git a/samples/openapi3/client/petstore/python/petstore_api/rest.py b/samples/openapi3/client/petstore/python/petstore_api/rest.py index 3c7cc883f69ba..abc7aa2893841 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/rest.py +++ b/samples/openapi3/client/petstore/python/petstore_api/rest.py @@ -76,6 +76,7 @@ def __init__(self, configuration) -> None: "ca_certs": configuration.ssl_ca_cert, "cert_file": configuration.cert_file, "key_file": configuration.key_file, + "ca_cert_data": configuration.ca_cert_data, } if configuration.assert_hostname is not None: pool_args['assert_hostname'] = (