# HG changeset patch # User Patrick Vane # Date 1522765205 -7200 # Node ID 44f7f73da4a66b35a04a8e960886d1eba11a011f # Parent 70262a0dca6b8b0c6b0c86f51f0c486a84d0ecd0 recaptcha: Update to Google recaptcha API v2 (Issue #313) Recaptcha stopped working. It was using google recaptcha v1, and https://developers.google.com/recaptcha/docs/faq says: "Any calls to the v1 API will not work after March 31, 2018." Note: 1) Not using 'async defer' - it's not used anywhere else, plus I have no idea of what exactly it does. 2) The recaptcha div has an ID so the label for="recaptcha_field" can reference it (although I'm not certain a div can technically have a label, but it's better than removing the label, or the for=""). diff -r 70262a0dca6b -r 44f7f73da4a6 kallithea/controllers/login.py --- a/kallithea/controllers/login.py Tue Apr 03 16:20:05 2018 +0200 +++ b/kallithea/controllers/login.py Tue Apr 03 16:20:05 2018 +0200 @@ -133,11 +133,10 @@ if c.captcha_active: from kallithea.lib.recaptcha import submit - response = submit(request.POST.get('recaptcha_challenge_field'), - request.POST.get('recaptcha_response_field'), + response = submit(request.POST.get('g-recaptcha-response'), private_key=captcha_private_key, remoteip=request.ip_addr) - if c.captcha_active and not response.is_valid: + if not response.is_valid: _value = form_result _msg = _('Bad captcha') error_dict = {'recaptcha_field': _msg} @@ -179,11 +178,10 @@ form_result = password_reset_form.to_python(dict(request.POST)) if c.captcha_active: from kallithea.lib.recaptcha import submit - response = submit(request.POST.get('recaptcha_challenge_field'), - request.POST.get('recaptcha_response_field'), + response = submit(request.POST.get('g-recaptcha-response'), private_key=captcha_private_key, remoteip=request.ip_addr) - if c.captcha_active and not response.is_valid: + if not response.is_valid: _value = form_result _msg = _('Bad captcha') error_dict = {'recaptcha_field': _msg} diff -r 70262a0dca6b -r 44f7f73da4a6 kallithea/lib/recaptcha.py --- a/kallithea/lib/recaptcha.py Tue Apr 03 16:20:05 2018 +0200 +++ b/kallithea/lib/recaptcha.py Tue Apr 03 16:20:05 2018 +0200 @@ -1,10 +1,7 @@ # -*- coding: utf-8 -*- import urllib import urllib2 - -API_SSL_SERVER = "https://www.google.com/recaptcha/api" -API_SERVER = "http://www.google.com/recaptcha/api" -VERIFY_SERVER = "www.google.com" +import json class RecaptchaResponse(object): @@ -16,23 +13,17 @@ return '' % (self.is_valid) -def submit(recaptcha_challenge_field, recaptcha_response_field, private_key, - remoteip): +def submit(g_recaptcha_response, private_key, remoteip): """ - Submits a reCAPTCHA request for verification. Returns RecaptchaResponse - for the request + 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 + g_recaptcha_response -- The value of g_recaptcha_response 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') + if not (g_recaptcha_response and len(g_recaptcha_response)): + return RecaptchaResponse(is_valid=False, error_code='incorrect-captcha-sol') def encode_if_necessary(s): if isinstance(s, unicode): @@ -40,14 +31,13 @@ return s params = urllib.urlencode({ - 'privatekey': encode_if_necessary(private_key), + 'secret': encode_if_necessary(private_key), 'remoteip': encode_if_necessary(remoteip), - 'challenge': encode_if_necessary(recaptcha_challenge_field), - 'response': encode_if_necessary(recaptcha_response_field), + 'response': encode_if_necessary(g_recaptcha_response), }) req = urllib2.Request( - url="http://%s/recaptcha/api/verify" % VERIFY_SERVER, + url="https://www.google.com/recaptcha/api/siteverify", data=params, headers={ "Content-type": "application/x-www-form-urlencoded", @@ -56,13 +46,14 @@ ) httpresp = urllib2.urlopen(req) - - return_values = httpresp.read().splitlines() + return_values = json.loads(httpresp.read()) httpresp.close() - return_code = return_values[0] - - if return_code == "true": + if not (isinstance(return_values, dict)): + return RecaptchaResponse(is_valid=False, error_code='incorrect-captcha-sol') + elif (("success" in return_values) and ((return_values["success"] == True) or (return_values["success"] == "true"))): return RecaptchaResponse(is_valid=True) + elif (("error-codes" in return_values) and isinstance(return_values["error-codes"], list) and (len(return_values["error-codes"]) > 0)): + return RecaptchaResponse(is_valid=False, error_code=return_values["error-codes"][0]) else: - return RecaptchaResponse(is_valid=False, error_code=return_values[1]) + return RecaptchaResponse(is_valid=False, error_code='incorrect-captcha-sol') diff -r 70262a0dca6b -r 44f7f73da4a6 kallithea/templates/password_reset.html --- a/kallithea/templates/password_reset.html Tue Apr 03 16:20:05 2018 +0200 +++ b/kallithea/templates/password_reset.html Tue Apr 03 16:20:05 2018 +0200 @@ -5,6 +5,12 @@ ${_('Password Reset')} +<%block name="js_extra"> + %if c.captcha_active: + + %endif + + <%include file="/base/flash_msg.html"/>
@@ -31,8 +37,7 @@
- ${h.hidden('recaptcha_field')} -
+
%endif @@ -48,19 +53,9 @@
${h.end_form()} - %if c.captcha_active: - - %endif diff -r 70262a0dca6b -r 44f7f73da4a6 kallithea/templates/register.html --- a/kallithea/templates/register.html Tue Apr 03 16:20:05 2018 +0200 +++ b/kallithea/templates/register.html Tue Apr 03 16:20:05 2018 +0200 @@ -5,6 +5,12 @@ ${_('Sign Up')} +<%block name="js_extra"> + %if c.captcha_active: + + %endif + + <%include file="/base/flash_msg.html"/>
@@ -67,8 +73,7 @@
- ${h.hidden('recaptcha_field')} -
+
%endif @@ -85,20 +90,9 @@
${h.end_form()} - %if c.captcha_active: - - %endif