-
Notifications
You must be signed in to change notification settings - Fork 6
Merge 'stable' into 'develop' with resolved conflicts. #594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3eadf55
be0b0cf
edc7839
2198a06
78cf233
496376e
7b4adf7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| import inspect | ||
| import ssl | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
| from pytest_httpx import HTTPXMock | ||
|
|
||
| from infrahub_sdk import InfrahubClient, InfrahubClientSync | ||
| from infrahub_sdk import Config, InfrahubClient, InfrahubClientSync | ||
| from infrahub_sdk.exceptions import NodeNotFoundError | ||
| from infrahub_sdk.node import InfrahubNode, InfrahubNodeSync | ||
| from tests.unit.sdk.conftest import BothClients | ||
|
|
@@ -28,6 +30,88 @@ | |
|
|
||
| client_types = ["standard", "sync"] | ||
|
|
||
| CURRENT_DIRECTORY = Path(__file__).parent | ||
|
|
||
|
|
||
| async def test_verify_config_caches_default_ssl_context(monkeypatch) -> None: | ||
| contexts: list[tuple[str | None, object]] = [] | ||
|
|
||
| def fake_create_default_context(*args: object, **kwargs: object) -> object: | ||
| context = object() | ||
| contexts.append((kwargs.get("cafile"), context)) | ||
| return context | ||
|
|
||
| monkeypatch.setattr("ssl.create_default_context", fake_create_default_context) | ||
|
|
||
| client = InfrahubClient(config=Config(address="http://mock")) | ||
|
|
||
| first = client.config.tls_context | ||
| second = client.config.tls_context | ||
|
|
||
| assert first is second | ||
| assert contexts == [(None, first)] | ||
|
|
||
|
|
||
| async def test_verify_config_caches_tls_ca_file_context(monkeypatch) -> None: | ||
| contexts: list[tuple[str | None, object]] = [] | ||
|
|
||
| def fake_create_default_context(*args: object, **kwargs: object) -> object: | ||
| context = object() | ||
| contexts.append((kwargs.get("cafile"), context)) | ||
| return context | ||
|
|
||
| monkeypatch.setattr("ssl.create_default_context", fake_create_default_context) | ||
|
|
||
| client = InfrahubClient( | ||
| config=Config(address="http://mock", tls_ca_file=str(CURRENT_DIRECTORY / "test_data/path-1.pem")) | ||
| ) | ||
|
|
||
| first = client.config.tls_context | ||
| second = client.config.tls_context | ||
|
|
||
| assert first is second | ||
| assert contexts == [(str(CURRENT_DIRECTORY / "test_data/path-1.pem"), first)] | ||
|
|
||
| client.config.tls_ca_file = str(CURRENT_DIRECTORY / "test_data/path-2.pem") | ||
| third = client.config.tls_context | ||
|
|
||
| assert third is first | ||
| assert contexts == [ | ||
| (str(CURRENT_DIRECTORY / "test_data/path-1.pem"), first), | ||
| ] | ||
|
Comment on lines
+75
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rebuild SSL context when configuration changes. This test codifies that mutating 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| async def test_verify_config_respects_tls_insecure(monkeypatch) -> None: | ||
| def fake_create_default_context(*args: object, **kwargs: object) -> object: | ||
| raise AssertionError("create_default_context should not be called when TLS is insecure") | ||
|
|
||
| monkeypatch.setattr("ssl.create_default_context", fake_create_default_context) | ||
|
|
||
| client = InfrahubClient(config=Config(address="http://mock", tls_insecure=True)) | ||
|
|
||
| verify_value = client.config.tls_context | ||
|
|
||
| assert verify_value.check_hostname is False | ||
| assert verify_value.verify_mode == ssl.CERT_NONE | ||
|
|
||
|
|
||
| async def test_verify_config_uses_custom_tls_context(monkeypatch) -> None: | ||
| def fake_create_default_context(*args: object, **kwargs: object) -> object: | ||
| raise AssertionError("create_default_context should not be called when custom context is provided") | ||
|
|
||
| monkeypatch.setattr("ssl.create_default_context", fake_create_default_context) | ||
|
|
||
| config = Config(address="http://mock") | ||
| custom_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) | ||
| config.set_ssl_context(custom_context) | ||
|
|
||
| client = InfrahubClient(config=config) | ||
|
|
||
| clone_client = client.clone() | ||
|
|
||
| assert client.config.tls_context is custom_context | ||
| assert clone_client.config.tls_context is custom_context | ||
|
|
||
|
|
||
| async def test_method_sanity() -> None: | ||
| """Validate that there is at least one public method and that both clients look the same.""" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| -----BEGIN CERTIFICATE----- | ||
| MIIBQDCB86ADAgECAhR6y429KiST51bZy+t330M7dN5SbzAFBgMrZXAwFjEUMBIG | ||
| A1UEAwwLZXhhbXBsZS5jb20wHhcNMjUxMDE1MTE0MjUwWhcNMzUxMDEzMTE0MjUw | ||
| WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAqMAUGAytlcAMhAPIl8y8AXSWF33vX | ||
| JT2YwhMJzarOuSdPif01Gxr3Rr6Lo1MwUTAdBgNVHQ4EFgQU4heN1ZhyXpOujgcJ | ||
| WZ4LQk2m7RAwHwYDVR0jBBgwFoAU4heN1ZhyXpOujgcJWZ4LQk2m7RAwDwYDVR0T | ||
| AQH/BAUwAwEB/zAFBgMrZXADQQBoEf+8R+KWwGdaoeqinWOvrqbVZatMis0eUMvA | ||
| o+vABSPU7LIYGxLT6fpUwFSTvempzNqGZMVJ9UvVH+hYDU4D | ||
| -----END CERTIFICATE----- |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| -----BEGIN CERTIFICATE----- | ||
| MIIBQDCB86ADAgECAhQTRmRZxUSA5L7VfYJb3/t+dRK0ETAFBgMrZXAwFjEUMBIG | ||
| A1UEAwwLZXhhbXBsZS5jb20wHhcNMjUxMDE1MTE0MzM0WhcNMzUxMDEzMTE0MzM0 | ||
| WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAqMAUGAytlcAMhAK1O3ZhE5qzfT7Qx | ||
| +0My3ToDVDi5wwpllkKn0X50zXFao1MwUTAdBgNVHQ4EFgQUH+qBMU+h4t1vdLbO | ||
| jMSSgXdURewwHwYDVR0jBBgwFoAUH+qBMU+h4t1vdLbOjMSSgXdURewwDwYDVR0T | ||
| AQH/BAUwAwEB/zAFBgMrZXADQQB3Z03f3gQcktxk4h/v8pVi5soz8viPx17TSPXf | ||
| 1WYG+Jlk4C5GQ+tyjZgZUE9LL2BFRYBv28V/NPT/0TjPGtcC | ||
| -----END CERTIFICATE----- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against stale/insecure TLS contexts.
Once
_ssl_contextis populated, this property returns it forever. Because we eagerly load the context inBaseClient.__init__, changingconfig.tls_insecureorconfig.tls_ca_filelater never takes effect—e.g., starting in insecure mode leavesverify_mode == CERT_NONEeven after you fliptls_insecure=False. That’s an immediate security regression. Please invalidate the cache whenever the relevant settings change (or track the settings used to build the cache). One approach:Any similar invalidation is fine so long as updating the config rebuilds the context.
🤖 Prompt for AI Agents