henrysher / duplicity

mirror of duplicity: https://code.launchpad.net/duplicity
81 stars 13 forks source link

WebDAV backend broken in Python 3 due to change in base64 encodestring #23

Open andrewdsmith opened 4 years ago

andrewdsmith commented 4 years ago

I get the following failure and backtrace when running duplicity with the WebDAV backend in Ubuntu 19.10, where Python 3 is the default version. It worked fine in 19.04, where I think Python 2 was the default.

  File "/usr/lib/python3/dist-packages/duplicity/backend.py", line 371, in inner_retry
    return fn(self, *args)
  File "/usr/lib/python3/dist-packages/duplicity/backend.py", line 580, in list
    return [tobytes(x) for x in self.backend._list()]
  File "/usr/lib/python3/dist-packages/duplicity/backends/webdavbackend.py", line 343, in _list
    raise e
  File "/usr/lib/python3/dist-packages/duplicity/backends/webdavbackend.py", line 317, in _list
    response = self.request(u"PROPFIND", self.directory, self.listbody)
  File "/usr/lib/python3/dist-packages/duplicity/backends/webdavbackend.py", line 240, in request
    self.headers[u'Authorization'] = self.get_authorization(response, quoted_path)
  File "/usr/lib/python3/dist-packages/duplicity/backends/webdavbackend.py", line 271, in get_authorization
    return self.get_basic_authorization()
  File "/usr/lib/python3/dist-packages/duplicity/backends/webdavbackend.py", line 291, in get_basic_authorization
    return u'Basic %s' % base64.encodestring(auth_string).strip()
  File "/usr/lib/python3.7/base64.py", line 540, in encodestring
    return encodebytes(s)
  File "/usr/lib/python3.7/base64.py", line 527, in encodebytes
    _input_type_check(s)
  File "/usr/lib/python3.7/base64.py", line 513, in _input_type_check
    raise TypeError(msg) from err
 TypeError: expected bytes-like object, not str

It looks like the problem is due to the encodestring method changing between Python 2 and 3, where in the latter it has become a (deprecated) alias for encodebytes.

    def get_basic_authorization(self):
        """
        Returns the basic auth header
        """
        auth_string = '%s:%s' % (self.username, self.password)
        return 'Basic %s' % base64.encodestring(auth_string).strip()

Not knowing Python, I don't know what's a good way to fix this that will be compatible with both Python 2 and 3. After a quick search, I tried hacking in a b'...' prefix on the strings but that blows things up on the % method. I don't mind sinking a bit more time in to get this fixed if I can be pointed in the right direction on Python 2 vs 3 problem.

tirkarthi commented 4 years ago

Note: base64.encodestring was deprecated and removed in python 3.9 in favor of base64.decodebytes.