# -*- coding: UTF-8 -*- import time import datetime import base64 from django import forms from django.utils.translation import ugettext from django.conf import settings MIN_TIME = getattr(settings, "MIN_TIME", 5) # 5 seconds MAX_TIME = getattr(settings, "MAX_TIME", 3600) # 1 hour def cryptString(plain): # Your implementation for encrypting a string. # For example: return base64.encodestring(plain) def decryptString(cipher): # Your implementation for decrypting a string # For example: return base64.decodestring(cipher) class SecurityField(forms.CharField): """ A field which checks whether the form was filled in within the given range of time The concept works only for Unbounded forms. """ time_elapsed = 0 def generate_value(self): started = cryptString(str(int(time.mktime(datetime.datetime.now().timetuple())))) return started def _pass_test(self, value): started = int(decryptString(value)) current = int(time.mktime(datetime.datetime.now().timetuple())) self.time_elapsed = current - started return self.MIN_TIME < current - started < self.MAX_TIME def __init__(self, *args, **kwargs): super(type(self), self).__init__(*args, **kwargs) self.widget = forms.HiddenInput() self.initial = self.generate_value() self.required = True self.MIN_TIME = MIN_TIME self.MAX_TIME = MAX_TIME def clean(self, value): value = super(type(self), self).clean(value) if not self._pass_test(value): raise forms.ValidationError(ugettext(u"The data transfer didn't pass the security test. You are considered as a spambot.")) return value