From 7171c1279405866e537a1dfd213cf6d90a914b5f Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Fri, 27 Jan 2023 13:51:53 +0100 Subject: [PATCH 1/8] feat(proxy): add setting to be able to use proxies --- .../sdk/utils/authentication/confidential.py | 61 +++++++++++++++++-- .../utils/authentication/test_confidential.py | 26 +++++++- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/fds/sdk/utils/authentication/confidential.py b/src/fds/sdk/utils/authentication/confidential.py index 5c4b078..9227de7 100644 --- a/src/fds/sdk/utils/authentication/confidential.py +++ b/src/fds/sdk/utils/authentication/confidential.py @@ -33,7 +33,14 @@ class ConfidentialClient(OAuth2Client): the access token, caching it and refreshing it as needed. """ - def __init__(self, config_path: str = "", config: dict = None) -> None: + def __init__( + self, + config_path: str = "", + config: dict = None, + proxy: dict = None, + verify_ssl: bool = True, + proxy_headers: dict = None, + ) -> None: """ Creates a new ConfidentialClient. @@ -70,7 +77,23 @@ def __init__(self, config_path: str = "", config: dict = None) -> None: } } - `NB`: Within the JWK parameters kty, alg, use, kid, n, e, d, p, q, dp, dq, qi are required for authorization. + `NB`: Within the JWK parameters kty, alg, use, kid, n, e, d, p, q, dp, dq, qi are + required for authorization. + + `proxy` (dict) : Dictionary to tell the client which proxies should be used + + `Example Proxy Settings` + { + "http": "http://10.10.10.10:8000", + "https”: "http://10.10.10.10:8000", + } + + `verify_ssl` (bool): Toggles the verification of SSL Certificates, could be used if a proxy or firewall + uses self-signed certificates + + `proxy_headers` (dict) : Sometimes it is necessary to add custom headers to http requests to be able to + use a proxy or firewall + Raises: AuthServerMetadataError: Raised if there's an issue retrieving the authorization server metadata AuthServerMetadataContentError: Raised if the authorization server metadata is incomplete @@ -84,7 +107,7 @@ def __init__(self, config_path: str = "", config: dict = None) -> None: raise ValueError("Either 'config_path' or 'config' must be set.") if config_path and config: - raise ValueError("Either 'config_path' or 'config' must be set. Not Both.") + raise ValueError("Either 'config_path' or 'config' must be set. Not Both.") if config_path: try: @@ -97,6 +120,14 @@ def __init__(self, config_path: str = "", config: dict = None) -> None: if config: self._config = config + if proxy: + self._proxies = {"http": proxy, "https": proxy} + else: + self._proxies = None + + self._verify_ssl = verify_ssl + self._proxy_headers = proxy_headers + try: self._oauth_session = OAuth2Session( client=BackendApplicationClient(client_id=self._config[CONSTS.CONFIG_CLIENT_ID]) @@ -127,7 +158,17 @@ def _init_auth_server_metadata(self) -> None: log.debug( "Attempting metadata retrieval from well_known_uri: %s", self._config[CONSTS.CONFIG_WELL_KNOWN_URI] ) - res = requests.get(self._config[CONSTS.CONFIG_WELL_KNOWN_URI]) + + with requests.Session() as session: + if self._proxies: + session.proxies = self._proxies + + if self._proxy_headers: + session.headers.update(self._proxy_headers) + + session.verify = self._verify_ssl + + res = requests.get(url=self._config[CONSTS.CONFIG_WELL_KNOWN_URI]) log.debug("Request from well_known_uri completed with status: %s", res.status_code) log.debug("Response headers from well_known_uri were %s", res.headers) self._well_known_uri_metadata = res.json() @@ -208,11 +249,23 @@ def get_access_token(self) -> str: try: log.debug("Fetching new access token") + + headers = { + "Accept": "application/json", + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", + } + + if self._proxy_headers: + headers |= self._proxy_headers + token = self._oauth_session.fetch_token( token_url=self._well_known_uri_metadata[CONSTS.META_TOKEN_ENDPOINT], client_id=self._config[CONSTS.CONFIG_CLIENT_ID], client_assertion_type="urn:ietf:params:oauth:client-assertion-type:jwt-bearer", client_assertion=self._get_client_assertion_jws(), + verify=self._verify_ssl, + proxies=self._proxies, + headers=headers, ) self._cached_token = token log.info("Caching token that expires at %s", token[CONSTS.TOKEN_EXPIRES_AT]) diff --git a/tests/fds/sdk/utils/authentication/test_confidential.py b/tests/fds/sdk/utils/authentication/test_confidential.py index 81fb622..53427eb 100644 --- a/tests/fds/sdk/utils/authentication/test_confidential.py +++ b/tests/fds/sdk/utils/authentication/test_confidential.py @@ -166,6 +166,24 @@ def test_constructor_session_instantiation(mocker, example_config): mock_oauth2_session.assert_called_with(client=backend_result) +def test_constructor_session_instantiation_with_additional_parameters(mocker, example_config): + test_client_id = "good_test" + backend_result = "good_mock_backend" + example_config["clientId"] = test_client_id + mock_oauth_backend = mocker.patch( + "fds.sdk.utils.authentication.confidential.BackendApplicationClient", return_value=backend_result + ) + + mock_oauth2_session = mocker.patch("fds.sdk.utils.authentication.confidential.OAuth2Session") + + additional_parameters = {"proxy": "http://my:pass@test.test.test", "verify_ssl": False, "proxy_headers": {}} + + ConfidentialClient(config=example_config, **additional_parameters) + + mock_oauth_backend.assert_called_with(client_id=test_client_id) + mock_oauth2_session.assert_called_with(client=backend_result) + + def test_constructor_custom_well_known_uri(mocker, example_config, caplog): caplog.set_level(logging.DEBUG) mocker.patch("fds.sdk.utils.authentication.confidential.BackendApplicationClient") @@ -188,7 +206,7 @@ def json(self): client = ConfidentialClient(config=example_config) - get_mock.assert_called_with(auth_test) + get_mock.assert_called_with(url=auth_test) assert client assert "Attempting metadata retrieval from well_known_uri: https://auth.test" in caplog.text @@ -325,6 +343,12 @@ def test_get_access_token_fetch(client, mocker): client_id="test-clientid", client_assertion_type="urn:ietf:params:oauth:client-assertion-type:jwt-bearer", client_assertion="jws", + proxies=None, + verify=True, + headers={ + "Accept": "application/json", + "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", + }, ) From efacf84b2d305e0dc7c31434840e8812eb0ba140 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:34:30 +0100 Subject: [PATCH 2/8] chore(config): fix verify_ssl docs, fix proxy settings --- src/fds/sdk/utils/authentication/confidential.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/fds/sdk/utils/authentication/confidential.py b/src/fds/sdk/utils/authentication/confidential.py index 9227de7..633dd5c 100644 --- a/src/fds/sdk/utils/authentication/confidential.py +++ b/src/fds/sdk/utils/authentication/confidential.py @@ -38,7 +38,7 @@ def __init__( config_path: str = "", config: dict = None, proxy: dict = None, - verify_ssl: bool = True, + verify_ssl=True, proxy_headers: dict = None, ) -> None: """ @@ -88,8 +88,12 @@ def __init__( "https”: "http://10.10.10.10:8000", } - `verify_ssl` (bool): Toggles the verification of SSL Certificates, could be used if a proxy or firewall - uses self-signed certificates + `verify_ssl` (bool | string): Either a boolean, in which case it controls whether we verify the server's + TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults + to ``True``. When set to ``False``, requests will accept any TLS certificate presented by the server, + and will ignore hostname mismatches and/or expired certificates, which will make your application + vulnerable to man-in-the-middle (MitM) attacks. Setting verify to ``False`` may be useful during + local development or testing. `proxy_headers` (dict) : Sometimes it is necessary to add custom headers to http requests to be able to use a proxy or firewall @@ -121,7 +125,11 @@ def __init__( self._config = config if proxy: - self._proxies = {"http": proxy, "https": proxy} + self._proxies = {} + if proxy['http']: + self._proxies['http'] = proxy['http'] + if proxy['https']: + self._proxies['https'] = proxy['https'] else: self._proxies = None From 666153d0b3bb70867ef2fd9967d75235258295b3 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:47:58 +0100 Subject: [PATCH 3/8] chore(config): fix verify_ssl docs, fix proxy settings --- src/fds/sdk/utils/authentication/confidential.py | 8 ++++---- tests/fds/sdk/utils/authentication/test_confidential.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fds/sdk/utils/authentication/confidential.py b/src/fds/sdk/utils/authentication/confidential.py index 633dd5c..8943098 100644 --- a/src/fds/sdk/utils/authentication/confidential.py +++ b/src/fds/sdk/utils/authentication/confidential.py @@ -126,10 +126,10 @@ def __init__( if proxy: self._proxies = {} - if proxy['http']: - self._proxies['http'] = proxy['http'] - if proxy['https']: - self._proxies['https'] = proxy['https'] + if "http" in proxy: + self._proxies["http"] = proxy["http"] + if "https" in proxy: + self._proxies["https"] = proxy["https"] else: self._proxies = None diff --git a/tests/fds/sdk/utils/authentication/test_confidential.py b/tests/fds/sdk/utils/authentication/test_confidential.py index 53427eb..8557661 100644 --- a/tests/fds/sdk/utils/authentication/test_confidential.py +++ b/tests/fds/sdk/utils/authentication/test_confidential.py @@ -176,7 +176,7 @@ def test_constructor_session_instantiation_with_additional_parameters(mocker, ex mock_oauth2_session = mocker.patch("fds.sdk.utils.authentication.confidential.OAuth2Session") - additional_parameters = {"proxy": "http://my:pass@test.test.test", "verify_ssl": False, "proxy_headers": {}} + additional_parameters = {"proxy": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, "verify_ssl": False, "proxy_headers": {}} ConfidentialClient(config=example_config, **additional_parameters) From 9645cb8de95f73c5ec67a34ab00b033e9d2e0c63 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:53:15 +0100 Subject: [PATCH 4/8] chore(config): fix verify_ssl docs, fix proxy settings --- tests/fds/sdk/utils/authentication/test_confidential.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/fds/sdk/utils/authentication/test_confidential.py b/tests/fds/sdk/utils/authentication/test_confidential.py index 8557661..680bf6d 100644 --- a/tests/fds/sdk/utils/authentication/test_confidential.py +++ b/tests/fds/sdk/utils/authentication/test_confidential.py @@ -176,7 +176,11 @@ def test_constructor_session_instantiation_with_additional_parameters(mocker, ex mock_oauth2_session = mocker.patch("fds.sdk.utils.authentication.confidential.OAuth2Session") - additional_parameters = {"proxy": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, "verify_ssl": False, "proxy_headers": {}} + additional_parameters = { + "proxy": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, + "verify_ssl": False, + "proxy_headers": {}, + } ConfidentialClient(config=example_config, **additional_parameters) From 144afa5e85b733d0eb19c940a4c6a6fa3098c791 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:21:34 +0100 Subject: [PATCH 5/8] chore(doc): add proxy and ssl documentation --- README.md | 43 ++++++++++++++++++- .../sdk/utils/authentication/confidential.py | 19 ++++---- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 8bbd410..ac4eb54 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ from fds.sdk.utils.authentication import ConfidentialClient import requests # The ConfidentialClient instance should be reused in production environments. -client = ConfidentialClient('/path/to/config.json') +client = ConfidentialClient( + config_path='/path/to/config.json' +) res = requests.get( 'https://api.factset.com/analytics/lookups/v3/currencies', headers={ @@ -47,6 +49,45 @@ res = requests.get( print(res.text) ``` +### Configure a Proxy + +You can pass proxy settings to the ConfidentialClient if necessary. +The `proxies` parameter takes a dictionary to tell the request library which proxies should be used. + +If necessary it is possible to set custom `proxy_headers` as dictionary. + +```python +from fds.sdk.utils.authentication import ConfidentialClient + +client = ConfidentialClient( + config_path='/path/to/config.json', + proxies={ + "http": "http://secret:password@localhost:5050", + "https": "http://secret:password@localhost:5050", + }, + proxy_headers={ + "Custom-Proxy-Header": "Custom-Proxy-Header-Value" + } +) +``` + +### Custom SSL Certificate + +If you have proxies or firewalls which are using custom TLS certificates, +you are able to pass a custom pem file so that the request library is able to verify +the validity of that certificate. The default value is `True` which validates certificates against +the python build in certificates. It is possible to disable the validation with `False`, +this is not recommended + +```python +from fds.sdk.utils.authentication import ConfidentialClient + +client = ConfidentialClient( + config_path='/path/to/config.json', + verify_ssl='/path/to/ca.pem' +) +``` + ## Modules Information about the various utility modules contained in this library can be found below. diff --git a/src/fds/sdk/utils/authentication/confidential.py b/src/fds/sdk/utils/authentication/confidential.py index 8943098..0b90497 100644 --- a/src/fds/sdk/utils/authentication/confidential.py +++ b/src/fds/sdk/utils/authentication/confidential.py @@ -37,9 +37,9 @@ def __init__( self, config_path: str = "", config: dict = None, - proxy: dict = None, - verify_ssl=True, + proxies: dict = None, proxy_headers: dict = None, + verify_ssl=True, ) -> None: """ Creates a new ConfidentialClient. @@ -80,7 +80,7 @@ def __init__( `NB`: Within the JWK parameters kty, alg, use, kid, n, e, d, p, q, dp, dq, qi are required for authorization. - `proxy` (dict) : Dictionary to tell the client which proxies should be used + `proxies` (dict) : Dictionary to tell the client which proxies should be used `Example Proxy Settings` { @@ -88,6 +88,9 @@ def __init__( "https”: "http://10.10.10.10:8000", } + `proxy_headers` (dict) : Sometimes it is necessary to add custom headers to http requests to be able to + use a proxy or firewall + `verify_ssl` (bool | string): Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to ``True``. When set to ``False``, requests will accept any TLS certificate presented by the server, @@ -95,8 +98,6 @@ def __init__( vulnerable to man-in-the-middle (MitM) attacks. Setting verify to ``False`` may be useful during local development or testing. - `proxy_headers` (dict) : Sometimes it is necessary to add custom headers to http requests to be able to - use a proxy or firewall Raises: AuthServerMetadataError: Raised if there's an issue retrieving the authorization server metadata @@ -124,12 +125,8 @@ def __init__( if config: self._config = config - if proxy: - self._proxies = {} - if "http" in proxy: - self._proxies["http"] = proxy["http"] - if "https" in proxy: - self._proxies["https"] = proxy["https"] + if proxies: + self._proxies = proxies else: self._proxies = None From 84714ea9827730289ba9d7f8ddb3907137e174a4 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:24:10 +0100 Subject: [PATCH 6/8] fix(tests): fix broken unit test --- tests/fds/sdk/utils/authentication/test_confidential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fds/sdk/utils/authentication/test_confidential.py b/tests/fds/sdk/utils/authentication/test_confidential.py index 680bf6d..038adf6 100644 --- a/tests/fds/sdk/utils/authentication/test_confidential.py +++ b/tests/fds/sdk/utils/authentication/test_confidential.py @@ -177,7 +177,7 @@ def test_constructor_session_instantiation_with_additional_parameters(mocker, ex mock_oauth2_session = mocker.patch("fds.sdk.utils.authentication.confidential.OAuth2Session") additional_parameters = { - "proxy": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, + "proxies": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, "verify_ssl": False, "proxy_headers": {}, } From 04f6257a394245a8c236cd4ea244b058dace2ea9 Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Tue, 21 Mar 2023 11:11:56 +0100 Subject: [PATCH 7/8] feat(config): use config parameters like in the SDKs --- README.md | 22 ++++---- .../sdk/utils/authentication/confidential.py | 55 ++++++++++--------- .../utils/authentication/test_confidential.py | 19 ++++++- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index ac4eb54..2c6d683 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ print(res.text) ### Configure a Proxy You can pass proxy settings to the ConfidentialClient if necessary. -The `proxies` parameter takes a dictionary to tell the request library which proxies should be used. +The `proxy` parameter takes a URL to tell the request library which proxy should be used. If necessary it is possible to set custom `proxy_headers` as dictionary. @@ -61,10 +61,7 @@ from fds.sdk.utils.authentication import ConfidentialClient client = ConfidentialClient( config_path='/path/to/config.json', - proxies={ - "http": "http://secret:password@localhost:5050", - "https": "http://secret:password@localhost:5050", - }, + proxy= "http://secret:password@localhost:5050", proxy_headers={ "Custom-Proxy-Header": "Custom-Proxy-Header-Value" } @@ -74,17 +71,22 @@ client = ConfidentialClient( ### Custom SSL Certificate If you have proxies or firewalls which are using custom TLS certificates, -you are able to pass a custom pem file so that the request library is able to verify -the validity of that certificate. The default value is `True` which validates certificates against -the python build in certificates. It is possible to disable the validation with `False`, -this is not recommended +you are able to pass a custom pem file (`ssl_ca_cert` parameter) so that the +request library is able to verify the validity of that certificate. If a +ca cert is passed it is validated whether `verify_ssl` is set to true. + +With `verify_ssl` it is possible to disable the verifications of certificates. +Disabling the verification is not recommended, but it might be useful during +local development or testing + ```python from fds.sdk.utils.authentication import ConfidentialClient client = ConfidentialClient( config_path='/path/to/config.json', - verify_ssl='/path/to/ca.pem' + verify_ssl=True, + ssl_ca_cert='/path/to/ca.pem' ) ``` diff --git a/src/fds/sdk/utils/authentication/confidential.py b/src/fds/sdk/utils/authentication/confidential.py index 0b90497..a38b7c5 100644 --- a/src/fds/sdk/utils/authentication/confidential.py +++ b/src/fds/sdk/utils/authentication/confidential.py @@ -35,11 +35,12 @@ class ConfidentialClient(OAuth2Client): def __init__( self, - config_path: str = "", + config_path: str = None, config: dict = None, - proxies: dict = None, + proxy: str = None, proxy_headers: dict = None, - verify_ssl=True, + verify_ssl: bool = True, + ssl_ca_cert: str = None, ) -> None: """ Creates a new ConfidentialClient. @@ -80,24 +81,20 @@ def __init__( `NB`: Within the JWK parameters kty, alg, use, kid, n, e, d, p, q, dp, dq, qi are required for authorization. - `proxies` (dict) : Dictionary to tell the client which proxies should be used - - `Example Proxy Settings` - { - "http": "http://10.10.10.10:8000", - "https”: "http://10.10.10.10:8000", - } + `proxy` (str) : Proxy URL `proxy_headers` (dict) : Sometimes it is necessary to add custom headers to http requests to be able to use a proxy or firewall - `verify_ssl` (bool | string): Either a boolean, in which case it controls whether we verify the server's - TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults - to ``True``. When set to ``False``, requests will accept any TLS certificate presented by the server, + `verify_ssl` (bool): Set this to ``False`` to skip verifying SSL certificate when calling API from + https server. When set to ``False``, requests will accept any TLS certificate presented by the server, and will ignore hostname mismatches and/or expired certificates, which will make your application vulnerable to man-in-the-middle (MitM) attacks. Setting verify to ``False`` may be useful during local development or testing. + `ssl_ca_cert` (str): Set this to customize the certificate file to verify the peer. If ``ssl_ca_cert`` is + set, the ca_cert will be verified whether ``verify_ssl`` is enabled + Raises: AuthServerMetadataError: Raised if there's an issue retrieving the authorization server metadata @@ -125,13 +122,14 @@ def __init__( if config: self._config = config - if proxies: - self._proxies = proxies + if proxy: + self._proxy = {"http": proxy, "https": proxy} else: - self._proxies = None + self._proxy = None self._verify_ssl = verify_ssl self._proxy_headers = proxy_headers + self._ssl_ca_cert = ssl_ca_cert try: self._oauth_session = OAuth2Session( @@ -164,16 +162,17 @@ def _init_auth_server_metadata(self) -> None: "Attempting metadata retrieval from well_known_uri: %s", self._config[CONSTS.CONFIG_WELL_KNOWN_URI] ) - with requests.Session() as session: - if self._proxies: - session.proxies = self._proxies + verify = self._verify_ssl - if self._proxy_headers: - session.headers.update(self._proxy_headers) + if self._ssl_ca_cert: + verify = self._ssl_ca_cert - session.verify = self._verify_ssl - - res = requests.get(url=self._config[CONSTS.CONFIG_WELL_KNOWN_URI]) + res = requests.get( + url=self._config[CONSTS.CONFIG_WELL_KNOWN_URI], + proxies=self._proxy, + verify=verify, + headers=self._proxy_headers, + ) log.debug("Request from well_known_uri completed with status: %s", res.status_code) log.debug("Response headers from well_known_uri were %s", res.headers) self._well_known_uri_metadata = res.json() @@ -263,13 +262,17 @@ def get_access_token(self) -> str: if self._proxy_headers: headers |= self._proxy_headers + verify = self._verify_ssl + if self._ssl_ca_cert: + verify = self._ssl_ca_cert + token = self._oauth_session.fetch_token( token_url=self._well_known_uri_metadata[CONSTS.META_TOKEN_ENDPOINT], client_id=self._config[CONSTS.CONFIG_CLIENT_ID], client_assertion_type="urn:ietf:params:oauth:client-assertion-type:jwt-bearer", client_assertion=self._get_client_assertion_jws(), - verify=self._verify_ssl, - proxies=self._proxies, + verify=verify, + proxies=self._proxy, headers=headers, ) self._cached_token = token diff --git a/tests/fds/sdk/utils/authentication/test_confidential.py b/tests/fds/sdk/utils/authentication/test_confidential.py index 038adf6..821cdea 100644 --- a/tests/fds/sdk/utils/authentication/test_confidential.py +++ b/tests/fds/sdk/utils/authentication/test_confidential.py @@ -177,15 +177,30 @@ def test_constructor_session_instantiation_with_additional_parameters(mocker, ex mock_oauth2_session = mocker.patch("fds.sdk.utils.authentication.confidential.OAuth2Session") additional_parameters = { - "proxies": {"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, + "proxy": "http://my:pass@test.test.test", "verify_ssl": False, "proxy_headers": {}, } + class AuthServerMetadataRes: + status_code = 200 + headers = {"header": "value"} + + def json(self): + return {"issuer": "test", "token_endpoint": "http://test.test"} + + get_mock = mocker.patch("requests.get", return_value=AuthServerMetadataRes()) + ConfidentialClient(config=example_config, **additional_parameters) mock_oauth_backend.assert_called_with(client_id=test_client_id) mock_oauth2_session.assert_called_with(client=backend_result) + get_mock.assert_called_with( + url="https://auth.factset.com/.well-known/openid-configuration", + proxies={"http": "http://my:pass@test.test.test", "https": "http://my:pass@test.test.test"}, + verify=False, + headers={}, + ) def test_constructor_custom_well_known_uri(mocker, example_config, caplog): @@ -210,7 +225,7 @@ def json(self): client = ConfidentialClient(config=example_config) - get_mock.assert_called_with(url=auth_test) + get_mock.assert_called_with(url=auth_test, proxies=None, verify=True, headers=None) assert client assert "Attempting metadata retrieval from well_known_uri: https://auth.test" in caplog.text From fc985a3b3f1c056eecf2243ced9ed245b80341cf Mon Sep 17 00:00:00 2001 From: Michael Matzka <14311597+mima0815@users.noreply.github.com> Date: Tue, 28 Mar 2023 11:29:37 +0200 Subject: [PATCH 8/8] docs: clarify ca cert verification --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c6d683..de969c9 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ client = ConfidentialClient( If you have proxies or firewalls which are using custom TLS certificates, you are able to pass a custom pem file (`ssl_ca_cert` parameter) so that the request library is able to verify the validity of that certificate. If a -ca cert is passed it is validated whether `verify_ssl` is set to true. +ca cert is passed it is validated regardless if `verify_ssl` is set to false. With `verify_ssl` it is possible to disable the verifications of certificates. Disabling the verification is not recommended, but it might be useful during