Commit db7fecd9 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

add captcha field in local user creation form

Ref: #2117
parent c3ef34ef
......@@ -63,6 +63,8 @@ ASTAKOS_SITENAME GRNET Cloud
ASTAKOS_CLOUD_SERVICES ({'icon': 'home-icon.png', 'id': 'cloud', 'name': 'grnet cloud', 'url': '/'}, Cloud services appear in the horizontal bar
{'id': 'okeanos', 'name': '~okeanos', 'url': '/okeanos.html'},
{'id': 'pithos', 'name': 'pithos+', 'url': '/ui/'})
RECAPTCHA_PUBLIC_KEY Recaptcha public key obtained after registration here: http://recaptcha.net
RECAPTCHA_PRIVATE_KEY Recaptcha private key obtained after registration here: http://recaptcha.net
============================== ============================================================================= ===========================================================================================
Administrator functions
......
......@@ -104,7 +104,7 @@ class InvitationsBackend(object):
main = provider.capitalize() if provider == 'local' else 'ThirdParty'
suffix = 'UserCreationForm'
formclass = '%s%s%s' % (prefix, main, suffix)
return globals()[formclass](initial_data)
return globals()[formclass](initial_data, ip=self.request.META['REMOTE_ADDR'])
def get_signup_initial_data(self, provider):
"""
......@@ -198,7 +198,7 @@ class SimpleBackend(object):
if request.method == 'POST':
if provider == request.POST.get('provider', ''):
initial_data = request.POST
return globals()[formclass](initial_data)
return globals()[formclass](initial_data, ip=self.request.META['REMOTE_ADDR'])
@transaction.commit_manually
def signup(self, form, email_template_name='im/activation_email.txt'):
......
......@@ -42,9 +42,11 @@ from django.utils.http import int_to_base36
from django.core.urlresolvers import reverse
from astakos.im.models import AstakosUser
from astakos.im.settings import INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, BASEURL, SITENAME
from astakos.im.settings import INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY
from astakos.im.widgets import DummyWidget, RecaptchaWidget
import logging
import recaptcha.client.captcha as captcha
logger = logging.getLogger(__name__)
......@@ -56,6 +58,8 @@ class LocalUserCreationForm(UserCreationForm):
* The username field isn't visible and it is assigned a generated id.
* User created is not active.
"""
recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
recaptcha_response_field = forms.CharField(widget=RecaptchaWidget, label='')
class Meta:
model = AstakosUser
......@@ -65,9 +69,14 @@ class LocalUserCreationForm(UserCreationForm):
"""
Changes the order of fields, and removes the username field.
"""
if 'ip' in kwargs:
self.ip = kwargs['ip']
kwargs.pop('ip')
super(LocalUserCreationForm, self).__init__(*args, **kwargs)
self.fields.keyOrder = ['email', 'first_name', 'last_name',
'password1', 'password2']
'password1', 'password2',
'recaptcha_challenge_field',
'recaptcha_response_field']
def clean_email(self):
email = self.cleaned_data['email']
......@@ -79,6 +88,23 @@ class LocalUserCreationForm(UserCreationForm):
except AstakosUser.DoesNotExist:
return email
def clean_recaptcha_response_field(self):
if 'recaptcha_challenge_field' in self.cleaned_data:
self.validate_captcha()
return self.cleaned_data['recaptcha_response_field']
def clean_recaptcha_challenge_field(self):
if 'recaptcha_response_field' in self.cleaned_data:
self.validate_captcha()
return self.cleaned_data['recaptcha_challenge_field']
def validate_captcha(self):
rcf = self.cleaned_data['recaptcha_challenge_field']
rrf = self.cleaned_data['recaptcha_response_field']
check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
if not check.is_valid:
raise forms.ValidationError(_('You have not entered the correct words'))
def save(self, commit=True):
"""
Saves the email, first_name and last_name properties, after the normal
......@@ -163,6 +189,9 @@ class ThirdPartyUserCreationForm(ProfileForm):
fields = ('email', 'last_name', 'first_name', 'affiliation', 'provider', 'third_party_identifier')
def __init__(self, *args, **kwargs):
if 'ip' in kwargs:
self.ip = kwargs['ip']
kwargs.pop('ip')
super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
self.fields.keyOrder = ['email']
......
......@@ -51,3 +51,7 @@ CLOUD_SERVICES = getattr(settings, 'ASTAKOS_CLOUD_SERVICES', (
{ 'url':'/', 'name':'grnet cloud', 'id':'cloud', 'icon':'home-icon.png' },
{ 'url':'/okeanos.html', 'name':'~okeanos', 'id':'okeanos' },
{ 'url':'/ui/', 'name':'pithos+', 'id':'pithos' }))
# Set recaptcha keys
RECAPTCHA_PUBLIC_KEY = getattr(settings, 'ASTAKOS_RECAPTCHA_PUBLIC_KEY', '')
RECAPTCHA_PRIVATE_KEY = getattr(settings, 'ASTAKOS_RECAPTCHA_PRIVATE_KEY', '')
......@@ -167,7 +167,7 @@ def authenticated(request, backend=None, login_template='im/login.html', on_sign
elif user and not user.is_active:
messages.add_message(request, messages.ERROR, 'Inactive account: %s' % user.email)
return render_response(login_template,
form = LocalUserCreationForm(),
form = LocalUserCreationForm(ip=request.META['REMOTE_ADDR']),
context_instance=get_context(request, extra_context))
def reserved_screen_name(screen_name):
......@@ -231,5 +231,5 @@ def create_user(request, form, backend=None, post_data={}, next = None, on_failu
for provider in IM_MODULES:
extra_context['%s_form' % provider] = backend.get_signup_form(provider)
return render_response(on_failure,
form = LocalUserCreationForm(),
form = LocalUserCreationForm(ip=request.META['REMOTE_ADDR']),
context_instance=get_context(request, extra_context))
\ No newline at end of file
......@@ -10,7 +10,7 @@
{{ field.errors }}
<p class="{% if field.blank %}required{% endif %}">
{{ field.label_tag }}
{{ field }}
{{ field|safe }}
</p>
</div>
{% endfor %}
# Copyright 2011-2012 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
# conditions are met:
#
# 1. Redistributions of source code must retain the above
# copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# The views and conclusions contained in the software and
# documentation are those of the authors and should not be
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
import recaptcha.client.captcha as captcha
from django import forms
from astakos.im.settings import RECAPTCHA_PUBLIC_KEY
class RecaptchaWidget(forms.Widget):
""" A Widget which "renders" the output of captcha.displayhtml """
def render(self, *args, **kwargs):
return captcha.displayhtml(RECAPTCHA_PUBLIC_KEY)
class DummyWidget(forms.Widget):
"""
A dummy Widget class for a placeholder input field which will
be created by captcha.displayhtml
"""
# make sure that labels are not displayed either
is_hidden=True
def render(self, *args, **kwargs):
return ''
\ No newline at end of file
......@@ -78,7 +78,8 @@ INSTALL_REQUIRES = [
'Django>=1.2, <1.3',
'South>=0.7, <=0.7.3',
'httplib2==0.6.0',
'snf-common>=0.8.1'
'snf-common>=0.8.1',
'recaptcha-client>=1.0.5'
]
EXTRAS_REQUIRES = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment