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