Commits

George Notaras committed 87d7d93

Migrated to the Google API and added support for SSL

Comments (0)

Files changed (4)

src/recaptchaworks/fields.py

             '%(code)s.',
     }
 
-    def __init__(self, private_key=None, *args, **kwargs):
+    def __init__(self, private_key=None, use_ssl=False, *args, **kwargs):
         """
         The optional ``private_key`` argument can be used to override the
         default use of the project-wide ``RECAPTCHA_PRIVATE_KEY`` setting.
         """
         self.remote_ip = None
         self.private_key = private_key or settings.RECAPTCHA_PRIVATE_KEY
+        self.use_ssl = use_ssl or settings.RECAPTCHA_USE_SSL
         super(RecaptchaField, self).__init__(*args, **kwargs)
 
     def clean(self, value):
             raise forms.ValidationError(self.error_messages['required'])
         try:
             value = validate_recaptcha(self.remote_ip, challenge, response,
-                                       self.private_key)
+                                       self.private_key, self.use_ssl)
         except RecaptchaError, e:
             if e.code == 'incorrect-captcha-sol':
                 raise forms.ValidationError(self.error_messages['invalid'])

src/recaptchaworks/settings.py

 RECAPTCHA_PUBLIC_KEY = getattr(settings, 'RECAPTCHA_PUBLIC_KEY', '')
 RECAPTCHA_USE_SSL = getattr(settings, 'RECAPTCHA_USE_SSL', True)
 
-_RECAPTCHA_OPTIONS_SCRIPT_HTML = u'''<script type="text/javascript">
-   var RecaptchaOptions = %r;
+# See the following page for valid options:
+# http://code.google.com/apis/recaptcha/docs/customization.html
+_RECAPTCHA_OPTIONS = {
+    'theme': 'red',
+    'lang': 'en',
+    'tabindex': 0,
+    #'custom_translations': {},
+    #'custom_theme_widget': None
+    }
+RECAPTCHA_OPTIONS = getattr(settings, 'RECAPTCHA_OPTIONS', _RECAPTCHA_OPTIONS)
+
+_RECAPTCHA_HTML = u'''
+%(options)s
+<script type="text/javascript"
+   src="%(proto)s://www.google.com/recaptcha/api/challenge?k=%(public_key)s">
 </script>
-'''
-RECAPTCHA_OPTIONS_SCRIPT_HTML = getattr(settings, 'RECAPTCHA_OPTIONS_SCRIPT_HTML', _RECAPTCHA_OPTIONS_SCRIPT_HTML)
-
-_RECAPTCHA_HTML = u'''%(options)s<script type="text/javascript" src="http://api.recaptcha.net/challenge?k=%(public_key)s"></script>
 <noscript>
-   <iframe src="http://api.recaptcha.net/noscript?k=%(public_key)s"
-       height="300" width="500" frameborder="0"></iframe><br />
+   <iframe src="%(proto)s://www.google.com/recaptcha/api/noscript?k=%(public_key)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>'''
+   <input type="hidden" name="recaptcha_response_field" value="manual_challenge">
+</noscript>
+'''
 RECAPTCHA_HTML = getattr(settings, 'RECAPTCHA_HTML', _RECAPTCHA_HTML)
 

src/recaptchaworks/utils.py

 from django.utils.http import urlencode
 
 from recaptchaworks.exceptions import RecaptchaError
-        
+from recaptchaworks import settings
 
-def validate_recaptcha(remote_ip, challenge, response, private_key):
+
+def validate_recaptcha(remote_ip, challenge, response, private_key, use_ssl):
     assert challenge, 'No challenge was provided for reCaptcha validation'
     # Request validation from recaptcha.net
     params = dict(privatekey=private_key, remoteip=remote_ip,
     params = urlencode(params)
     headers = {"Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/plain"}
-    conn = httplib.HTTPConnection("api-verify.recaptcha.net")
-    conn.request("POST", "/verify", params, headers)
+    if use_ssl:
+        conn = httplib.HTTPSConnection("www.google.com")
+    else:
+        conn = httplib.HTTPConnection("www.google.com")
+    conn.request("POST", "/recaptcha/api/verify", params, headers)
     response = conn.getresponse()
     if response.status == 200:
         data = response.read()

src/recaptchaworks/widgets.py

 
 from django import forms
 from django.utils.safestring import mark_safe
+from django.utils import simplejson
 
 from recaptchaworks import settings
 
 
 class RecaptchaWidget(forms.Widget):
-    def __init__(self, theme=None, tabindex=None, public_key=None):
+    
+    RECAPTCHA_OPTIONS_SCRIPT = u'''<script type="text/javascript">
+var RecaptchaOptions = {
+%s
+};
+</script>
+'''
+    
+    def __init__(self, recaptcha_options=None, public_key=None, use_ssl=False):
         '''
-        From http://recaptcha.net/apidocs/captcha/client.html#look-n-feel:
-
-            theme:      'red' | 'white' | 'blackglass' | 'clean'
-    
-                Defines which theme to use for reCAPTCHA.
-    
-            tabindex:   any integer
-    
-                Sets a tabindex for the reCAPTCHA text box. If other elements
-                in the form use a tabindex, this should be set so that
-                navigation is easier for the user.
-            
+        
+        http://code.google.com/apis/recaptcha/docs/customization.html
+        
+        The optional ``recaptcha_options`` argument can be used to override
+        the default project wide ``RECAPTCHA_OPTIONS`` setting.
+        
         The optional ``public_key`` argument can be used to override the
         default use of the project-wide ``RECAPTCHA_PUBLIC_KEY`` setting.
+        
+        The optional ``use_ssl`` argument can be used to override the default
+        use of the project-wide ``RECAPTCHA_USE_SSL`` setting.
         '''
-        options = {}
-        if theme:
-            options['theme'] = theme
-        if tabindex:
-            options['tabindex'] = tabindex
-        self.options = options
+        self.options = recaptcha_options
+        if recaptcha_options is None:
+            self.options = settings.RECAPTCHA_OPTIONS
+        
+        self.proto = 'http'
+        if use_ssl or settings.RECAPTCHA_USE_SSL:
+            self.proto = 'https'
+        
         self.public_key = public_key or settings.RECAPTCHA_PUBLIC_KEY
+        
         super(RecaptchaWidget, self).__init__()
 
     def render(self, name, value, attrs=None):
-        args = dict(public_key=self.public_key, options='')
+        args = dict(public_key=self.public_key, proto=self.proto, options='')
         if self.options:
-            args['options'] = settings.RECAPTCHA_OPTIONS_SCRIPT_HTML % self.options
+            args['options'] = self.RECAPTCHA_OPTIONS_SCRIPT % simplejson.dumps(
+                self.options, indent=4).strip('{}')
         return mark_safe(settings.RECAPTCHA_HTML % args)
 
     def value_from_datadict(self, data, files, name):
 
     def id_for_label(self, id_):
         return None
-