calc.validatePatch(
`--- a/home/kreijstal/.local/share/pipx/venvs/plann/lib/python3.13/site-packages/caldav/davclient.py.bak
+++ b/home/kreijstal/.local/share/pipx/venvs/plann/lib/python3.13/site-packages/caldav/davclient.py
@@ -695,10 +695,17 @@
if not r.status_code == 401:
raise
+ # davclient.py already has a log object defined at the top:
+ # from .objects import log
+ # So we can use log.debug, log.error etc.
+
## Returned headers
r_headers = CaseInsensitiveDict(r.headers)
- if (
+ elif (
r.status_code == 401
- and "WWW-Authenticate" in r_headers
and not self.auth
and self.username
+ and self.password is not None # We have a password (even if it's an empty string)
):
- auth_types = self.extract_auth_types(r_headers["WWW-Authenticate"])
+ log.debug(f"DAVClient: Received 401. Attempting to set up authentication.")
+ auth_setup_done = False
+ if "WWW-Authenticate" in r_headers:
+ auth_types = self.extract_auth_types(r_headers["WWW-Authenticate"])
+ log.debug(f"DAVClient: WWW-Authenticate header found. Types: {auth_types}")
+ if "digest" in auth_types: # self.password and self.username already checked
+ log.debug("DAVClient: Setting up Digest Auth based on WWW-Authenticate.")
+ self.auth = niquests.auth.HTTPDigestAuth(self.username, self.password)
+ auth_setup_done = True
+ elif "basic" in auth_types: # self.password and self.username already checked
+ log.debug("DAVClient: Setting up Basic Auth based on WWW-Authenticate.")
+ self.auth = niquests.auth.HTTPBasicAuth(self.username, self.password)
+ auth_setup_done = True
+ elif "bearer" in auth_types: # Assuming self.password is the token for bearer
+ log.debug("DAVClient: Setting up Bearer Auth based on WWW-Authenticate.")
+ self.auth = HTTPBearerAuth(self.password)
+ auth_setup_done = True
+
+ if not auth_setup_done:
+ # If WWW-Authenticate was missing, or didn't list a usable type,
+ # but we have username/password, default to trying Basic Auth.
+ # This is for servers like Radicale with auth=none which might not
+ # send a WWW-Authenticate header or send one that's not 'basic'.
+ log.debug("DAVClient: No suitable auth type from WWW-Authenticate or header missing. Defaulting to Basic Auth attempt.")
+ self.auth = niquests.auth.HTTPBasicAuth(self.username, self.password)
+ # auth_setup_done = True # Not strictly needed here as we set self.auth
- if self.password and self.username and "digest" in auth_types:
- self.auth = niquests.auth.HTTPDigestAuth(self.username, self.password)
- elif self.password and self.username and "basic" in auth_types:
- self.auth = niquests.auth.HTTPBasicAuth(self.username, self.password)
- elif self.password and "bearer" in auth_types:
- self.auth = HTTPBearerAuth(self.password)
- else:
- raise NotImplementedError(
- "The server does not provide any of the currently "
- "supported authentication methods: basic, digest, bearer"
- )
-
+ log.debug(f"DAVClient: Retrying request with auth object: {self.auth}")
return self.request(url, method, body, headers)
elif (
@@ -736,11 +743,26 @@
if (
response.status == niquests.codes.forbidden
or response.status == niquests.codes.unauthorized
):
+ # If self.auth is still None after trying to handle 401 above, then we truly failed to auth
+ if response.status == niquests.codes.unauthorized and not self.auth:
+ # This re-raises a NotImplementedError if we couldn't set an auth type
+ # after the 401 response.
+ if "WWW-Authenticate" in r_headers:
+ auth_types_str = str(self.extract_auth_types(r_headers["WWW-Authenticate"]))
+ else:
+ auth_types_str = "Header not present"
+
+ raise NotImplementedError(
+ f"The server (at {str(url_obj)}) responded with 401, but after attempting to handle, "
+ f"no suitable authentication method could be established. "
+ f"Provided username: '{self.username}'. WWW-Authenticate types: {auth_types_str}. "
+ f"Supported by client: basic, digest, bearer."
+ )
+
try:
reason = response.reason
except AttributeError:`,
true
)