From c76613e09930adb3322b74a100012619bc0448ac Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:21:11 -0500 Subject: [PATCH 01/28] Not entirely sure what im doing. --- .gitignore | 3 +++ src/anaconda_auth/client.py | 53 ++++++++++++++++++++++++++++++++++++- src/anaconda_auth/config.py | 5 ++-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b8c73e82..6280c524 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,6 @@ src/*/_version.py /tokens.json .DS_Store + +# Pyright +pyrightconfig.json diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 8831ac57..ab514e8d 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -2,16 +2,18 @@ import warnings from functools import cached_property from hashlib import md5 -from typing import Any +from typing import Any, MutableMapping from typing import Dict from typing import Optional from typing import Union from typing import cast from urllib.parse import urljoin +from conda import CondaError import requests from requests import PreparedRequest from requests import Response +from requests.adapters import HTTPAdapter from requests.auth import AuthBase from anaconda_auth import __version__ as version @@ -87,6 +89,7 @@ def __init__( ssl_verify: Optional[bool] = None, extra_headers: Optional[Union[str, dict]] = None, hash_hostname: Optional[bool] = None, + proxy_servers: Optional[MutableMapping[str, str]] = None, ): super().__init__() @@ -104,9 +107,57 @@ def __init__( kwargs["extra_headers"] = extra_headers if hash_hostname is not None: kwargs["hash_hostname"] = hash_hostname + if proxy_servers is not None: + kwargs["proxy_servers"] = proxy_servers self.config = AnacondaAuthConfig(**kwargs) + # Begin sorting out SSL errors + + # Attempt to load base conda context + + try: + from conda.base.context import context + from conda.gateways.connection.adapters.http import HTTPAdapter + + # We need to decide which takes precendence, for now im assuming conda base config. + self.config.ssl_verify_policy = context.ssl_verify + self.config.proxy_servers = context.proxy_servers + self.config.ssl_verify = context.ssl_verify + + self.proxies = self.config.proxy_servers + + ssl_context = None + if self.config.ssl_verify == "truststore": + try: + import ssl + + import truststore + + ssl_context = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + except ImportError: + raise CondaError( + "The `ssl_verify: truststore` setting is only supported on Python 3.10 or later." + ) + self.verify = True + else: + self.verify = self.config.ssl_verify + + # We need an http adapter + + http_adapter = HTTPAdapter(ssl_context=ssl_context) + + self.mount("http://", http_adapter) + self.mount("https://", http_adapter) + + if context.client_ssl_cert_key: + self.cert = (context.client_ssl_cert, context.client_ssl_cert_key) + elif context.client_ssl_cert: + self.cert = context.client_ssl_cert + + except Exception: + pass + # base_url overrides domain self._base_uri = base_uri or f"https://{self.config.domain}" self.headers["User-Agent"] = user_agent or self._user_agent diff --git a/src/anaconda_auth/config.py b/src/anaconda_auth/config.py index 5ecf7191..16db8829 100644 --- a/src/anaconda_auth/config.py +++ b/src/anaconda_auth/config.py @@ -1,6 +1,6 @@ import warnings from functools import cached_property -from typing import Any +from typing import Any, MutableMapping from typing import Dict from typing import Literal from typing import Optional @@ -38,7 +38,7 @@ class AnacondaAuthConfig(AnacondaBaseSettings, plugin_name="auth"): domain: str = "anaconda.com" auth_domain_override: Optional[str] = None api_key: Optional[str] = None - ssl_verify: bool = True + ssl_verify: Optional[Union[bool, str]] = True extra_headers: Optional[Union[Dict[str, str], str]] = None client_id: str = "b4ad7f1d-c784-46b5-a9fe-106e50441f5a" redirect_uri: str = "http://127.0.0.1:8000/auth/oidc" @@ -48,6 +48,7 @@ class AnacondaAuthConfig(AnacondaBaseSettings, plugin_name="auth"): login_error_path: str = "/app/local-login-error" use_unified_repo_api_key: bool = False hash_hostname: bool = True + proxy_servers: Optional[MutableMapping[str, str]] = None def __init__(self, **kwargs: Any): if self.__class__ == AnacondaAuthConfig: From c9dcfb006638770093f86d6acaee8ef4bb76402e Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 22 Oct 2025 20:23:44 +0000 Subject: [PATCH 02/28] chore(pre-commit): linting --- src/anaconda_auth/client.py | 8 ++++---- src/anaconda_auth/config.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ab514e8d..34f8696c 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -2,18 +2,18 @@ import warnings from functools import cached_property from hashlib import md5 -from typing import Any, MutableMapping +from typing import Any from typing import Dict +from typing import MutableMapping from typing import Optional from typing import Union from typing import cast from urllib.parse import urljoin -from conda import CondaError import requests +from conda import CondaError from requests import PreparedRequest from requests import Response -from requests.adapters import HTTPAdapter from requests.auth import AuthBase from anaconda_auth import __version__ as version @@ -120,7 +120,7 @@ def __init__( from conda.base.context import context from conda.gateways.connection.adapters.http import HTTPAdapter - # We need to decide which takes precendence, for now im assuming conda base config. + # We need to decide which takes precedence, for now im assuming conda base config. self.config.ssl_verify_policy = context.ssl_verify self.config.proxy_servers = context.proxy_servers self.config.ssl_verify = context.ssl_verify diff --git a/src/anaconda_auth/config.py b/src/anaconda_auth/config.py index 16db8829..6c3e9791 100644 --- a/src/anaconda_auth/config.py +++ b/src/anaconda_auth/config.py @@ -1,8 +1,9 @@ import warnings from functools import cached_property -from typing import Any, MutableMapping +from typing import Any from typing import Dict from typing import Literal +from typing import MutableMapping from typing import Optional from typing import Union from urllib.parse import urljoin From 0122e395ef49661a40da2a9e63af196ff1d92fdc Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:28:00 -0500 Subject: [PATCH 03/28] conda import needs to be in try except --- src/anaconda_auth/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ab514e8d..10fea6b0 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -9,7 +9,6 @@ from typing import cast from urllib.parse import urljoin -from conda import CondaError import requests from requests import PreparedRequest from requests import Response @@ -119,6 +118,7 @@ def __init__( try: from conda.base.context import context from conda.gateways.connection.adapters.http import HTTPAdapter + from conda import CondaError # We need to decide which takes precendence, for now im assuming conda base config. self.config.ssl_verify_policy = context.ssl_verify From 0c5fad91e9b9476b9fd67894acc2547de9a049c6 Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 22 Oct 2025 20:29:38 +0000 Subject: [PATCH 04/28] chore(pre-commit): linting --- src/anaconda_auth/client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ca3b6bbd..021fa248 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -11,7 +11,6 @@ from urllib.parse import urljoin import requests -from conda import CondaError from requests import PreparedRequest from requests import Response from requests.auth import AuthBase @@ -117,9 +116,9 @@ def __init__( # Attempt to load base conda context try: + from conda import CondaError from conda.base.context import context from conda.gateways.connection.adapters.http import HTTPAdapter - from conda import CondaError # We need to decide which takes precedence, for now im assuming conda base config. self.config.ssl_verify_policy = context.ssl_verify From c08c7b908c0463ee054e5b394609f4473ed8a947 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:40:00 -0500 Subject: [PATCH 05/28] fixing a mypy issue --- src/anaconda_auth/actions.py | 5 ++++- src/anaconda_auth/client.py | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/anaconda_auth/actions.py b/src/anaconda_auth/actions.py index d57e3c32..4f5d2b2f 100644 --- a/src/anaconda_auth/actions.py +++ b/src/anaconda_auth/actions.py @@ -153,7 +153,10 @@ def _do_login(config: AnacondaAuthConfig, basic: bool) -> None: access_token = _login_with_username(config=config) else: access_token = _do_auth_flow(config=config) - api_key = get_api_key(access_token, config.ssl_verify) + + api_key = get_api_key( + access_token, config.ssl_verify if isinstance(config.ssl_verify, bool) else True + ) token_info = TokenInfo(api_key=api_key, domain=config.domain) token_info.save() diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ca3b6bbd..c70dcee3 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -11,7 +11,6 @@ from urllib.parse import urljoin import requests -from conda import CondaError from requests import PreparedRequest from requests import Response from requests.auth import AuthBase From 27f4f55ac7eff11464c17e949f1a952f061448be Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:40:49 -0500 Subject: [PATCH 06/28] removing uneeded var --- src/anaconda_auth/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 021fa248..7ea2678e 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -121,7 +121,6 @@ def __init__( from conda.gateways.connection.adapters.http import HTTPAdapter # We need to decide which takes precedence, for now im assuming conda base config. - self.config.ssl_verify_policy = context.ssl_verify self.config.proxy_servers = context.proxy_servers self.config.ssl_verify = context.ssl_verify From a50f64a1039d969812d96df1f23693f1a5699564 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:47:26 -0500 Subject: [PATCH 07/28] does adding this dep work? --- environment-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environment-dev.yml b/environment-dev.yml index afd5ae9e..d79e7189 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -4,6 +4,7 @@ channels: - conda-forge dependencies: - conda +- truststore - python=3.10 - anaconda-anon-usage - anaconda-cli-base >=0.4.0 From f5da00c35d6215066ada31681ad5fe6012aab291 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 22 Oct 2025 15:53:18 -0500 Subject: [PATCH 08/28] tsk tsk shouldnt do this --- environment-dev.yml | 1 - src/anaconda_auth/client.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/environment-dev.yml b/environment-dev.yml index d79e7189..afd5ae9e 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -4,7 +4,6 @@ channels: - conda-forge dependencies: - conda -- truststore - python=3.10 - anaconda-anon-usage - anaconda-cli-base >=0.4.0 diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 7ea2678e..9234020f 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -131,7 +131,7 @@ def __init__( try: import ssl - import truststore + import truststore # type: ignore ssl_context = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) except ImportError: From 14f10eda1679eee65671ffda0a9b69cc6a3ecdba Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Thu, 23 Oct 2025 12:22:12 -0500 Subject: [PATCH 09/28] cleaning up a bit --- src/anaconda_auth/client.py | 61 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 9234020f..101bb8c6 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -111,18 +111,45 @@ def __init__( self.config = AnacondaAuthConfig(**kwargs) - # Begin sorting out SSL errors + self.configure_ssl() - # Attempt to load base conda context + # base_url overrides domain + self._base_uri = base_uri or f"https://{self.config.domain}" + self.headers["User-Agent"] = user_agent or self._user_agent + self.headers["X-Client-Hostname"] = get_hostname(hash=self.config.hash_hostname) + self.api_version = api_version or self._api_version + if self.api_version: + self.headers["Api-Version"] = self.api_version + + if self.config.extra_headers is not None: + if isinstance(self.config.extra_headers, str): + try: + self.config.extra_headers = cast( + dict, json.loads(self.config.extra_headers) + ) + except json.decoder.JSONDecodeError: + raise ValueError( + f"{repr(self.config.extra_headers)} is not valid JSON." + ) + keys_to_add = self.config.extra_headers.keys() - self.headers.keys() + for k in keys_to_add: + self.headers[k] = self.config.extra_headers[k] + + self.auth = BearerAuth(domain=domain, api_key=self.config.api_key) + self.hooks["response"].append(login_required) + + def configure_ssl(self) -> None: try: from conda import CondaError from conda.base.context import context from conda.gateways.connection.adapters.http import HTTPAdapter # We need to decide which takes precedence, for now im assuming conda base config. - self.config.proxy_servers = context.proxy_servers - self.config.ssl_verify = context.ssl_verify + + if self.config.proxy_servers is None and context.proxy_servers: + self.config.proxy_servers = context.proxy_servers + self.config.ssl_verify = context.ssl_verify self.proxies = self.config.proxy_servers @@ -157,32 +184,6 @@ def __init__( except Exception: pass - # base_url overrides domain - self._base_uri = base_uri or f"https://{self.config.domain}" - self.headers["User-Agent"] = user_agent or self._user_agent - self.headers["X-Client-Hostname"] = get_hostname(hash=self.config.hash_hostname) - self.api_version = api_version or self._api_version - if self.api_version: - self.headers["Api-Version"] = self.api_version - - if self.config.extra_headers is not None: - if isinstance(self.config.extra_headers, str): - try: - self.config.extra_headers = cast( - dict, json.loads(self.config.extra_headers) - ) - except json.decoder.JSONDecodeError: - raise ValueError( - f"{repr(self.config.extra_headers)} is not valid JSON." - ) - - keys_to_add = self.config.extra_headers.keys() - self.headers.keys() - for k in keys_to_add: - self.headers[k] = self.config.extra_headers[k] - - self.auth = BearerAuth(domain=domain, api_key=self.config.api_key) - self.hooks["response"].append(login_required) - def urljoin(self, url: str) -> str: return urljoin(self._base_uri, url) From a703eba09f80df7ea377d53f5af3bfba8084e948 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Thu, 23 Oct 2025 12:30:50 -0500 Subject: [PATCH 10/28] fixing types --- src/anaconda_auth/client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 101bb8c6..9afe6238 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -151,7 +151,8 @@ def configure_ssl(self) -> None: self.config.proxy_servers = context.proxy_servers self.config.ssl_verify = context.ssl_verify - self.proxies = self.config.proxy_servers + if self.config.proxy_servers: + self.proxies = self.config.proxy_servers ssl_context = None if self.config.ssl_verify == "truststore": From 209ae9eaa296afd0bcdf6c0825f9257e21d13fac Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 11:29:48 -0500 Subject: [PATCH 11/28] oopsie --- src/anaconda_auth/actions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/anaconda_auth/actions.py b/src/anaconda_auth/actions.py index 38c2e9f3..6e9379d7 100644 --- a/src/anaconda_auth/actions.py +++ b/src/anaconda_auth/actions.py @@ -157,7 +157,9 @@ def _do_login(config: AnacondaAuthSite, basic: bool) -> None: access_token = _do_auth_flow(config=config) api_key = get_api_key( - access_token, config.ssl_verify if isinstance(config.ssl_verify, bool), config=config else True + access_token, + config.ssl_verify if isinstance(config.ssl_verify, bool) else True, + config=config, ) token_info = TokenInfo(api_key=api_key, domain=config.domain) From 904ab508e705837371cb0a3a4cb7ab3e06cd37c2 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 11:43:07 -0500 Subject: [PATCH 12/28] standardizing the ssl_verify type --- src/anaconda_auth/actions.py | 8 ++++++-- src/anaconda_auth/client.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/anaconda_auth/actions.py b/src/anaconda_auth/actions.py index 6e9379d7..65435a9d 100644 --- a/src/anaconda_auth/actions.py +++ b/src/anaconda_auth/actions.py @@ -158,7 +158,7 @@ def _do_login(config: AnacondaAuthSite, basic: bool) -> None: api_key = get_api_key( access_token, - config.ssl_verify if isinstance(config.ssl_verify, bool) else True, + config.ssl_verify, config=config, ) @@ -168,9 +168,13 @@ def _do_login(config: AnacondaAuthSite, basic: bool) -> None: def get_api_key( access_token: str, - ssl_verify: bool = True, + ssl_verify: Union[str, bool] = True, config: Optional[AnacondaAuthSite] = None, ) -> str: + + if isinstance(ssl_verify, str): + ssl_verify = True + config = config or AnacondaAuthSitesConfig.load_site() headers = {"Authorization": f"Bearer {access_token}"} diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 6ea05778..ebc729c7 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -88,7 +88,7 @@ def __init__( api_key: Optional[str] = None, user_agent: Optional[str] = None, api_version: Optional[str] = None, - ssl_verify: Optional[bool] = None, + ssl_verify: Optional[Union[bool, str]] = None, extra_headers: Optional[Union[str, dict]] = None, hash_hostname: Optional[bool] = None, proxy_servers: Optional[MutableMapping[str, str]] = None, From 86264e07747e955c63707b147b54e0001c807420 Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Tue, 28 Oct 2025 16:43:58 +0000 Subject: [PATCH 13/28] chore(pre-commit): linting --- src/anaconda_auth/actions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anaconda_auth/actions.py b/src/anaconda_auth/actions.py index 65435a9d..6fc8c7c3 100644 --- a/src/anaconda_auth/actions.py +++ b/src/anaconda_auth/actions.py @@ -171,7 +171,6 @@ def get_api_key( ssl_verify: Union[str, bool] = True, config: Optional[AnacondaAuthSite] = None, ) -> str: - if isinstance(ssl_verify, str): ssl_verify = True From bd0faeb49bd48006f09ad55cd5786d5f5897dda2 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 11:46:00 -0500 Subject: [PATCH 14/28] specifying exception --- src/anaconda_auth/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ebc729c7..394ed6da 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -194,7 +194,7 @@ def configure_ssl(self) -> None: elif context.client_ssl_cert: self.cert = context.client_ssl_cert - except Exception: + except ImportError: pass def urljoin(self, url: str) -> str: From dea838abb4f02abc2da596f747fa6eead949f776 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 12:54:59 -0500 Subject: [PATCH 15/28] fixing optional --- src/anaconda_auth/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anaconda_auth/config.py b/src/anaconda_auth/config.py index 2ff91ef4..26618c94 100644 --- a/src/anaconda_auth/config.py +++ b/src/anaconda_auth/config.py @@ -44,7 +44,7 @@ class AnacondaAuthSite(BaseModel): domain: str = "anaconda.com" auth_domain_override: Optional[str] = None api_key: Optional[str] = None - ssl_verify: Optional[Union[bool, str]] = True + ssl_verify: Union[bool, str] = True extra_headers: Optional[Union[Dict[str, str], str]] = None client_id: str = "b4ad7f1d-c784-46b5-a9fe-106e50441f5a" redirect_uri: str = "http://127.0.0.1:8000/auth/oidc" From df5294a9cad086f3e19c80ff004533dbb845beb0 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 14:47:59 -0500 Subject: [PATCH 16/28] splitting up retrieving and settin --- src/anaconda_auth/adapters.py | 46 ++++++++++++++++++++ src/anaconda_auth/client.py | 82 ++++++++++++++++++++++------------- 2 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 src/anaconda_auth/adapters.py diff --git a/src/anaconda_auth/adapters.py b/src/anaconda_auth/adapters.py new file mode 100644 index 00000000..08118017 --- /dev/null +++ b/src/anaconda_auth/adapters.py @@ -0,0 +1,46 @@ +from typing import TYPE_CHECKING, Any, Optional +from requests.adapters import HTTPAdapter as BaseHttpAdapter + + +if TYPE_CHECKING: + from ssl import SSLContext + + from urllib3 import PoolManager + + +class _SSLContextAdapterMixin: + """Mixin to add the ``ssl_context`` constructor argument to HTTP adapters. + + The additional argument is forwarded directly to the pool manager. This allows us + to dynamically decide what SSL store to use at runtime, which is used to implement + the optional ``truststore`` backend. + """ + + def __init__( + self, + *, + ssl_context: Optional["SSLContext"] = None, + **kwargs: Any, + ) -> None: + self._ssl_context = ssl_context + super().__init__(**kwargs) + + def init_poolmanager( + self, + connections: int, + maxsize: int, + block: bool = False, + **pool_kwargs: Any, + ) -> "PoolManager": + if self._ssl_context is not None: + pool_kwargs.setdefault("ssl_context", self._ssl_context) + return super().init_poolmanager( # type: ignore[misc] + connections=connections, + maxsize=maxsize, + block=block, + **pool_kwargs, + ) + + +class HTTPAdapter(_SSLContextAdapterMixin, BaseHttpAdapter): + pass diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 394ed6da..8872687d 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -10,12 +10,15 @@ from typing import cast from urllib.parse import urljoin +from anaconda_cli_base.exceptions import AnacondaConfigValidationError +from pydantic import BaseModel import requests from requests import PreparedRequest from requests import Response from requests.auth import AuthBase from anaconda_auth import __version__ as version +from anaconda_auth.adapters import HTTPAdapter from anaconda_auth.config import AnacondaAuthSite from anaconda_auth.config import AnacondaAuthSitesConfig from anaconda_auth.exceptions import TokenExpiredError @@ -52,6 +55,12 @@ def login_required(response: Response, *args: Any, **kwargs: Any) -> Response: return response +class CondaConfig(BaseModel): + proxy_servers: Optional[MutableMapping[str, str]] = None + ssl_verify: Optional[Union[bool, str]] = None + cert: Optional[str | tuple[str, str]] = None + + class BearerAuth(AuthBase): def __init__( self, domain: Optional[str] = None, api_key: Optional[str] = None @@ -121,9 +130,11 @@ def __init__( if proxy_servers is not None: kwargs["proxy_servers"] = proxy_servers + conda_config = self.retrieve_base_conda_ssl_config() + self.config = config.model_copy(update=kwargs) - self.configure_ssl() + self.configure_ssl(conda_config) # base_url overrides domain self._base_uri = base_uri or f"https://{self.config.domain}" @@ -151,52 +162,61 @@ def __init__( self.auth = BearerAuth(domain=self.config.domain, api_key=self.config.api_key) self.hooks["response"].append(login_required) - def configure_ssl(self) -> None: - try: - from conda import CondaError - from conda.base.context import context - from conda.gateways.connection.adapters.http import HTTPAdapter + def configure_ssl(self, cfg: CondaConfig): - # We need to decide which takes precedence, for now im assuming conda base config. + if cfg.proxy_servers and self.config.proxy_servers is None: + self.proxies = self.config.proxy_servers - if self.config.proxy_servers is None and context.proxy_servers: - self.config.proxy_servers = context.proxy_servers - self.config.ssl_verify = context.ssl_verify + ssl_context = None - if self.config.proxy_servers: - self.proxies = self.config.proxy_servers + if self.config.ssl_verify == "truststore" or cfg.ssl_verify == "trustore": + try: + import ssl - ssl_context = None - if self.config.ssl_verify == "truststore": - try: - import ssl + import truststore # type: ignore + + ssl_context = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + except ImportError: + raise AnacondaConfigValidationError( + "The `ssl_verify: truststore` setting is only supported on Python 3.10 or later." + ) + self.verify = True + else: + self.verify = self.config.ssl_verify - import truststore # type: ignore + # We need an http adapter - ssl_context = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - except ImportError: - raise CondaError( - "The `ssl_verify: truststore` setting is only supported on Python 3.10 or later." - ) - self.verify = True - else: - self.verify = self.config.ssl_verify + http_adapter = HTTPAdapter(ssl_context=ssl_context) + + self.mount("http://", http_adapter) + self.mount("https://", http_adapter) + self.cert = cfg.cert + + def retrieve_base_conda_ssl_config(self) -> CondaConfig: + conda_config = CondaConfig() + try: + from conda.base.context import context - # We need an http adapter + # from conda.gateways.connection.adapters.http import HTTPAdapter - http_adapter = HTTPAdapter(ssl_context=ssl_context) + # We need to decide which takes precedence, for now im assuming conda base config. - self.mount("http://", http_adapter) - self.mount("https://", http_adapter) + conda_config.proxy_servers = context.proxy_servers + conda_config.ssl_verify = context.ssl_verify if context.client_ssl_cert_key: - self.cert = (context.client_ssl_cert, context.client_ssl_cert_key) + conda_config.cert = ( + context.client_ssl_cert, + context.client_ssl_cert_key, + ) elif context.client_ssl_cert: - self.cert = context.client_ssl_cert + conda_config.cert = context.client_ssl_cert except ImportError: pass + return conda_config + def urljoin(self, url: str) -> str: return urljoin(self._base_uri, url) From 2c4b199b18241d1a277616d0a02a611fdf7858af Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Tue, 28 Oct 2025 19:49:02 +0000 Subject: [PATCH 17/28] chore(pre-commit): linting --- src/anaconda_auth/adapters.py | 6 ++++-- src/anaconda_auth/client.py | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/anaconda_auth/adapters.py b/src/anaconda_auth/adapters.py index 08118017..e3d84db9 100644 --- a/src/anaconda_auth/adapters.py +++ b/src/anaconda_auth/adapters.py @@ -1,6 +1,8 @@ -from typing import TYPE_CHECKING, Any, Optional -from requests.adapters import HTTPAdapter as BaseHttpAdapter +from typing import TYPE_CHECKING +from typing import Any +from typing import Optional +from requests.adapters import HTTPAdapter as BaseHttpAdapter if TYPE_CHECKING: from ssl import SSLContext diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 8872687d..50fdcdc6 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -10,9 +10,8 @@ from typing import cast from urllib.parse import urljoin -from anaconda_cli_base.exceptions import AnacondaConfigValidationError -from pydantic import BaseModel import requests +from pydantic import BaseModel from requests import PreparedRequest from requests import Response from requests.auth import AuthBase @@ -25,6 +24,7 @@ from anaconda_auth.exceptions import TokenNotFoundError from anaconda_auth.token import TokenInfo from anaconda_auth.utils import get_hostname +from anaconda_cli_base.exceptions import AnacondaConfigValidationError # VersionInfo was renamed and is deprecated in semver>=3 try: @@ -163,7 +163,6 @@ def __init__( self.hooks["response"].append(login_required) def configure_ssl(self, cfg: CondaConfig): - if cfg.proxy_servers and self.config.proxy_servers is None: self.proxies = self.config.proxy_servers From f5a079c1ca47b88787857f58778c483bef839134 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Tue, 28 Oct 2025 16:17:03 -0500 Subject: [PATCH 18/28] fixing tox mypy --- src/anaconda_auth/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 8872687d..ed0b623e 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -58,7 +58,7 @@ def login_required(response: Response, *args: Any, **kwargs: Any) -> Response: class CondaConfig(BaseModel): proxy_servers: Optional[MutableMapping[str, str]] = None ssl_verify: Optional[Union[bool, str]] = None - cert: Optional[str | tuple[str, str]] = None + cert: Optional[Union[str, tuple[str, str]]] = None class BearerAuth(AuthBase): @@ -162,10 +162,10 @@ def __init__( self.auth = BearerAuth(domain=self.config.domain, api_key=self.config.api_key) self.hooks["response"].append(login_required) - def configure_ssl(self, cfg: CondaConfig): + def configure_ssl(self, cfg: CondaConfig) -> None: if cfg.proxy_servers and self.config.proxy_servers is None: - self.proxies = self.config.proxy_servers + self.proxies = cfg.proxy_servers ssl_context = None From 40f963527b010a3af97ec1fdbe5633de9c7f5b8f Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Tue, 28 Oct 2025 21:19:23 +0000 Subject: [PATCH 19/28] chore(pre-commit): linting --- src/anaconda_auth/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 5749f4e5..7b6eed58 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -163,7 +163,6 @@ def __init__( self.hooks["response"].append(login_required) def configure_ssl(self, cfg: CondaConfig) -> None: - if cfg.proxy_servers and self.config.proxy_servers is None: self.proxies = cfg.proxy_servers From fee8435638a627bcb40871212fef9319b92dd201 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 29 Oct 2025 14:31:12 -0500 Subject: [PATCH 20/28] adding tests --- src/anaconda_auth/client.py | 6 ++ tests/test_client.py | 118 ++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index 7b6eed58..cd5b4691 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -163,8 +163,11 @@ def __init__( self.hooks["response"].append(login_required) def configure_ssl(self, cfg: CondaConfig) -> None: + print(f"self.config.proxy_servers: {self.config.proxy_servers}") if cfg.proxy_servers and self.config.proxy_servers is None: self.proxies = cfg.proxy_servers + elif self.config.proxy_servers: + self.proxies = self.config.proxy_servers ssl_context = None @@ -199,8 +202,10 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: # from conda.gateways.connection.adapters.http import HTTPAdapter # We need to decide which takes precedence, for now im assuming conda base config. + print("Here we are the import has succeeded") conda_config.proxy_servers = context.proxy_servers + print(f"Look at our proxy servers: {context.proxy_servers}") conda_config.ssl_verify = context.ssl_verify if context.client_ssl_cert_key: @@ -212,6 +217,7 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: conda_config.cert = context.client_ssl_cert except ImportError: + print("Here we are the import has failed") pass return conda_config diff --git a/tests/test_client.py b/tests/test_client.py index 7cf15e5a..8aa45059 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -18,6 +18,7 @@ from anaconda_auth.config import AnacondaAuthSite from anaconda_auth.exceptions import UnknownSiteName from anaconda_auth.token import TokenInfo +from tests.conda_token.test_condarc import make_temp_condarc from .conftest import MockedRequest @@ -445,6 +446,123 @@ def test_client_site_selection_by_name(config_toml: Path) -> None: _ = BaseClient(site="unknown") +@pytest.mark.usefixtures("disable_dot_env") +def test_client_condarc_base_defaults() -> None: + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert client.proxies["http"] == "condarc" + assert client.proxies["https"] == "condarc" + + +@pytest.mark.usefixtures("disable_dot_env") +def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: + + config_toml.write_text( + dedent( + """\ + [sites.local] + domain = "localhost" + auth_domain_override = "auth-local" + ssl_verify = false + api_key = "foo" + + + [plugin.auth.proxy_servers] + http = "toml" + https = "toml" + """ + ) + ) + + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert client.proxies["http"] == "toml" + assert client.proxies["https"] == "toml" + + +@pytest.mark.usefixtures("disable_dot_env") +def test_client_kwargs_supremecy(config_toml: Path) -> None: + + config_toml.write_text( + dedent( + """\ + [sites.local] + domain = "localhost" + auth_domain_override = "auth-local" + ssl_verify = false + api_key = "foo" + + + [plugin.auth.proxy_servers] + http = "toml" + https = "toml" + """ + ) + ) + + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) + assert client.config.ssl_verify == True + assert client.proxies["http"] == "kwargy" + assert client.proxies["https"] == "kwargy" + + @pytest.mark.usefixtures("disable_dot_env", "config_toml") def test_client_site_selection_with_config() -> None: # make sure the default hasn't changed From 01c6787a307390e891d195cf105b591ec984bef5 Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 29 Oct 2025 19:32:15 +0000 Subject: [PATCH 21/28] chore(pre-commit): linting --- tests/test_client.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index 8aa45059..502a9787 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -466,7 +466,6 @@ def test_client_condarc_base_defaults() -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert client.proxies["http"] == "condarc" @@ -475,7 +474,6 @@ def test_client_condarc_base_defaults() -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: - config_toml.write_text( dedent( """\ @@ -488,7 +486,7 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: [plugin.auth.proxy_servers] http = "toml" - https = "toml" + https = "toml" """ ) ) @@ -511,7 +509,6 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert client.proxies["http"] == "toml" @@ -520,7 +517,6 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_kwargs_supremecy(config_toml: Path) -> None: - config_toml.write_text( dedent( """\ @@ -533,7 +529,7 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: [plugin.auth.proxy_servers] http = "toml" - https = "toml" + https = "toml" """ ) ) @@ -556,7 +552,6 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) assert client.config.ssl_verify == True assert client.proxies["http"] == "kwargy" From 8890fa8183cc714852480354a2a8c0effe04fab6 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 29 Oct 2025 15:00:20 -0500 Subject: [PATCH 22/28] testing certs from condarc --- src/anaconda_auth/client.py | 10 ++----- tests/test_client.py | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index cd5b4691..dca0330d 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -163,7 +163,6 @@ def __init__( self.hooks["response"].append(login_required) def configure_ssl(self, cfg: CondaConfig) -> None: - print(f"self.config.proxy_servers: {self.config.proxy_servers}") if cfg.proxy_servers and self.config.proxy_servers is None: self.proxies = cfg.proxy_servers elif self.config.proxy_servers: @@ -199,15 +198,11 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: try: from conda.base.context import context - # from conda.gateways.connection.adapters.http import HTTPAdapter - - # We need to decide which takes precedence, for now im assuming conda base config. - print("Here we are the import has succeeded") - conda_config.proxy_servers = context.proxy_servers - print(f"Look at our proxy servers: {context.proxy_servers}") conda_config.ssl_verify = context.ssl_verify + print(f"cert keys: {context.client_ssl_cert}") + if context.client_ssl_cert_key: conda_config.cert = ( context.client_ssl_cert, @@ -217,7 +212,6 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: conda_config.cert = context.client_ssl_cert except ImportError: - print("Here we are the import has failed") pass return conda_config diff --git a/tests/test_client.py b/tests/test_client.py index 8aa45059..63a94455 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -12,6 +12,7 @@ from requests import Request from requests.exceptions import SSLError +from anaconda_auth.adapters import HTTPAdapter from anaconda_auth.client import BaseClient from anaconda_auth.client import client_factory from anaconda_auth.config import AnacondaAuthConfig @@ -563,6 +564,62 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: assert client.proxies["https"] == "kwargy" +@pytest.mark.usefixtures("disable_dot_env") +def test_client_ssl_context(config_toml: Path) -> None: + + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert isinstance(client.adapters["http://"], HTTPAdapter) + assert isinstance(client.adapters["https://"], HTTPAdapter) + + +@pytest.mark.usefixtures("disable_dot_env") +def test_client_condarc_certs(config_toml: Path) -> None: + + original_condarc = dedent( + """\ + ssl_verify: truststore + client_cert: client_cert.pem + client_cert_key: client_cert_key + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.cert == ("client_cert.pem", "client_cert_key") + + @pytest.mark.usefixtures("disable_dot_env", "config_toml") def test_client_site_selection_with_config() -> None: # make sure the default hasn't changed From 2adfdb67f518dce5b721f7702aa8939afd50198a Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 29 Oct 2025 20:01:17 +0000 Subject: [PATCH 23/28] chore(pre-commit): linting --- tests/test_client.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index 16597a48..9c8456cb 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -561,7 +561,6 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_ssl_context(config_toml: Path) -> None: - original_condarc = dedent( """\ ssl_verify: truststore @@ -580,7 +579,6 @@ def test_client_ssl_context(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert isinstance(client.adapters["http://"], HTTPAdapter) @@ -589,7 +587,6 @@ def test_client_ssl_context(config_toml: Path) -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_condarc_certs(config_toml: Path) -> None: - original_condarc = dedent( """\ ssl_verify: truststore @@ -610,7 +607,6 @@ def test_client_condarc_certs(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.cert == ("client_cert.pem", "client_cert_key") From 47c6e08ede5f8efaf42877149e88969b03148df4 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 29 Oct 2025 15:05:16 -0500 Subject: [PATCH 24/28] removing print statemetn --- src/anaconda_auth/client.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index dca0330d..ab54aff8 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -201,8 +201,6 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: conda_config.proxy_servers = context.proxy_servers conda_config.ssl_verify = context.ssl_verify - print(f"cert keys: {context.client_ssl_cert}") - if context.client_ssl_cert_key: conda_config.cert = ( context.client_ssl_cert, From 2f1bab884c3df5207fc544b3c8d46213cccf93e4 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 29 Oct 2025 15:16:10 -0500 Subject: [PATCH 25/28] bypassing tests in non-conda envs --- src/anaconda_auth/client.py | 1 + tests/test_client.py | 302 ++++++++++++++++++++---------------- 2 files changed, 169 insertions(+), 134 deletions(-) diff --git a/src/anaconda_auth/client.py b/src/anaconda_auth/client.py index ab54aff8..cade05b1 100644 --- a/src/anaconda_auth/client.py +++ b/src/anaconda_auth/client.py @@ -210,6 +210,7 @@ def retrieve_base_conda_ssl_config(self) -> CondaConfig: conda_config.cert = context.client_ssl_cert except ImportError: + print("Here we are the import has failed") pass return conda_config diff --git a/tests/test_client.py b/tests/test_client.py index 9c8456cb..b419b295 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -19,7 +19,6 @@ from anaconda_auth.config import AnacondaAuthSite from anaconda_auth.exceptions import UnknownSiteName from anaconda_auth.token import TokenInfo -from tests.conda_token.test_condarc import make_temp_condarc from .conftest import MockedRequest @@ -449,166 +448,201 @@ def test_client_site_selection_by_name(config_toml: Path) -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_condarc_base_defaults() -> None: - original_condarc = dedent( - """\ - ssl_verify: truststore - proxy_servers: - http: condarc - https: condarc - - default_channels: - - https://repo.anaconda.com/pkgs/main - channels: - - defaults - - conda-forge - - channel_alias: https://conda.anaconda.org/ - """ - ) - with make_temp_condarc(original_condarc) as rc: - client = BaseClient() - assert client.config.ssl_verify == True - assert client.proxies["http"] == "condarc" - assert client.proxies["https"] == "condarc" + try: + from tests.conda_token.test_condarc import make_temp_condarc -@pytest.mark.usefixtures("disable_dot_env") -def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: - config_toml.write_text( - dedent( + original_condarc = dedent( """\ - [sites.local] - domain = "localhost" - auth_domain_override = "auth-local" - ssl_verify = false - api_key = "foo" + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert client.proxies["http"] == "condarc" + assert client.proxies["https"] == "condarc" + except ImportError: + assert 1 - [plugin.auth.proxy_servers] - http = "toml" - https = "toml" - """ +@pytest.mark.usefixtures("disable_dot_env") +def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: + try: + from tests.conda_token.test_condarc import make_temp_condarc + + config_toml.write_text( + dedent( + """\ + [sites.local] + domain = "localhost" + auth_domain_override = "auth-local" + ssl_verify = false + api_key = "foo" + + + [plugin.auth.proxy_servers] + http = "toml" + https = "toml" + """ + ) ) - ) - original_condarc = dedent( - """\ - ssl_verify: truststore - proxy_servers: - http: condarc - https: condarc - - default_channels: - - https://repo.anaconda.com/pkgs/main - channels: - - defaults - - conda-forge - - channel_alias: https://conda.anaconda.org/ - """ - ) + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) - with make_temp_condarc(original_condarc) as rc: - client = BaseClient() - assert client.config.ssl_verify == True - assert client.proxies["http"] == "toml" - assert client.proxies["https"] == "toml" + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert client.proxies["http"] == "toml" + assert client.proxies["https"] == "toml" + except ImportError: + assert 1 @pytest.mark.usefixtures("disable_dot_env") def test_client_kwargs_supremecy(config_toml: Path) -> None: - config_toml.write_text( - dedent( - """\ - [sites.local] - domain = "localhost" - auth_domain_override = "auth-local" - ssl_verify = false - api_key = "foo" - + try: + from tests.conda_token.test_condarc import make_temp_condarc + + config_toml.write_text( + dedent( + """\ + [sites.local] + domain = "localhost" + auth_domain_override = "auth-local" + ssl_verify = false + api_key = "foo" + + + [plugin.auth.proxy_servers] + http = "toml" + https = "toml" + """ + ) + ) - [plugin.auth.proxy_servers] - http = "toml" - https = "toml" - """ + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ ) - ) - original_condarc = dedent( - """\ - ssl_verify: truststore - proxy_servers: - http: condarc - https: condarc - - default_channels: - - https://repo.anaconda.com/pkgs/main - channels: - - defaults - - conda-forge - - channel_alias: https://conda.anaconda.org/ - """ - ) + with make_temp_condarc(original_condarc) as rc: - with make_temp_condarc(original_condarc) as rc: - client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) - assert client.config.ssl_verify == True - assert client.proxies["http"] == "kwargy" - assert client.proxies["https"] == "kwargy" + client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) + assert client.config.ssl_verify == True + assert client.proxies["http"] == "kwargy" + assert client.proxies["https"] == "kwargy" + + except ImportError: + assert 1 @pytest.mark.usefixtures("disable_dot_env") def test_client_ssl_context(config_toml: Path) -> None: - original_condarc = dedent( - """\ - ssl_verify: truststore - proxy_servers: - http: condarc - https: condarc - - default_channels: - - https://repo.anaconda.com/pkgs/main - channels: - - defaults - - conda-forge - - channel_alias: https://conda.anaconda.org/ - """ - ) + try: + from tests.conda_token.test_condarc import make_temp_condarc + + original_condarc = dedent( + """\ + ssl_verify: truststore + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.config.ssl_verify == True + assert isinstance(client.adapters["http://"], HTTPAdapter) + assert isinstance(client.adapters["https://"], HTTPAdapter) - with make_temp_condarc(original_condarc) as rc: - client = BaseClient() - assert client.config.ssl_verify == True - assert isinstance(client.adapters["http://"], HTTPAdapter) - assert isinstance(client.adapters["https://"], HTTPAdapter) + except ImportError: + assert 1 @pytest.mark.usefixtures("disable_dot_env") def test_client_condarc_certs(config_toml: Path) -> None: - original_condarc = dedent( - """\ - ssl_verify: truststore - client_cert: client_cert.pem - client_cert_key: client_cert_key - proxy_servers: - http: condarc - https: condarc - - default_channels: - - https://repo.anaconda.com/pkgs/main - channels: - - defaults - - conda-forge - - channel_alias: https://conda.anaconda.org/ - """ - ) + try: + from tests.conda_token.test_condarc import make_temp_condarc + + original_condarc = dedent( + """\ + ssl_verify: truststore + client_cert: client_cert.pem + client_cert_key: client_cert_key + proxy_servers: + http: condarc + https: condarc + + default_channels: + - https://repo.anaconda.com/pkgs/main + channels: + - defaults + - conda-forge + + channel_alias: https://conda.anaconda.org/ + """ + ) + + with make_temp_condarc(original_condarc) as rc: + + client = BaseClient() + assert client.cert == ("client_cert.pem", "client_cert_key") - with make_temp_condarc(original_condarc) as rc: - client = BaseClient() - assert client.cert == ("client_cert.pem", "client_cert_key") + except ImportError: + assert 1 @pytest.mark.usefixtures("disable_dot_env", "config_toml") From 6c9466d13ecb270c9eb0c0142a78bfc07698762f Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 29 Oct 2025 20:17:15 +0000 Subject: [PATCH 26/28] chore(pre-commit): linting --- tests/test_client.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index b419b295..d68270e9 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -448,9 +448,7 @@ def test_client_site_selection_by_name(config_toml: Path) -> None: @pytest.mark.usefixtures("disable_dot_env") def test_client_condarc_base_defaults() -> None: - try: - from tests.conda_token.test_condarc import make_temp_condarc original_condarc = dedent( @@ -471,7 +469,6 @@ def test_client_condarc_base_defaults() -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert client.proxies["http"] == "condarc" @@ -497,7 +494,7 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: [plugin.auth.proxy_servers] http = "toml" - https = "toml" + https = "toml" """ ) ) @@ -520,7 +517,6 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert client.proxies["http"] == "toml" @@ -546,7 +542,7 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: [plugin.auth.proxy_servers] http = "toml" - https = "toml" + https = "toml" """ ) ) @@ -569,7 +565,6 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) assert client.config.ssl_verify == True assert client.proxies["http"] == "kwargy" @@ -602,7 +597,6 @@ def test_client_ssl_context(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.config.ssl_verify == True assert isinstance(client.adapters["http://"], HTTPAdapter) @@ -637,7 +631,6 @@ def test_client_condarc_certs(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc) as rc: - client = BaseClient() assert client.cert == ("client_cert.pem", "client_cert_key") From 010ec5545d577c919b7b0f00e273a79cd568ae60 Mon Sep 17 00:00:00 2001 From: Zeke Fralish Date: Wed, 29 Oct 2025 15:21:27 -0500 Subject: [PATCH 27/28] pre commit fixes --- tests/test_client.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index b419b295..2a9e678c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -470,10 +470,10 @@ def test_client_condarc_base_defaults() -> None: """ ) - with make_temp_condarc(original_condarc) as rc: + with make_temp_condarc(original_condarc): client = BaseClient() - assert client.config.ssl_verify == True + assert client.config.ssl_verify assert client.proxies["http"] == "condarc" assert client.proxies["https"] == "condarc" except ImportError: @@ -519,10 +519,10 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: """ ) - with make_temp_condarc(original_condarc) as rc: + with make_temp_condarc(original_condarc): client = BaseClient() - assert client.config.ssl_verify == True + assert client.config.ssl_verify assert client.proxies["http"] == "toml" assert client.proxies["https"] == "toml" except ImportError: @@ -568,10 +568,10 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: """ ) - with make_temp_condarc(original_condarc) as rc: + with make_temp_condarc(original_condarc): client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) - assert client.config.ssl_verify == True + assert client.config.ssl_verify assert client.proxies["http"] == "kwargy" assert client.proxies["https"] == "kwargy" @@ -601,10 +601,10 @@ def test_client_ssl_context(config_toml: Path) -> None: """ ) - with make_temp_condarc(original_condarc) as rc: + with make_temp_condarc(original_condarc): client = BaseClient() - assert client.config.ssl_verify == True + assert client.config.ssl_verify assert isinstance(client.adapters["http://"], HTTPAdapter) assert isinstance(client.adapters["https://"], HTTPAdapter) @@ -636,7 +636,7 @@ def test_client_condarc_certs(config_toml: Path) -> None: """ ) - with make_temp_condarc(original_condarc) as rc: + with make_temp_condarc(original_condarc): client = BaseClient() assert client.cert == ("client_cert.pem", "client_cert_key") From 5717b5f4e573b46d11d88b73ba819df565863fa1 Mon Sep 17 00:00:00 2001 From: Anaconda Bot Date: Wed, 29 Oct 2025 20:22:53 +0000 Subject: [PATCH 28/28] chore(pre-commit): linting --- tests/test_client.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index ccf2c1cf..5beeb354 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -469,7 +469,6 @@ def test_client_condarc_base_defaults() -> None: ) with make_temp_condarc(original_condarc): - client = BaseClient() assert client.config.ssl_verify assert client.proxies["http"] == "condarc" @@ -518,7 +517,6 @@ def test_client_condarc_override_with_anaconda_toml(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc): - client = BaseClient() assert client.config.ssl_verify assert client.proxies["http"] == "toml" @@ -567,7 +565,6 @@ def test_client_kwargs_supremecy(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc): - client = BaseClient(proxy_servers={"http": "kwargy", "https": "kwargy"}) assert client.config.ssl_verify assert client.proxies["http"] == "kwargy" @@ -600,7 +597,6 @@ def test_client_ssl_context(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc): - client = BaseClient() assert client.config.ssl_verify assert isinstance(client.adapters["http://"], HTTPAdapter) @@ -635,7 +631,6 @@ def test_client_condarc_certs(config_toml: Path) -> None: ) with make_temp_condarc(original_condarc): - client = BaseClient() assert client.cert == ("client_cert.pem", "client_cert_key")