|
0
|
1 |
try: |
|
|
2 |
import cPickle as pickle |
|
|
3 |
except ImportError: |
|
|
4 |
import pickle |
|
|
5 |
|
|
|
6 |
from django.conf import settings |
|
|
7 |
from django.utils.hashcompat import md5_constructor |
|
|
8 |
from django.forms import BooleanField |
|
|
9 |
|
|
|
10 |
def security_hash(request, form, *args): |
|
|
11 |
""" |
|
|
12 |
Calculates a security hash for the given Form instance. |
|
|
13 |
|
|
|
14 |
This creates a list of the form field names/values in a deterministic |
|
|
15 |
order, pickles the result with the SECRET_KEY setting, then takes an md5 |
|
|
16 |
hash of that. |
|
|
17 |
""" |
|
|
18 |
|
|
|
19 |
data = [] |
|
|
20 |
for bf in form: |
|
|
21 |
# Get the value from the form data. If the form allows empty or hasn't |
|
|
22 |
# changed then don't call clean() to avoid trigger validation errors. |
|
|
23 |
if form.empty_permitted and not form.has_changed(): |
|
|
24 |
value = bf.data or '' |
|
|
25 |
else: |
|
|
26 |
value = bf.field.clean(bf.data) or '' |
|
|
27 |
if isinstance(value, basestring): |
|
|
28 |
value = value.strip() |
|
|
29 |
data.append((bf.name, value)) |
|
|
30 |
|
|
|
31 |
data.extend(args) |
|
|
32 |
data.append(settings.SECRET_KEY) |
|
|
33 |
|
|
|
34 |
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires |
|
|
35 |
# Python 2.3, but Django requires 2.3 anyway, so that's OK. |
|
|
36 |
pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) |
|
|
37 |
|
|
|
38 |
return md5_constructor(pickled).hexdigest() |
|
|
39 |
|