##// END OF EJS Templates
re-captcha: adjust for v2 that is the only left one supported since 1st of May.
marcink -
r2731:f80f9da7 default
parent child Browse files
Show More
@@ -225,13 +225,6 b' self: super: {'
225 225 };
226 226 });
227 227
228 recaptcha-client = super.recaptcha-client.override (attrs: {
229 meta = {
230 # TODO: It is MIT/X11
231 license = pkgs.lib.licenses.mit;
232 };
233 });
234
235 228 python-editor = super.python-editor.override (attrs: {
236 229 meta = {
237 230 license = pkgs.lib.licenses.asl20;
@@ -1497,19 +1497,6 b''
1497 1497 license = [ pkgs.lib.licenses.bsdOriginal { fullName = "LGPL+BSD"; } { fullName = "GNU Library or Lesser General Public License (LGPL)"; } ];
1498 1498 };
1499 1499 };
1500 recaptcha-client = super.buildPythonPackage {
1501 name = "recaptcha-client-1.0.6";
1502 buildInputs = with self; [];
1503 doCheck = false;
1504 propagatedBuildInputs = with self; [];
1505 src = fetchurl {
1506 url = "https://files.pythonhosted.org/packages/0a/ea/5f2fbbfd894bdac1c68ef8d92019066cfcf9fbff5fe3d728d2b5c25c8db4/recaptcha-client-1.0.6.tar.gz";
1507 sha256 = "28c6853c1d13d365b7dc71a6b05e5ffb56471f70a850de318af50d3d7c0dea2f";
1508 };
1509 meta = {
1510 license = [ { fullName = "MIT/X11"; } ];
1511 };
1512 };
1513 1500 redis = super.buildPythonPackage {
1514 1501 name = "redis-2.10.6";
1515 1502 buildInputs = with self; [];
@@ -1553,7 +1540,7 b''
1553 1540 name = "rhodecode-enterprise-ce-4.13.0";
1554 1541 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock webtest cov-core coverage configobj];
1555 1542 doCheck = true;
1556 propagatedBuildInputs = with self; [setuptools-scm amqp authomatic babel beaker celery chameleon channelstream click colander configobj cssselect decorator deform docutils dogpile.cache dogpile.core ecdsa formencode future futures gnureadline infrae.cache iso8601 itsdangerous jinja2 billiard kombu lxml mako markdown markupsafe msgpack-python mysql-python objgraph packaging paste pastedeploy pastescript pathlib2 peppercorn psutil psycopg2 py-bcrypt pycrypto pycurl pyflakes pygments-markdown-lexer pygments pyparsing pyramid-beaker pyramid-debugtoolbar pyramid-jinja2 pyramid-mako pyramid pysqlite python-dateutil python-ldap python-memcached python-pam pytz tzlocal pyzmq py-gfm recaptcha-client redis repoze.lru requests routes setproctitle simplejson six sqlalchemy sshpubkeys subprocess32 supervisor tempita translationstring trollius urllib3 urlobject venusian weberror webhelpers2 webhelpers webob whoosh wsgiref zope.cachedescriptors zope.deprecation zope.event zope.interface nbconvert bleach nbformat jupyter-client alembic invoke bumpversion gevent greenlet gunicorn waitress ipdb ipython cprofilev bottle rhodecode-tools appenlight-client pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock webtest cov-core coverage];
1543 propagatedBuildInputs = with self; [setuptools-scm amqp authomatic babel beaker celery chameleon channelstream click colander configobj cssselect decorator deform docutils dogpile.cache dogpile.core ecdsa formencode future futures gnureadline infrae.cache iso8601 itsdangerous jinja2 billiard kombu lxml mako markdown markupsafe msgpack-python mysql-python objgraph packaging paste pastedeploy pastescript pathlib2 peppercorn psutil psycopg2 py-bcrypt pycrypto pycurl pyflakes pygments-markdown-lexer pygments pyparsing pyramid-beaker pyramid-debugtoolbar pyramid-jinja2 pyramid-mako pyramid pysqlite python-dateutil python-ldap python-memcached python-pam pytz tzlocal pyzmq py-gfm redis repoze.lru requests routes setproctitle simplejson six sqlalchemy sshpubkeys subprocess32 supervisor tempita translationstring trollius urllib3 urlobject venusian weberror webhelpers2 webhelpers webob whoosh wsgiref zope.cachedescriptors zope.deprecation zope.event zope.interface nbconvert bleach nbformat jupyter-client alembic invoke bumpversion gevent greenlet gunicorn waitress ipdb ipython cprofilev bottle rhodecode-tools appenlight-client pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock webtest cov-core coverage];
1557 1544 src = ./.;
1558 1545 meta = {
1559 1546 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
@@ -65,7 +65,6 b' pytz==2018.4'
65 65 tzlocal==1.5.1
66 66 pyzmq==14.6.0
67 67 py-gfm==0.1.3
68 recaptcha-client==1.0.6
69 68 redis==2.10.6
70 69 repoze.lru==0.7
71 70 requests==2.9.1
@@ -97,16 +97,16 b' class TestRegisterCaptcha(object):'
97 97 assertr.no_element_exists('#recaptcha_field')
98 98
99 99 @pytest.mark.parametrize('valid', [False, True])
100 @mock.patch('rhodecode.apps.login.views.submit')
100 @mock.patch.object(LoginView, 'validate_captcha')
101 101 @mock.patch.object(LoginView, '_get_captcha_data')
102 102 def test_register_with_active_captcha(
103 self, m_get_captcha_data, m_submit, valid, app, csrf_token):
103 self, m_get_captcha_data, m_validate_captcha, valid, app, csrf_token):
104 104 captcha = CaptchaData(
105 105 active=True, private_key='PRIVATE_KEY', public_key='PUBLIC_KEY')
106 106 m_get_captcha_data.return_value = captcha
107 107 m_response = mock.Mock()
108 108 m_response.is_valid = valid
109 m_submit.return_value = m_response
109 m_validate_captcha.return_value = valid, 'ok'
110 110
111 111 params = {
112 112 'csrf_token': csrf_token,
@@ -25,10 +25,10 b' import formencode'
25 25 import formencode.htmlfill
26 26 import logging
27 27 import urlparse
28 import requests
28 29
29 30 from pyramid.httpexceptions import HTTPFound
30 31 from pyramid.view import view_config
31 from recaptcha.client.captcha import submit
32 32
33 33 from rhodecode.apps._base import BaseAppView
34 34 from rhodecode.authentication.base import authenticate, HTTP_TYPE
@@ -124,6 +124,29 b' class LoginView(BaseAppView):'
124 124 return CaptchaData(
125 125 active=active, private_key=private_key, public_key=public_key)
126 126
127 def validate_captcha(self, private_key):
128
129 captcha_rs = self.request.POST.get('g-recaptcha-response')
130 url = "https://www.google.com/recaptcha/api/siteverify"
131 params = {
132 'secret': private_key,
133 'response': captcha_rs,
134 'remoteip': get_ip_addr(self.request.environ)
135 }
136 verify_rs = requests.get(url, params=params, verify=True)
137 verify_rs = verify_rs.json()
138 captcha_status = verify_rs.get('success', False)
139 captcha_errors = verify_rs.get('error-codes', [])
140 if not isinstance(captcha_errors, list):
141 captcha_errors = [captcha_errors]
142 captcha_errors = ', '.join(captcha_errors)
143 captcha_message = ''
144 if captcha_status is False:
145 captcha_message = "Bad captcha. Errors: {}".format(
146 captcha_errors)
147
148 return captcha_status, captcha_message
149
127 150 @view_config(
128 151 route_name='login', request_method='GET',
129 152 renderer='rhodecode:templates/login.mako')
@@ -262,17 +285,15 b' class LoginView(BaseAppView):'
262 285 form_result['active'] = auto_active
263 286
264 287 if captcha.active:
265 response = submit(
266 self.request.POST.get('recaptcha_challenge_field'),
267 self.request.POST.get('recaptcha_response_field'),
268 private_key=captcha.private_key,
269 remoteip=get_ip_addr(self.request.environ))
270 if not response.is_valid:
288 captcha_status, captcha_message = self.validate_captcha(
289 captcha.private_key)
290
291 if not captcha_status:
271 292 _value = form_result
272 293 _msg = _('Bad captcha')
273 error_dict = {'recaptcha_field': _msg}
274 raise formencode.Invalid(_msg, _value, None,
275 error_dict=error_dict)
294 error_dict = {'recaptcha_field': captcha_message}
295 raise formencode.Invalid(
296 _msg, _value, None, error_dict=error_dict)
276 297
277 298 new_user = UserModel().create_registration(form_result)
278 299
@@ -339,15 +360,13 b' class LoginView(BaseAppView):'
339 360 user_email = form_result['email']
340 361
341 362 if captcha.active:
342 response = submit(
343 self.request.POST.get('recaptcha_challenge_field'),
344 self.request.POST.get('recaptcha_response_field'),
345 private_key=captcha.private_key,
346 remoteip=get_ip_addr(self.request.environ))
347 if not response.is_valid:
363 captcha_status, captcha_message = self.validate_captcha(
364 captcha.private_key)
365
366 if not captcha_status:
348 367 _value = form_result
349 368 _msg = _('Bad captcha')
350 error_dict = {'recaptcha_field': _msg}
369 error_dict = {'recaptcha_field': captcha_message}
351 370 raise formencode.Invalid(
352 371 _msg, _value, None, error_dict=error_dict)
353 372
@@ -305,9 +305,6 b''
305 305 "python2.7-pyzmq-14.6.0": {
306 306 "BSD 4-clause \"Original\" or \"Old\" License": "http://spdx.org/licenses/BSD-4-Clause"
307 307 },
308 "python2.7-recaptcha-client-1.0.6": {
309 "MIT License": "http://spdx.org/licenses/MIT"
310 },
311 308 "python2.7-repoze.lru-0.6": {
312 309 "Repoze License": "http://www.repoze.org/LICENSE.txt"
313 310 },
@@ -65,26 +65,26 b''
65 65 </div>
66 66 <div class="panel-body">
67 67 <div class="label">
68 <label for="rhodecode_captcha_public_key">${_('Google ReCaptcha public key')}</label>
68 <label for="rhodecode_captcha_public_key">${_('Google reCaptcha v2 site key.')}</label>
69 69 </div>
70 70 <div class="field input">
71 71 ${h.text('rhodecode_captcha_public_key',size=60)}
72 72 </div>
73 73 <div class="field">
74 74 <span class="help-block">
75 ${_('Public key for reCaptcha system.')}
75 ${_('Site key for reCaptcha v2 system.')}
76 76 </span>
77 77 </div>
78 78
79 79 <div class="label">
80 <label for="rhodecode_captcha_private_key">${_('Google ReCaptcha private key')}</label>
80 <label for="rhodecode_captcha_private_key">${_('Google reCaptcha v2 secret key.')}</label>
81 81 </div>
82 82 <div class="field input">
83 83 ${h.text('rhodecode_captcha_private_key',size=60)}
84 84 </div>
85 85 <div class="field">
86 86 <span class="help-block">
87 ${_('Private key for reCaptcha system. Setting this value will enable captcha on registration')}
87 ${_('Secret key for reCaptcha v2 system. Setting this value will enable captcha on registration and password reset forms.')}
88 88 </span>
89 89 </div>
90 90 </div>
@@ -61,6 +61,7 b''
61 61 <label for="email">${_('Captcha')}:</label>
62 62 ${h.hidden('recaptcha_field')}
63 63 <div id="recaptcha"></div>
64
64 65 %if 'recaptcha_field' in errors:
65 66 <span class="error-message">${errors.get('recaptcha_field')}</span>
66 67 <br />
@@ -78,14 +79,20 b''
78 79 </div>
79 80 </div>
80 81
81 %if captcha_active:
82 <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
83 %endif
84 82 <script type="text/javascript">
85 83 $(document).ready(function(){
86 84 $('#email').focus();
87 %if captcha_active:
88 Recaptcha.create("${captcha_public_key}", "recaptcha", {theme: "white"});
89 %endif
90 85 });
91 86 </script>
87
88 % if captcha_active:
89 <script type="text/javascript">
90 var onloadCallback = function() {
91 grecaptcha.render('recaptcha', {
92 'sitekey' : "${captcha_public_key}"
93 });
94 };
95 </script>
96 <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
97 % endif
98
@@ -110,14 +110,21 b''
110 110 </div>
111 111 </div>
112 112
113 %if captcha_active:
114 <script type="text/javascript" src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
115 %endif
113
116 114 <script type="text/javascript">
117 $(document).ready(function(){
115 $(document).ready(function(){
118 116 $('#username').focus();
119 %if captcha_active:
120 Recaptcha.create("${captcha_public_key}", "recaptcha", {theme: "white"});
121 %endif
122 });
117 });
123 118 </script>
119
120 % if captcha_active:
121 <script type="text/javascript">
122 var onloadCallback = function() {
123 grecaptcha.render('recaptcha', {
124 'sitekey' : "${captcha_public_key}"
125 });
126 };
127 </script>
128 <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
129 % endif
130
General Comments 0
You need to be logged in to leave comments. Login now