Commit 8830eebe authored by Laurent Bachelier's avatar Laurent Bachelier

Make the login form more user-friendly

* Labels are associated with the inputs
* Errors and information messages are displayed.
* Try to redirect to the "real" referer or at least the home on success
* Use the partials
* Prefix the form to avoid conflicts

refs #599
parent 01858b89
......@@ -19,6 +19,7 @@
import sys
import re
from ass2m.plugin import Plugin
from ass2m.cmd import Command, ConsolePart
......@@ -342,20 +343,32 @@ class ContactsRemoveCmd(Command):
class LoginAction(Action):
def get(self):
FORM_RE = re.compile('login\[(\w+)\]')
def _get_form(self):
form = dict([(self.FORM_RE.match(k).groups()[0], v) \
for k, v in self.ctx.req.str_POST.iteritems() \
if self.FORM_RE.match(k)])
form['referer'] = form.get('referer') \
or self.ctx.req.referer \
or quote_url(self.ctx.root_url)
return form
def get(self, form = None):
form = form or self._get_form()
self.ctx.template_vars['form'] = form
self.ctx.res.body = self.ctx.render('login.html')
def post(self):
form_username = self.ctx.req.str_POST.get('username')
form_password = self.ctx.req.str_POST.get('password')
if form_username and form_password:
user = self.ctx.storage.get_user(form_username)
if user and user.is_valid_password(form_password):
self.ctx.res = HTTPFound(location=quote_url(self.ctx.url))
form = self._get_form()
if form.get('username') and form.get('password'):
user = self.ctx.storage.get_user(form['username'])
if user and user.is_valid_password(form['password']):
self.ctx.res = HTTPFound(location=form['referer'])
# set cookie
self.ctx.login(user)
return
self.get()
self.get(form)
class LogoutAction(Action):
......
......@@ -3,20 +3,35 @@
<article>
<section>
% if user:
Current user: ${partials.display_user(user)}<br/>
% if 'username' in form or 'password' in form:
<p class="error message"><span>Invalid username or password.</span></p>
% elif not user:
<p class="message"><span>Not logged in.</p>
% else:
Not logged in.
<p class="message"><span>Already logged in as ${partials.display_user(user)}.</p>
% endif
</section>
<section>
<form method="post" action="${url | n,U,h}">
<label>Username</label><input name="username" />
<label>Password</label><input name="password" type="password" />
<label for="login_username">Username</label>
<input id="login_username"
name="login[username]"
value="${form.get('username', '') | h}" />
<label for="login_password">Password</label>
<input id="login_password"
name="login[password]"
value="${form.get('password', '') | h}"
type="password" />
<input id="login_referer"
name="login[referer]"
value="${form.get('referer', '') | h}"
type="hidden" />
<input type="submit" value="Login"/>
</form>
</section>
</article>
<%def name="title(html=False)">Login</%def>
<%def name="header()">
${parent.header()}
<nav id="toolbox">${partials.loginbox()}</nav>
</%def>
......@@ -63,8 +63,8 @@ Attendees:
res = self.app.get('/?action=login', status=200)
form = res.form
form['username'] = 'penguin'
form['password'] = 'monkey1'
form['login[username]'] = 'penguin'
form['login[password]'] = 'monkey1'
res = form.submit(status=302)
res = res.follow(status=200)
......
......@@ -32,25 +32,35 @@ class LoginTest(TestCase):
def test_formLogin(self):
res = self.app.get('/?action=login', status=200)
assert 'Not logged in.' in res.body
assert 'Invalid username or password.' not in res.body
assert 'Logged as.' not in res.body
form = res.form
form['username'] = 'invalid'
form['password'] = 'invalid'
form['login[username]'] = 'invalid'
form['login[password]'] = 'invalid'
res = form.submit()
assert 'Not logged in.' in res.body
assert 'Not logged in.' not in res.body
assert 'Invalid username or password.' in res.body
assert 'Logged as.' not in res.body
form = res.form
form['username'] = 'penguin'
form['password'] = 'invalid'
form['login[username]'] = 'penguin'
form['login[password]'] = 'invalid'
res = form.submit()
assert 'Not logged in.' in res.body
assert 'Not logged in.' not in res.body
assert 'Invalid username or password.' in res.body
assert 'Logged as.' not in res.body
form = res.form
form['username'] = 'penguin'
form['password'] = 'monkey1'
form['login[username]'] = 'penguin'
form['login[password]'] = 'monkey1'
res = form.submit(status=302)
res = res.follow(status=200)
assert 'Current user: <abbr title="Penguin">penguin</abbr>' in res.body
assert 'Logged as <abbr title="Penguin">penguin</abbr>' in res.body
res = self.app.get('/?action=login', status=200)
assert 'Not logged in.' not in res.body
assert 'Invalid username or password.' not in res.body
assert 'Already logged in as <abbr title="Penguin">penguin</abbr>' in res.body
res = self.app.get('/')
assert 'Login' not in res.body
......
......@@ -89,8 +89,8 @@ class WebPermsTest(TestCase):
# login
form = res.form
form['username'] = 'penguin'
form['password'] = 'monkey1'
form['login[username]'] = 'penguin'
form['login[password]'] = 'monkey1'
res = form.submit(status=302)
# check user perms
......
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