Skip to content

Commit f75f305

Browse files
committedAug 8, 2015
Add reCAPTCHA support
Signed-off-by: Chris Warrick <kwpolska@gmail.com>
1 parent bb9f00a commit f75f305

File tree

6 files changed

+45
-3
lines changed

6 files changed

+45
-3
lines changed
 

‎coil/data/templates/jinja/coil_login.tmpl

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{# -*- coding: utf-8 -*- #}
22
{% extends 'base.tmpl' %}
3+
{% block extra_head %}
4+
{{ super() }}
5+
{% if captcha['enabled'] %}
6+
<script src='https://www.google.com/recaptcha/api.js'></script>
7+
{% endif %}
8+
{% endblock %}
39
{% block content %}
410
{% if alert %}
511
<div class="alert alert-{{ alert_status }}" role="alert">{{ alert }}</div>
@@ -11,6 +17,9 @@
1117
<input name="username" type="text" id="inputUsername" class="form-control" placeholder="Username" required autofocus>
1218
<label for="inputPassword" class="sr-only">Password</label>
1319
<input name="password" type="password" id="inputPassword" class="form-control" placeholder="Password" required>
20+
{% if captcha['enabled'] %}
21+
<div class="g-recaptcha" data-sitekey="{{ captcha['site_key'] }}"></div>
22+
{% endif %}
1423
<div class="checkbox">
1524
<label>
1625
<input type="checkbox" name="remember" value="remember"> Remember me

‎coil/data/templates/mako/coil_login.tmpl

+9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## -*- coding: utf-8 -*-
22
<%inherit file="base.tmpl"/>
3+
<%block name="extra_head">
4+
${parent.extra_head()}
5+
% if captcha['enabled']:
6+
<script src='https://www.google.com/recaptcha/api.js'></script>
7+
% endif
8+
</%block>
39
<%block name="content">
410
% if alert:
511
<div class="alert alert-${alert_status}" role="alert">${alert}</div>
@@ -11,6 +17,9 @@
1117
<input name="username" type="text" id="inputUsername" class="form-control" placeholder="Username" required autofocus>
1218
<label for="inputPassword" class="sr-only">Password</label>
1319
<input name="password" type="password" id="inputPassword" class="form-control" placeholder="Password" required>
20+
% if captcha['enabled']:
21+
<div class="g-recaptcha" data-sitekey="${captcha['site_key']}"></div>
22+
% endif
1423
<div class="checkbox">
1524
<label>
1625
<input type="checkbox" name="remember" value="remember"> Remember me

‎coil/web.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import redis
3737
import rq
3838
import operator
39+
import requests
3940
import coil.tasks
4041
from nikola.utils import (unicode_str, get_logger, ColorfulStderrHandler,
4142
write_metadata, TranslatableSetting)
@@ -119,6 +120,9 @@ def configure_site():
119120

120121
app.secret_key = _site.config.get('COIL_SECRET_KEY')
121122
app.config['COIL_URL'] = _site.config.get('COIL_URL')
123+
app.config['COIL_LOGIN_CAPTCHA'] = _site.config.get(
124+
'COIL_LOGIN_CAPTCHA',
125+
{'enabled': False, 'site_key': '', 'secret_key': ''})
122126
app.config['COIL_LIMITED'] = _site.config.get('COIL_LIMITED', False)
123127
app.config['REDIS_URL'] = _site.config.get('COIL_REDIS_URL',
124128
'redis://localhost:6379/0')
@@ -543,14 +547,28 @@ def login():
543547
alert = None
544548
alert_status = 'danger'
545549
code = 200
550+
captcha = app.config['COIL_LOGIN_CAPTCHA']
546551
form = LoginForm()
547552
if request.method == 'POST':
548553
if form.validate():
549554
user = find_user_by_name(request.form['username'])
550555
if not user:
551556
alert = 'Invalid credentials.'
552557
code = 401
553-
else:
558+
if captcha['enabled']:
559+
r = requests.post('https://www.google.com/recaptcha/api/siteverify',
560+
data={'secret': captcha['secret_key'],
561+
'response': request.form['g-recaptcha-response'],
562+
'remoteip': request.remote_addr})
563+
if r.status_code != 200:
564+
alert = 'Cannot check CAPTCHA response.'
565+
code = 500
566+
else:
567+
rj = r.json()
568+
if not rj['success']:
569+
alert = 'Invalid CAPTCHA response. Please try again.'
570+
code = 401
571+
if code == 200:
554572
try:
555573
pwd_ok = check_password(user.password,
556574
request.form['password'])
@@ -584,7 +602,8 @@ def login():
584602
alert_status = 'success'
585603
return render('coil_login.tmpl', {'title': 'Login', 'alert': alert, 'form':
586604
form, 'alert_status': alert_status,
587-
'pwdchange_skip': True},
605+
'pwdchange_skip': True,
606+
'captcha': captcha},
588607
code)
589608

590609

‎docs/admin/setup.rst

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ Then, you must make some changes to the config:
5353
**Store it in a safe place** — git is not one! You can use
5454
``os.urandom(24)`` to generate something good.
5555
* ``COIL_URL`` — the URL under which Coil can be accessed.
56+
* ``COIL_LOGIN_CAPTCHA`` — if you want reCAPTCHA to appear on the login page
57+
(aimed at plugic environments, eg. the demo site), set this to a dict of
58+
``{'enabled': True, 'site_key': '', 'secret_key': ''}`` and fill in your data.
59+
If you don’t want a CAPTCHA, don’t set this setting.
5660
* ``_MAKO_DISABLE_CACHING = True``
5761
* Modify ``POSTS`` and ``PAGES``, replacing ``.txt`` with ``.html``.
5862
* You must set the mode (Limited vs Full) and configure it accordingly — see

‎requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pyinotify==0.9.5
1313
python-bcrypt==0.3.1
1414
pytz==2015.2
1515
redis==2.10.3
16+
requests==2.7.0
1617
rq==0.5.3
1718
six==1.9.0
1819
webassets==0.10.1

‎setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
dependencies = [l.strip() for l in fh]
88

99
setup(name='coil',
10-
version='1.3.3',
10+
version='1.3.4-alpha.1',
1111
description='A user-friendly CMS frontend for Nikola.',
1212
keywords='coil,nikola,cms',
1313
author='Chris Warrick, Roberto Alsina, Henry Hirsch et al.',

0 commit comments

Comments
 (0)
Please sign in to comment.