From b37267ee0e0c1daaea9a7481bcc00cce32101b6a Mon Sep 17 00:00:00 2001 From: disqualifier Date: Fri, 16 Oct 2026 04:19:41 -0400 Subject: [PATCH] refactor: drop the unreachable XOAUTH2 .authenticate fallback T3-21: aioimaplib's IMAP4 always has .xoauth2 and never .authenticate, so the fallback branch and its _sasl_xoauth2 helper could not run. call mail.xoauth2 directly. Signed-off-by: disqualifier --- src/aiomail/auth.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/aiomail/auth.py b/src/aiomail/auth.py index a3937dd..30e8810 100644 --- a/src/aiomail/auth.py +++ b/src/aiomail/auth.py @@ -1,5 +1,4 @@ """authentication mechanisms for the IMAP client: `PasswordAuth` (LOGIN), `OAuth2Auth` (XOAUTH2).""" -import base64 import logging from typing import Awaitable, Callable, Optional, Protocol, Union, runtime_checkable @@ -36,12 +35,6 @@ def _as_str(token) -> str: return token.decode() if isinstance(token, bytes) else token -def _sasl_xoauth2(user: str, token: str) -> str: - """build the base64 XOAUTH2 SASL initial-response string""" - raw = f"user={user}\x01auth=Bearer {token}\x01\x01".encode() - return base64.b64encode(raw).decode() - - class OAuth2Auth: """XOAUTH2 auth: a static `token`, or a `token_provider` (sync/async callable) fetched fresh at connect time""" @@ -71,18 +64,6 @@ class OAuth2Auth: token = await self._resolve_token() # mail.xoauth2(user, token) f-string-interpolates token, so it MUST be str - # bytes would interpolate the b'...' repr and corrupt the Bearer value. - xoauth2 = getattr(mail, "xoauth2", None) - if xoauth2 is not None: - result, data = await xoauth2(self.user, token) - elif hasattr(mail, "authenticate"): - # escape hatch for a non-aioimaplib client (aioimaplib's IMAP4 always - # has .xoauth2, never .authenticate); untested against any real driver - result, data = await mail.authenticate( - "XOAUTH2", lambda _: _sasl_xoauth2(self.user, token) - ) - else: - raise RuntimeError( - "IMAP client exposes no XOAUTH2 entrypoint (no .xoauth2 or .authenticate)" - ) + result, data = await mail.xoauth2(self.user, token) if result != "OK": raise RuntimeError(f"xoauth2 auth failed: {result} {data}")