summaryrefslogtreecommitdiff
path: root/recaptcha
diff options
context:
space:
mode:
authorsupriya <supriya@dragbox.(none)>2012-09-26 15:49:52 +0530
committersupriya <supriya@dragbox.(none)>2012-09-26 15:49:52 +0530
commit94535d4adc3a4960795d22e3b229a8375de10b74 (patch)
tree8d77de86b443495d67360dcd40786f2b8208d334 /recaptcha
parentcad11e2f7ed848cdfd7779451bb0f4f931e062c3 (diff)
downloadgnowsys-94535d4adc3a4960795d22e3b229a8375de10b74.tar.gz
all modules integrated
Diffstat (limited to 'recaptcha')
-rw-r--r--recaptcha/__init__.py1
-rw-r--r--recaptcha/client/__init__.py0
-rw-r--r--recaptcha/client/captcha.py94
-rw-r--r--recaptcha/client/mailhide.py68
-rw-r--r--recaptcha/fields.py27
-rw-r--r--recaptcha/widgets.py15
6 files changed, 205 insertions, 0 deletions
diff --git a/recaptcha/__init__.py b/recaptcha/__init__.py
new file mode 100644
index 0000000..de40ea7
--- /dev/null
+++ b/recaptcha/__init__.py
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/recaptcha/client/__init__.py b/recaptcha/client/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/recaptcha/client/__init__.py
diff --git a/recaptcha/client/captcha.py b/recaptcha/client/captcha.py
new file mode 100644
index 0000000..1213fc4
--- /dev/null
+++ b/recaptcha/client/captcha.py
@@ -0,0 +1,94 @@
+import urllib2, urllib
+
+API_SSL_SERVER="https://www.google.com/recaptcha/api"
+API_SERVER="http://www.google.com/recaptcha/api"
+VERIFY_SERVER="www.google.com"
+
+class RecaptchaResponse(object):
+ def __init__(self, is_valid, error_code=None):
+ self.is_valid = is_valid
+ self.error_code = error_code
+
+def displayhtml (public_key,
+ use_ssl = False,
+ error = None):
+ """Gets the HTML to display for reCAPTCHA
+
+ public_key -- The public api key
+ use_ssl -- Should the request be sent over ssl?
+ error -- An error message to display (from RecaptchaResponse.error_code)"""
+
+ error_param = ''
+ if error:
+ error_param = '&error=%s' % error
+
+ if use_ssl:
+ server = API_SSL_SERVER
+ else:
+ server = API_SERVER
+
+ return """<script type="text/javascript" src="%(ApiServer)s/challenge?k=%(PublicKey)s%(ErrorParam)s"></script>
+
+<noscript>
+ <iframe src="%(ApiServer)s/noscript?k=%(PublicKey)s%(ErrorParam)s" height="300" width="500" frameborder="0"></iframe><br />
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
+ <input type='hidden' name='recaptcha_response_field' value='manual_challenge' />
+</noscript>
+""" % {
+ 'ApiServer' : server,
+ 'PublicKey' : public_key,
+ 'ErrorParam' : error_param,
+ }
+
+
+def submit (recaptcha_challenge_field,
+ recaptcha_response_field,
+ private_key,
+ remoteip):
+ """
+ Submits a reCAPTCHA request for verification. Returns RecaptchaResponse
+ for the request
+
+ recaptcha_challenge_field -- The value of recaptcha_challenge_field from the form
+ recaptcha_response_field -- The value of recaptcha_response_field from the form
+ private_key -- your reCAPTCHA private key
+ remoteip -- the user's ip address
+ """
+
+ if not (recaptcha_response_field and recaptcha_challenge_field and
+ len (recaptcha_response_field) and len (recaptcha_challenge_field)):
+ return RecaptchaResponse (is_valid = False, error_code = 'incorrect-captcha-sol')
+
+
+ def encode_if_necessary(s):
+ if isinstance(s, unicode):
+ return s.encode('utf-8')
+ return s
+
+ params = urllib.urlencode ({
+ 'privatekey': encode_if_necessary(private_key),
+ 'remoteip' : encode_if_necessary(remoteip),
+ 'challenge': encode_if_necessary(recaptcha_challenge_field),
+ 'response' : encode_if_necessary(recaptcha_response_field),
+ })
+
+ request = urllib2.Request (
+ url = "http://%s/recaptcha/api/verify" % VERIFY_SERVER,
+ data = params,
+ headers = {
+ "Content-type": "application/x-www-form-urlencoded",
+ "User-agent": "reCAPTCHA Python"
+ }
+ )
+
+ httpresp = urllib2.urlopen (request)
+
+ return_values = httpresp.read ().splitlines ();
+ httpresp.close();
+
+ return_code = return_values [0]
+
+ if (return_code == "true"):
+ return RecaptchaResponse (is_valid=True)
+ else:
+ return RecaptchaResponse (is_valid=False, error_code = return_values [1])
diff --git a/recaptcha/client/mailhide.py b/recaptcha/client/mailhide.py
new file mode 100644
index 0000000..437b2c2
--- /dev/null
+++ b/recaptcha/client/mailhide.py
@@ -0,0 +1,68 @@
+import base64
+import cgi
+
+try:
+ from Crypto.Cipher import AES
+except:
+ raise Exception ("You need the pycrpyto library: http://cheeseshop.python.org/pypi/pycrypto/")
+
+MAIL_HIDE_BASE="http://www.google.com/recaptcha/mailhide"
+
+def asurl (email,
+ public_key,
+ private_key):
+ """Wraps an email address with reCAPTCHA mailhide and
+ returns the url. public_key is the public key from reCAPTCHA
+ (in the base 64 encoded format). Private key is the AES key, and should
+ be 32 hex chars."""
+
+ cryptmail = _encrypt_string (email, base64.b16decode (private_key, casefold=True), '\0' * 16)
+ base64crypt = base64.urlsafe_b64encode (cryptmail)
+
+ return "%s/d?k=%s&c=%s" % (MAIL_HIDE_BASE, public_key, base64crypt)
+
+def ashtml (email,
+ public_key,
+ private_key):
+ """Wraps an email address with reCAPTCHA Mailhide and
+ returns html that displays the email"""
+
+ url = asurl (email, public_key, private_key)
+ (userpart, domainpart) = _doterizeemail (email)
+
+ return """%(user)s<a href='%(url)s' onclick="window.open('%(url)s', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@%(domain)s""" % {
+ 'user' : cgi.escape (userpart),
+ 'domain' : cgi.escape (domainpart),
+ 'url' : cgi.escape (url),
+ }
+
+
+def _pad_string (str, block_size):
+ numpad = block_size - (len (str) % block_size)
+ return str + numpad * chr (numpad)
+
+def _encrypt_string (str, aes_key, aes_iv):
+ if len (aes_key) != 16:
+ raise Exception ("expecting key of length 16")
+ if len (aes_iv) != 16:
+ raise Exception ("expecting iv of length 16")
+ return AES.new (aes_key, AES.MODE_CBC, aes_iv).encrypt (_pad_string (str, 16))
+
+def _doterizeemail (email):
+ """replaces part of the username with dots"""
+
+ try:
+ [user, domain] = email.split ('@')
+ except:
+ # handle invalid emails... sorta
+ user = email
+ domain = ""
+
+ if len(user) <= 4:
+ user_prefix = user[:1]
+ elif len(user) <= 6:
+ user_prefix = user[:3]
+ else:
+ user_prefix = user[:4]
+
+ return (user_prefix, domain)
diff --git a/recaptcha/fields.py b/recaptcha/fields.py
new file mode 100644
index 0000000..ce79a6d
--- /dev/null
+++ b/recaptcha/fields.py
@@ -0,0 +1,27 @@
+from django.conf import settings
+from django import forms
+from django.utils.encoding import smart_unicode
+from django.utils.translation import ugettext_lazy as _
+
+from recaptcha.widgets import ReCaptcha
+from recaptcha.client import captcha
+
+class ReCaptchaField(forms.CharField):
+ default_error_messages = {
+ 'captcha_invalid': _(u'Invalid captcha')
+ }
+
+ def __init__(self, *args, **kwargs):
+ self.widget = ReCaptcha
+ self.required = True
+ super(ReCaptchaField, self).__init__(*args, **kwargs)
+
+ def clean(self, values):
+ super(ReCaptchaField, self).clean(values[1])
+ recaptcha_challenge_value = smart_unicode(values[0])
+ recaptcha_response_value = smart_unicode(values[1])
+ check_captcha = captcha.submit(recaptcha_challenge_value,
+ recaptcha_response_value, settings.RECAPTCHA_PRIVATE_KEY, {})
+ if not check_captcha.is_valid:
+ raise forms.util.ValidationError(self.error_messages['captcha_invalid'])
+ return values[0]
diff --git a/recaptcha/widgets.py b/recaptcha/widgets.py
new file mode 100644
index 0000000..45dfd7e
--- /dev/null
+++ b/recaptcha/widgets.py
@@ -0,0 +1,15 @@
+from django import forms
+from django.utils.safestring import mark_safe
+from django.conf import settings
+from recaptcha.client import captcha
+
+class ReCaptcha(forms.widgets.Widget):
+ recaptcha_challenge_name = 'recaptcha_challenge_field'
+ recaptcha_response_name = 'recaptcha_response_field'
+
+ def render(self, name, value, attrs=None):
+ return mark_safe(u'%s' % captcha.displayhtml(settings.RECAPTCHA_PUBLIC_KEY))
+
+ def value_from_datadict(self, data, files, name):
+ return [data.get(self.recaptcha_challenge_name, None),
+ data.get(self.recaptcha_response_name, None)]