OMG..lots of changes for sake of mobile login / user menu etc.
Feeling a bit sloppy right about now...oh well good enough
This commit is contained in:
parent
e3ae427e37
commit
ee0bdc4b74
10 changed files with 335 additions and 183 deletions
tailbone/views
|
@ -28,164 +28,181 @@ from __future__ import unicode_literals, absolute_import
|
|||
|
||||
from rattail.db.auth import authenticate_user, set_user_password
|
||||
|
||||
import formencode
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPForbidden
|
||||
import formencode as fe
|
||||
from pyramid.httpexceptions import HTTPForbidden
|
||||
from pyramid.security import remember, forget
|
||||
from pyramid_simpleform import Form
|
||||
from webhelpers.html import literal
|
||||
from webhelpers.html import tags
|
||||
from webhelpers.html import tags, literal
|
||||
|
||||
from tailbone import forms
|
||||
from tailbone.db import Session
|
||||
from tailbone.forms.simpleform import FormRenderer
|
||||
from tailbone.views import View
|
||||
|
||||
|
||||
def forbidden(request):
|
||||
"""
|
||||
Access forbidden view.
|
||||
|
||||
This is triggered whenever access is not allowed for an otherwise
|
||||
appropriate view.
|
||||
"""
|
||||
msg = literal("You do not have permission to do that.")
|
||||
if not request.authenticated_userid:
|
||||
msg += literal(" (Perhaps you should %s?)" %
|
||||
tags.link_to("log in", request.route_url('login')))
|
||||
# Store current URL in session, for smarter redirect after login.
|
||||
request.session['next_url'] = request.current_route_url()
|
||||
request.session.flash(msg, allow_duplicate=False)
|
||||
return HTTPFound(location=request.get_referrer())
|
||||
|
||||
|
||||
class UserLogin(formencode.Schema):
|
||||
class UserLogin(fe.Schema):
|
||||
allow_extra_fields = True
|
||||
filter_extra_fields = True
|
||||
username = formencode.validators.NotEmpty()
|
||||
password = formencode.validators.NotEmpty()
|
||||
username = fe.validators.NotEmpty()
|
||||
password = fe.validators.NotEmpty()
|
||||
|
||||
|
||||
def login(request):
|
||||
"""
|
||||
The login view, responsible for displaying and handling the login form.
|
||||
"""
|
||||
referrer = request.get_referrer()
|
||||
|
||||
# Redirect if already logged in.
|
||||
if request.user:
|
||||
return HTTPFound(location=referrer)
|
||||
|
||||
form = Form(request, schema=UserLogin)
|
||||
if form.validate():
|
||||
user = authenticate_user(Session(),
|
||||
form.data['username'],
|
||||
form.data['password'])
|
||||
if user:
|
||||
headers = remember(request, user.uuid)
|
||||
# Treat URL from session as referrer, if available.
|
||||
referrer = request.session.pop('next_url', referrer)
|
||||
return HTTPFound(location=referrer, headers=headers)
|
||||
request.session.flash("Invalid username or password")
|
||||
|
||||
return {'form': FormRenderer(form), 'referrer': referrer}
|
||||
|
||||
|
||||
def logout(request):
|
||||
"""
|
||||
View responsible for logging out the current user.
|
||||
|
||||
This deletes/invalidates the current session and then redirects to the
|
||||
login page.
|
||||
"""
|
||||
|
||||
request.session.delete()
|
||||
request.session.invalidate()
|
||||
headers = forget(request)
|
||||
referrer = request.get_referrer()
|
||||
return HTTPFound(location=referrer, headers=headers)
|
||||
|
||||
|
||||
def become_root(request):
|
||||
"""
|
||||
Elevate the current request to 'root' for full system access.
|
||||
"""
|
||||
if not request.is_admin:
|
||||
raise HTTPForbidden()
|
||||
request.session['is_root'] = True
|
||||
request.session.flash("You have been elevated to 'root' and now have full system access")
|
||||
return HTTPFound(location=request.get_referrer())
|
||||
|
||||
|
||||
def stop_root(request):
|
||||
"""
|
||||
Lower the current request from 'root' back to normal access.
|
||||
"""
|
||||
if not request.is_admin:
|
||||
raise HTTPForbidden()
|
||||
request.session['is_root'] = False
|
||||
request.session.flash("Your normal system access has been restored")
|
||||
return HTTPFound(location=request.get_referrer())
|
||||
|
||||
|
||||
class CurrentPasswordCorrect(formencode.validators.FancyValidator):
|
||||
class CurrentPasswordCorrect(fe.validators.FancyValidator):
|
||||
|
||||
def _to_python(self, value, state):
|
||||
user = state
|
||||
if not authenticate_user(Session, user.username, value):
|
||||
raise formencode.Invalid("The password is incorrect.", value, state)
|
||||
raise fe.Invalid("The password is incorrect.", value, state)
|
||||
return value
|
||||
|
||||
|
||||
class ChangePassword(formencode.Schema):
|
||||
class ChangePassword(fe.Schema):
|
||||
|
||||
allow_extra_fields = True
|
||||
filter_extra_fields = True
|
||||
|
||||
current_password = formencode.All(
|
||||
formencode.validators.NotEmpty(),
|
||||
current_password = fe.All(
|
||||
fe.validators.NotEmpty(),
|
||||
CurrentPasswordCorrect())
|
||||
|
||||
new_password = formencode.validators.NotEmpty()
|
||||
confirm_password = formencode.validators.NotEmpty()
|
||||
new_password = fe.validators.NotEmpty()
|
||||
confirm_password = fe.validators.NotEmpty()
|
||||
|
||||
chained_validators = [formencode.validators.FieldsMatch(
|
||||
chained_validators = [fe.validators.FieldsMatch(
|
||||
'new_password', 'confirm_password')]
|
||||
|
||||
|
||||
def change_password(request):
|
||||
"""
|
||||
Allows a user to change his or her password.
|
||||
"""
|
||||
class AuthenticationView(View):
|
||||
|
||||
if not request.user:
|
||||
return HTTPFound(location=request.route_url('home'))
|
||||
def forbidden(self):
|
||||
"""
|
||||
Access forbidden view.
|
||||
|
||||
form = Form(request, schema=ChangePassword, state=request.user)
|
||||
if form.validate():
|
||||
set_user_password(request.user, form.data['new_password'])
|
||||
return HTTPFound(location=request.get_referrer())
|
||||
This is triggered whenever access is not allowed for an otherwise
|
||||
appropriate view.
|
||||
"""
|
||||
msg = literal("You do not have permission to do that.")
|
||||
if not self.request.authenticated_userid:
|
||||
msg += literal(" (Perhaps you should %s?)" %
|
||||
tags.link_to("log in", self.request.route_url('login')))
|
||||
# Store current URL in session, for smarter redirect after login.
|
||||
self.request.session['next_url'] = self.request.current_route_url()
|
||||
self.request.session.flash(msg, allow_duplicate=False)
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
return {'form': FormRenderer(form)}
|
||||
def login(self, mobile=False):
|
||||
"""
|
||||
The login view, responsible for displaying and handling the login form.
|
||||
"""
|
||||
home = 'mobile.home' if mobile else 'home'
|
||||
referrer = self.request.get_referrer(default=self.request.route_url(home))
|
||||
|
||||
# redirect if already logged in
|
||||
if self.request.user:
|
||||
if not mobile:
|
||||
self.request.session.flash("{} is already logged in".format(self.request.user), 'error')
|
||||
return self.redirect(referrer)
|
||||
|
||||
form = Form(self.request, schema=UserLogin)
|
||||
context = {'form': forms.FormRenderer(form), 'referrer': referrer, 'dialog': mobile}
|
||||
if form.validate():
|
||||
user = authenticate_user(Session(),
|
||||
form.data['username'],
|
||||
form.data['password'])
|
||||
if user:
|
||||
# okay now they're truly logged in
|
||||
headers = remember(self.request, user.uuid)
|
||||
# Treat URL from session as referrer, if available.
|
||||
referrer = self.request.session.pop('next_url', referrer)
|
||||
return self.redirect(referrer, headers=headers)
|
||||
else:
|
||||
if mobile:
|
||||
context['error'] = "Invalid username or password"
|
||||
else:
|
||||
self.request.session.flash("Invalid username or password")
|
||||
return context
|
||||
|
||||
def mobile_login(self):
|
||||
return self.login(mobile=True)
|
||||
|
||||
def logout(self, mobile=False):
|
||||
"""
|
||||
View responsible for logging out the current user.
|
||||
|
||||
This deletes/invalidates the current session and then redirects to the
|
||||
login page.
|
||||
"""
|
||||
self.request.session.delete()
|
||||
self.request.session.invalidate()
|
||||
headers = forget(self.request)
|
||||
login = 'mobile.login' if mobile else 'login'
|
||||
referrer = self.request.get_referrer(default=self.request.route_url(login))
|
||||
return self.redirect(referrer, headers=headers)
|
||||
|
||||
def mobile_logout(self):
|
||||
return self.logout(mobile=True)
|
||||
|
||||
def change_password(self):
|
||||
"""
|
||||
Allows a user to change his or her password.
|
||||
"""
|
||||
if not self.request.user:
|
||||
return self.redirect(self.request.route_url('home'))
|
||||
|
||||
form = Form(self.request, schema=ChangePassword, state=self.request.user)
|
||||
if form.validate():
|
||||
set_user_password(self.request.user, form.data['new_password'])
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
return {'form': forms.FormRenderer(form)}
|
||||
|
||||
def become_root(self):
|
||||
"""
|
||||
Elevate the current request to 'root' for full system access.
|
||||
"""
|
||||
if not self.request.is_admin:
|
||||
raise HTTPForbidden()
|
||||
self.request.session['is_root'] = True
|
||||
self.request.session.flash("You have been elevated to 'root' and now have full system access")
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
def stop_root(self):
|
||||
"""
|
||||
Lower the current request from 'root' back to normal access.
|
||||
"""
|
||||
if not self.request.is_admin:
|
||||
raise HTTPForbidden()
|
||||
self.request.session['is_root'] = False
|
||||
self.request.session.flash("Your normal system access has been restored")
|
||||
return self.redirect(self.request.get_referrer())
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
|
||||
# forbidden
|
||||
config.add_forbidden_view(cls, attr='forbidden')
|
||||
|
||||
# login
|
||||
config.add_route('login', '/login')
|
||||
config.add_view(cls, attr='login', route_name='login', renderer='/login.mako')
|
||||
config.add_route('mobile.login', '/mobile/login')
|
||||
config.add_view(cls, attr='mobile_login', route_name='mobile.login', renderer='/mobile/login.mako')
|
||||
|
||||
# logout
|
||||
config.add_route('logout', '/logout')
|
||||
config.add_view(cls, attr='logout', route_name='logout')
|
||||
config.add_route('mobile.logout', '/mobile/logout')
|
||||
config.add_view(cls, attr='mobile_logout', route_name='mobile.logout')
|
||||
|
||||
# change password
|
||||
config.add_route('change_password', '/change-password')
|
||||
config.add_view(cls, attr='change_password', route_name='change_password', renderer='/change_password.mako')
|
||||
|
||||
# become/stop root
|
||||
config.add_route('become_root', '/root/yes')
|
||||
config.add_view(cls, attr='become_root', route_name='become_root')
|
||||
config.add_route('stop_root', '/root/no')
|
||||
config.add_view(cls, attr='stop_root', route_name='stop_root')
|
||||
|
||||
def add_routes(config):
|
||||
config.add_route('login', '/login')
|
||||
config.add_route('logout', '/logout')
|
||||
config.add_route('become_root', '/root/yes')
|
||||
config.add_route('stop_root', '/root/no')
|
||||
config.add_route('change_password', '/change-password')
|
||||
|
||||
|
||||
def includeme(config):
|
||||
add_routes(config)
|
||||
|
||||
config.add_forbidden_view(forbidden)
|
||||
|
||||
config.add_view(login, route_name='login',
|
||||
renderer='/login.mako')
|
||||
|
||||
config.add_view(logout, route_name='logout')
|
||||
|
||||
config.add_view(become_root, route_name='become_root')
|
||||
config.add_view(stop_root, route_name='stop_root')
|
||||
|
||||
config.add_view(change_password, route_name='change_password',
|
||||
renderer='/change_password.mako')
|
||||
AuthenticationView.defaults(config)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue