From ee9df9bfb7fe4a3779da8d53ad3dc07d28e0bd2d Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Mon, 12 May 2014 12:21:55 +0530 Subject: [PATCH] Convert login page to Django forms --- modules/installed/lib/auth.py | 10 ++-- modules/installed/lib/auth_page.py | 74 ++++++++++++++++++++---------- templates/form.html | 39 ++++++++++++++++ 3 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 templates/form.html diff --git a/modules/installed/lib/auth.py b/modules/installed/lib/auth.py index 71b10c387..974ecef93 100644 --- a/modules/installed/lib/auth.py +++ b/modules/installed/lib/auth.py @@ -67,12 +67,14 @@ def check_credentials(username, passphrase): cfg.log(error) return error - bad_authentication = "Bad user-name or password." + bad_authentication = "Bad username or password." hashed_password = None - if username in cfg.users: - if "passphrase" in cfg.users[username]: - hashed_password = cfg.users[username]['passphrase'] + if username not in cfg.users or 'passphrase' not in cfg.users[username]: + cfg.log(bad_authentication) + return bad_authentication + + hashed_password = cfg.users[username]['passphrase'] try: # time-dependent comparison when non-ASCII characters are used. diff --git a/modules/installed/lib/auth_page.py b/modules/installed/lib/auth_page.py index 075ce5032..1d9b49ca3 100644 --- a/modules/installed/lib/auth_page.py +++ b/modules/installed/lib/auth_page.py @@ -4,45 +4,70 @@ Controller to provide login and logout actions import cherrypy import cfg +from django import forms +from gettext import gettext as _ from plugin_mount import PagePlugin -from modules.forms import Form -from auth import * +import auth import util +class LoginForm(forms.Form): # pylint: disable-msg=W0232 + """Login form""" + from_page = forms.CharField(widget=forms.HiddenInput(), required=False) + + username = forms.CharField(label=_('Username')) + password = forms.CharField(label=_('Passphrase'), + widget=forms.PasswordInput()) + + def clean(self): + """Check for valid credentials""" + # pylint: disable-msg=E1101 + if 'username' in self._errors or 'password' in self._errors: + return self.cleaned_data + + error_msg = auth.check_credentials(self.cleaned_data['username'], + self.cleaned_data['password']) + if error_msg: + raise forms.ValidationError(error_msg, code='invalid_credentials') + + return self.cleaned_data + + class AuthController(PagePlugin): + """Login and logout pages""" + def __init__(self, *args, **kwargs): PagePlugin.__init__(self, *args, **kwargs) - self.register_page("auth") + + self.register_page('auth') def on_login(self, username): """Called on successful login""" - + def on_logout(self, username): """Called on logout""" - - def get_loginform(self, username, msg='', from_page=cfg.server_dir+"/"): - form = Form(title="Login", action=cfg.server_dir + "/auth/login", message=msg) - form.text_input(name="from_page", value=from_page, type="hidden") - form.text_input("Username", name="username", value=username) - form.text_input("Passphrase", name="passphrase", type="password") - form.submit(label="Login") - return util.render_template(main=form.render()) - @cherrypy.expose - def login(self, username=None, passphrase=None, from_page=cfg.server_dir+"/", **kwargs): - if username is None or passphrase is None: - return self.get_loginform("", from_page=from_page) - - error_msg = check_credentials(username, passphrase) - if error_msg: - return self.get_loginform(username, error_msg, from_page) + def login(self, from_page=cfg.server_dir+"/", **kwargs): + """Serve the login page""" + form = None + + if kwargs: + form = LoginForm(kwargs, prefix='auth') + # pylint: disable-msg=E1101 + if form.is_valid(): + username = form.cleaned_data['username'] + cherrypy.session[cfg.session_key] = username + cherrypy.request.login = username + self.on_login(username) + raise cherrypy.HTTPRedirect(from_page or + (cfg.server_dir + "/")) else: - cherrypy.session[cfg.session_key] = cherrypy.request.login = username - self.on_login(username) - raise cherrypy.HTTPRedirect(from_page or (cfg.server_dir + "/")) - + form = LoginForm(prefix='auth') + + return util.render_template(template='form', title=_('Login'), + form=form, submit_text=_('Login')) + @cherrypy.expose def logout(self, from_page=cfg.server_dir+"/"): sess = cherrypy.session @@ -51,4 +76,5 @@ class AuthController(PagePlugin): if username: cherrypy.request.login = None self.on_logout(username) + raise cherrypy.HTTPRedirect(from_page or (cfg.server_dir + "/")) diff --git a/templates/form.html b/templates/form.html new file mode 100644 index 000000000..e1a948ba3 --- /dev/null +++ b/templates/form.html @@ -0,0 +1,39 @@ +{% extends "login_nav.html" %} +{% comment %} +# +# 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 . +# +{% endcomment %} + +{% load bootstrap %} + +{% block main_block %} + + {% for severity, message in messages %} +
{{ message }}
+ {% endfor %} + +
+ {% csrf_token %} + + {{ form|bootstrap }} + + + +
+ +{% endblock %}