# Changelog
+## 0.2.6 (2019-02-13)
+
+* Django 1.9-1.11 compatibility.
+
## 0.2.5 (2015-04-16)
* Unescape var values in render middleware.
],
LANGUAGE_CODE='pl',
MEDIA_URL='/media/',
- MIDDLEWARE_CLASSES=[
+ MIDDLEWARE_CLASSES=[ # Django < 1.10
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'ssify.middleware.SsiMiddleware',
+ 'django.middleware.cache.UpdateCacheMiddleware',
+ 'ssify.middleware.PrepareForCacheMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'ssify.middleware.LocaleMiddleware',
+ 'django.middleware.cache.FetchFromCacheMiddleware',
+ ],
+ SMIDDLEWARE = [ # Django < 1.10
'django.middleware.csrf.CsrfViewMiddleware',
'ssify.middleware.SsiMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
STATIC_URL='/static/',
ROOT_URLCONF='tests.urls',
SITE_ID=1,
- TEMPLATE_CONTEXT_PROCESSORS=(
+ TEMPLATE_CONTEXT_PROCESSORS=( # Django < 1.8
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.tz",
"django.core.context_processors.request",
),
+ TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.tz",
+ "django.template.context_processors.request",
+ ],
+ }
+ },
+ ]
)
try:
import warnings
from django.conf import settings
from django.http import Http404
-from django.template.base import parse_bits
+try:
+ # Django 1.9
+ from django.template.library import parse_bits
+except ImportError:
+ from django.template.base import parse_bits
+
from django.utils.translation import get_language, activate
from .cache import cache_include, DEFAULT_TIMEOUT
from . import exceptions
"""
from __future__ import unicode_literals
import re
+
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
+
+try:
+ from django.urls import NoReverseMatch, reverse, resolve
+except ImportError:
+ # Django < 2
+ from django.core.urlresolvers import NoReverseMatch, reverse, resolve
+
from django.core.urlresolvers import resolve
from .cache import get_caches
#
from __future__ import absolute_import, unicode_literals
from django.conf import settings
-from django.core.urlresolvers import NoReverseMatch, reverse, resolve
+try:
+ from django.urls import NoReverseMatch, reverse, resolve
+except ImportError:
+ # Django < 2
+ from django.core.urlresolvers import NoReverseMatch, reverse, resolve
+
from django.middleware.csrf import get_token, _sanitize_token, rotate_token
from django import template
+from django.utils.safestring import mark_safe
from django.utils.translation import get_language
from ssify.decorators import ssi_variable
from ssify.utils import ssi_vary_on_cookie
request.ssi_patch_response.extend(patch_response)
# Output the SSI include.
- return "<!--#include file='%s'-->" % url
+ return mark_safe("<!--#include file='%s'-->" % url)
@ssi_variable(register, patch_response=[ssi_vary_on_cookie])
from __future__ import unicode_literals
from hashlib import md5
from django.template import Node
-from django.template.base import get_library
+
+try:
+ # Django < 1.9
+ from django.template.base import get_library
+except:
+ from importlib import import_module
+ from django.template.backends.django import get_installed_libraries
+
+ def get_library(taglib):
+ if not hasattr(get_library, 'libraries'):
+ get_library.libraries = get_installed_libraries()
+ if isinstance(get_library.libraries[taglib], str):
+ get_library.libraries[taglib] = import_module(get_library.libraries[taglib]).register
+ return get_library.libraries[taglib]
+
from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.functional import Promise
from django.utils.safestring import mark_safe
from __future__ import unicode_literals
-VERSION = '0.2.5'
+VERSION = '0.2.6'
#
from __future__ import unicode_literals
+import re
from django.conf import settings
from django.test import Client, TestCase
+try:
+ from django.middleware.csrf import _compare_salted_tokens
+except ImportError:
+ # Django < 1.10
+ _compare_salted_tokens = lambda t1, t2: t1 == t2
+
class CsrfTestCase(TestCase):
def setUp(self):
def assertCsrfTokenOk(self, response):
token = response.cookies[settings.CSRF_COOKIE_NAME].value
self.assertTrue(token)
- self.assertEqual(
- response.content.strip(),
- ("<!--#set var='vd07f6920655622adc90dd591c545bb2a' value='%s'-->\n\n"
- "<input type='hidden' name='csrfmiddlewaretoken' value='"
- "<!--#echo var='vd07f6920655622adc90dd591c545bb2a' "
- "encoding='none'-->' />" % token).encode('ascii')
+ match = re.match(
+ r"<!--#set var='vd07f6920655622adc90dd591c545bb2a' value='([A-Za-z0-9]*)'-->\n\n"
+ r"<input type='hidden' name='csrfmiddlewaretoken' value='"
+ r"<!--#echo var='vd07f6920655622adc90dd591c545bb2a' "
+ r"encoding='none'-->' />",
+ response.content.strip().decode('ascii'),
+ re.MULTILINE
)
+ self.assertTrue(_compare_salted_tokens(match.group(1), token))
return token
def test_csrf_token(self):
response = self.client.get('/csrf')
token = self.assertCsrfTokenOk(response)
- # And now for a second request, with the token cookie.
- response = self.client.get('/csrf')
- new_token = self.assertCsrfTokenOk(response)
- self.assertEqual(new_token, token)
-
# Make a bad request to see that CSRF protection works.
response = self.client.post('/csrf_check', {
'test': 'some data',
# This file is part of django-ssify, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See README.md for more information.
#
-from __future__ import unicode_literals
+from __future__ import absolute_import, unicode_literals
-from django.conf.urls import patterns, url
+#from django.conf.urls import patterns, url
+from django.conf.urls import url
from django.views.generic import TemplateView
+from tests import views
-urlpatterns = patterns(
- 'tests.views',
-
+urlpatterns = [
# tests.basic
url(r'^$',
TemplateView.as_view(template_name='tests_basic/main.html')
url(r'^basic_include$',
TemplateView.as_view(template_name='tests_basic/basic_include.html')
),
- url(r'^random_quote$', 'random_quote', name='random_quote'),
- url(r'^quote/(?P<number>.+)$', 'quote', name='quote'),
+ url(r'^random_quote$', views.random_quote, name='random_quote'),
+ url(r'^quote/(?P<number>.+)$', views.quote, name='quote'),
- url(r'^quote_undeclared/(?P<number>.+)$', 'quote_undeclared'),
- url(r'^quote_overdeclared/(?P<number>.+)$', 'quote_overdeclared'),
+ url(r'^quote_undeclared/(?P<number>.+)$', views.quote_undeclared),
+ url(r'^quote_overdeclared/(?P<number>.+)$', views.quote_overdeclared),
# tests.args
url(r'^include_args$',
TemplateView.as_view(template_name='tests_args/args.html'),
{'limit': 3}
),
- url(r'^args/(?P<limit>\d+)$', 'args', name='args'),
+ url(r'^args/(?P<limit>\d+)$', views.args, name='args'),
# tests.csrf
url(r'^csrf$',
TemplateView.as_view(template_name='tests_csrf/csrf_token.html'),
),
- url(r'^csrf_check$', 'csrf_check'),
+ url(r'^csrf_check$', views.csrf_check),
# tests.locale
url(r'^include_language_with_lang$',
url(r'^include_language_without_lang$',
TemplateView.as_view(template_name='tests_locale/include_language_without_lang.html')
),
- url(r'^language/(?P<lang>.+)$', 'language_with_lang', name='language_with_lang'),
- url(r'^language$', 'language_without_lang', name='language_without_lang'),
- url(r'^bad_language$', 'language_with_lang', name='bad_language_with_lang'),
+ url(r'^language/(?P<lang>.+)$', views.language_with_lang, name='language_with_lang'),
+ url(r'^language$', views.language_without_lang, name='language_without_lang'),
+ url(r'^bad_language$', views.language_with_lang, name='bad_language_with_lang'),
# tests.render
url(r'^render$',
TemplateView.as_view(template_name='tests_render/test_render.html')
),
-)
+]
#
[tox]
envlist=clear,
- d1{5,6}-py{26,27,32,33,py},
- d{17,18}-py{27,32,33,34,py},
- d{d}-py{27,33,34,py},
+ d1{5,6}-py{26,27,32,33},
+ d{17,18}-py{27,32,33,34},
+ d{19,110}-py{27,34,35},
+ d111-py{27,34,35,36,37},
+ #d20-py{34,35,36,37},
+ #d21-py{35,36,37},
stats
[testenv]
d16: Django>=1.6,<1.7
d17: Django>=1.7,<1.8
d18: Django>=1.8,<1.9
- dd: https://github.com/django/django/archive/master.tar.gz
+ d19: Django>=1.9,<1.10
+ d110: Django>=1.10,<1.11
+ d111: Django>=1.11,<2.0
+ d20: Django>=2.0,<2.1
+ d21: Django>=2.1,<2.2
coverage
[testenv:clear]