Skip to content

Commit

Permalink
Adding REAME, and initial project with form code.
Browse files Browse the repository at this point in the history
  • Loading branch information
ntucker committed May 31, 2011
0 parents commit 3915277
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Provides form widgets and class mixin for django newforms. This allows adding a recaptcha test to any django form.

Make sure to set these settings in your django settings file:
RECAPTCHA_PUB_KEY
RECAPTCHA_PRIV_KEY

Requires recaptcha library: http://pypi.python.org/pypi/recaptcha-client

For more information about recaptcha, and to get a recaptcha key, visit: http://www.google.com/recaptcha
Empty file added recaptcha_form/__init__.py
Empty file.
107 changes: 107 additions & 0 deletions recaptcha_form/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# This code is public domain.
# Thanks to SmileyChris for the original implementation

import django.forms as forms
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe

import recaptcha.client.captcha as captcha


# Do you want to bypass reCAPTCHA validation while in DEBUG mode?
SKIP_IF_IN_DEBUG_MODE = False

RECAPTCHA_LANG = settings.LANGUAGE_CODE[:2]
RECAPTCHA_THEME = getattr(settings, 'RECAPTCHA_THEME', 'red')


### ERROR_CODES
ERROR_CODES = {
"unknown" : _("Unknown error."),
"invalid-site-public-key" : _("We weren't able to verify the public key. Please try again later."),
"invalid-site-private-key" : _("We weren't able to verify the private key. Please try again later."),
"invalid-request-cookie" : _("The challenge parameter of the verify script was incorrect."),
"incorrect-captcha-sol" : _("The CAPTCHA solution was incorrect."),
"verify-params-incorrect" : _("The parameters to /verify were incorrect, make sure you are passing all the required parameters. Please try again later."),
"invalid-referrer" : _("reCAPTCHA API keys are tied to a specific domain name for security reasons. Please try again later."),
"recaptcha-not-reachable" : _("Unable to contact the reCAPTCHA verify server. Please try again later.")
}


class RecaptchaWidget(forms.Widget):
def __init__(self):
super(RecaptchaWidget, self).__init__()

def render(self, name, value, attrs=None):
html = captcha.displayhtml(settings.RECAPTCHA_PUB_KEY,
theme=RECAPTCHA_THEME,
lang=RECAPTCHA_LANG)
return mark_safe(html)

def value_from_datadict(self, data, files, name):
challenge = data.get('recaptcha_challenge_field')
response = data.get('recaptcha_response_field')
return (challenge, response)

def id_for_label(self, id_):
return None


class RecaptchaField(forms.Field):
widget = RecaptchaWidget

def __init__(self, remote_ip, *args, **kwargs):
self.remote_ip = remote_ip
super(RecaptchaField, self).__init__(*args, **kwargs)

def clean(self, value):
if SKIP_IF_IN_DEBUG_MODE and settings.DEBUG:
return True
value = super(RecaptchaField, self).clean(value)
challenge, response = value

if not challenge:
raise forms.ValidationError(_('An error occured with the CAPTCHA service. Please try again.'))
if not response:
raise forms.ValidationError(_('Please enter the CAPTCHA solution.'))

rc = captcha.submit(challenge, response,
settings.RECAPTCHA_PRIV_KEY,
self.remote_ip)
if not rc.is_valid:
msg = ERROR_CODES.get(rc.error_code, ERROR_CODES['unknown'])
raise forms.ValidationError(msg)

# reCAPTCHA validates!
return True


class RecaptchaFieldPlaceholder(forms.Field):
'''
Placeholder field for use with RecaptchaBaseForm which gets replaced with
RecaptchaField (which is passed the remote_ip) when RecaptchaBaseForm is
initialised.
'''
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs


class RecaptchaBaseForm(forms.BaseForm):
def __init__(self, remote_ip, *args, **kwargs):
for key, field in self.base_fields.items():
if isinstance(field, RecaptchaFieldPlaceholder):
self.base_fields[key] = RecaptchaField(remote_ip, *field.args, **field.kwargs)
super(RecaptchaBaseForm, self).__init__(*args, **kwargs)


class RecaptchaForm(RecaptchaBaseForm, forms.Form):
'''
Inheriting from this form gives you a reCAPTCHA field at the bottom.
'''
def __init__(self, remote_ip, *args, **kwargs):
self.base_fields['captcha'] = RecaptchaFieldPlaceholder(
label=_('Are you human?') )
super(RecaptchaForm, self).__init__(remote_ip, *args, **kwargs)

0 comments on commit 3915277

Please sign in to comment.