Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-debug-toolbar for 
openSUSE:Factory checked in at 2021-05-10 15:39:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-debug-toolbar (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-debug-toolbar.new.2988 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-debug-toolbar"

Mon May 10 15:39:13 2021 rev:18 rq:891926 version:3.2.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-debug-toolbar/python-django-debug-toolbar.changes
  2021-01-25 18:24:35.772513753 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-django-debug-toolbar.new.2988/python-django-debug-toolbar.changes
        2021-05-10 15:41:58.320947338 +0200
@@ -1,0 +2,6 @@
+Sun May  9 23:52:34 UTC 2021 - Daniel Molkentin <daniel.molken...@suse.com>
+
+- Update to v3.2.1 
+  * Fix CVE-2021-30459 by creating signature from all data fields
+
+-------------------------------------------------------------------

Old:
----
  django-debug-toolbar-3.2.tar.gz

New:
----
  django-debug-toolbar-3.2.1.tar.gz

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

Other differences:
------------------
++++++ python-django-debug-toolbar.spec ++++++
--- /var/tmp/diff_new_pack.gavX1D/_old  2021-05-10 15:41:58.748945664 +0200
+++ /var/tmp/diff_new_pack.gavX1D/_new  2021-05-10 15:41:58.748945664 +0200
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-django-debug-toolbar
-Version:        3.2
+Version:        3.2.1
 Release:        0
 Summary:        A configurable set of panels that display various debug 
information
 License:        BSD-3-Clause

++++++ django-debug-toolbar-3.2.tar.gz -> django-debug-toolbar-3.2.1.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/.github/workflows/test.yml 
new/django-debug-toolbar-3.2.1/.github/workflows/test.yml
--- old/django-debug-toolbar-3.2/.github/workflows/test.yml     2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/.github/workflows/test.yml   2021-04-14 
17:18:10.000000000 +0200
@@ -15,8 +15,7 @@
       mariadb:
         image: mariadb:10.3
         env:
-          MYSQL_ROOT_PASSWORD: mysql
-          MYSQL_DATABASE: mysql
+          MYSQL_ROOT_PASSWORD: debug_toolbar
         options: >-
           --health-cmd "mysqladmin ping"
           --health-interval 10s
@@ -61,11 +60,10 @@
       run: tox
       env:
         DB_BACKEND: mysql
-        DB_NAME: mysql
         DB_USER: root
-        DB_PASSWORD: mysql
-        DB_HOST: "127.0.0.1"
-        DB_PORT: "3306"
+        DB_PASSWORD: debug_toolbar
+        DB_HOST: 127.0.0.1
+        DB_PORT: 3306
 
     - name: Upload coverage
       uses: codecov/codecov-action@v1
@@ -84,7 +82,9 @@
       postgres:
         image: 'postgres:9.5'
         env:
-          POSTGRES_PASSWORD: postgres
+          POSTGRES_DB: debug_toolbar
+          POSTGRES_USER: debug_toolbar
+          POSTGRES_PASSWORD: debug_toolbar
         ports:
         - 5432:5432
         options: >-
@@ -129,9 +129,6 @@
       run: tox
       env:
         DB_BACKEND: postgresql
-        DB_NAME: postgres
-        DB_USER: postgres
-        DB_PASSWORD: postgres
         DB_HOST: localhost
         DB_PORT: 5432
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/.tx/config 
new/django-debug-toolbar-3.2.1/.tx/config
--- old/django-debug-toolbar-3.2/.tx/config     2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/.tx/config   2021-04-14 17:18:10.000000000 
+0200
@@ -2,7 +2,7 @@
 host = https://www.transifex.com
 lang_map = sr@latin:sr_Latn
 
-[django-debug-toolbar.master]
+[django-debug-toolbar.main]
 file_filter = debug_toolbar/locale/<lang>/LC_MESSAGES/django.po
 source_file = debug_toolbar/locale/en/LC_MESSAGES/django.po
 source_lang = en
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/Makefile 
new/django-debug-toolbar-3.2.1/Makefile
--- old/django-debug-toolbar-3.2/Makefile       2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/Makefile     2021-04-14 17:18:10.000000000 
+0200
@@ -8,6 +8,7 @@
        flake8
        npx eslint --ignore-path .gitignore --fix .
        npx prettier --ignore-path .gitignore --write $(PRETTIER_TARGETS)
+       ! grep -r '\(style=\|onclick=\|<script>\|<style\)' 
debug_toolbar/templates/
 
 style_check: package-lock.json
        isort -c .
@@ -15,6 +16,7 @@
        flake8
        npx eslint --ignore-path .gitignore .
        npx prettier --ignore-path .gitignore --check $(PRETTIER_TARGETS)
+       ! grep -r '\(style=\|onclick=\|<script>\|<style\)' 
debug_toolbar/templates/
 
 example:
        python example/manage.py migrate --noinput
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/README.rst 
new/django-debug-toolbar-3.2.1/README.rst
--- old/django-debug-toolbar-3.2/README.rst     2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/README.rst   2021-04-14 17:18:10.000000000 
+0200
@@ -10,7 +10,7 @@
    :target: https://github.com/jazzband/django-debug-toolbar/actions
    :alt: Build Status
 
-.. image:: 
https://codecov.io/gh/jazzband/django-debug-toolbar/branch/master/graph/badge.svg
+.. image:: 
https://codecov.io/gh/jazzband/django-debug-toolbar/branch/main/graph/badge.svg
    :target: https://codecov.io/gh/jazzband/django-debug-toolbar
    :alt: Test coverage status
 
@@ -28,13 +28,13 @@
 
 Here's a screenshot of the toolbar in action:
 
-.. image:: 
https://raw.github.com/jazzband/django-debug-toolbar/master/example/django-debug-toolbar.png
+.. image:: 
https://raw.github.com/jazzband/django-debug-toolbar/main/example/django-debug-toolbar.png
    :alt: Django Debug Toolbar screenshot
 
 In addition to the built-in panels, a number of third-party panels are
 contributed by the community.
 
-The current stable version of the Debug Toolbar is 3.2. It works on
+The current stable version of the Debug Toolbar is 3.2.1. It works on
 Django ??? 2.2.
 
 Documentation, including installation and configuration instructions, is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/__init__.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/__init__.py
--- old/django-debug-toolbar-3.2/debug_toolbar/__init__.py      2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/__init__.py    2021-04-14 
17:18:10.000000000 +0200
@@ -1,13 +1,9 @@
 __all__ = ["VERSION"]
 
 
-try:
-    import pkg_resources
-
-    VERSION = pkg_resources.get_distribution("django-debug-toolbar").version
-except Exception:
-    VERSION = "unknown"
-
+# Do not use pkg_resources to find the version but set it here directly!
+# see issue #1446
+VERSION = "3.2.1"
 
 # Code that discovers files or modules in INSTALLED_APPS imports this module.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/decorators.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/decorators.py
--- old/django-debug-toolbar-3.2/debug_toolbar/decorators.py    2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/decorators.py  2021-04-14 
17:18:10.000000000 +0200
@@ -1,6 +1,6 @@
 import functools
 
-from django.http import Http404
+from django.http import Http404, HttpResponseBadRequest
 
 
 def require_show_toolbar(view):
@@ -15,3 +15,21 @@
         return view(request, *args, **kwargs)
 
     return inner
+
+
+def signed_data_view(view):
+    """Decorator that handles unpacking a signed data form"""
+
+    @functools.wraps(view)
+    def inner(request, *args, **kwargs):
+        from debug_toolbar.forms import SignedDataForm
+
+        data = request.GET if request.method == "GET" else request.POST
+        signed_form = SignedDataForm(data)
+        if signed_form.is_valid():
+            return view(
+                request, *args, verified_data=signed_form.verified_data(), 
**kwargs
+            )
+        return HttpResponseBadRequest("Invalid signature")
+
+    return inner
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/forms.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/forms.py
--- old/django-debug-toolbar-3.2/debug_toolbar/forms.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/forms.py       2021-04-14 
17:18:10.000000000 +0200
@@ -0,0 +1,53 @@
+import json
+
+from django import forms
+from django.core import signing
+from django.core.exceptions import ValidationError
+from django.utils.encoding import force_str
+
+
+class SignedDataForm(forms.Form):
+    """Helper form that wraps a form to validate its contents on post.
+
+    class PanelForm(forms.Form):
+        # fields
+
+    On render:
+        form = SignedDataForm(initial=PanelForm(initial=data).initial)
+
+    On POST:
+        signed_form = SignedDataForm(request.POST)
+        if signed_form.is_valid():
+            panel_form = PanelForm(signed_form.verified_data)
+            if panel_form.is_valid():
+                # Success
+    Or wrap the FBV with ``debug_toolbar.decorators.signed_data_view``
+    """
+
+    salt = "django_debug_toolbar"
+    signed = forms.CharField(required=True, widget=forms.HiddenInput)
+
+    def __init__(self, *args, **kwargs):
+        initial = kwargs.pop("initial", None)
+        if initial:
+            initial = {"signed": self.sign(initial)}
+        super().__init__(*args, initial=initial, **kwargs)
+
+    def clean_signed(self):
+        try:
+            verified = json.loads(
+                
signing.Signer(salt=self.salt).unsign(self.cleaned_data["signed"])
+            )
+            return verified
+        except signing.BadSignature:
+            raise ValidationError("Bad signature")
+
+    def verified_data(self):
+        return self.is_valid() and self.cleaned_data["signed"]
+
+    @classmethod
+    def sign(cls, data):
+        items = sorted(data.items(), key=lambda item: item[0])
+        return signing.Signer(salt=cls.salt).sign(
+            json.dumps({key: force_str(value) for key, value in items})
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/middleware.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/middleware.py
--- old/django-debug-toolbar-3.2/debug_toolbar/middleware.py    2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/middleware.py  2021-04-14 
17:18:10.000000000 +0200
@@ -44,7 +44,7 @@
     def __call__(self, request):
         # Decide whether the toolbar is active for this request.
         show_toolbar = get_show_toolbar()
-        if not show_toolbar(request) or request.path.startswith("/__debug__/"):
+        if not show_toolbar(request) or 
DebugToolbar.is_toolbar_request(request):
             return self.get_response(request)
 
         toolbar = DebugToolbar(request, self.get_response)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/cache.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/cache.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/cache.py  2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/cache.py        
2021-04-14 17:18:10.000000000 +0200
@@ -3,9 +3,19 @@
 import time
 from collections import OrderedDict
 
+try:
+    from django.utils.connection import ConnectionProxy
+except ImportError:
+    ConnectionProxy = None
+
 from django.conf import settings
 from django.core import cache
-from django.core.cache import CacheHandler, caches as original_caches
+from django.core.cache import (
+    DEFAULT_CACHE_ALIAS,
+    CacheHandler,
+    cache as original_cache,
+    caches as original_caches,
+)
 from django.core.cache.backends.base import BaseCache
 from django.dispatch import Signal
 from django.middleware import cache as middleware_cache
@@ -246,8 +256,13 @@
         else:
             cache.caches = CacheHandlerPatch()
 
+        # Wrap the patched cache inside Django's ConnectionProxy
+        if ConnectionProxy:
+            cache.cache = ConnectionProxy(cache.caches, DEFAULT_CACHE_ALIAS)
+
     def disable_instrumentation(self):
         cache.caches = original_caches
+        cache.cache = original_cache
         # While it can be restored to the original, any views that were
         # wrapped with the cache_page decorator will continue to use a
         # monkey patched cache.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/history/forms.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/forms.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/history/forms.py  
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/forms.py        
2021-04-14 17:18:10.000000000 +0200
@@ -1,11 +1,4 @@
-import hashlib
-import hmac
-
 from django import forms
-from django.conf import settings
-from django.core.exceptions import ValidationError
-from django.utils.crypto import constant_time_compare
-from django.utils.encoding import force_bytes
 
 
 class HistoryStoreForm(forms.Form):
@@ -16,26 +9,3 @@
     """
 
     store_id = forms.CharField(widget=forms.HiddenInput())
-    hash = forms.CharField(widget=forms.HiddenInput())
-
-    def __init__(self, *args, **kwargs):
-        initial = kwargs.get("initial", None)
-
-        if initial is not None:
-            initial["hash"] = self.make_hash(initial)
-
-        super().__init__(*args, **kwargs)
-
-    @staticmethod
-    def make_hash(data):
-        m = hmac.new(key=force_bytes(settings.SECRET_KEY), 
digestmod=hashlib.sha1)
-        m.update(force_bytes(data["store_id"]))
-        return m.hexdigest()
-
-    def clean_hash(self):
-        hash = self.cleaned_data["hash"]
-
-        if not constant_time_compare(hash, self.make_hash(self.data)):
-            raise ValidationError("Tamper alert")
-
-        return hash
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/history/panel.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/panel.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/history/panel.py  
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/panel.py        
2021-04-14 17:18:10.000000000 +0200
@@ -8,6 +8,7 @@
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 
+from debug_toolbar.forms import SignedDataForm
 from debug_toolbar.panels import Panel
 from debug_toolbar.panels.history import views
 from debug_toolbar.panels.history.forms import HistoryStoreForm
@@ -76,7 +77,9 @@
         for id, toolbar in reversed(self.toolbar._store.items()):
             stores[id] = {
                 "toolbar": toolbar,
-                "form": HistoryStoreForm(initial={"store_id": id}),
+                "form": SignedDataForm(
+                    initial=HistoryStoreForm(initial={"store_id": id}).initial
+                ),
             }
 
         return render_to_string(
@@ -84,8 +87,10 @@
             {
                 "current_store_id": self.toolbar.store_id,
                 "stores": stores,
-                "refresh_form": HistoryStoreForm(
-                    initial={"store_id": self.toolbar.store_id}
+                "refresh_form": SignedDataForm(
+                    initial=HistoryStoreForm(
+                        initial={"store_id": self.toolbar.store_id}
+                    ).initial
                 ),
             },
         )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/history/views.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/views.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/history/views.py  
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/history/views.py        
2021-04-14 17:18:10.000000000 +0200
@@ -1,15 +1,16 @@
 from django.http import HttpResponseBadRequest, JsonResponse
 from django.template.loader import render_to_string
 
-from debug_toolbar.decorators import require_show_toolbar
+from debug_toolbar.decorators import require_show_toolbar, signed_data_view
 from debug_toolbar.panels.history.forms import HistoryStoreForm
 from debug_toolbar.toolbar import DebugToolbar
 
 
 @require_show_toolbar
-def history_sidebar(request):
+@signed_data_view
+def history_sidebar(request, verified_data):
     """Returns the selected debug toolbar history snapshot."""
-    form = HistoryStoreForm(request.GET)
+    form = HistoryStoreForm(verified_data)
 
     if form.is_valid():
         store_id = form.cleaned_data["store_id"]
@@ -32,9 +33,10 @@
 
 
 @require_show_toolbar
-def history_refresh(request):
+@signed_data_view
+def history_refresh(request, verified_data):
     """Returns the refreshed list of table rows for the History Panel."""
-    form = HistoryStoreForm(request.GET)
+    form = HistoryStoreForm(verified_data)
 
     if form.is_valid():
         requests = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/request.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/request.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/request.py        
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/request.py      
2021-04-14 17:18:10.000000000 +0200
@@ -44,7 +44,16 @@
             view_info["view_func"] = get_name_from_obj(func)
             view_info["view_args"] = args
             view_info["view_kwargs"] = kwargs
-            view_info["view_urlname"] = getattr(match, "url_name", 
_("<unavailable>"))
+
+            if getattr(match, "url_name", False):
+                url_name = match.url_name
+                if match.namespaces:
+                    url_name = ":".join([*match.namespaces, url_name])
+            else:
+                url_name = _("<unavailable>")
+
+            view_info["view_urlname"] = url_name
+
         except Http404:
             pass
         self.record_stats(view_info)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/forms.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/forms.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/forms.py      
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/forms.py    
2021-04-14 17:18:10.000000000 +0200
@@ -1,13 +1,8 @@
-import hashlib
-import hmac
 import json
 
 from django import forms
-from django.conf import settings
 from django.core.exceptions import ValidationError
 from django.db import connections
-from django.utils.crypto import constant_time_compare
-from django.utils.encoding import force_bytes
 from django.utils.functional import cached_property
 
 from debug_toolbar.panels.sql.utils import reformat_sql
@@ -21,7 +16,6 @@
         raw_sql: The sql statement with placeholders
         params: JSON encoded parameter values
         duration: time for SQL to execute passed in from toolbar just for 
redisplay
-        hash: the hash of (secret + sql + params) for tamper checking
     """
 
     sql = forms.CharField()
@@ -29,17 +23,6 @@
     params = forms.CharField()
     alias = forms.CharField(required=False, initial="default")
     duration = forms.FloatField()
-    hash = forms.CharField()
-
-    def __init__(self, *args, **kwargs):
-        initial = kwargs.get("initial")
-        if initial is not None:
-            initial["hash"] = self.make_hash(initial)
-
-        super().__init__(*args, **kwargs)
-
-        for name in self.fields:
-            self.fields[name].widget = forms.HiddenInput()
 
     def clean_raw_sql(self):
         value = self.cleaned_data["raw_sql"]
@@ -65,23 +48,9 @@
 
         return value
 
-    def clean_hash(self):
-        hash = self.cleaned_data["hash"]
-
-        if not constant_time_compare(hash, self.make_hash(self.data)):
-            raise ValidationError("Tamper alert")
-
-        return hash
-
     def reformat_sql(self):
         return reformat_sql(self.cleaned_data["sql"], with_toggle=False)
 
-    def make_hash(self, data):
-        m = hmac.new(key=force_bytes(settings.SECRET_KEY), 
digestmod=hashlib.sha1)
-        for item in [data["sql"], data["params"]]:
-            m.update(force_bytes(item))
-        return m.hexdigest()
-
     @property
     def connection(self):
         return connections[self.cleaned_data["alias"]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/panel.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/panel.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/panel.py      
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/panel.py    
2021-04-14 17:18:10.000000000 +0200
@@ -7,6 +7,7 @@
 from django.urls import path
 from django.utils.translation import gettext_lazy as _, ngettext_lazy as __
 
+from debug_toolbar.forms import SignedDataForm
 from debug_toolbar.panels import Panel
 from debug_toolbar.panels.sql import views
 from debug_toolbar.panels.sql.forms import SQLSelectForm
@@ -211,7 +212,9 @@
                         query["vendor"], query["trans_status"]
                     )
 
-                query["form"] = SQLSelectForm(auto_id=None, 
initial=copy(query))
+                query["form"] = SignedDataForm(
+                    auto_id=None, 
initial=SQLSelectForm(initial=copy(query)).initial
+                )
 
                 if query["sql"]:
                     query["sql"] = reformat_sql(query["sql"], with_toggle=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/utils.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/utils.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/utils.py      
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/utils.py    
2021-04-14 17:18:10.000000000 +0200
@@ -4,6 +4,8 @@
 from django.utils.html import escape
 from sqlparse import tokens as T
 
+from debug_toolbar import settings as dt_settings
+
 
 class BoldKeywordFilter:
     """sqlparse filter to bold SQL keywords"""
@@ -31,7 +33,8 @@
 
 def parse_sql(sql, aligned_indent=False):
     stack = sqlparse.engine.FilterStack()
-    stack.enable_grouping()
+    if dt_settings.get_config()["PRETTIFY_SQL"]:
+        stack.enable_grouping()
     if aligned_indent:
         stack.stmtprocess.append(
             sqlparse.filters.AlignedIndentFilter(char="&nbsp;", n="<br/>")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/views.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/views.py
--- old/django-debug-toolbar-3.2/debug_toolbar/panels/sql/views.py      
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/panels/sql/views.py    
2021-04-14 17:18:10.000000000 +0200
@@ -2,15 +2,16 @@
 from django.template.loader import render_to_string
 from django.views.decorators.csrf import csrf_exempt
 
-from debug_toolbar.decorators import require_show_toolbar
+from debug_toolbar.decorators import require_show_toolbar, signed_data_view
 from debug_toolbar.panels.sql.forms import SQLSelectForm
 
 
 @csrf_exempt
 @require_show_toolbar
-def sql_select(request):
+@signed_data_view
+def sql_select(request, verified_data):
     """Returns the output of the SQL SELECT statement"""
-    form = SQLSelectForm(request.POST or None)
+    form = SQLSelectForm(verified_data)
 
     if form.is_valid():
         sql = form.cleaned_data["raw_sql"]
@@ -34,9 +35,10 @@
 
 @csrf_exempt
 @require_show_toolbar
-def sql_explain(request):
+@signed_data_view
+def sql_explain(request, verified_data):
     """Returns the output of the SQL EXPLAIN on the given query"""
-    form = SQLSelectForm(request.POST or None)
+    form = SQLSelectForm(verified_data)
 
     if form.is_valid():
         sql = form.cleaned_data["raw_sql"]
@@ -69,9 +71,10 @@
 
 @csrf_exempt
 @require_show_toolbar
-def sql_profile(request):
+@signed_data_view
+def sql_profile(request, verified_data):
     """Returns the output of running the SQL and getting the profiling 
statistics"""
-    form = SQLSelectForm(request.POST or None)
+    form = SQLSelectForm(verified_data)
 
     if form.is_valid():
         sql = form.cleaned_data["raw_sql"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/settings.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/settings.py
--- old/django-debug-toolbar-3.2/debug_toolbar/settings.py      2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/settings.py    2021-04-14 
17:18:10.000000000 +0200
@@ -37,6 +37,7 @@
         "django.utils.deprecation",
         "django.utils.functional",
     ),
+    "PRETTIFY_SQL": True,
     "PROFILER_MAX_DEPTH": 10,
     "SHOW_TEMPLATE_CONTEXT": True,
     "SKIP_TEMPLATE_PREFIXES": ("django/forms/widgets/", "admin/widgets/"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/css/toolbar.css 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/css/toolbar.css
--- 
old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/css/toolbar.css 
    2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/css/toolbar.css
   2021-04-14 17:18:10.000000000 +0200
@@ -601,6 +601,9 @@
 #djDebug .djdt-width-60 {
     width: 60%;
 }
+#djDebug .djdt-max-height-100 {
+    max-height: 100%;
+}
 #djDebug .djdt-highlighted {
     background-color: lightgrey;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/js/toolbar.js 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/js/toolbar.js
--- 
old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/js/toolbar.js   
    2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/js/toolbar.js 
    2021-04-14 17:18:10.000000000 +0200
@@ -44,6 +44,7 @@
                             inner.previousElementSibling.remove(); // Remove 
AJAX loader
                             inner.innerHTML = data.content;
                             $$.executeScripts(data.scripts);
+                            $$.applyStyles(inner);
                         });
                     }
                 }
@@ -270,6 +271,9 @@
                 options.path ? "; path=" + options.path : "",
                 options.domain ? "; domain=" + options.domain : "",
                 options.secure ? "; secure" : "",
+                "sameSite" in options
+                    ? "; sameSite=" + options.samesite
+                    : "; sameSite=Lax",
             ].join("");
 
             return value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/js/utils.js 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/js/utils.js
--- old/django-debug-toolbar-3.2/debug_toolbar/static/debug_toolbar/js/utils.js 
2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/static/debug_toolbar/js/utils.js   
    2021-04-14 17:18:10.000000000 +0200
@@ -32,6 +32,26 @@
             document.head.appendChild(el);
         });
     },
+    applyStyles(container) {
+        /*
+         * Given a container element, apply styles set via data-djdt-styles 
attribute.
+         * The format is data-djdt-styles="styleName1:value;styleName2:value2"
+         * The style names should use the CSSStyleDeclaration camel cased 
names.
+         */
+        container
+            .querySelectorAll("[data-djdt-styles]")
+            .forEach(function (element) {
+                const styles = element.dataset.djdtStyles || "";
+                styles.split(";").forEach(function (styleText) {
+                    const styleKeyPair = styleText.split(":");
+                    if (styleKeyPair.length === 2) {
+                        const name = styleKeyPair[0].trim();
+                        const value = styleKeyPair[1].trim();
+                        element.style[name] = value;
+                    }
+                });
+            });
+    },
 };
 
 function ajax(url, init) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/history.html
 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/history.html
--- 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/history.html
      2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/history.html
    2021-04-14 17:18:10.000000000 +0200
@@ -3,7 +3,7 @@
     {{ refresh_form }}
     <button class="refreshHistory">Refresh</button>
 </form>
-<table style="max-height:100%;">
+<table class="djdt-max-height-100">
     <thead>
         <tr>
             <th>{% trans "Time" %}</th>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/profiling.html
 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/profiling.html
--- 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/profiling.html
    2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/profiling.html
  2021-04-14 17:18:10.000000000 +0200
@@ -14,7 +14,7 @@
     {% for call in func_list %}
       <tr class="{% for parent_id in call.parent_ids %} djToggleDetails_{{ 
parent_id }}{% endfor %}" id="profilingMain_{{ call.id }}">
         <td>
-          <div style="padding-left:{{ call.indent }}px">
+          <div data-djdt-styles="paddingLeft:{{ call.indent }}px">
             {% if call.has_subfuncs %}
               <button type="button" class="djProfileToggleDetails 
djToggleSwitch" data-toggle-name="profilingMain" data-toggle-id="{{ call.id 
}}">-</button>
             {% else %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/sql.html
 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/sql.html
--- 
old/django-debug-toolbar-3.2/debug_toolbar/templates/debug_toolbar/panels/sql.html
  2020-12-03 09:11:15.000000000 +0100
+++ 
new/django-debug-toolbar-3.2.1/debug_toolbar/templates/debug_toolbar/panels/sql.html
        2021-04-14 17:18:10.000000000 +0200
@@ -2,7 +2,7 @@
 <ul>
   {% for alias, info in databases %}
     <li>
-      <strong><span class="djdt-color" style="background-color:rgb({{ 
info.rgb_color|join:', ' }})"></span> {{ alias }}</strong>
+      <strong><span class="djdt-color" 
data-djdt-styles="backgroundColor:rgb({{ info.rgb_color|join:', ' }})"></span> 
{{ alias }}</strong>
       {{ info.time_spent|floatformat:"2" }} ms ({% blocktrans count 
info.num_queries as num %}{{ num }} query{% plural %}{{ num }} queries{% 
endblocktrans %}
       {% if info.similar_count %}
         {% blocktrans with count=info.similar_count trimmed %}
@@ -40,7 +40,7 @@
     <tbody>
       {% for query in queries %}
         <tr class="{% if query.is_slow %} djDebugRowWarning{% endif %}" 
id="sqlMain_{{ forloop.counter }}">
-          <td><span class="djdt-color" style="background-color:rgb({{ 
query.rgb_color|join:', '}})"></span></td>
+          <td><span class="djdt-color" 
data-djdt-styles="backgroundColor:rgb({{ query.rgb_color|join:', 
'}})"></span></td>
           <td class="djdt-toggle">
             <button type="button" class="djToggleSwitch" 
data-toggle-name="sqlMain" data-toggle-id="{{ forloop.counter }}">+</button>
           </td>
@@ -48,13 +48,13 @@
             <div class="djDebugSql">{{ query.sql|safe }}</div>
             {% if query.similar_count %}
               <strong>
-                <span class="djdt-color" style="background-color:{{ 
query.similar_color }}"></span>
+                <span class="djdt-color" data-djdt-styles="backgroundColor:{{ 
query.similar_color }}"></span>
                 {% blocktrans with count=query.similar_count %}{{ count }} 
similar queries.{% endblocktrans %}
               </strong>
             {% endif %}
             {% if query.duplicate_count %}
               <strong>
-                <span class="djdt-color" style="background-color:{{ 
query.duplicate_color }}"></span>
+                <span class="djdt-color" data-djdt-styles="backgroundColor:{{ 
query.duplicate_color }}"></span>
                 {% blocktrans with dupes=query.duplicate_count %}Duplicated {{ 
dupes }} times.{% endblocktrans %}
               </strong>
             {% endif %}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/debug_toolbar/toolbar.py 
new/django-debug-toolbar-3.2.1/debug_toolbar/toolbar.py
--- old/django-debug-toolbar-3.2/debug_toolbar/toolbar.py       2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/debug_toolbar/toolbar.py     2021-04-14 
17:18:10.000000000 +0200
@@ -9,7 +9,8 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.template import TemplateSyntaxError
 from django.template.loader import render_to_string
-from django.urls import path
+from django.urls import path, resolve
+from django.urls.exceptions import Resolver404
 from django.utils.module_loading import import_string
 
 from debug_toolbar import settings as dt_settings
@@ -133,6 +134,19 @@
             cls._urlpatterns = urlpatterns
         return cls._urlpatterns
 
+    @classmethod
+    def is_toolbar_request(cls, request):
+        """
+        Determine if the request is for a DebugToolbar view.
+        """
+        # The primary caller of this function is in the middleware which may
+        # not have resolver_match set.
+        try:
+            resolver_match = request.resolver_match or resolve(request.path)
+        except Resolver404:
+            return False
+        return resolver_match.namespaces and resolver_match.namespaces[-1] == 
app_name
+
 
 app_name = "djdt"
 urlpatterns = DebugToolbar.get_urls()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/changes.rst 
new/django-debug-toolbar-3.2.1/docs/changes.rst
--- old/django-debug-toolbar-3.2/docs/changes.rst       2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/docs/changes.rst     2021-04-14 
17:18:10.000000000 +0200
@@ -1,6 +1,24 @@
 Change log
 ==========
 
+Next version
+------------
+
+
+3.2.1 (2021-04-14)
+------------------
+
+* Fixed SQL Injection vulnerability, CVE-2021-30459. The toolbar now
+  calculates a signature on all fields for the SQL select, explain,
+  and analyze forms.
+* Changed ``djdt.cookie.set()`` to set ``sameSite=Lax`` by default if
+  callers do not provide a value.
+* Added ``PRETTIFY_SQL`` configuration option to support controlling
+  SQL token grouping. By default it's set to True. When set to False,
+  a performance improvement can be seen by the SQL panel.
+* Fixed issue with toolbar expecting URL paths to start with `/__debug__/`
+  while the documentation indicates it's not required.
+
 3.2 (2020-12-03)
 ----------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/conf.py 
new/django-debug-toolbar-3.2.1/docs/conf.py
--- old/django-debug-toolbar-3.2/docs/conf.py   2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/docs/conf.py 2021-04-14 17:18:10.000000000 
+0200
@@ -25,7 +25,7 @@
 copyright = copyright.format(datetime.date.today().year)
 
 # The full version, including alpha/beta/rc tags
-release = "3.2"
+release = "3.2.1"
 
 
 # -- General configuration ---------------------------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/configuration.rst 
new/django-debug-toolbar-3.2.1/docs/configuration.rst
--- old/django-debug-toolbar-3.2/docs/configuration.rst 2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/docs/configuration.rst       2021-04-14 
17:18:10.000000000 +0200
@@ -180,6 +180,39 @@
   Useful for eliminating server-related entries which can result
   in enormous DOM structures and toolbar rendering delays.
 
+* ``PRETTIFY_SQL``
+
+  Default: ``True``
+
+  Panel: SQL
+
+  Controls SQL token grouping.
+
+  Token grouping allows pretty print of similar tokens,
+  like aligned indentation for every selected field.
+
+  When set to ``True``, it might cause render slowdowns
+  when a view make long SQL textual queries.
+
+  **Without grouping**::
+
+    SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", 
"auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", 
"auth_user"."last_name"
+    FROM "auth_user"
+    WHERE "auth_user"."username" = '''test_username'''
+    LIMIT 21
+
+  **With grouping**::
+
+    SELECT "auth_user"."id",
+       "auth_user"."password",
+       "auth_user"."last_login",
+       "auth_user"."is_superuser",
+       "auth_user"."username",
+       "auth_user"."first_name",
+       "auth_user"."last_name",
+      FROM "auth_user"
+    WHERE "auth_user"."username" = '''test_username'''
+    LIMIT 21
 
 * ``PROFILER_MAX_DEPTH``
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/contributing.rst 
new/django-debug-toolbar-3.2.1/docs/contributing.rst
--- old/django-debug-toolbar-3.2/docs/contributing.rst  2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/docs/contributing.rst        2021-04-14 
17:18:10.000000000 +0200
@@ -53,7 +53,7 @@
 
 Once you've set up a development environment as explained above, you can run
 the test suite for the versions of Django and Python installed in that
-environment::
+environment using the SQLite database::
 
     $ make test
 
@@ -79,8 +79,23 @@
     $ DJANGO_SELENIUM_TESTS=true make coverage
     $ DJANGO_SELENIUM_TESTS=true tox
 
-At this time, there isn't an easy way to test against databases other than
-SQLite.
+To test via `tox` against other databases, you'll need to create the user,
+database and assign the proper permissions. For PostgreSQL in a `psql`
+shell (note this allows the debug_toolbar user the permission to create
+databases)::
+
+    psql> CREATE USER debug_toolbar WITH PASSWORD 'debug_toolbar';
+    psql> ALTER USER debug_toolbar CREATEDB;
+    psql> CREATE DATABASE debug_toolbar;
+    psql> GRANT ALL PRIVILEGES ON DATABASE debug_toolbar to debug_toolbar;
+
+For MySQL/MariaDB in a `mysql` shell::
+
+    mysql> CREATE DATABASE debug_toolbar;
+    mysql> CREATE USER 'debug_toolbar'@'localhost' IDENTIFIED BY 
'debug_toolbar';
+    mysql> GRANT ALL PRIVILEGES ON debug_toolbar.* TO 
'debug_toolbar'@'localhost';
+    mysql> GRANT ALL PRIVILEGES ON test_debug_toolbar.* TO 
'debug_toolbar'@'localhost';
+
 
 Style
 -----
@@ -141,8 +156,8 @@
    Commit.
 
 #. Bump version numbers in ``docs/changes.rst``, ``docs/conf.py``,
-   ``README.rst`` and ``setup.py``. Add the release date to
-   ``docs/changes.rst``. Commit.
+   ``README.rst``, ``debug_toolbar/__init__.py`` and ``setup.py``.
+   Add the release date to ``docs/changes.rst``. Commit.
 
 #. Tag the new version.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/installation.rst 
new/django-debug-toolbar-3.2.1/docs/installation.rst
--- old/django-debug-toolbar-3.2/docs/installation.rst  2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/docs/installation.rst        2021-04-14 
17:18:10.000000000 +0200
@@ -83,8 +83,8 @@
 ------------------------
 
 The Debug Toolbar is shown only if your IP address is listed in the
-:django:setting:`INTERNAL_IPS` setting.  This means that for local
-development, you *must* add ``'127.0.0.1'`` to :django:setting:`INTERNAL_IPS`;
+:setting:`INTERNAL_IPS` setting.  This means that for local
+development, you *must* add ``'127.0.0.1'`` to :setting:`INTERNAL_IPS`;
 you'll need to create this setting if it doesn't already exist in your
 settings module::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/docs/panels.rst 
new/django-debug-toolbar-3.2.1/docs/panels.rst
--- old/django-debug-toolbar-3.2/docs/panels.rst        2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/docs/panels.rst      2021-04-14 
17:18:10.000000000 +0200
@@ -177,6 +177,18 @@
 Inspector panel also logs to the console by default, but may be instructed not
 to.
 
+LDAP Tracing
+~~~~~~~~~~~~
+
+URL: https://github.com/danyi1212/django-windowsauth
+
+Path: ``windows_auth.panels.LDAPPanel``
+
+LDAP Operations performed during the request, including timing, request and 
response messages, 
+the entries received, write changes list, stack-tracing and error debugging.
+This panel also shows connection usage metrics when it is collected. 
+`Check out the docs 
<https://django-windowsauth.readthedocs.io/en/latest/howto/debug_toolbar.html>`_.
+
 Line Profiler
 ~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/example/settings.py 
new/django-debug-toolbar-3.2.1/example/settings.py
--- old/django-debug-toolbar-3.2/example/settings.py    2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/example/settings.py  2021-04-14 
17:18:10.000000000 +0200
@@ -73,26 +73,23 @@
 
 # To use another database, set the DB_BACKEND environment variable.
 if os.environ.get("DB_BACKEND", "").lower() == "postgresql":
-    # % su postgres
-    # % createuser debug_toolbar
-    # % createdb debug_toolbar -O debug_toolbar
+    # See docs/contributing for instructions on configuring PostgreSQL.
     DATABASES = {
         "default": {
             "ENGINE": "django.db.backends.postgresql",
             "NAME": "debug_toolbar",
             "USER": "debug_toolbar",
+            "PASSWORD": "debug_toolbar",
         }
     }
 if os.environ.get("DB_BACKEND", "").lower() == "mysql":
-    # % mysql
-    # mysql> CREATE DATABASE debug_toolbar;
-    # mysql> CREATE USER 'debug_toolbar'@'localhost';
-    # mysql> GRANT ALL PRIVILEGES ON debug_toolbar.* TO 
'debug_toolbar'@'localhost';
+    # See docs/contributing for instructions on configuring MySQL/MariaDB.
     DATABASES = {
         "default": {
             "ENGINE": "django.db.backends.mysql",
             "NAME": "debug_toolbar",
             "USER": "debug_toolbar",
+            "PASSWORD": "debug_toolbar",
         }
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/setup.cfg 
new/django-debug-toolbar-3.2.1/setup.cfg
--- old/django-debug-toolbar-3.2/setup.cfg      2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/setup.cfg    2021-04-14 17:18:10.000000000 
+0200
@@ -1,6 +1,6 @@
 [metadata]
 name = django-debug-toolbar
-version = 3.2
+version = 3.2.1
 description = A configurable set of panels that display various debug 
information about the current request/response.
 long_description = file: README.rst
 author = Rob Hudson
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/tests/panels/test_history.py 
new/django-debug-toolbar-3.2.1/tests/panels/test_history.py
--- old/django-debug-toolbar-3.2/tests/panels/test_history.py   2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/panels/test_history.py 2021-04-14 
17:18:10.000000000 +0200
@@ -1,9 +1,7 @@
-from unittest.mock import patch
-
 from django.test import RequestFactory, override_settings
 from django.urls import resolve, reverse
 
-from debug_toolbar.panels.history.forms import HistoryStoreForm
+from debug_toolbar.forms import SignedDataForm
 from debug_toolbar.toolbar import DebugToolbar
 
 from ..base import BaseTestCase, IntegrationTestCase
@@ -83,33 +81,15 @@
         response = self.client.get(reverse("djdt:history_sidebar"))
         self.assertEqual(response.status_code, 400)
 
-        data = {
-            "store_id": "foo",
-            "hash": "invalid",
-        }
+        data = {"signed": SignedDataForm.sign({"store_id": "foo"}) + "invalid"}
         response = self.client.get(reverse("djdt:history_sidebar"), data=data)
         self.assertEqual(response.status_code, 400)
 
-    @patch("debug_toolbar.panels.history.views.DebugToolbar.fetch")
-    def test_history_sidebar_hash(self, fetch):
-        """Validate the hashing mechanism."""
-        fetch.return_value.panels = []
-        data = {
-            "store_id": "foo",
-            "hash": "3280d66a3cca10098a44907c5a1fd255265eed31",
-        }
-        response = self.client.get(reverse("djdt:history_sidebar"), data=data)
-        self.assertEqual(response.status_code, 200)
-        self.assertEqual(response.json(), {})
-
     def test_history_sidebar(self):
         """Validate the history sidebar view."""
         self.client.get("/json_view/")
         store_id = list(DebugToolbar._store.keys())[0]
-        data = {
-            "store_id": store_id,
-            "hash": HistoryStoreForm.make_hash({"store_id": store_id}),
-        }
+        data = {"signed": SignedDataForm.sign({"store_id": store_id})}
         response = self.client.get(reverse("djdt:history_sidebar"), data=data)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(
@@ -130,25 +110,20 @@
             },
         )
 
-    def test_history_refresh_invalid(self):
+    def test_history_refresh_invalid_signature(self):
         response = self.client.get(reverse("djdt:history_refresh"))
         self.assertEqual(response.status_code, 400)
 
-        data = {
-            "store_id": "foo",
-            "hash": "invalid",
-        }
+        data = {"signed": 
"eyJzdG9yZV9pZCI6ImZvbyIsImhhc2giOiI4YWFiMzIzZGZhODIyMW"}
         response = self.client.get(reverse("djdt:history_refresh"), data=data)
         self.assertEqual(response.status_code, 400)
+        self.assertEqual(b"Invalid signature", response.content)
 
     def test_history_refresh(self):
         """Verify refresh history response has request variables."""
         data = {"foo": "bar"}
         self.client.get("/json_view/", data, content_type="application/json")
-        data = {
-            "store_id": "foo",
-            "hash": "3280d66a3cca10098a44907c5a1fd255265eed31",
-        }
+        data = {"signed": SignedDataForm.sign({"store_id": "foo"})}
         response = self.client.get(reverse("djdt:history_refresh"), data=data)
         self.assertEqual(response.status_code, 200)
         data = response.json()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/tests/panels/test_request.py 
new/django-debug-toolbar-3.2.1/tests/panels/test_request.py
--- old/django-debug-toolbar-3.2/tests/panels/test_request.py   2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/panels/test_request.py 2021-04-14 
17:18:10.000000000 +0200
@@ -84,3 +84,10 @@
         content = self.panel.content
         self.assertIn("foo", content)
         self.assertIn("bar", content)
+
+    def test_namespaced_url(self):
+        self.request.path = "/admin/login/"
+        response = self.panel.process_request(self.request)
+        self.panel.generate_stats(self.request, response)
+        panel_stats = self.panel.get_stats()
+        self.assertEqual(panel_stats["view_urlname"], "admin:login")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/panels/test_sql.py 
new/django-debug-toolbar-3.2.1/tests/panels/test_sql.py
--- old/django-debug-toolbar-3.2/tests/panels/test_sql.py       2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/panels/test_sql.py     2021-04-14 
17:18:10.000000000 +0200
@@ -9,6 +9,8 @@
 from django.shortcuts import render
 from django.test.utils import override_settings
 
+from debug_toolbar import settings as dt_settings
+
 from ..base import BaseTestCase
 
 try:
@@ -357,3 +359,40 @@
 
         # ensure the stacktrace is populated
         self.assertTrue(len(query[1]["stacktrace"]) > 0)
+
+    @override_settings(
+        DEBUG_TOOLBAR_CONFIG={"PRETTIFY_SQL": True},
+    )
+    def test_prettify_sql(self):
+        """
+        Test case to validate that the PRETTIFY_SQL setting changes the output
+        of the sql when it's toggled. It does not validate what it does
+        though.
+        """
+        list(User.objects.filter(username__istartswith="spam"))
+
+        response = self.panel.process_request(self.request)
+        self.panel.generate_stats(self.request, response)
+        pretty_sql = self.panel._queries[-1][1]["sql"]
+        self.assertEqual(len(self.panel._queries), 1)
+
+        # Reset the queries
+        self.panel._queries = []
+        # Run it again, but with prettyify off. Verify that it's different.
+        dt_settings.get_config()["PRETTIFY_SQL"] = False
+        list(User.objects.filter(username__istartswith="spam"))
+        response = self.panel.process_request(self.request)
+        self.panel.generate_stats(self.request, response)
+        self.assertEqual(len(self.panel._queries), 1)
+        self.assertNotEqual(pretty_sql, self.panel._queries[-1][1]["sql"])
+
+        self.panel._queries = []
+        # Run it again, but with prettyify back on.
+        # This is so we don't have to check what PRETTIFY_SQL does exactly,
+        # but we know it's doing something.
+        dt_settings.get_config()["PRETTIFY_SQL"] = True
+        list(User.objects.filter(username__istartswith="spam"))
+        response = self.panel.process_request(self.request)
+        self.panel.generate_stats(self.request, response)
+        self.assertEqual(len(self.panel._queries), 1)
+        self.assertEqual(pretty_sql, self.panel._queries[-1][1]["sql"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-debug-toolbar-3.2/tests/panels/test_staticfiles.py 
new/django-debug-toolbar-3.2.1/tests/panels/test_staticfiles.py
--- old/django-debug-toolbar-3.2/tests/panels/test_staticfiles.py       
2020-12-03 09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/panels/test_staticfiles.py     
2021-04-14 17:18:10.000000000 +0200
@@ -1,13 +1,11 @@
 import os
+import unittest
 
+import django
 from django.conf import settings
 from django.contrib.staticfiles import finders
-from django.core.checks import Warning
-from django.test import SimpleTestCase
 from django.test.utils import override_settings
 
-from debug_toolbar.panels.staticfiles import StaticFilesPanel
-
 from ..base import BaseTestCase
 
 PATH_DOES_NOT_EXIST = os.path.join(settings.BASE_DIR, "tests", 
"invalid_static")
@@ -54,6 +52,7 @@
         )
         self.assertValidHTML(content)
 
+    @unittest.skipIf(django.VERSION >= (4,), "Django>=4 handles missing dirs 
itself.")
     @override_settings(
         STATICFILES_DIRS=[PATH_DOES_NOT_EXIST] + settings.STATICFILES_DIRS,
         STATIC_ROOT=PATH_DOES_NOT_EXIST,
@@ -81,20 +80,3 @@
         self.assertEqual(
             self.panel.get_staticfiles_dirs(), 
finders.FileSystemFinder().locations
         )
-
-
-@override_settings(DEBUG=True)
-class StaticFilesPanelChecksTestCase(SimpleTestCase):
-    @override_settings(STATICFILES_DIRS=[PATH_DOES_NOT_EXIST])
-    def test_run_checks(self):
-        messages = StaticFilesPanel.run_checks()
-        self.assertEqual(
-            messages,
-            [
-                Warning(
-                    "debug_toolbar requires the STATICFILES_DIRS directories 
to exist.",
-                    hint="Running manage.py collectstatic may help uncover the 
issue.",
-                    id="debug_toolbar.staticfiles.W001",
-                )
-            ],
-        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/settings.py 
new/django-debug-toolbar-3.2.1/tests/settings.py
--- old/django-debug-toolbar-3.2/tests/settings.py      2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/settings.py    2021-04-14 
17:18:10.000000000 +0200
@@ -81,8 +81,8 @@
 
 DATABASES = {
     "default": {
-        "ENGINE": "django.db.backends.%s" % os.getenv("DB_BACKEND"),
-        "NAME": os.getenv("DB_NAME"),
+        "ENGINE": "django.db.backends.%s" % os.getenv("DB_BACKEND", "sqlite3"),
+        "NAME": os.getenv("DB_NAME", ":memory:"),
         "USER": os.getenv("DB_USER"),
         "PASSWORD": os.getenv("DB_PASSWORD"),
         "HOST": os.getenv("DB_HOST", ""),
@@ -93,6 +93,8 @@
     },
 }
 
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
+
 # Debug Toolbar configuration
 
 DEBUG_TOOLBAR_CONFIG = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/test_checks.py 
new/django-debug-toolbar-3.2.1/tests/test_checks.py
--- old/django-debug-toolbar-3.2/tests/test_checks.py   2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/test_checks.py 2021-04-14 
17:18:10.000000000 +0200
@@ -1,5 +1,7 @@
 import os
+import unittest
 
+import django
 from django.conf import settings
 from django.core.checks import Warning, run_checks
 from django.test import SimpleTestCase, override_settings
@@ -89,6 +91,7 @@
             messages,
         )
 
+    @unittest.skipIf(django.VERSION >= (4,), "Django>=4 handles missing dirs 
itself.")
     @override_settings(
         STATICFILES_DIRS=[PATH_DOES_NOT_EXIST],
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/test_forms.py 
new/django-debug-toolbar-3.2.1/tests/test_forms.py
--- old/django-debug-toolbar-3.2/tests/test_forms.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/test_forms.py  2021-04-14 
17:18:10.000000000 +0200
@@ -0,0 +1,56 @@
+from datetime import datetime
+
+import django
+from django import forms
+from django.test import TestCase
+
+from debug_toolbar.forms import SignedDataForm
+
+# Django 3.1 uses sha256 by default.
+SIGNATURE = (
+    "v02QBcJplEET6QXHNWejnRcmSENWlw6_RjxLTR7QG9g"
+    if django.VERSION >= (3, 1)
+    else "ukcAFUqYhUUnqT-LupnYoo-KvFg"
+)
+
+DATA = {"value": "foo", "date": datetime(2020, 1, 1)}
+SIGNED_DATA = f'{{"date": "2020-01-01 00:00:00", "value": "foo"}}:{SIGNATURE}'
+
+
+class FooForm(forms.Form):
+    value = forms.CharField()
+    # Include a datetime in the tests because it's not serializable back
+    # to a datetime by SignedDataForm
+    date = forms.DateTimeField()
+
+
+class TestSignedDataForm(TestCase):
+    def test_signed_data(self):
+        data = {"signed": SignedDataForm.sign(DATA)}
+        form = SignedDataForm(data=data)
+        self.assertTrue(form.is_valid())
+        # Check the signature value
+        self.assertEqual(data["signed"], SIGNED_DATA)
+
+    def test_verified_data(self):
+        form = SignedDataForm(data={"signed": SignedDataForm.sign(DATA)})
+        self.assertEqual(
+            form.verified_data(),
+            {
+                "value": "foo",
+                "date": "2020-01-01 00:00:00",
+            },
+        )
+        # Take it back to the foo form to validate the datetime is serialized
+        foo_form = FooForm(data=form.verified_data())
+        self.assertTrue(foo_form.is_valid())
+        self.assertDictEqual(foo_form.cleaned_data, DATA)
+
+    def test_initial_set_signed(self):
+        form = SignedDataForm(initial=DATA)
+        self.assertEqual(form.initial["signed"], SIGNED_DATA)
+
+    def test_prevents_tampering(self):
+        data = {"signed": SIGNED_DATA.replace('"value": "foo"', '"value": 
"bar"')}
+        form = SignedDataForm(data=data)
+        self.assertFalse(form.is_valid())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/test_integration.py 
new/django-debug-toolbar-3.2.1/tests/test_integration.py
--- old/django-debug-toolbar-3.2/tests/test_integration.py      2020-12-03 
09:11:15.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/test_integration.py    2021-04-14 
17:18:10.000000000 +0200
@@ -12,6 +12,7 @@
 from django.test import RequestFactory
 from django.test.utils import override_settings
 
+from debug_toolbar.forms import SignedDataForm
 from debug_toolbar.middleware import DebugToolbarMiddleware, show_toolbar
 from debug_toolbar.panels import Panel
 from debug_toolbar.toolbar import DebugToolbar
@@ -101,6 +102,25 @@
         self.client.get("/cached_view/")
         
self.assertEqual(len(self.toolbar.get_panel_by_id("CachePanel").calls), 5)
 
+    def test_is_toolbar_request(self):
+        self.request.path = "/__debug__/render_panel/"
+        self.assertTrue(self.toolbar.is_toolbar_request(self.request))
+
+        self.request.path = "/invalid/__debug__/render_panel/"
+        self.assertFalse(self.toolbar.is_toolbar_request(self.request))
+
+        self.request.path = "/render_panel/"
+        self.assertFalse(self.toolbar.is_toolbar_request(self.request))
+
+    @override_settings(ROOT_URLCONF="tests.urls_invalid")
+    def test_is_toolbar_request_without_djdt_urls(self):
+        """Test cases when the toolbar urls aren't configured."""
+        self.request.path = "/__debug__/render_panel/"
+        self.assertFalse(self.toolbar.is_toolbar_request(self.request))
+
+        self.request.path = "/render_panel/"
+        self.assertFalse(self.toolbar.is_toolbar_request(self.request))
+
 
 @override_settings(DEBUG=True)
 class DebugToolbarIntegrationTestCase(IntegrationTestCase):
@@ -193,12 +213,15 @@
     def test_sql_select_checks_show_toolbar(self):
         url = "/__debug__/sql_select/"
         data = {
-            "sql": "SELECT * FROM auth_user",
-            "raw_sql": "SELECT * FROM auth_user",
-            "params": "{}",
-            "alias": "default",
-            "duration": "0",
-            "hash": "6e12daa636b8c9a8be993307135458f90a877606",
+            "signed": SignedDataForm.sign(
+                {
+                    "sql": "SELECT * FROM auth_user",
+                    "raw_sql": "SELECT * FROM auth_user",
+                    "params": "{}",
+                    "alias": "default",
+                    "duration": "0",
+                }
+            )
         }
 
         response = self.client.post(url, data)
@@ -216,12 +239,15 @@
     def test_sql_explain_checks_show_toolbar(self):
         url = "/__debug__/sql_explain/"
         data = {
-            "sql": "SELECT * FROM auth_user",
-            "raw_sql": "SELECT * FROM auth_user",
-            "params": "{}",
-            "alias": "default",
-            "duration": "0",
-            "hash": "6e12daa636b8c9a8be993307135458f90a877606",
+            "signed": SignedDataForm.sign(
+                {
+                    "sql": "SELECT * FROM auth_user",
+                    "raw_sql": "SELECT * FROM auth_user",
+                    "params": "{}",
+                    "alias": "default",
+                    "duration": "0",
+                }
+            )
         }
 
         response = self.client.post(url, data)
@@ -246,12 +272,15 @@
         )
         query = base_query + """ '{"foo": "bar"}'"""
         data = {
-            "sql": query,
-            "raw_sql": base_query + " %s",
-            "params": '["{\\"foo\\": \\"bar\\"}"]',
-            "alias": "default",
-            "duration": "0",
-            "hash": "2b7172eb2ac8e2a8d6f742f8a28342046e0d00ba",
+            "signed": SignedDataForm.sign(
+                {
+                    "sql": query,
+                    "raw_sql": base_query + " %s",
+                    "params": '["{\\"foo\\": \\"bar\\"}"]',
+                    "alias": "default",
+                    "duration": "0",
+                }
+            )
         }
         response = self.client.post(url, data)
         self.assertEqual(response.status_code, 200)
@@ -268,12 +297,15 @@
     def test_sql_profile_checks_show_toolbar(self):
         url = "/__debug__/sql_profile/"
         data = {
-            "sql": "SELECT * FROM auth_user",
-            "raw_sql": "SELECT * FROM auth_user",
-            "params": "{}",
-            "alias": "default",
-            "duration": "0",
-            "hash": "6e12daa636b8c9a8be993307135458f90a877606",
+            "signed": SignedDataForm.sign(
+                {
+                    "sql": "SELECT * FROM auth_user",
+                    "raw_sql": "SELECT * FROM auth_user",
+                    "params": "{}",
+                    "alias": "default",
+                    "duration": "0",
+                }
+            )
         }
 
         response = self.client.post(url, data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/urls.py 
new/django-debug-toolbar-3.2.1/tests/urls.py
--- old/django-debug-toolbar-3.2/tests/urls.py  2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/tests/urls.py        2021-04-14 
17:18:10.000000000 +0200
@@ -1,3 +1,4 @@
+from django.contrib import admin
 from django.contrib.auth.views import LoginView
 from django.urls import include, path, re_path
 
@@ -22,5 +23,6 @@
     path("json_view/", views.json_view),
     path("redirect/", views.redirect_view),
     path("login_without_redirect/", 
LoginView.as_view(redirect_field_name=None)),
+    path("admin/", admin.site.urls),
     path("__debug__/", include(debug_toolbar.urls)),
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tests/urls_invalid.py 
new/django-debug-toolbar-3.2.1/tests/urls_invalid.py
--- old/django-debug-toolbar-3.2/tests/urls_invalid.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/django-debug-toolbar-3.2.1/tests/urls_invalid.py        2021-04-14 
17:18:10.000000000 +0200
@@ -0,0 +1,2 @@
+"""Invalid urls.py file for testing"""
+urlpatterns = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-debug-toolbar-3.2/tox.ini 
new/django-debug-toolbar-3.2.1/tox.ini
--- old/django-debug-toolbar-3.2/tox.ini        2020-12-03 09:11:15.000000000 
+0100
+++ new/django-debug-toolbar-3.2.1/tox.ini      2021-04-14 17:18:10.000000000 
+0200
@@ -3,20 +3,20 @@
     docs
     style
     readme
-    py{36,37,38,39}-dj22-sqlite
-    py{36,37,38,39}-dj{30,31}-sqlite
-    py{36,37,38,39}-djmaster-sqlite
-    py{37,38,39}-dj{22,30,31}-{postgresql,mysql}
+    py{36,37}-dj{22,30,31,32}-sqlite
+    py{38,39}-dj{22,30,31,32,main}-sqlite
+    py{36,37,38,39}-dj{22,30,31,32}-{postgresql,mysql}
 
 [testenv]
 deps =
     dj22: Django==2.2.*
     dj30: Django==3.0.*
     dj31: Django==3.1.*
+    dj32: Django>=3.2a1,<4.0
     sqlite: mock
     postgresql: psycopg2-binary
     mysql: mysqlclient
-    djmaster: https://github.com/django/django/archive/master.tar.gz
+    djmain: https://github.com/django/django/archive/main.tar.gz
     coverage
     Jinja2
     html5lib
@@ -35,10 +35,32 @@
     PYTHONPATH = {toxinidir}
     PYTHONWARNINGS = d
     py38-dj31-postgresql: DJANGO_SELENIUM_TESTS = true
+    DB_NAME = {env:DB_NAME:debug_toolbar}
+    DB_USER = {env:DB_USER:debug_toolbar}
+    DB_HOST = {env:DB_HOST:localhost}
+    DB_PASSWORD =  {env:DB_PASSWORD:debug_toolbar}
 whitelist_externals = make
 pip_pre = True
 commands = make coverage TEST_ARGS='{posargs:tests}'
 
+[testenv:py{36,37,38,39}-dj{22,30,31,32}-postgresql]
+setenv =
+    {[testenv]setenv}
+    DB_BACKEND = postgresql
+    DB_PORT = {env:DB_PORT:5432}
+
+[testenv:py{36,37,38,39}-dj{22,30,31,32}-mysql]
+setenv =
+    {[testenv]setenv}
+    DB_BACKEND = mysql
+    DB_PORT = {env:DB_PORT:3306}
+
+[testenv:py{36,37,38,39}-dj{22,30,31,32,main}-sqlite]
+setenv =
+    {[testenv]setenv}
+    DB_BACKEND = sqlite3
+    DB_NAME = ":memory:"
+
 [testenv:docs]
 commands = make -C {toxinidir}/docs spelling
 deps =

Reply via email to