remove captcha
parent
b40c433406
commit
ce468c48fe
146
CaptchaPage.py
146
CaptchaPage.py
|
@ -1,146 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- mode: python; indent-tabs-mode: nil; -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
CaptchaPage.py
|
||||
|
||||
Copyright 2013-14 by Marcello Perathoner
|
||||
|
||||
Distributable under the GNU General Public License Version 3 or newer.
|
||||
|
||||
Serve a captcha page.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import requests
|
||||
import cherrypy
|
||||
import logging
|
||||
|
||||
import Page
|
||||
import BaseSearcher
|
||||
|
||||
#
|
||||
# reCaptcha API docs:
|
||||
# https://developers.google.com/recaptcha/docs/verify
|
||||
#
|
||||
|
||||
API = "https://www.google.com/recaptcha/api/verify"
|
||||
|
||||
|
||||
class QuestionPage (Page.Page):
|
||||
""" Output captcha page. """
|
||||
|
||||
def index (self, **kwargs):
|
||||
""" Output captcha. """
|
||||
|
||||
cherrypy.lib.caching.expires (3600, True)
|
||||
|
||||
os = BaseSearcher.OpenSearch ()
|
||||
os.template = 'recaptcha'
|
||||
os.recaptcha_public_key = cherrypy.config['recaptcha_public_key']
|
||||
os.error = kwargs.get ('error')
|
||||
os.finalize ()
|
||||
|
||||
# Remove Session cookie, so that page can be cached.
|
||||
name = cherrypy.serving.request.config.get ('tools.sessions.name', 'session_id')
|
||||
del cherrypy.serving.response.cookie[name]
|
||||
|
||||
return self.format (os)
|
||||
|
||||
|
||||
class AnswerPage (object):
|
||||
""" Check answer with google. """
|
||||
|
||||
def index (self, **kwargs):
|
||||
""" Check with google. """
|
||||
|
||||
cherrypy.lib.caching.expires (0, True)
|
||||
|
||||
os = BaseSearcher.OpenSearch ()
|
||||
|
||||
# Remove Session cookie.
|
||||
name = cherrypy.serving.request.config.get ('tools.sessions.name', 'session_id')
|
||||
del cherrypy.serving.response.cookie[name]
|
||||
|
||||
if 'recaptcha_challenge_field' in kwargs:
|
||||
response = submit (
|
||||
kwargs['recaptcha_challenge_field'],
|
||||
kwargs['recaptcha_response_field'],
|
||||
cherrypy.config['recaptcha_private_key'],
|
||||
cherrypy.request.remote.ip)
|
||||
|
||||
cherrypy.ipsession.captcha_answer (response)
|
||||
|
||||
if not response.is_valid:
|
||||
raise cherrypy.HTTPRedirect (
|
||||
os.url ('captcha.question', error = 'incorrect-captcha-sol'))
|
||||
|
||||
for req in reversed (cherrypy.ipsession['requests']):
|
||||
if 'captcha' not in req:
|
||||
raise cherrypy.HTTPRedirect (req)
|
||||
|
||||
raise cherrypy.HTTPRedirect (os.url ('start'))
|
||||
|
||||
#
|
||||
# Following is stolen from pypi package recaptcha-client 1.0.6
|
||||
# http://code.google.com/p/recaptcha/
|
||||
# to make it compatible with Python 3 requests.
|
||||
#
|
||||
|
||||
class RecaptchaResponse (object):
|
||||
""" The response from the reCaptcha server. """
|
||||
|
||||
def __init__ (self, is_valid, error_code = None):
|
||||
self.is_valid = is_valid
|
||||
self.error_code = error_code
|
||||
|
||||
|
||||
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')
|
||||
|
||||
|
||||
data = {
|
||||
'privatekey': private_key,
|
||||
'remoteip': remoteip,
|
||||
'challenge': recaptcha_challenge_field,
|
||||
'response': recaptcha_response_field,
|
||||
}
|
||||
headers = {
|
||||
"User-agent": "reCAPTCHA Python"
|
||||
}
|
||||
|
||||
cherrypy.log ('Data=' + repr (data), context = 'CAPTCHA', severity = logging.INFO)
|
||||
|
||||
try:
|
||||
r = requests.post (API, data = data, headers = headers)
|
||||
r.raise_for_status ()
|
||||
|
||||
lines = r.text.splitlines ()
|
||||
|
||||
cherrypy.log ('Response=' + "/".join (lines), context = 'CAPTCHA', severity = logging.INFO)
|
||||
|
||||
if lines[0] == "true":
|
||||
return RecaptchaResponse (is_valid = True)
|
||||
else:
|
||||
return RecaptchaResponse (is_valid = False, error_code = lines[1])
|
||||
|
||||
except requests.exceptions.RequestException as what:
|
||||
cherrypy.log (str (what), context = 'CAPTCHA', severity = logging.ERROR)
|
||||
return RecaptchaResponse (is_valid = False, error_code = 'recaptcha-not-reachable')
|
|
@ -39,10 +39,6 @@ gdrive_client_secret: 'add secret in .autocat3 or /etc/autocat3.conf files'
|
|||
msdrive_client_id: '6902b111-a9d6-461f-bd8a-83dafee3da66'
|
||||
msdrive_client_secret: 'add secret in .autocat3 or /etc/autocat3.conf files'
|
||||
|
||||
recaptcha_public_key: '6Lf0cpkUAAAAAIHB6OW_6H0SIqt5O2xmgsnF4Is8'
|
||||
recaptcha_private_key: 'add secret in .autocat or /etc/autocat3.conf files'
|
||||
|
||||
|
||||
log.screen: False
|
||||
log.error_file: CherryPyApp.install_dir + '/log/error.log'
|
||||
log.access_file: CherryPyApp.install_dir + '/log/access.log'
|
||||
|
|
1
Pipfile
1
Pipfile
|
@ -28,7 +28,6 @@ pyparsing = "*"
|
|||
pytz = "*"
|
||||
qrcode = "*"
|
||||
rdflib = "*"
|
||||
recaptcha-client = "*"
|
||||
regex = "*"
|
||||
requests = "*"
|
||||
requests-oauthlib = "*"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "faa368c84714ecc94bc3f9b3a0bb08d4d8075fe70ae633afb9909ad5ae4f0bd5"
|
||||
"sha256": "e572637bcd906d1c709a30dc233b8b835861fb78f13dbd1733908631bd2f811a"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -282,13 +282,6 @@
|
|||
"index": "pypi",
|
||||
"version": "==4.2.2"
|
||||
},
|
||||
"recaptcha-client": {
|
||||
"hashes": [
|
||||
"sha256:28c6853c1d13d365b7dc71a6b05e5ffb56471f70a850de318af50d3d7c0dea2f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.6"
|
||||
},
|
||||
"regex": {
|
||||
"hashes": [
|
||||
"sha256:020429dcf9b76cc7648a99c81b3a70154e45afebc81e0b85364457fe83b525e4",
|
||||
|
@ -378,11 +371,11 @@
|
|||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
|
||||
"sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
|
||||
"sha256:4c291ca23bbb55c76518905869ef34bdd5f0e46af7afe6861e8375643ffee1a0",
|
||||
"sha256:9a247273df709c4fedb38c711e44292304f73f39ab01beda9f6b9fc375669ac3"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.24.1"
|
||||
"version": "==1.24.2"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
|
|
|
@ -48,7 +48,7 @@ pipenv install
|
|||
# add local conf file. keep secrets here!
|
||||
# for production .autocat3 should set values for these parameters:
|
||||
# pghost, pguser,
|
||||
# dropbox_client_secret, gdrive_client_secret, msdrive_client_secret, recaptcha_private_key
|
||||
# dropbox_client_secret, gdrive_client_secret, msdrive_client_secret,
|
||||
# log.error_file, log.access_file
|
||||
|
||||
#!! from local
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:py="http://genshi.edgewall.org/"
|
||||
xmlns:i18n="http://genshi.edgewall.org/i18n">
|
||||
|
||||
<xi:include href="site-layout.html" />
|
||||
|
||||
<head>
|
||||
|
||||
${site_head ()}
|
||||
|
||||
<title>Captcha</title>
|
||||
<style type="text/css">
|
||||
.ui-dialog-titlebar-close {
|
||||
display: none;
|
||||
}
|
||||
#recaptcha_response_field {
|
||||
margin-bottom: 1em;
|
||||
width: 300px;
|
||||
}
|
||||
.recaptcha_only_if_incorrect_sol {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js" />
|
||||
<script type="text/javascript">
|
||||
function on_recaptcha_loaded () {
|
||||
$('#need_javascript').hide ();
|
||||
Recaptcha.focus_response_field ();
|
||||
}
|
||||
var RecaptchaOptions = {
|
||||
theme: "custom",
|
||||
custom_theme_widget: "recaptcha_widget",
|
||||
callback: on_recaptcha_loaded
|
||||
};
|
||||
|
||||
require (
|
||||
[
|
||||
'jquery',
|
||||
'jquery-ui/dialog',
|
||||
'jquery.cookie/jquery.cookie'
|
||||
],
|
||||
function (jquery, dialog, cookie) {
|
||||
if (jquery.cookie ('session_id')) {
|
||||
jquery ('#need_cookies').hide ();
|
||||
}
|
||||
Recaptcha.create ("${os.recaptcha_public_key}", "id_captcha", RecaptchaOptions);
|
||||
var dlg = jquery ('#dialog');
|
||||
dlg.dialog ({
|
||||
width: 350,
|
||||
resizable: false,
|
||||
modal: true,
|
||||
closeOnEscape: false
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mw-head-dummy" class="noprint" />
|
||||
|
||||
<div id="content">
|
||||
|
||||
<div class="body">
|
||||
|
||||
<div id="dialog" title="Are you human?" class="hidden">
|
||||
|
||||
<p py:if="os.error is not None" style="color: red">Incorrect please try again</p>
|
||||
|
||||
<p>You have used Project Gutenberg quite a lot today or clicked through it really fast. Email help2019@pglaf.org to report problems. To make sure you are human, we ask you to resolve this captcha:</p>
|
||||
|
||||
<form method="post" action="/w/captcha/answer/">
|
||||
<div id="recaptcha_widget">
|
||||
<div id="recaptcha_image"></div>
|
||||
<p class="recaptcha_only_if_incorrect_sol">Incorrect please try again</p>
|
||||
<p class="recaptcha_only_if_image">Enter the words you see:</p>
|
||||
<p class="recaptcha_only_if_audio">Enter the numbers you hear:</p>
|
||||
<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
|
||||
<input type="submit" name="SubmitButton" value="Submit" />
|
||||
<input type="button" name="ReloadButton" value="Get another captcha"
|
||||
onclick="Recaptcha.reload ()" />
|
||||
<input type="button" name="AudioButton" value="Get an audio captcha"
|
||||
class="recaptcha_only_if_image" onclick="Recaptcha.switch_type ('audio')" />
|
||||
<input type="button" name="ImageButton" value="Get an image captcha"
|
||||
class="recaptcha_only_if_audio" onclick="Recaptcha.switch_type ('image')" />
|
||||
<input type="button" name="HelpButton" value="Help"
|
||||
onclick="Recaptcha.showhelp ()" />
|
||||
<p id="need_cookies">Project Gutenberg works better with cookies enabled.</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<p id="need_javascript">You need javascript for this.</p>
|
||||
|
||||
</div>
|
||||
|
||||
${site_footer ()}
|
||||
|
||||
</div>
|
||||
|
||||
${site_top ()}
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,89 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--! recaptcha is broken with application/xhtml+xml -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:py="http://genshi.edgewall.org/"
|
||||
xmlns:i18n="http://genshi.edgewall.org/i18n"
|
||||
xml:lang="${os.lang}">
|
||||
|
||||
<xi:include href="site-layout.mobile" />
|
||||
|
||||
<head>
|
||||
${site_head ()}
|
||||
|
||||
<title>Captcha</title>
|
||||
|
||||
<style type="text/css">
|
||||
#recaptcha_response_field {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
width: 300px;
|
||||
}
|
||||
.recaptcha_only_if_incorrect_sol {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="application/javascript" src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js" />
|
||||
<script type="application/javascript">
|
||||
function on_recaptcha_loaded () {
|
||||
$('#need_javascript').hide ();
|
||||
Recaptcha.focus_response_field ();
|
||||
}
|
||||
var RecaptchaOptions = {
|
||||
theme: "custom",
|
||||
custom_theme_widget: "recaptcha_widget",
|
||||
callback: on_recaptcha_loaded
|
||||
};
|
||||
|
||||
require (
|
||||
[
|
||||
'jquery',
|
||||
'jquery.cookie/jquery.cookie'
|
||||
],
|
||||
function (jquery, cookie) {
|
||||
if (jquery.cookie ('session_id')) {
|
||||
jquery ('#need_cookies').hide ();
|
||||
}
|
||||
Recaptcha.create ("${os.recaptcha_public_key}", "id_captcha", RecaptchaOptions);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="content">
|
||||
|
||||
<p>You have used Project Gutenberg quite a lot today or clicked through it really fast. To make sure you are human, we ask you to resolve this captcha:</p>
|
||||
|
||||
<form method="post" action="/w/captcha/answer/">
|
||||
<div id="recaptcha_widget">
|
||||
<div id="recaptcha_image"></div>
|
||||
<p class="recaptcha_only_if_incorrect_sol">Incorrect please try again</p>
|
||||
<p class="recaptcha_only_if_image">Enter the words you see:</p>
|
||||
<p class="recaptcha_only_if_audio">Enter the numbers you hear:</p>
|
||||
<input type="text" id="recaptcha_response_field" name="recaptcha_response_field" />
|
||||
<input type="submit" name="SubmitButton" value="Submit" />
|
||||
<input type="button" name="ReloadButton" value="Get another captcha"
|
||||
onclick="Recaptcha.reload ()" />
|
||||
<input type="button" name="AudioButton" value="Get an audio captcha"
|
||||
class="recaptcha_only_if_image" onclick="Recaptcha.switch_type ('audio')" />
|
||||
<input type="button" name="ImageButton" value="Get an image captcha"
|
||||
class="recaptcha_only_if_audio" onclick="Recaptcha.switch_type ('image')" />
|
||||
<input type="button" name="HelpButton" value="Help"
|
||||
onclick="Recaptcha.showhelp ()" />
|
||||
<p id="need_cookies">Project Gutenberg works better with cookies enabled.</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p id="need_javascript">You need javascript for this.</p>
|
||||
|
||||
</div>
|
||||
|
||||
${site_footer ()}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue