Skip to content

Commit 27838f6

Browse files
committed
Added workaround for unit testing. Updated documentation for same. Version bump
1 parent fb729d1 commit 27838f6

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

README.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,24 @@ Usage
5959

6060
name = forms.CharField()
6161

62+
63+
Unit Testing
64+
------------
65+
66+
If you want to write unit tests for forms that derive from SecureForm, you will
67+
need to let this application know you are testing. SecureForm looks for
68+
settings.TESTING to evaluate to True. If so, it disables the security allowing
69+
the Django test client to send POST data using the original field names.
70+
71+
In the future, I would rather provide tools so that testing can happen with
72+
security enabled, but this is a quick workaround. Our test framework uses an
73+
environment variable to set settings.TESTING. For example, in settings.py...
74+
75+
::
76+
77+
import os
78+
79+
TESTING = True if 'TESTING' in os.environ else False
80+
6281
.. _SmartFile: http://www.smartfile.com/
6382
.. _Read more: http://www.smartfile.com/open-source.html

django_secureform/forms/__init__.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import time
22
import string
3+
34
from Crypto.Random import random
45
from Crypto.Cipher import Blowfish
6+
57
from django import forms
68
from django.conf import settings
79
from django.core.cache import cache
@@ -15,6 +17,7 @@
1517
from django.utils.translation import ugettext as _
1618
from django.utils.safestring import mark_safe
1719

20+
1821
# Chars that are safe to use in field names.
1922
SAFE_CHARS = string.ascii_letters + string.digits
2023

@@ -43,6 +46,14 @@ def random_name(choices=SAFE_CHARS, length=16):
4346
return ''.join(random.sample(choices, length))
4447

4548

49+
def testing():
50+
"""
51+
Detects if we are running under Django unit tests. If so, security is
52+
disabled.
53+
"""
54+
return getattr(settings, 'TESTING', False)
55+
56+
4657
class SecureFormException(Exception):
4758
'Base exception for security faults.'
4859

@@ -174,11 +185,12 @@ def __iter__(self):
174185

175186
def __getitem__(self, name):
176187
'Returns a SecureBoundField with the given name.'
177-
try:
178-
field = self.fields[name]
179-
except KeyError:
180-
raise KeyError('Key %r not found in Form' % name)
181-
return SecureBoundField(self, field, name)
188+
if not testing():
189+
try:
190+
return SecureBoundField(self, self.fields[name], name)
191+
except KeyError:
192+
raise KeyError('Key %r not found in Form' % name)
193+
return super(SecureFormBase, self).__getitem__(name)
182194

183195
def _script(self):
184196
'''Generates the JavaScript necessary for hiding the honeypots or an empty string
@@ -211,6 +223,8 @@ def decode_data(self):
211223
and while the honeypots are checked to ensure they are empty.'''
212224
if not self.is_bound:
213225
return
226+
if testing():
227+
return
214228
cleaned_data = {}
215229
secure = self.data[self._meta.secure_field_name]
216230
secure = self.crypt.decrypt(secure.decode('hex')).rstrip()
@@ -266,6 +280,8 @@ def full_clean(self):
266280

267281
def secure_data(self):
268282
'Prepares the secure data before the form is rendered.'
283+
if testing():
284+
return
269285
# Empty out the previous map, we will generate a new one.
270286
self._secure_field_map = {}
271287
labels = []

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from distutils.core import setup
55

66
name = 'django-secureform'
7-
version = '0.2'
7+
version = '0.3'
88
release = '1'
99
versrel = version + '-' + release
1010
readme = os.path.join(os.path.dirname(__file__), 'README.rst')

0 commit comments

Comments
 (0)