Hello community,

here is the log from the commit of package python-django-debreach for 
openSUSE:Factory checked in at 2019-10-30 14:49:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-debreach (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-debreach.new.2990 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-debreach"

Wed Oct 30 14:49:00 2019 rev:4 rq:744147 version:2.0.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-debreach/python-django-debreach.changes
    2019-10-21 12:29:15.496019025 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-debreach.new.2990/python-django-debreach.changes
  2019-10-30 14:49:02.594260405 +0100
@@ -1,0 +2,7 @@
+Wed Oct 30 12:04:59 UTC 2019 - Tomáš Chvátal <tchva...@suse.com>
+
+- Update to 2.0.1:
+  * Drop python2 support upstream
+  * Various tests and description fixes
+
+-------------------------------------------------------------------

Old:
----
  django-debreach-1.5.2.tar.gz

New:
----
  django-debreach-2.0.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-debreach.spec ++++++
--- /var/tmp/diff_new_pack.3GjH7d/_old  2019-10-30 14:49:03.886261779 +0100
+++ /var/tmp/diff_new_pack.3GjH7d/_new  2019-10-30 14:49:03.886261779 +0100
@@ -19,18 +19,16 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-django-debreach
-Version:        1.5.2
+Version:        2.0.1
 Release:        0
 Summary:        Middleware to protect against the BREACH attack in Django
 License:        BSD-2-Clause
-Group:          Development/Languages/Python
-URL:            http://github.com/lpomfrey/django-debreach
+URL:            https://github.com/lpomfrey/django-debreach
 Source:         
https://files.pythonhosted.org/packages/source/d/django-debreach/django-debreach-%{version}.tar.gz
 BuildRequires:  %{python_module Django}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-BuildRequires:  python python3
 Requires:       python-Django
 BuildArch:      noarch
 %python_subpackages

++++++ django-debreach-1.5.2.tar.gz -> django-debreach-2.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/PKG-INFO 
new/django-debreach-2.0.1/PKG-INFO
--- old/django-debreach-1.5.2/PKG-INFO  2018-08-31 15:32:05.000000000 +0200
+++ new/django-debreach-2.0.1/PKG-INFO  2019-10-10 11:09:54.000000000 +0200
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: django-debreach
-Version: 1.5.2
-Summary: Adds middleware and context processors to give some protection 
against the BREACH attack in Django.
+Version: 2.0.1
+Summary: Adds middleware to give some added protection against the BREACH 
attack in Django.
 Home-page: http://github.com/lpomfrey/django-debreach
 Author: Luke Pomfrey
 Author-email: lpomf...@gmail.com
@@ -14,14 +14,9 @@
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.8
-Classifier: Framework :: Django :: 1.11
-Classifier: Framework :: Django :: 2.0
+Classifier: Framework :: Django :: 2.2
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: CPython
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/README.rst 
new/django-debreach-2.0.1/README.rst
--- old/django-debreach-1.5.2/README.rst        2016-08-13 13:15:42.000000000 
+0200
+++ new/django-debreach-2.0.1/README.rst        2019-10-10 09:58:23.000000000 
+0200
@@ -4,6 +4,12 @@
 Basic/extra mitigation against the `BREACH attack <http://breachattack.com/>`_ 
 for Django projects. 
 
+django-debreach provides additional protection to Django's built in CSRF
+token masking by randomising the content length of each response. This is 
+acheived by adding a random string of between 12 and 25 characters as a 
+comment to the end of the HTML content. Note that this will only be applied to 
+responses with a content type of ``text/html``.
+
 When combined with rate limiting in your web-server, or by using something
 like `django-ratelimit <http://django-ratelimit.readthedocs.org/>`_, the 
 techniques here should provide at least some protection against the BREACH 
@@ -20,89 +26,13 @@
     :target: https://coveralls.io/r/lpomfrey/django-debreach?branch=master
     :alt: Coverage
 
-Installation
-------------
+Installation & Usage
+--------------------
 
 Install from PyPI using::
 
     $ pip install django-debreach
 
-Add to your `INSTALLED_APPS`::
-
-    INSTALLED_APPS = (
-        ...
-        'debreach',
-        ...
-    )
-
-Configuration
--------------
-
-CSRF token masking (for Django < 1.10)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Django 1.10+ provides built-in support for masking CSRF tokens so you should 
-use that. Including the middleware in a Django 1.10 project will raise an
-``ImproperlyConfigured`` exception.
-
-To mask CSRF tokens in the template add the
-``debreach.context_processors.csrf`` context processor to the end of your 
-`TEMPLATE_CONTEXT_PROCESSORS`::
-
-    TEMPLATE_CONTEXT_PROCESSORS = (
-        ...
-        'debreach.context_processors.csrf',
-    )
-
-And add the ``debreach.middleware.CSRFCryptMiddleware`` to your middleware,
-*before* ``django.middleware.csrf.CSRFMiddleware``::
-
-    MIDDLEWARE_CLASSES = (
-        'debreach.middleware.CSRFCryptMiddleware',
-        ...
-        'django.middleware.csrf.CSRFMiddleware',
-        ...
-    )
-
-This works by xor-ing the CSRF token when it is added to the template,
-so that ``{% csrf_token %}`` now produces a hidden field with a value that is 
-``"<random-string>$<actual-csrf-token-xor-ed-with-random-string>"``.
-Then, when the form is POSTed, the middleware xors the CSRF token back into
-it's original form. This ensures that the CSRF content is never the same
-between requests. If you are passing the token using the ``X-CSRFToken``
-header (e.g. using XHR) that header will also be processed in the same way.
-
-Note that values that are unchanged by django-debreach, or rather, don't 
-contain a delimiting ``$``, will be left unmodified. The middleware will
-also not operate on views marked as being exempt from CSRF protection
-using the ``django.views.decorators.csrf.csrf_exempt`` decorator.
-
-CSRF protection using csrf_protect
-""""""""""""""""""""""""""""""""""
-
-If you don't use the CSRF middleware from django but, instead, apply the
-``django.views.decorators.csrf.csrf_protect`` decorator to selected
-views, and don't want to use the ``debreach.middleware.CSRFCryptMiddleware``, 
-then you can use the ``debreach.decorators.csrf_decrypt`` decorator.
-
-To use the ``debreach.decorators.csrf_decrypt`` decorator simply wrap
-your CSRF protected view with the decorator, like so::
-
-    @csrf_protect
-    @csrf_decrypt
-    def view(request, *args, **kwargs):
-        return HttpResponse('')
-
-
-Content length modification
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-django-debreach also enables you to counter the BREACH attack by randomising 
the
-content length of each response. This is acheived by adding a random string of 
-between 12 and 25 characters as a comment to the end of the HTML content. Note
-that this will only be applied to responses with a content type of
-``text/html``.
-
 To enable content length modification for all responses, add the
 ``debreach.middleware.RandomCommentMiddleware`` to the *start* of your
 middleware, but *after* the ``GzipMiddleware`` if you are using that.::
@@ -127,3 +57,9 @@
 then it may be easier to not use the middleware, but to selectively apply the
 ``debreach.decorators.append_random_comment`` decorator to the views you want
 protected.
+
+Python 2 and Django < 2.0 support
+---------------------------------
+
+Version 2.0.0 drops all support for Python 2 and Django < 2.0. If you need 
+support for those versions continue using ``django-debreach>=1.5.2,<2.0``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/__init__.py 
new/django-debreach-2.0.1/debreach/__init__.py
--- old/django-debreach-1.5.2/debreach/__init__.py      2018-08-31 
15:31:47.000000000 +0200
+++ new/django-debreach-2.0.1/debreach/__init__.py      2019-10-10 
11:08:57.000000000 +0200
@@ -1,10 +1,8 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from distutils import version
 
 
-__version__ = '1.5.2'
+__version__ = '2.0.1'
 version_info = version.StrictVersion(__version__).version
 
 default_app_config = 'debreach.apps.DebreachConfig'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/apps.py 
new/django-debreach-2.0.1/debreach/apps.py
--- old/django-debreach-1.5.2/debreach/apps.py  2016-01-10 17:05:37.000000000 
+0100
+++ new/django-debreach-2.0.1/debreach/apps.py  2019-10-10 09:55:51.000000000 
+0200
@@ -1,6 +1,4 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from django.apps import AppConfig
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/context_processors.py 
new/django-debreach-2.0.1/debreach/context_processors.py
--- old/django-debreach-1.5.2/debreach/context_processors.py    2016-08-13 
12:47:13.000000000 +0200
+++ new/django-debreach-2.0.1/debreach/context_processors.py    1970-01-01 
01:00:00.000000000 +0100
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.core.signing import b64_encode
-from django.middleware.csrf import get_token
-from django.utils.crypto import get_random_string
-from django.utils.encoding import force_bytes, force_text
-from django.utils.functional import lazy
-from django.utils.six import text_type
-
-from debreach.utils import xor
-
-
-def csrf(request):
-    """
-    Context processor that provides a CSRF token, or the string 'NOTPROVIDED'
-    if it has not been provided by either a view decorator or the middleware
-    """
-    def _get_val():
-        token = get_token(request)
-        if token is None:
-            # In order to be able to provide debugging info in the
-            # case of misconfiguration, we use a sentinel value
-            # instead of returning an empty dict.
-            return 'NOTPROVIDED'
-        else:
-            token = force_bytes(token, encoding='latin-1')
-            key = force_bytes(
-                get_random_string(len(token)),
-                encoding='latin-1'
-            )
-            value = b64_encode(xor(token, key))
-            return force_text(b'$'.join((key, value)), encoding='latin-1')
-    _get_val = lazy(_get_val, text_type)
-
-    return {'csrf_token': _get_val()}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/decorators.py 
new/django-debreach-2.0.1/debreach/decorators.py
--- old/django-debreach-1.5.2/debreach/decorators.py    2016-08-13 
12:50:35.000000000 +0200
+++ new/django-debreach-2.0.1/debreach/decorators.py    2019-10-10 
11:08:27.000000000 +0200
@@ -1,12 +1,9 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 from functools import wraps
 
-import django
-from django.utils.decorators import available_attrs, decorator_from_middleware
+from django.utils.decorators import decorator_from_middleware
 
-from debreach.middleware import CSRFCryptMiddleware, RandomCommentMiddleware
+from debreach.middleware import RandomCommentMiddleware
 
 
 append_random_comment = decorator_from_middleware(RandomCommentMiddleware)
@@ -27,14 +24,4 @@
         response = view_func(*args, **kwargs)
         response._random_comment_exempt = True
         return response
-    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)
-
-
-if django.VERSION < (1, 10):
-    csrf_decrypt = decorator_from_middleware(CSRFCryptMiddleware)
-    append_random_comment.__name__ = str('append_random_comment')
-    append_random_comment.__doc__ = '''
-    Performs the function of the CSRFCryptMiddleware, xor-ing the crypted CSRF
-    token back into its original form. Using both, or using the decorator
-    multiple times is harmless and efficient.
-    '''
+    return wraps(view_func)(wrapped_view)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/middleware.py 
new/django-debreach-2.0.1/debreach/middleware.py
--- old/django-debreach-1.5.2/debreach/middleware.py    2018-08-24 
14:55:16.000000000 +0200
+++ new/django-debreach-2.0.1/debreach/middleware.py    2019-10-10 
09:54:15.000000000 +0200
@@ -1,87 +1,28 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import logging
 import random
 
-import django
-from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
-from django.core.signing import b64_decode
 from django.utils.crypto import get_random_string
-from django.utils.encoding import force_bytes, force_text
-from django.utils.six import binary_type, string_types
-
-from debreach.utils import xor
-
-try:
-    from django.utils.deprecation import MiddlewareMixin
-except ImportError:
-    class MiddlewareMixin(object):
-        pass
+from django.utils.deprecation import MiddlewareMixin
+from django.utils.encoding import force_str
 
 
 log = logging.getLogger(__name__)
 
 
-class CSRFCryptMiddleware(object):
-
-    def __init__(self, *args, **kwargs):
-        if django.VERSION >= (1, 10):
-            raise ImproperlyConfigured(
-                "Django 1.10 and above provides it's own CSRF mechanism to "
-                "mitigate the BREACH attack, please remove the "
-                "{}.{} middleware."
-                .format(self.__module__, self.__class__.__name__)
-            )
-
-    def _decode(self, token):
-        key, value = force_bytes(token, encoding='latin-1').split(b'$', 1)
-        return force_text(xor(b64_decode(value), key), encoding='latin-1')
-
-    def process_view(self, request, view, view_args, view_kwargs):
-        if getattr(view, 'csrf_exempt', False):
-            return None
-        if request.POST.get('csrfmiddlewaretoken') \
-                and '$' in request.POST.get('csrfmiddlewaretoken'):
-            try:
-                post_was_mutable = request.POST._mutable
-                POST = request.POST.copy()
-                token = POST.get('csrfmiddlewaretoken')
-                POST['csrfmiddlewaretoken'] = self._decode(token)
-                POST._mutable = post_was_mutable
-                request.POST = POST
-            except:
-                log.exception('Error decoding csrfmiddlewaretoken')
-                raise SuspiciousOperation(
-                    'csrfmiddlewaretoken has been tampered with')
-        if request.META.get('HTTP_X_CSRFTOKEN') \
-                and '$' in request.META.get('HTTP_X_CSRFTOKEN'):
-            try:
-                META = request.META.copy()
-                token = META.get('HTTP_X_CSRFTOKEN')
-                META['HTTP_X_CSRFTOKEN'] = self._decode(token)
-                request.META = META
-            except:
-                log.exception('Error decoding csrfmiddlewaretoken')
-                raise SuspiciousOperation(
-                    'X-CSRFToken header has been tampered with')
-        return None
-
-
 class RandomCommentMiddleware(MiddlewareMixin):
 
     def process_response(self, request, response):
-        str_types = string_types + (binary_type,)
         if not getattr(response, 'streaming', False) \
                 and response.get('Content-Type', '').startswith('text/html') \
                 and response.content \
-                and isinstance(response.content, str_types) \
+                and isinstance(response.content, (bytes, str)) \
                 and not getattr(response, '_random_comment_exempt', False) \
                 and not getattr(response, '_random_comment_applied', False):
             comment = '<!-- {0} -->'.format(
                 get_random_string(random.choice(range(12, 25))))
             response.content = '{0}{1}'.format(
-                force_text(response.content), comment)
+                force_str(response.content), comment)
             response._random_comment_applied = True
             if response.has_header('Content-Length'):
                 response['Content-Length'] = str(len(response.content))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/models.py 
new/django-debreach-2.0.1/debreach/models.py
--- old/django-debreach-1.5.2/debreach/models.py        2016-01-10 
17:05:37.000000000 +0100
+++ new/django-debreach-2.0.1/debreach/models.py        1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-# -*- coding: utf-8 -*-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/tests.py 
new/django-debreach-2.0.1/debreach/tests.py
--- old/django-debreach-1.5.2/debreach/tests.py 2017-12-21 18:33:54.000000000 
+0100
+++ new/django-debreach-2.0.1/debreach/tests.py 2019-10-10 09:56:08.000000000 
+0200
@@ -1,124 +1,21 @@
 # -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
 import os
-import re
 import unittest
 
-import django
-from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
 from django.http import HttpResponse
 from django.test import TestCase
 from django.test.client import RequestFactory
-from django.utils.crypto import get_random_string
-from django.utils.encoding import force_text
-from django.views.decorators.csrf import csrf_exempt
+from django.urls import reverse
+from django.utils.encoding import force_str
 
-from debreach.context_processors import csrf
 from debreach.decorators import append_random_comment, random_comment_exempt
-from debreach.middleware import CSRFCryptMiddleware, RandomCommentMiddleware
-
-
-try:
-    from django.urls import reverse
-except ImportError:
-    from django.core.urlresolvers import reverse
-
-
-try:
-    unichr
-except NameError:
-    pass
-else:
-    chr = unichr
+from debreach.middleware import RandomCommentMiddleware
 
 
 def test_view(request):
     return HttpResponse()
 
 
-class TestCSRFCryptMiddleware(TestCase):
-
-    if django.VERSION < (1, 10):
-
-        def test_not_encoded(self):
-            request = RequestFactory().post(
-                '/', {'csrfmiddlewaretoken': 'abc123'}
-            )
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertEqual(request.POST.get('csrfmiddlewaretoken'), 'abc123')
-
-        def test_encoded(self):
-            request = RequestFactory().post(
-                '/',
-                {'csrfmiddlewaretoken': 'aBcDeF$ACAAdVd1'}
-            )
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertEqual(request.POST.get('csrfmiddlewaretoken'), 'abc123')
-
-        def test_mutable_status(self):
-            request = RequestFactory().post(
-                '/',
-                {'csrfmiddlewaretoken': 'aBcDeF$ACAAdVd1'}
-            )
-            request.POST._mutable = False
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertFalse(request.POST._mutable)
-            request = RequestFactory().post(
-                '/',
-                {'csrfmiddlewaretoken': 'aBcDeF$ACAAdVd1'}
-            )
-            request.POST._mutable = True
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertTrue(request.POST._mutable)
-
-        def test_header_not_encoded(self):
-            request = RequestFactory().post('/', HTTP_X_CSRFTOKEN='abc123')
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertEqual(request.META.get('HTTP_X_CSRFTOKEN'), 'abc123')
-
-        def test_header_encoded(self):
-            request = RequestFactory().post(
-                '/', HTTP_X_CSRFTOKEN='aBcDeF$ACAAdVd1',
-            )
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, test_view, (), {})
-            self.assertEqual(request.META.get('HTTP_X_CSRFTOKEN'), 'abc123')
-
-        def test_tampering(self):
-            request = RequestFactory().post(
-                '/', {'csrfmiddlewaretoken': '123456$abc'})
-            middleware = CSRFCryptMiddleware()
-            with self.assertRaises(SuspiciousOperation):
-                middleware.process_view(request, test_view, (), {})
-
-        def test_header_tampering(self):
-            request = RequestFactory().post('/', HTTP_X_CSRFTOKEN='123456$abc')
-            middleware = CSRFCryptMiddleware()
-            with self.assertRaises(SuspiciousOperation):
-                middleware.process_view(request, test_view, (), {})
-
-        def test_csrf_exempt(self):
-            # This is an odd test. We're testing that, when a view is
-            # csrf_exempt, process_view will bail without performing any
-            # processing.
-            request = RequestFactory().post('/', HTTP_X_CSRFTOKEN="aB$AHM")
-            middleware = CSRFCryptMiddleware()
-            middleware.process_view(request, csrf_exempt(test_view), (), {})
-            self.assertEqual("aB$AHM", request.META['HTTP_X_CSRFTOKEN'])
-
-    else:
-
-        def test_middleware_raises_improperly_configured(self):
-            with self.assertRaises(ImproperlyConfigured):
-                CSRFCryptMiddleware()
-
-
 class TestRandomCommentMiddleware(TestCase):
 
     def test_noop_on_wrong_content_type(self):
@@ -160,7 +57,7 @@
         request = RequestFactory().get('/')
         middleware = RandomCommentMiddleware()
         response = middleware.process_response(request, response)
-        self.assertNotEqual(force_text(response.content), force_text(html))
+        self.assertNotEqual(force_str(response.content), force_str(html))
 
     def test_exemption(self):
         html = '''<html>
@@ -172,7 +69,7 @@
         request = RequestFactory().get('/')
         middleware = RandomCommentMiddleware()
         response = middleware.process_response(request, response)
-        self.assertEqual(force_text(response.content), html)
+        self.assertEqual(force_str(response.content), html)
 
     def test_missing_content_type(self):
         request = RequestFactory().get('/')
@@ -204,9 +101,9 @@
 
         request = RequestFactory().get('/')
         response = test_view(request)
-        self.assertNotEqual(force_text(response.content), html)
-        self.assertIn('<!-- ', force_text(response.content))
-        self.assertIn(' -->', force_text(response.content))
+        self.assertNotEqual(force_str(response.content), html)
+        self.assertIn('<!-- ', force_str(response.content))
+        self.assertIn(' -->', force_str(response.content))
 
     def test_random_comment_exempt(self):
         html = '''<html>
@@ -223,26 +120,6 @@
         self.assertTrue(response._random_comment_exempt)
 
 
-class TestContextProcessor(TestCase):
-
-    def test_csrf(self):
-        request = RequestFactory().get('/')
-        request.META['CSRF_COOKIE'] = 'abc123'
-        context = csrf(request)
-        self.assertTrue(force_text(context['csrf_token']))
-        self.assertNotEqual(force_text(context['csrf_token']), 'abc123')
-
-    @unittest.skipUnless(
-        django.VERSION < (1, 9),
-        'The CSRF token is always present in Django 1.9+'
-    )
-    def test_no_token_csrf(self):
-        request = RequestFactory().get('/')
-        context = csrf(request)
-        self.assertTrue(force_text(context['csrf_token']))
-        self.assertEqual(force_text(context['csrf_token']), 'NOTPROVIDED')
-
-
 @unittest.skipUnless(
     'test_project' in os.environ.get('DJANGO_SETTINGS_MODULE', ''),
     'Not running in test_project'
@@ -252,74 +129,3 @@
     def test_adds_comment(self):
         resp = self.client.get(reverse('home'))
         self.assertFalse(resp.content.endswith(b'</html>'))
-
-    if django.VERSION < (1, 10):
-        def test_crypt_csrf_token(self):
-            resp = self.client.get(reverse('test_form'))
-            m = re.search(
-                r'value=\'(.*\$.*)\'',
-                force_text(resp.content),
-                re.MULTILINE | re.DOTALL
-            )
-            self.assertEqual(len(m.groups()), 1)
-            token = m.groups()[0].strip()
-            post_resp = self.client.post(
-                reverse('test_form'),
-                {'csrfmiddlewaretoken': token, 'message': 'Some rubbish'}
-            )
-            self.assertRedirects(post_resp, reverse('home'))
-
-        def test_crypt_csrf_header(self):
-            resp = self.client.get(reverse('test_form'))
-            m = re.search(
-                r'value=\'(.*\$.*)\'',
-                force_text(resp.content),
-                re.MULTILINE | re.DOTALL
-            )
-            self.assertEqual(len(m.groups()), 1)
-            token = m.groups()[0].strip()
-            post_resp = self.client.post(
-                reverse('test_form'),
-                {'message': 'Some rubbish'},
-                X_CSRFTOKEN=token,
-            )
-            self.assertRedirects(post_resp, reverse('home'))
-
-        def test_round_trip_loop(self):
-            '''
-            Checks a wide range of input tokens and keys
-            '''
-            for _ in range(1000):
-                request = RequestFactory().get('/')
-                csrf_token = get_random_string(32)
-                request.META['CSRF_COOKIE'] = csrf_token
-                token = force_text(csrf(request)['csrf_token'])
-                request = RequestFactory().post(
-                    '/', {'csrfmiddlewaretoken': token})
-                middleware = CSRFCryptMiddleware()
-                middleware.process_view(request, test_view, (), {})
-                self.assertEqual(
-                    force_text(request.POST.get('csrfmiddlewaretoken')),
-                    force_text(csrf_token)
-                )
-
-        def test_round_trip_loop_header(self):
-            '''
-            Checks a wide range of input tokens and keys
-            '''
-            for _ in range(1000):
-                request = RequestFactory().get('/')
-                csrf_token = get_random_string(32)
-                request.META['CSRF_COOKIE'] = csrf_token
-                token = csrf(request)['csrf_token']
-                request = RequestFactory().post(
-                    '/',
-                    HTTP_X_CSRFTOKEN=force_text(token),
-                    HTTP_X_REQUESTED_WITH='XMLHttpRequest'
-                )
-                middleware = CSRFCryptMiddleware()
-                middleware.process_view(request, test_view, (), {})
-                self.assertEqual(
-                    force_text(request.META.get('HTTP_X_CSRFTOKEN')),
-                    force_text(csrf_token)
-                )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/debreach/utils.py 
new/django-debreach-2.0.1/debreach/utils.py
--- old/django-debreach-1.5.2/debreach/utils.py 2016-01-10 17:05:37.000000000 
+0100
+++ new/django-debreach-2.0.1/debreach/utils.py 1970-01-01 01:00:00.000000000 
+0100
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.utils.encoding import force_bytes
-from django.utils.six import binary_type
-
-
-def xor(s, pad):
-    '''XOR a given string ``s`` with the one-time-pad ``pad``'''
-    from itertools import cycle
-    s = bytearray(force_bytes(s, encoding='latin-1'))
-    pad = bytearray(force_bytes(pad, encoding='latin-1'))
-    return binary_type(bytearray(x ^ y for x, y in zip(s, cycle(pad))))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debreach-1.5.2/django_debreach.egg-info/PKG-INFO 
new/django-debreach-2.0.1/django_debreach.egg-info/PKG-INFO
--- old/django-debreach-1.5.2/django_debreach.egg-info/PKG-INFO 2018-08-31 
15:32:05.000000000 +0200
+++ new/django-debreach-2.0.1/django_debreach.egg-info/PKG-INFO 2019-10-10 
11:09:53.000000000 +0200
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: django-debreach
-Version: 1.5.2
-Summary: Adds middleware and context processors to give some protection 
against the BREACH attack in Django.
+Version: 2.0.1
+Summary: Adds middleware to give some added protection against the BREACH 
attack in Django.
 Home-page: http://github.com/lpomfrey/django-debreach
 Author: Luke Pomfrey
 Author-email: lpomf...@gmail.com
@@ -14,14 +14,9 @@
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
 Classifier: Framework :: Django
-Classifier: Framework :: Django :: 1.8
-Classifier: Framework :: Django :: 1.11
-Classifier: Framework :: Django :: 2.0
+Classifier: Framework :: Django :: 2.2
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: CPython
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debreach-1.5.2/django_debreach.egg-info/SOURCES.txt 
new/django-debreach-2.0.1/django_debreach.egg-info/SOURCES.txt
--- old/django-debreach-1.5.2/django_debreach.egg-info/SOURCES.txt      
2018-08-31 15:32:05.000000000 +0200
+++ new/django-debreach-2.0.1/django_debreach.egg-info/SOURCES.txt      
2019-10-10 11:09:53.000000000 +0200
@@ -5,12 +5,9 @@
 setup.py
 debreach/__init__.py
 debreach/apps.py
-debreach/context_processors.py
 debreach/decorators.py
 debreach/middleware.py
-debreach/models.py
 debreach/tests.py
-debreach/utils.py
 django_debreach.egg-info/PKG-INFO
 django_debreach.egg-info/SOURCES.txt
 django_debreach.egg-info/dependency_links.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/docs/index.rst 
new/django-debreach-2.0.1/docs/index.rst
--- old/django-debreach-1.5.2/docs/index.rst    2016-08-13 13:15:42.000000000 
+0200
+++ new/django-debreach-2.0.1/docs/index.rst    2019-10-10 09:58:23.000000000 
+0200
@@ -4,6 +4,12 @@
 Basic/extra mitigation against the `BREACH attack <http://breachattack.com/>`_ 
 for Django projects. 
 
+django-debreach provides additional protection to Django's built in CSRF
+token masking by randomising the content length of each response. This is 
+acheived by adding a random string of between 12 and 25 characters as a 
+comment to the end of the HTML content. Note that this will only be applied to 
+responses with a content type of ``text/html``.
+
 When combined with rate limiting in your web-server, or by using something
 like `django-ratelimit <http://django-ratelimit.readthedocs.org/>`_, the 
 techniques here should provide at least some protection against the BREACH 
@@ -20,89 +26,13 @@
     :target: https://coveralls.io/r/lpomfrey/django-debreach?branch=master
     :alt: Coverage
 
-Installation
-------------
+Installation & Usage
+--------------------
 
 Install from PyPI using::
 
     $ pip install django-debreach
 
-Add to your `INSTALLED_APPS`::
-
-    INSTALLED_APPS = (
-        ...
-        'debreach',
-        ...
-    )
-
-Configuration
--------------
-
-CSRF token masking (for Django < 1.10)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Django 1.10+ provides built-in support for masking CSRF tokens so you should 
-use that. Including the middleware in a Django 1.10 project will raise an
-``ImproperlyConfigured`` exception.
-
-To mask CSRF tokens in the template add the
-``debreach.context_processors.csrf`` context processor to the end of your 
-`TEMPLATE_CONTEXT_PROCESSORS`::
-
-    TEMPLATE_CONTEXT_PROCESSORS = (
-        ...
-        'debreach.context_processors.csrf',
-    )
-
-And add the ``debreach.middleware.CSRFCryptMiddleware`` to your middleware,
-*before* ``django.middleware.csrf.CSRFMiddleware``::
-
-    MIDDLEWARE_CLASSES = (
-        'debreach.middleware.CSRFCryptMiddleware',
-        ...
-        'django.middleware.csrf.CSRFMiddleware',
-        ...
-    )
-
-This works by xor-ing the CSRF token when it is added to the template,
-so that ``{% csrf_token %}`` now produces a hidden field with a value that is 
-``"<random-string>$<actual-csrf-token-xor-ed-with-random-string>"``.
-Then, when the form is POSTed, the middleware xors the CSRF token back into
-it's original form. This ensures that the CSRF content is never the same
-between requests. If you are passing the token using the ``X-CSRFToken``
-header (e.g. using XHR) that header will also be processed in the same way.
-
-Note that values that are unchanged by django-debreach, or rather, don't 
-contain a delimiting ``$``, will be left unmodified. The middleware will
-also not operate on views marked as being exempt from CSRF protection
-using the ``django.views.decorators.csrf.csrf_exempt`` decorator.
-
-CSRF protection using csrf_protect
-""""""""""""""""""""""""""""""""""
-
-If you don't use the CSRF middleware from django but, instead, apply the
-``django.views.decorators.csrf.csrf_protect`` decorator to selected
-views, and don't want to use the ``debreach.middleware.CSRFCryptMiddleware``, 
-then you can use the ``debreach.decorators.csrf_decrypt`` decorator.
-
-To use the ``debreach.decorators.csrf_decrypt`` decorator simply wrap
-your CSRF protected view with the decorator, like so::
-
-    @csrf_protect
-    @csrf_decrypt
-    def view(request, *args, **kwargs):
-        return HttpResponse('')
-
-
-Content length modification
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-django-debreach also enables you to counter the BREACH attack by randomising 
the
-content length of each response. This is acheived by adding a random string of 
-between 12 and 25 characters as a comment to the end of the HTML content. Note
-that this will only be applied to responses with a content type of
-``text/html``.
-
 To enable content length modification for all responses, add the
 ``debreach.middleware.RandomCommentMiddleware`` to the *start* of your
 middleware, but *after* the ``GzipMiddleware`` if you are using that.::
@@ -127,3 +57,9 @@
 then it may be easier to not use the middleware, but to selectively apply the
 ``debreach.decorators.append_random_comment`` decorator to the views you want
 protected.
+
+Python 2 and Django < 2.0 support
+---------------------------------
+
+Version 2.0.0 drops all support for Python 2 and Django < 2.0. If you need 
+support for those versions continue using ``django-debreach>=1.5.2,<2.0``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debreach-1.5.2/setup.py 
new/django-debreach-2.0.1/setup.py
--- old/django-debreach-1.5.2/setup.py  2017-12-21 18:53:44.000000000 +0100
+++ new/django-debreach-2.0.1/setup.py  2019-10-10 10:15:28.000000000 +0200
@@ -50,8 +50,8 @@
     version=version,
     url='http://github.com/lpomfrey/django-debreach',
     license='BSD',
-    description='Adds middleware and context processors to give some '
-                'protection against the BREACH attack in Django.',
+    description='Adds middleware to give some added protection against the '
+                'BREACH attack in Django.',
     author='Luke Pomfrey',
     author_email='lpomf...@gmail.com',
     packages=find_packages(exclude=('test_project', 'docs')),
@@ -67,14 +67,9 @@
         'License :: OSI Approved :: BSD License',
         'Operating System :: OS Independent',
         'Framework :: Django',
-        'Framework :: Django :: 1.8',
-        'Framework :: Django :: 1.11',
-        'Framework :: Django :: 2.0',
+        'Framework :: Django :: 2.2',
         'Programming Language :: Python',
-        'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: Implementation :: CPython',


Reply via email to