Hello community, here is the log from the commit of package python-Paste for openSUSE:Factory checked in at 2020-03-29 14:25:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Paste (Old) and /work/SRC/openSUSE:Factory/.python-Paste.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Paste" Sun Mar 29 14:25:03 2020 rev:27 rq:788612 version:3.4.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Paste/python-Paste.changes 2020-01-16 18:16:01.120797574 +0100 +++ /work/SRC/openSUSE:Factory/.python-Paste.new.3160/python-Paste.changes 2020-03-29 14:25:05.246084141 +0200 @@ -1,0 +2,8 @@ +Thu Mar 26 16:10:35 UTC 2020 - Marketa Calabkova <mcalabk...@suse.com> + +- update to 3.4.0 + * Python 3 updates for use of StringIO and auth_tkt.py. + * Use six.BytesIO when reading wsgi.input. + * Allow binding IPv6 address when starting a server. + +------------------------------------------------------------------- Old: ---- Paste-3.2.6.tar.gz New: ---- Paste-3.4.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Paste.spec ++++++ --- /var/tmp/diff_new_pack.6SV2XX/_old 2020-03-29 14:25:06.074084320 +0200 +++ /var/tmp/diff_new_pack.6SV2XX/_new 2020-03-29 14:25:06.082084322 +0200 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-Paste -Version: 3.2.6 +Version: 3.4.0 Release: 0 Summary: Tools for using a Web Server Gateway Interface stack License: MIT ++++++ Paste-3.2.6.tar.gz -> Paste-3.4.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/PKG-INFO new/Paste-3.4.0/PKG-INFO --- old/Paste-3.2.6/PKG-INFO 2020-01-13 13:49:12.000000000 +0100 +++ new/Paste-3.4.0/PKG-INFO 2020-02-12 11:51:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Paste -Version: 3.2.6 +Version: 3.4.0 Summary: Tools for using a Web Server Gateway Interface stack Home-page: https://pythonpaste.readthedocs.io/ Author: Chris Dent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/Paste.egg-info/PKG-INFO new/Paste-3.4.0/Paste.egg-info/PKG-INFO --- old/Paste-3.2.6/Paste.egg-info/PKG-INFO 2020-01-13 13:49:12.000000000 +0100 +++ new/Paste-3.4.0/Paste.egg-info/PKG-INFO 2020-02-12 11:51:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Paste -Version: 3.2.6 +Version: 3.4.0 Summary: Tools for using a Web Server Gateway Interface stack Home-page: https://pythonpaste.readthedocs.io/ Author: Chris Dent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/Paste.egg-info/SOURCES.txt new/Paste-3.4.0/Paste.egg-info/SOURCES.txt --- old/Paste-3.2.6/Paste.egg-info/SOURCES.txt 2020-01-13 13:49:12.000000000 +0100 +++ new/Paste-3.4.0/Paste.egg-info/SOURCES.txt 2020-02-12 11:51:00.000000000 +0100 @@ -204,6 +204,7 @@ tests/test_auth/__init__.py tests/test_auth/test_auth_cookie.py tests/test_auth/test_auth_digest.py +tests/test_auth/test_auth_tkt.py tests/test_exceptions/__init__.py tests/test_exceptions/test_error_middleware.py tests/test_exceptions/test_formatter.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/docs/news.txt new/Paste-3.4.0/docs/news.txt --- old/Paste-3.2.6/docs/news.txt 2020-01-13 13:47:14.000000000 +0100 +++ new/Paste-3.4.0/docs/news.txt 2020-02-12 11:48:58.000000000 +0100 @@ -3,6 +3,24 @@ .. contents:: +3.4.0 +----- + +* Allow binding IPv6 address when starting a server. + +Thanks to Lekinho for this patch. + +3.3.0 +----- + +* Use six.BytesIO when reading wsgi.input. +* Remove use of pytest-runner. + +3.2.7 +----- + +* Python 3 updates for use of StringIO and auth_tkt.py. + 3.2.6 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/paste/auth/auth_tkt.py new/Paste-3.4.0/paste/auth/auth_tkt.py --- old/Paste-3.2.6/paste/auth/auth_tkt.py 2018-10-24 15:03:13.000000000 +0200 +++ new/Paste-3.4.0/paste/auth/auth_tkt.py 2020-01-26 16:30:37.000000000 +0100 @@ -36,7 +36,7 @@ makes it possible to use the same authentication process with non-Python code run under Apache. """ - +import six import time as time_mod try: import hashlib @@ -49,8 +49,13 @@ # Python 2 from Cookie import SimpleCookie from paste import request -from urllib import quote as url_quote -from urllib import unquote as url_unquote + +try: + from urllib import quote as url_quote # Python 2.X + from urllib import unquote as url_unquote +except ImportError: + from urllib.parse import quote as url_quote # Python 3+ + from urllib.parse import unquote as url_unquote DEFAULT_DIGEST = hashlib.md5 @@ -98,7 +103,7 @@ self.secret = secret self.userid = userid self.ip = ip - if not isinstance(tokens, basestring): + if not isinstance(tokens, six.string_types): tokens = ','.join(tokens) self.tokens = tokens self.user_data = user_data @@ -108,7 +113,7 @@ self.time = time self.cookie_name = cookie_name self.secure = secure - if isinstance(digest_algo, str): + if isinstance(digest_algo, six.binary_type): # correct specification of digest from hashlib or fail self.digest_algo = getattr(hashlib, digest_algo) else: @@ -120,15 +125,20 @@ self.user_data, self.digest_algo) def cookie_value(self): - v = '%s%08x%s!' % (self.digest(), int(self.time), url_quote(self.userid)) + v = b'%s%08x%s!' % (self.digest(), int(self.time), maybe_encode(url_quote(self.userid))) if self.tokens: - v += self.tokens + '!' - v += self.user_data + v += maybe_encode(self.tokens) + b'!' + v += maybe_encode(self.user_data) return v def cookie(self): c = SimpleCookie() - c[self.cookie_name] = self.cookie_value().encode('base64').strip().replace('\n', '') + if six.PY3: + import base64 + cookie_value = base64.b64encode(self.cookie_value()) + else: + cookie_value = self.cookie_value().encode('base64').strip().replace('\n', '') + c[self.cookie_name] = cookie_value c[self.cookie_name]['path'] = '/' if self.secure: c[self.cookie_name]['secure'] = 'true' @@ -154,7 +164,7 @@ If the ticket cannot be parsed, ``BadTicket`` will be raised with an explanation. """ - if isinstance(digest_algo, str): + if isinstance(digest_algo, six.binary_type): # correct specification of digest from hashlib or fail digest_algo = getattr(hashlib, digest_algo) digest_hexa_size = digest_algo().digest_size * 2 @@ -196,26 +206,26 @@ userid = maybe_encode(userid) tokens = maybe_encode(tokens) user_data = maybe_encode(user_data) - digest0 = digest_algo( - encode_ip_timestamp(ip, timestamp) + secret + userid + '\0' - + tokens + '\0' + user_data).hexdigest() + digest0 = maybe_encode(digest_algo( + encode_ip_timestamp(ip, timestamp) + secret + userid + b'\0' + + tokens + b'\0' + user_data).hexdigest()) digest = digest_algo(digest0 + secret).hexdigest() - return digest + return maybe_encode(digest) def encode_ip_timestamp(ip, timestamp): - ip_chars = ''.join(map(chr, map(int, ip.split('.')))) + ip_chars = b''.join(map(six.int2byte, map(int, ip.split('.')))) t = int(timestamp) ts = ((t & 0xff000000) >> 24, (t & 0xff0000) >> 16, (t & 0xff00) >> 8, t & 0xff) - ts_chars = ''.join(map(chr, ts)) - return ip_chars + ts_chars + ts_chars = b''.join(map(six.int2byte, ts)) + return (ip_chars + ts_chars) def maybe_encode(s, encoding='utf8'): - if isinstance(s, unicode): + if isinstance(s, six.text_type): s = s.encode(encoding) return s @@ -349,7 +359,7 @@ return self.app(environ, cookie_setting_start_response) def set_user_cookie(self, environ, userid, tokens, user_data): - if not isinstance(tokens, basestring): + if not isinstance(tokens, six.string_types): tokens = ','.join(tokens) if self.include_ip: remote_addr = environ['REMOTE_ADDR'] @@ -415,7 +425,7 @@ Creates the `AuthTKTMiddleware <class-paste.auth.auth_tkt.AuthTKTMiddleware.html>`_. - ``secret`` is requird, but can be set globally or locally. + ``secret`` is required, but can be set globally or locally. """ from paste.deploy.converters import asbool secure = asbool(secure) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/paste/cascade.py new/Paste-3.4.0/paste/cascade.py --- old/Paste-3.2.6/paste/cascade.py 2018-10-24 15:03:13.000000000 +0200 +++ new/Paste-3.4.0/paste/cascade.py 2020-01-28 16:54:01.000000000 +0100 @@ -8,7 +8,7 @@ from paste import httpexceptions from paste.util import converters import tempfile -from cStringIO import StringIO +from six import BytesIO __all__ = ['Cascade'] @@ -104,7 +104,9 @@ copy_len -= len(chunk) f.seek(0) else: - f = StringIO(environ['wsgi.input'].read(length)) + f = BytesIO(environ['wsgi.input'].read(length)) + + environ['wsgi.input'] = f else: copy_wsgi_input = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/paste/httpserver.py new/Paste-3.4.0/paste/httpserver.py --- old/Paste-3.2.6/paste/httpserver.py 2020-01-05 14:55:49.000000000 +0100 +++ new/Paste-3.4.0/paste/httpserver.py 2020-02-12 11:40:19.000000000 +0100 @@ -1289,13 +1289,39 @@ ssl_context.use_certificate_chain_file(ssl_pem) host = host or '127.0.0.1' + is_ipv6 = False + if host.count(':') > 1 or '[' in host : + is_ipv6 = True + if port is None: - if ':' in host: + + if ':' in host and is_ipv6 is False: host, port = host.split(':', 1) + elif is_ipv6 and ']' in host: + + idx = host.find(']') + if (idx < (len(host) - 1)) and (host[(idx+1)] == ':'): + # check if the next position is ':', if so, split and grab the port + + host, port = host.rsplit(':', 1) + host = host.strip('[').strip(']') + + else : + + port = 8080 else: + port = 8080 + #strip '[' and ']' in host + host = host.strip('[').strip(']') server_address = (host, int(port)) + if is_ipv6: + # set address family + HTTPServer.address_family = socket.AF_INET6 + else: + HTTPServer.address_family = socket.AF_INET + if not handler: handler = WSGIHandler if server_version: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/setup.cfg new/Paste-3.4.0/setup.cfg --- old/Paste-3.2.6/setup.cfg 2020-01-13 13:49:12.000000000 +0100 +++ new/Paste-3.4.0/setup.cfg 2020-02-12 11:51:00.000000000 +0100 @@ -5,7 +5,6 @@ [aliases] distribute = register sdist bdist_egg upload pudge publish -test = pytest [bdist_wheel] universal = 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/setup.py new/Paste-3.4.0/setup.py --- old/Paste-3.2.6/setup.py 2020-01-13 13:45:58.000000000 +0100 +++ new/Paste-3.4.0/setup.py 2020-02-12 11:46:03.000000000 +0100 @@ -12,7 +12,7 @@ # - git push # - python setup.py sdist bdist_wheel upload --sign -__version__ = '3.2.6' +__version__ = '3.4.0' from setuptools import setup, find_packages import sys, os @@ -52,9 +52,7 @@ exclude_directories=finddata.standard_exclude_directories + ('tests',)), namespace_packages=['paste'], zip_safe=False, - setup_requires=['pytest-runner'], install_requires=['six>=1.4.0'], - tests_require=['pytest'], extras_require={ 'subprocess': [], 'hotshot': [], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/tests/test_auth/test_auth_tkt.py new/Paste-3.4.0/tests/test_auth/test_auth_tkt.py --- old/Paste-3.2.6/tests/test_auth/test_auth_tkt.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Paste-3.4.0/tests/test_auth/test_auth_tkt.py 2020-01-26 16:30:37.000000000 +0100 @@ -0,0 +1,120 @@ +import hashlib +import six +if six.PY3: + import base64 +from paste.auth.auth_tkt import AuthTicket +try: + from http.cookies import SimpleCookie +except ImportError: + # Python 2 + from Cookie import SimpleCookie + + +def test_auth_ticket_digest_and_cookie_value(): + test_parameters = [ + ( + ( + 'shared_secret', + 'username', + '0.0.0.0', # remote address + ), + { + 'tokens': ['admin'], + 'time': 1579782607 + }, + b'731274bec45f6983c1f33bac8e8baf43', + b'731274bec45f6983c1f33bac8e8baf435e2991cfusername!admin!', + ), + ( + ( + 'shared_secret', + 'username', + '0.0.0.0', + ), + { + 'tokens': ['admin'], + 'time': 1579782607, + 'digest_algo': hashlib.sha512 + }, + b'09e72a63c57ca4cfeca5fa578646deb2b27f7a461d91ad9aa32b85c93ef6fa7744ac006eb3d9a71a36375b5ab50cbae072bb3042e2a59198b7f314900cba4423', + b'09e72a63c57ca4cfeca5fa578646deb2b27f7a461d91ad9aa32b85c93ef6fa7744ac006eb3d9a71a36375b5ab50cbae072bb3042e2a59198b7f314900cba44235e2991cfusername!admin!', + ), + ] + + for test_args, test_kwargs, expected_digest, expected_cookie_value in test_parameters: + token = AuthTicket(*test_args, **test_kwargs) + assert expected_digest == token.digest() + assert expected_cookie_value == token.cookie_value() + + +def test_auth_ticket_cookie(): + test_parameters = [ + ( + ( + 'shared_secret', + 'username', + '0.0.0.0', # remote address + ), + { + 'tokens': ['admin'], + 'time': 1579782607 + }, + { + 'name': 'auth_tkt', + 'path': '/', + 'secure': '', + 'cookie_value': b'731274bec45f6983c1f33bac8e8baf435e2991cfusername!admin!' + } + ), + ( + ( + 'shared_secret', + 'username', + '0.0.0.0', # remote address + ), + { + 'tokens': ['admin'], + 'time': 1579782607, + 'secure': True + }, + { + 'name': 'auth_tkt', + 'path': '/', + 'secure': 'true', + 'cookie_value': b'731274bec45f6983c1f33bac8e8baf435e2991cfusername!admin!' + } + ), + ( + ( + 'shared_secret', + 'username', + '0.0.0.0', # remote address + ), + { + 'tokens': ['admin'], + 'time': 1579782607, + 'cookie_name': 'custom_cookie', + 'secure': False + }, + { + 'name': 'custom_cookie', + 'path': '/', + 'secure': '', + 'cookie_value': b'731274bec45f6983c1f33bac8e8baf435e2991cfusername!admin!' + } + ), + ] + + for test_args, test_kwargs, expected_values in test_parameters: + token = AuthTicket(*test_args, **test_kwargs) + expected_cookie = SimpleCookie() + if six.PY3: + # import pdb; pdb.set_trace() + expected_cookie_value = base64.b64encode(expected_values['cookie_value']) + else: + expected_cookie_value = expected_values['cookie_value'].encode('base64') + + expected_cookie[expected_values['name']] = expected_cookie_value + expected_cookie[expected_values['name']]['path'] = expected_values['path'] + expected_cookie[expected_values['name']]['secure'] = expected_values['secure'] + assert expected_cookie == token.cookie() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Paste-3.2.6/tests/test_httpserver.py new/Paste-3.4.0/tests/test_httpserver.py --- old/Paste-3.2.6/tests/test_httpserver.py 2019-09-25 14:27:36.000000000 +0200 +++ new/Paste-3.4.0/tests/test_httpserver.py 2020-02-12 11:40:19.000000000 +0100 @@ -4,7 +4,7 @@ import six -from paste.httpserver import LimitedLengthFile, WSGIHandler +from paste.httpserver import LimitedLengthFile, WSGIHandler, serve from six.moves import StringIO @@ -72,3 +72,62 @@ assert f.read() == b'123456789' assert f.tell() == 10 backing_read.close() + + +def test_address_family_v4(): + #ipv4 + app = None + host = '127.0.0.1' + port = '9090' + + svr = serve(app, host=host, port=port, start_loop=False, use_threadpool=False) + + af = svr.address_family + addr = svr.server_address + p = svr.server_port + + svr.server_close() + + assert (af == socket.AF_INET) + assert (addr[0] == '127.0.0.1') + assert (str(p) == port) + + +def test_address_family_v4_host_and_port(): + #ipv4 + app = None + host = '127.0.0.1:9091' + + svr = serve(app, host=host, start_loop=False, use_threadpool=False) + + af = svr.address_family + addr = svr.server_address + p = svr.server_port + + svr.server_close() + + assert (af == socket.AF_INET) + assert (addr[0] == '127.0.0.1') + assert (str(p) == '9091') + +def test_address_family_v6(): + #ipv6 + app = None + host = '[::1]' + port = '9090' + + try: + svr = serve(app, host=host, port=port, start_loop=False, use_threadpool=False) + + af = svr.address_family + addr = svr.server_address + p = svr.server_port + + svr.server_close() + + assert (af == socket.AF_INET6) + assert (addr[0] == '::1') + assert (str(p) == port) + except (socket.error, OSError) as err: + # v6 support not available in this OS, pass the test + assert True \ No newline at end of file