Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
import os
|
2011-06-01 21:47:00 +08:00
|
|
|
import re
|
2011-04-02 21:26:19 +08:00
|
|
|
import warnings
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
from django import http
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
from django.conf import settings
|
2010-10-11 20:55:17 +08:00
|
|
|
from django.contrib.formtools import preview, wizard, utils
|
2007-11-30 00:32:23 +08:00
|
|
|
from django.test import TestCase
|
2011-04-02 21:26:19 +08:00
|
|
|
from django.test.utils import get_warnings_state, restore_warnings_state
|
2010-10-11 20:55:17 +08:00
|
|
|
from django.utils import unittest
|
2007-11-30 00:32:23 +08:00
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
from django.contrib.formtools.wizard.tests import *
|
|
|
|
from django.contrib.formtools.tests.forms import *
|
|
|
|
|
|
|
|
warnings.filterwarnings('ignore', category=PendingDeprecationWarning,
|
|
|
|
module='django.contrib.formtools.wizard')
|
2007-11-30 00:32:23 +08:00
|
|
|
|
2010-12-04 15:28:12 +08:00
|
|
|
success_string = "Done was called!"
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2007-11-30 00:32:23 +08:00
|
|
|
class TestFormPreview(preview.FormPreview):
|
2010-11-21 21:47:38 +08:00
|
|
|
def get_context(self, request, form):
|
|
|
|
context = super(TestFormPreview, self).get_context(request, form)
|
|
|
|
context.update({'custom_context': True})
|
|
|
|
return context
|
|
|
|
|
|
|
|
def get_initial(self, request):
|
|
|
|
return {'field1': 'Works!'}
|
2007-11-30 00:32:23 +08:00
|
|
|
|
|
|
|
def done(self, request, cleaned_data):
|
|
|
|
return http.HttpResponse(success_string)
|
|
|
|
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2007-11-30 00:32:23 +08:00
|
|
|
class PreviewTests(TestCase):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
urls = 'django.contrib.formtools.tests.urls'
|
2007-11-30 00:32:23 +08:00
|
|
|
|
|
|
|
def setUp(self):
|
2011-04-02 21:26:19 +08:00
|
|
|
self.save_warnings_state()
|
|
|
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
|
|
|
module='django.contrib.formtools.utils')
|
|
|
|
|
2007-11-30 00:32:23 +08:00
|
|
|
# Create a FormPreview instance to share between tests
|
|
|
|
self.preview = preview.FormPreview(TestForm)
|
|
|
|
input_template = '<input type="hidden" name="%s" value="%s" />'
|
|
|
|
self.input = input_template % (self.preview.unused_name('stage'), "%d")
|
2008-08-27 04:19:12 +08:00
|
|
|
self.test_data = {'field1':u'foo', 'field1_':u'asdf'}
|
2007-11-30 00:32:23 +08:00
|
|
|
|
2011-04-02 21:26:19 +08:00
|
|
|
def tearDown(self):
|
|
|
|
self.restore_warnings_state()
|
|
|
|
|
2007-11-30 00:32:23 +08:00
|
|
|
def test_unused_name(self):
|
|
|
|
"""
|
|
|
|
Verifies name mangling to get uniue field name.
|
|
|
|
"""
|
|
|
|
self.assertEqual(self.preview.unused_name('field1'), 'field1__')
|
|
|
|
|
|
|
|
def test_form_get(self):
|
|
|
|
"""
|
|
|
|
Test contrib.formtools.preview form retrieval.
|
|
|
|
|
|
|
|
Use the client library to see if we can sucessfully retrieve
|
|
|
|
the form (mostly testing the setup ROOT_URLCONF
|
|
|
|
process). Verify that an additional hidden input field
|
|
|
|
is created to manage the stage.
|
|
|
|
|
|
|
|
"""
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.get('/preview/')
|
2007-11-30 00:32:23 +08:00
|
|
|
stage = self.input % 1
|
|
|
|
self.assertContains(response, stage, 1)
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertEqual(response.context['custom_context'], True)
|
|
|
|
self.assertEqual(response.context['form'].initial, {'field1': 'Works!'})
|
2007-11-30 00:32:23 +08:00
|
|
|
|
|
|
|
def test_form_preview(self):
|
|
|
|
"""
|
|
|
|
Test contrib.formtools.preview form preview rendering.
|
|
|
|
|
|
|
|
Use the client library to POST to the form to see if a preview
|
|
|
|
is returned. If we do get a form back check that the hidden
|
|
|
|
value is correctly managing the state of the form.
|
|
|
|
|
|
|
|
"""
|
|
|
|
# Pass strings for form submittal and add stage variable to
|
|
|
|
# show we previously saw first stage of the form.
|
2008-08-27 04:19:12 +08:00
|
|
|
self.test_data.update({'stage': 1})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
2007-11-30 00:32:23 +08:00
|
|
|
# Check to confirm stage is set to 2 in output form.
|
|
|
|
stage = self.input % 2
|
|
|
|
self.assertContains(response, stage, 1)
|
|
|
|
|
|
|
|
def test_form_submit(self):
|
|
|
|
"""
|
|
|
|
Test contrib.formtools.preview form submittal.
|
|
|
|
|
|
|
|
Use the client library to POST to the form with stage set to 3
|
|
|
|
to see if our forms done() method is called. Check first
|
|
|
|
without the security hash, verify failure, retry with security
|
|
|
|
hash and verify sucess.
|
|
|
|
|
|
|
|
"""
|
|
|
|
# Pass strings for form submittal and add stage variable to
|
|
|
|
# show we previously saw first stage of the form.
|
2008-08-27 04:19:12 +08:00
|
|
|
self.test_data.update({'stage':2})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
2010-12-04 15:28:12 +08:00
|
|
|
self.assertNotEqual(response.content, success_string)
|
2008-08-27 04:19:12 +08:00
|
|
|
hash = self.preview.security_hash(None, TestForm(self.test_data))
|
|
|
|
self.test_data.update({'hash': hash})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
2008-08-27 04:19:12 +08:00
|
|
|
self.assertEqual(response.content, success_string)
|
|
|
|
|
|
|
|
def test_bool_submit(self):
|
|
|
|
"""
|
|
|
|
Test contrib.formtools.preview form submittal when form contains:
|
|
|
|
BooleanField(required=False)
|
|
|
|
|
|
|
|
Ticket: #6209 - When an unchecked BooleanField is previewed, the preview
|
|
|
|
form's hash would be computed with no value for ``bool1``. However, when
|
|
|
|
the preview form is rendered, the unchecked hidden BooleanField would be
|
|
|
|
rendered with the string value 'False'. So when the preview form is
|
|
|
|
resubmitted, the hash would be computed with the value 'False' for
|
|
|
|
``bool1``. We need to make sure the hashes are the same in both cases.
|
|
|
|
|
|
|
|
"""
|
|
|
|
self.test_data.update({'stage':2})
|
|
|
|
hash = self.preview.security_hash(None, TestForm(self.test_data))
|
|
|
|
self.test_data.update({'hash':hash, 'bool1':u'False'})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
2007-11-30 00:32:23 +08:00
|
|
|
self.assertEqual(response.content, success_string)
|
|
|
|
|
2011-03-31 01:35:01 +08:00
|
|
|
def test_form_submit_good_hash(self):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
"""
|
2011-03-31 01:35:01 +08:00
|
|
|
Test contrib.formtools.preview form submittal, using a correct
|
|
|
|
hash
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
"""
|
|
|
|
# Pass strings for form submittal and add stage variable to
|
|
|
|
# show we previously saw first stage of the form.
|
|
|
|
self.test_data.update({'stage':2})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
2010-12-04 15:28:12 +08:00
|
|
|
self.assertNotEqual(response.content, success_string)
|
2011-03-31 01:35:01 +08:00
|
|
|
hash = utils.form_hmac(TestForm(self.test_data))
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
self.test_data.update({'hash': hash})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
self.assertEqual(response.content, success_string)
|
|
|
|
|
|
|
|
|
2011-03-31 01:35:01 +08:00
|
|
|
def test_form_submit_bad_hash(self):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
"""
|
2011-03-31 01:35:01 +08:00
|
|
|
Test contrib.formtools.preview form submittal does not proceed
|
|
|
|
if the hash is incorrect.
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
"""
|
|
|
|
# Pass strings for form submittal and add stage variable to
|
|
|
|
# show we previously saw first stage of the form.
|
|
|
|
self.test_data.update({'stage':2})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/preview/', self.test_data)
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
self.assertEqual(response.status_code, 200)
|
2010-12-04 15:28:12 +08:00
|
|
|
self.assertNotEqual(response.content, success_string)
|
2011-03-31 01:35:01 +08:00
|
|
|
hash = utils.form_hmac(TestForm(self.test_data)) + "bad"
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
self.test_data.update({'hash': hash})
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/previewpreview/', self.test_data)
|
2010-12-04 15:28:12 +08:00
|
|
|
self.assertNotEqual(response.content, success_string)
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
|
|
|
|
2009-05-13 05:54:58 +08:00
|
|
|
class SecurityHashTests(unittest.TestCase):
|
2011-04-02 21:26:19 +08:00
|
|
|
def setUp(self):
|
|
|
|
self._warnings_state = get_warnings_state()
|
|
|
|
warnings.filterwarnings('ignore', category=DeprecationWarning,
|
|
|
|
module='django.contrib.formtools.utils')
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
restore_warnings_state(self._warnings_state)
|
2009-05-13 05:54:58 +08:00
|
|
|
|
|
|
|
def test_textfield_hash(self):
|
|
|
|
"""
|
|
|
|
Regression test for #10034: the hash generation function should ignore
|
|
|
|
leading/trailing whitespace so as to be friendly to broken browsers that
|
|
|
|
submit it (usually in textareas).
|
|
|
|
"""
|
2009-05-13 06:02:38 +08:00
|
|
|
f1 = HashTestForm({'name': 'joe', 'bio': 'Nothing notable.'})
|
|
|
|
f2 = HashTestForm({'name': ' joe', 'bio': 'Nothing notable. '})
|
|
|
|
hash1 = utils.security_hash(None, f1)
|
|
|
|
hash2 = utils.security_hash(None, f2)
|
|
|
|
self.assertEqual(hash1, hash2)
|
2010-10-11 20:55:17 +08:00
|
|
|
|
2009-05-13 06:02:38 +08:00
|
|
|
def test_empty_permitted(self):
|
|
|
|
"""
|
|
|
|
Regression test for #10643: the security hash should allow forms with
|
|
|
|
empty_permitted = True, or forms where data has not changed.
|
|
|
|
"""
|
|
|
|
f1 = HashTestBlankForm({})
|
|
|
|
f2 = HashTestForm({}, empty_permitted=True)
|
2009-05-13 05:54:58 +08:00
|
|
|
hash1 = utils.security_hash(None, f1)
|
|
|
|
hash2 = utils.security_hash(None, f2)
|
|
|
|
self.assertEqual(hash1, hash2)
|
|
|
|
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
|
|
|
class FormHmacTests(unittest.TestCase):
|
|
|
|
"""
|
|
|
|
Same as SecurityHashTests, but with form_hmac
|
|
|
|
"""
|
|
|
|
|
|
|
|
def test_textfield_hash(self):
|
|
|
|
"""
|
|
|
|
Regression test for #10034: the hash generation function should ignore
|
|
|
|
leading/trailing whitespace so as to be friendly to broken browsers that
|
|
|
|
submit it (usually in textareas).
|
|
|
|
"""
|
|
|
|
f1 = HashTestForm({'name': 'joe', 'bio': 'Nothing notable.'})
|
|
|
|
f2 = HashTestForm({'name': ' joe', 'bio': 'Nothing notable. '})
|
|
|
|
hash1 = utils.form_hmac(f1)
|
|
|
|
hash2 = utils.form_hmac(f2)
|
|
|
|
self.assertEqual(hash1, hash2)
|
|
|
|
|
|
|
|
def test_empty_permitted(self):
|
|
|
|
"""
|
|
|
|
Regression test for #10643: the security hash should allow forms with
|
|
|
|
empty_permitted = True, or forms where data has not changed.
|
|
|
|
"""
|
|
|
|
f1 = HashTestBlankForm({})
|
|
|
|
f2 = HashTestForm({}, empty_permitted=True)
|
|
|
|
hash1 = utils.form_hmac(f1)
|
|
|
|
hash2 = utils.form_hmac(f2)
|
|
|
|
self.assertEqual(hash1, hash2)
|
|
|
|
|
|
|
|
|
2008-08-27 05:33:56 +08:00
|
|
|
#
|
|
|
|
# FormWizard tests
|
|
|
|
#
|
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
class TestWizardClass(wizard.FormWizard):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
|
|
|
def get_template(self, step):
|
2011-06-01 21:47:00 +08:00
|
|
|
return 'forms/wizard.html'
|
2008-08-27 05:33:56 +08:00
|
|
|
|
|
|
|
def done(self, request, cleaned_data):
|
|
|
|
return http.HttpResponse(success_string)
|
|
|
|
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
class DummyRequest(http.HttpRequest):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2008-08-27 05:33:56 +08:00
|
|
|
def __init__(self, POST=None):
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
super(DummyRequest, self).__init__()
|
2008-08-27 05:33:56 +08:00
|
|
|
self.method = POST and "POST" or "GET"
|
Fixed #9977 - CsrfMiddleware gets template tag added, session dependency removed, and turned on by default.
This is a large change to CSRF protection for Django. It includes:
* removing the dependency on the session framework.
* deprecating CsrfResponseMiddleware, and replacing with a core template tag.
* turning on CSRF protection by default by adding CsrfViewMiddleware to
the default value of MIDDLEWARE_CLASSES.
* protecting all contrib apps (whatever is in settings.py)
using a decorator.
For existing users of the CSRF functionality, it should be a seamless update,
but please note that it includes DEPRECATION of features in Django 1.1,
and there are upgrade steps which are detailed in the docs.
Many thanks to 'Glenn' and 'bthomas', who did a lot of the thinking and work
on the patch, and to lots of other people including Simon Willison and
Russell Keith-Magee who refined the ideas.
Details of the rationale for these changes is found here:
http://code.djangoproject.com/wiki/CsrfProtection
As of this commit, the CSRF code is mainly in 'contrib'. The code will be
moved to core in a separate commit, to make the changeset as readable as
possible.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11660 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2009-10-27 07:23:07 +08:00
|
|
|
if POST is not None:
|
|
|
|
self.POST.update(POST)
|
|
|
|
self._dont_enforce_csrf_checks = True
|
2008-08-27 05:33:56 +08:00
|
|
|
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2008-08-27 05:33:56 +08:00
|
|
|
class WizardTests(TestCase):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
urls = 'django.contrib.formtools.tests.urls'
|
2011-06-01 21:47:00 +08:00
|
|
|
input_re = re.compile('name="([^"]+)" value="([^"]+)"')
|
|
|
|
wizard_step_data = (
|
|
|
|
{
|
|
|
|
'0-name': 'Pony',
|
|
|
|
'0-thirsty': '2',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'1-address1': '123 Main St',
|
|
|
|
'1-address2': 'Djangoland',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'2-random_crap': 'blah blah',
|
|
|
|
}
|
|
|
|
)
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
|
|
|
|
settings.TEMPLATE_DIRS = (
|
|
|
|
os.path.join(
|
|
|
|
os.path.dirname(__file__),
|
|
|
|
'templates'
|
|
|
|
),
|
|
|
|
)
|
|
|
|
# Use a known SECRET_KEY to make security_hash tests deterministic
|
|
|
|
self.old_SECRET_KEY = settings.SECRET_KEY
|
|
|
|
settings.SECRET_KEY = "123"
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
|
|
|
|
settings.SECRET_KEY = self.old_SECRET_KEY
|
|
|
|
|
2008-08-27 05:33:56 +08:00
|
|
|
def test_step_starts_at_zero(self):
|
|
|
|
"""
|
|
|
|
step should be zero for the first form
|
|
|
|
"""
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.get('/wizard1/')
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertEqual(0, response.context['step0'])
|
2008-08-27 05:33:56 +08:00
|
|
|
|
|
|
|
def test_step_increments(self):
|
|
|
|
"""
|
|
|
|
step should be incremented when we go to the next page
|
|
|
|
"""
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/wizard1/', {"0-field":"test", "wizard_step":"0"})
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertEqual(1, response.context['step0'])
|
2008-08-27 05:33:56 +08:00
|
|
|
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
def test_bad_hash(self):
|
|
|
|
"""
|
|
|
|
Form should not advance if the hash is missing or bad
|
|
|
|
"""
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/wizard1/',
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
{"0-field":"test",
|
|
|
|
"1-field":"test2",
|
|
|
|
"wizard_step": "1"})
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertEqual(0, response.context['step0'])
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
|
2011-03-31 01:34:49 +08:00
|
|
|
def test_good_hash(self):
|
Fixed #14445 - Use HMAC and constant-time comparison functions where needed.
All adhoc MAC applications have been updated to use HMAC, using SHA1 to
generate unique keys for each application based on the SECRET_KEY, which is
common practice for this situation. In all cases, backwards compatibility
with existing hashes has been maintained, aiming to phase this out as per
the normal deprecation process. In this way, under most normal
circumstances the old hashes will have expired (e.g. by session expiration
etc.) before they become invalid.
In the case of the messages framework and the cookie backend, which was
already using HMAC, there is the possibility of a backwards incompatibility
if the SECRET_KEY is shorter than the default 50 bytes, but the low
likelihood and low impact meant compatibility code was not worth it.
All known instances where tokens/hashes were compared using simple string
equality, which could potentially open timing based attacks, have also been
fixed using a constant-time comparison function.
There are no known practical attacks against the existing implementations,
so these security improvements will not be backported.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14218 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2010-10-15 04:54:30 +08:00
|
|
|
"""
|
|
|
|
Form should advance if the hash is present and good, as calculated using
|
|
|
|
current method.
|
|
|
|
"""
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
|
|
|
"wizard_step": "1"}
|
2011-06-01 21:47:00 +08:00
|
|
|
response = self.client.post('/wizard1/', data)
|
2011-03-03 23:04:39 +08:00
|
|
|
self.assertEqual(2, response.context['step0'])
|
2010-10-20 04:45:40 +08:00
|
|
|
|
2011-04-28 22:19:25 +08:00
|
|
|
def test_11726(self):
|
|
|
|
"""
|
|
|
|
Regression test for ticket #11726.
|
|
|
|
Wizard should not raise Http404 when steps are added dynamically.
|
|
|
|
"""
|
|
|
|
reached = [False]
|
|
|
|
that = self
|
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
class WizardWithProcessStep(TestWizardClass):
|
2011-04-28 22:19:25 +08:00
|
|
|
def process_step(self, request, form, step):
|
|
|
|
if step == 0:
|
|
|
|
if self.num_steps() < 2:
|
|
|
|
self.form_list.append(WizardPageTwoForm)
|
|
|
|
if step == 1:
|
|
|
|
that.assertTrue(isinstance(form, WizardPageTwoForm))
|
|
|
|
reached[0] = True
|
|
|
|
|
|
|
|
wizard = WizardWithProcessStep([WizardPageOneForm])
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
|
|
|
"wizard_step": "1"}
|
|
|
|
wizard(DummyRequest(POST=data))
|
|
|
|
self.assertTrue(reached[0])
|
|
|
|
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
|
|
|
"hash_1": "d5b434e3934cc92fee4bd2964c4ebc06f81d362d",
|
|
|
|
"wizard_step": "2"}
|
|
|
|
self.assertRaises(http.Http404, wizard, DummyRequest(POST=data))
|
|
|
|
|
2010-10-20 04:45:40 +08:00
|
|
|
def test_14498(self):
|
|
|
|
"""
|
2011-01-14 05:58:11 +08:00
|
|
|
Regression test for ticket #14498. All previous steps' forms should be
|
|
|
|
validated.
|
2010-10-20 04:45:40 +08:00
|
|
|
"""
|
2011-01-14 07:18:54 +08:00
|
|
|
reached = [False]
|
2010-10-20 04:45:40 +08:00
|
|
|
that = self
|
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
class WizardWithProcessStep(TestWizardClass):
|
2010-10-20 04:45:40 +08:00
|
|
|
def process_step(self, request, form, step):
|
|
|
|
that.assertTrue(hasattr(form, 'cleaned_data'))
|
2011-01-14 07:18:54 +08:00
|
|
|
reached[0] = True
|
2010-10-20 04:45:40 +08:00
|
|
|
|
|
|
|
wizard = WizardWithProcessStep([WizardPageOneForm,
|
|
|
|
WizardPageTwoForm,
|
|
|
|
WizardPageThreeForm])
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
|
|
|
"wizard_step": "1"}
|
|
|
|
wizard(DummyRequest(POST=data))
|
2011-01-14 07:18:54 +08:00
|
|
|
self.assertTrue(reached[0])
|
2010-10-20 04:45:40 +08:00
|
|
|
|
2010-11-16 22:37:00 +08:00
|
|
|
def test_14576(self):
|
|
|
|
"""
|
|
|
|
Regression test for ticket #14576.
|
|
|
|
|
|
|
|
The form of the last step is not passed to the done method.
|
|
|
|
"""
|
|
|
|
reached = [False]
|
|
|
|
that = self
|
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
class Wizard(TestWizardClass):
|
2010-11-16 22:37:00 +08:00
|
|
|
def done(self, request, form_list):
|
|
|
|
reached[0] = True
|
|
|
|
that.assertTrue(len(form_list) == 2)
|
|
|
|
|
|
|
|
wizard = Wizard([WizardPageOneForm,
|
|
|
|
WizardPageTwoForm])
|
|
|
|
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
2011-01-14 07:19:10 +08:00
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
2010-11-16 22:37:00 +08:00
|
|
|
"wizard_step": "1"}
|
|
|
|
wizard(DummyRequest(POST=data))
|
|
|
|
self.assertTrue(reached[0])
|
2011-01-14 05:58:11 +08:00
|
|
|
|
|
|
|
def test_15075(self):
|
|
|
|
"""
|
|
|
|
Regression test for ticket #15075. Allow modifying wizard's form_list
|
|
|
|
in process_step.
|
|
|
|
"""
|
2011-01-14 07:18:54 +08:00
|
|
|
reached = [False]
|
2011-01-14 05:58:11 +08:00
|
|
|
that = self
|
|
|
|
|
2011-06-01 21:47:00 +08:00
|
|
|
class WizardWithProcessStep(TestWizardClass):
|
2011-01-14 05:58:11 +08:00
|
|
|
def process_step(self, request, form, step):
|
|
|
|
if step == 0:
|
|
|
|
self.form_list[1] = WizardPageTwoAlternativeForm
|
|
|
|
if step == 1:
|
|
|
|
that.assertTrue(isinstance(form, WizardPageTwoAlternativeForm))
|
2011-01-14 07:18:54 +08:00
|
|
|
reached[0] = True
|
2011-01-14 05:58:11 +08:00
|
|
|
|
|
|
|
wizard = WizardWithProcessStep([WizardPageOneForm,
|
|
|
|
WizardPageTwoForm,
|
|
|
|
WizardPageThreeForm])
|
|
|
|
data = {"0-field": "test",
|
|
|
|
"1-field": "test2",
|
|
|
|
"hash_0": "7e9cea465f6a10a6fb47fcea65cb9a76350c9a5c",
|
|
|
|
"wizard_step": "1"}
|
|
|
|
wizard(DummyRequest(POST=data))
|
2011-01-14 07:18:54 +08:00
|
|
|
self.assertTrue(reached[0])
|
2011-06-01 21:47:00 +08:00
|
|
|
|
|
|
|
def grab_field_data(self, response):
|
|
|
|
"""
|
|
|
|
Pull the appropriate field data from the context to pass to the next wizard step
|
|
|
|
"""
|
|
|
|
previous_fields = response.context['previous_fields']
|
|
|
|
fields = {'wizard_step': response.context['step0']}
|
|
|
|
|
|
|
|
def grab(m):
|
|
|
|
fields[m.group(1)] = m.group(2)
|
|
|
|
return ''
|
|
|
|
|
|
|
|
self.input_re.sub(grab, previous_fields)
|
|
|
|
return fields
|
|
|
|
|
|
|
|
def check_wizard_step(self, response, step_no):
|
|
|
|
"""
|
|
|
|
Helper function to test each step of the wizard
|
|
|
|
- Make sure the call succeeded
|
|
|
|
- Make sure response is the proper step number
|
|
|
|
- return the result from the post for the next step
|
|
|
|
"""
|
|
|
|
step_count = len(self.wizard_step_data)
|
|
|
|
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.assertContains(response, 'Step %d of %d' % (step_no, step_count))
|
|
|
|
|
|
|
|
data = self.grab_field_data(response)
|
|
|
|
data.update(self.wizard_step_data[step_no - 1])
|
|
|
|
|
|
|
|
return self.client.post('/wizard2/', data)
|
|
|
|
|
|
|
|
def test_9473(self):
|
|
|
|
response = self.client.get('/wizard2/')
|
|
|
|
for step_no in range(1, len(self.wizard_step_data) + 1):
|
|
|
|
response = self.check_wizard_step(response, step_no)
|