diff options
author | Bjoern Kahl <mls@bjoern-kahl.de> | 2022-01-01 21:35:55 +0100 |
---|---|---|
committer | Tobias Brox <tobias@redpill-linpro.com> | 2022-01-25 20:47:26 +0100 |
commit | a809c3420f30ceb8e7d8314bbed4425a9f0eda86 (patch) | |
tree | 5b43ffc3b4798027ae90d2b2e263863c812f8ae1 | |
parent | afde24719955ae1d1ac79c41ef4bb01007402282 (diff) | |
download | python-caldav-v0.8-stable.zip |
Fix HTTP Auth failure with old (pre UTF-8) serversv0.8-stable
Some servers, like really old SabreDAV based servers, seem to choke on
password if we pass a bytes sequence instead of a string to the
"requests" libraries HTTPDigestAuth object.
This Fix retries authentication in case of authentication failure with
the same password as plain string (which, in Python3 is anyway UTF-8).
-rw-r--r-- | caldav/davclient.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/caldav/davclient.py b/caldav/davclient.py index e5f9e51..894cd1a 100644 --- a/caldav/davclient.py +++ b/caldav/davclient.py @@ -518,6 +518,7 @@ class DAVClient: (combined_headers, proxies) = self._pre_request(url, body, headers) + auth_type = None if not self.auth: ## Try a test request w/o auth resp = self.session.request( @@ -557,6 +558,22 @@ class DAVClient: verify=self.ssl_verify_cert, cert=self.ssl_cert) if resp.status_code > 399: + ## Some (ancient) servers don't like UTF-8 binary auth with Digest authentication. + ## An example are old SabreDAV based servers. Not sure about UTF-8 and Basic Auth, + ## but likely the same. so retry if password is a bytes sequence and not a string + ## (see commit 13a4714, which introduced this regression) + if auth_type is not None and hasattr(self.password, 'decode'): + if auth_type == 'Basic': + self.auth = requests.auth.HTTPBasicAuth(self.username, self.password.decode()) + elif auth_type == 'Digest': + self.auth = requests.auth.HTTPDigestAuth(self.username, self.password.decode()) + resp = self.session.request( + method, url, data=to_wire(body), + headers=combined_headers, proxies=proxies, auth=self.auth, + verify=self.ssl_verify_cert, cert=self.ssl_cert) + + if resp.status_code > 399: + ## We tried all we can, probably the credentials are _really_ wrong... raise error.AuthorizationError(url=url, reason=resp.reason) def request(self, url, method="GET", body="", headers={}): |