From ec438ead513a9f35d87f658ed04d7bbb0c4e7842 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 10 Feb 2018 16:47:53 -0600 Subject: [PATCH] Refactor user login, change password to use colander/deform --- tailbone/static/js/login.js | 14 ++--- tailbone/templates/change_password.mako | 13 +---- tailbone/templates/forms2/deform.mako | 3 + tailbone/templates/login.mako | 16 +----- tailbone/views/auth.py | 76 +++++++++++++------------ 5 files changed, 53 insertions(+), 69 deletions(-) diff --git a/tailbone/static/js/login.js b/tailbone/static/js/login.js index f0794734..f2a072b8 100644 --- a/tailbone/static/js/login.js +++ b/tailbone/static/js/login.js @@ -1,24 +1,24 @@ $(function() { - $('#username').keydown(function(event) { + $('input[name="username"]').keydown(function(event) { if (event.which == 13) { - $('#password').focus().select(); + $('input[name="password"]').focus().select(); return false; } return true; }); $('form').submit(function() { - if (! $('#username').val()) { - with ($('#username').get(0)) { + if (! $('input[name="username"]').val()) { + with ($('input[name="username"]').get(0)) { select(); focus(); } return false; } - if (! $('#password').val()) { - with ($('#password').get(0)) { + if (! $('input[name="password"]').val()) { + with ($('input[name="password"]').get(0)) { select(); focus(); } @@ -27,6 +27,6 @@ $(function() { return true; }); - $('#username').focus(); + $('input[name="username"]').focus(); }); diff --git a/tailbone/templates/change_password.mako b/tailbone/templates/change_password.mako index d9c67235..91f66a72 100644 --- a/tailbone/templates/change_password.mako +++ b/tailbone/templates/change_password.mako @@ -1,17 +1,8 @@ -## -*- coding: utf-8 -*- +## -*- coding: utf-8; -*- <%inherit file="/base.mako" /> <%def name="title()">Change Password
- ${h.form(url('change_password'))} - ${form.csrf_token()} - ${form.referrer_field()} - ${form.field_div('current_password', form.password('current_password'))} - ${form.field_div('new_password', form.password('new_password'))} - ${form.field_div('confirm_password', form.password('confirm_password'))} -
- ${h.submit('submit', "Change Password")} -
- ${h.end_form()} + ${form.render_deform()|n}
diff --git a/tailbone/templates/forms2/deform.mako b/tailbone/templates/forms2/deform.mako index 3dcbbfaf..ed7b3928 100644 --- a/tailbone/templates/forms2/deform.mako +++ b/tailbone/templates/forms2/deform.mako @@ -76,6 +76,9 @@ ${h.csrf_token(request)} ## % if form.creating and form.allow_successive_creates: ## ${h.submit('create_and_continue', form.successive_create_label)} ## % endif + % if getattr(form, 'show_reset', False): + + % endif % if getattr(form, 'show_cancel', True): ${h.link_to("Cancel", form.cancel_url, class_='cancel button{}'.format(' autodisable' if form.auto_disable_cancel else ''))} % endif diff --git a/tailbone/templates/login.mako b/tailbone/templates/login.mako index 93d62ef8..7ec87274 100644 --- a/tailbone/templates/login.mako +++ b/tailbone/templates/login.mako @@ -1,4 +1,4 @@ -## -*- coding: utf-8 -*- +## -*- coding: utf-8; -*- <%inherit file="/base.mako" /> <%def name="title()">Login @@ -19,19 +19,7 @@ <%def name="login_form()">
- ${form.begin(**{'data-ajax': 'false'})} - ${form.hidden('referrer', value=referrer)} - ${form.csrf_token()} - - ${form.field_div('username', form.text('username'))} - ${form.field_div('password', form.password('password'))} - -
- ${form.submit('submit', "Login")} - -
- - ${form.end()} + ${form.render_deform(form_kwargs={'data-ajax': 'false'})|n}
diff --git a/tailbone/views/auth.py b/tailbone/views/auth.py index 44a6ac0d..2d2a79a5 100644 --- a/tailbone/views/auth.py +++ b/tailbone/views/auth.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2017 Lance Edgar +# Copyright © 2010-2018 Lance Edgar # # This file is part of Rattail. # @@ -28,47 +28,42 @@ from __future__ import unicode_literals, absolute_import from rattail.db.auth import authenticate_user, set_user_password -import formencode as fe +import colander +from deform import widget as dfwidget from pyramid.httpexceptions import HTTPForbidden -from pyramid_simpleform import Form from webhelpers2.html import tags, literal -from tailbone import forms +from tailbone import forms2 as forms from tailbone.db import Session from tailbone.views import View from tailbone.auth import login_user, logout_user -class UserLogin(fe.Schema): - allow_extra_fields = True - filter_extra_fields = True - username = fe.validators.NotEmpty() - password = fe.validators.NotEmpty() +class UserLogin(colander.MappingSchema): + + username = colander.SchemaNode(colander.String()) + + password = colander.SchemaNode(colander.String(), + widget=dfwidget.PasswordWidget()) -class CurrentPasswordCorrect(fe.validators.FancyValidator): - - def _to_python(self, value, state): - user = state - if not authenticate_user(Session, user.username, value): - raise fe.Invalid("The password is incorrect.", value, state) - return value +@colander.deferred +def current_password_correct(node, kw): + user = kw['user'] + def validate(node, value): + if not authenticate_user(Session(), user.username, value): + raise colander.Invalid(node, "The password is incorrect") + return validate -class ChangePassword(fe.Schema): +class ChangePassword(colander.MappingSchema): - allow_extra_fields = True - filter_extra_fields = True + current_password = colander.SchemaNode(colander.String(), + widget=dfwidget.PasswordWidget(), + validator=current_password_correct) - current_password = fe.All( - fe.validators.NotEmpty(), - CurrentPasswordCorrect()) - - new_password = fe.validators.NotEmpty() - confirm_password = fe.validators.NotEmpty() - - chained_validators = [fe.validators.FieldsMatch( - 'new_password', 'confirm_password')] + new_password = colander.SchemaNode(colander.String(), + widget=dfwidget.CheckedPasswordWidget()) class AuthenticationView(View): @@ -103,10 +98,15 @@ class AuthenticationView(View): self.request.session.flash("{} is already logged in".format(self.request.user), 'error') return self.redirect(referrer) - form = forms.SimpleForm(self.request, UserLogin) - if form.validate(): - user = self.authenticate_user(form.data['username'], - form.data['password']) + form = forms.Form(schema=UserLogin(), request=self.request) + form.save_label = "Login" + form.auto_disable_save = False + form.auto_disable = False # TODO: deprecate / remove this + form.show_reset = True + form.show_cancel = False + if form.validate(newstyle=True): + user = self.authenticate_user(form.validated['username'], + form.validated['password']) if user: # okay now they're truly logged in headers = login_user(self.request, user) @@ -122,7 +122,7 @@ class AuthenticationView(View): default=self.request.static_url('tailbone:static/img/home_logo.png')) return { - 'form': forms.FormRenderer(form), + 'form': form, 'referrer': referrer, 'image_url': image_url, 'dialog': mobile, @@ -169,12 +169,14 @@ class AuthenticationView(View): self.request.session.flash("Cannot change password for 'chuck' in demo mode", 'error') return self.redirect(self.request.get_referrer()) - form = Form(self.request, schema=ChangePassword, state=self.request.user) - if form.validate(): - set_user_password(self.request.user, form.data['new_password']) + schema = ChangePassword().bind(user=self.request.user) + form = forms.Form(schema=schema, request=self.request) + if form.validate(newstyle=True): + set_user_password(self.request.user, form.validated['new_password']) + self.request.session.flash("Your password has been changed.") return self.redirect(self.request.get_referrer()) - return {'form': forms.FormRenderer(form)} + return {'form': form} def become_root(self): """