summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Kahl <mls@bjoern-kahl.de>2022-01-24 23:10:01 +0100
committerTobias Brox <tobias@redpill-linpro.com>2022-01-26 22:15:21 +0100
commitdd260173be7aba31d02891bb2d0e880893cd589e (patch)
tree58bcfd131c274835198f86f4461be56d0e7f8d1a
parentbafa8103adee79ec4540b259be8672cbb9915584 (diff)
downloadpython-caldav-dd260173be7aba31d02891bb2d0e880893cd589e.zip
Fix HTTP Auth failure with old (pre UTF-8) servers
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). Refreshed to address review comments.
-rw-r--r--caldav/davclient.py22
1 files changed, 22 insertions, 0 deletions
diff --git a/caldav/davclient.py b/caldav/davclient.py
index 14ac40d..98dadcb 100644
--- a/caldav/davclient.py
+++ b/caldav/davclient.py
@@ -545,6 +545,28 @@ class DAVClient:
self.auth = requests.auth.HTTPDigestAuth(self.username, self.password)
else:
raise NotImplementedError("Auth method %s not supported yet" % auth_type)
+ return self.request(url, method, body, headers)
+
+ elif (r.status_code == 401 and
+ 'WWW-Authenticate' in r.headers and
+ self.password and
+ self.username and
+ self.auth):
+
+ ## 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)
+
+ auth_type = r.headers['WWW-Authenticate']
+ auth_type = auth_type[0:auth_type.find(" ")]
+
+ if 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())
+
self.username = None
self.password = None
return self.request(url, method, body, headers)