Add django-simple-captcha in the login page

User will be shown captcha in the second attempt to login if login
fails in the first attempt.

Signed-off-by: Joseph Nuthalpati <njoseph@thoughtworks.com>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Joseph Nuthalpati 2017-08-22 11:57:30 +05:30 committed by James Valleroy
parent 21d6174ba0
commit 62f26433e8
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
10 changed files with 80 additions and 18 deletions

View File

@ -27,6 +27,7 @@
python3-configobj \
python3-coverage \
python3-django \
python3-django-captcha \
python3-django-stronghold \
python3-gi \
python3-psutil \

View File

@ -209,6 +209,7 @@ def configure_django():
]
applications = ['bootstrapform',
'captcha',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
@ -242,6 +243,7 @@ def configure_django():
],
CACHES={'default':
{'BACKEND': 'django.core.cache.backends.dummy.DummyCache'}},
CAPTCHA_FONT_PATH=['/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf'],
DATABASES={'default':
{'ENGINE': 'django.db.backends.sqlite3',
'NAME': cfg.store_file}},
@ -271,6 +273,9 @@ def configure_django():
SESSION_ENGINE='django.contrib.sessions.backends.file',
SESSION_FILE_PATH=sessions_directory,
STATIC_URL='/'.join([cfg.server_dir, 'static/']).replace('//', '/'),
# STRONGHOLD_PUBLIC_URLS=(r'^captcha/', ),
STRONGHOLD_PUBLIC_NAMED_URLS=('captcha-image', 'captcha-image-2x',
'captcha-audio', 'captcha-refresh', ),
TEMPLATES=templates,
USE_L10N=True,
USE_X_FORWARDED_HOST=cfg.use_x_forwarded_host)

View File

@ -27,7 +27,6 @@ import os
import re
from plinth import cfg
from plinth import urls
from plinth import setup
from plinth.signals import pre_module_loading, post_module_loading
@ -114,6 +113,7 @@ def _insert_modules(module_name, module, remaining_modules, ordered_modules):
def _include_module_urls(module_import_path, module_name):
"""Include the module's URLs in global project URLs list"""
from plinth import urls
url_module = module_import_path + '.urls'
try:
urls.urlpatterns += [

View File

@ -0,0 +1,26 @@
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Forms for the Single Sign On module of Plinth
"""
from django.contrib.auth.forms import AuthenticationForm as DjangoAuthenticationForm
from captcha.fields import CaptchaField
class AuthenticationForm(DjangoAuthenticationForm):
captcha = CaptchaField()

View File

@ -20,6 +20,7 @@ URLs for the Single Sign On module.
from django.conf.urls import url
from .views import SSOLoginView, refresh
from stronghold.decorators import public

View File

@ -21,6 +21,8 @@ Views for the Single Sign On module of Plinth
import os
import urllib
from .forms import AuthenticationForm
from plinth import actions
from django.http import HttpResponseRedirect
@ -51,15 +53,21 @@ class SSOLoginView(LoginView):
"""View to login to Plinth and set a auth_pubtkt cookie which will be
used to provide Single Sign On for some other applications
"""
redirect_authenticated_user = True
template_name = 'login.html'
def dispatch(self, request, *args, **kwargs):
response = super(SSOLoginView, self).dispatch(request, *args, **kwargs)
return set_ticket_cookie(
request.user,
response) if request.user.is_authenticated else response
if request.POST:
if request.user.is_authenticated:
return set_ticket_cookie(request.user, response)
else: # Redirect user to captcha page
return HttpResponseRedirect('captcha')
return response
class CaptchaLoginView(SSOLoginView):
form_class = AuthenticationForm
class SSOLogoutView(LogoutView):

View File

@ -14,7 +14,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
URLs for the Users module
"""
@ -24,24 +23,31 @@ from django.urls import reverse_lazy
from stronghold.decorators import public
from plinth.utils import non_admin_view
from plinth.modules.sso.views import SSOLoginView, SSOLogoutView
from plinth.modules.sso.views import SSOLoginView, SSOLogoutView, CaptchaLoginView
from . import views
urlpatterns = [
url(r'^sys/users/$', views.UserList.as_view(), name='index'),
url(r'^sys/users/create/$', views.UserCreate.as_view(), name='create'),
url(r'^sys/users/(?P<slug>[\w.@+-]+)/edit/$',
non_admin_view(views.UserUpdate.as_view()), name='edit'),
url(r'^sys/users/(?P<slug>[\w.@+-]+)/delete/$', views.UserDelete.as_view(),
non_admin_view(views.UserUpdate.as_view()),
name='edit'),
url(r'^sys/users/(?P<slug>[\w.@+-]+)/delete/$',
views.UserDelete.as_view(),
name='delete'),
url(r'^sys/users/(?P<slug>[\w.@+-]+)/change_password/$',
non_admin_view(views.UserChangePassword.as_view()),
name='change_password'),
# Add Django's login/logout urls
url(r'^accounts/login/$', public(SSOLoginView.as_view()), name='login'),
url(r'^accounts/logout/$', non_admin_view(SSOLogoutView.as_view()),
{'next_page': reverse_lazy('index')}, name='logout'),
url(r'^users/firstboot/$', public(views.FirstBootView.as_view()),
url(r'^accounts/logout/$',
non_admin_view(SSOLogoutView.as_view()),
{'next_page': reverse_lazy('index')},
name='logout'),
url(r'^accounts/login/captcha/$',
public(CaptchaLoginView.as_view()),
name='captcha-login'),
url(r'^users/firstboot/$',
public(views.FirstBootView.as_view()),
name='firstboot'),
]

View File

@ -14,20 +14,33 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Django URLconf file containing all urls
"""
from django.conf.urls import url
from captcha import views as cviews
from django.conf.urls import url, include
from django.views.generic import TemplateView
from stronghold.decorators import public
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^apps/$', TemplateView.as_view(template_name='apps.html'),
url(r'^apps/$',
TemplateView.as_view(template_name='apps.html'),
name='apps'),
url(r'^sys/$', views.system_index, name='system'),
# captcha urls are public
url(r'image/(?P<key>\w+)/$',
public(cviews.captcha_image),
name='captcha-image',
kwargs={'scale': 1}),
url(r'image/(?P<key>\w+)@2/$',
public(cviews.captcha_image),
name='captcha-image-2x',
kwargs={'scale': 2}),
url(r'audio/(?P<key>\w+)/$', public(cviews.captcha_audio), name='captcha-audio'),
url(r'refresh/$', public(cviews.captcha_refresh), name='captcha-refresh'),
]

View File

@ -3,6 +3,7 @@ configobj
coverage >= 3.7
django >= 1.11.0
django-bootstrap-form
django-simple-captcha
django-stronghold
psutil
python-apt

View File

@ -212,6 +212,7 @@ setuptools.setup(
'configobj',
'django >= 1.11.0',
'django-bootstrap-form',
'django-simple-captcha',
'django-stronghold',
'psutil',
'python-apt',