Refactor to leverage all existing methods of auth handler

instead of importing and calling functions from core rattail
This commit is contained in:
Lance Edgar 2021-10-14 21:42:16 -04:00
parent 53fc1508f3
commit 232a02b944
7 changed files with 64 additions and 33 deletions

View file

@ -2,7 +2,7 @@
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2020 Lance Edgar
# Copyright © 2010-2021 Lance Edgar
#
# This file is part of Rattail.
#
@ -26,7 +26,7 @@ Tailbone Web API - Auth Views
from __future__ import unicode_literals, absolute_import
from rattail.db.auth import authenticate_user, set_user_password, cache_permissions
from rattail.db.auth import set_user_password
from cornice import Service
@ -82,15 +82,20 @@ class AuthenticationView(APIView):
if error:
return {'error': error}
app = self.get_rattail_app()
auth = app.get_auth_handler()
login_user(self.request, user)
return {
'ok': True,
'user': self.get_user_info(user),
'permissions': list(cache_permissions(Session(), user)),
'permissions': list(auth.cache_permissions(Session(), user)),
}
def authenticate_user(self, username, password):
return authenticate_user(Session(), username, password)
app = self.get_rattail_app()
auth = app.get_auth_handler()
return auth.authenticate_user(Session(), username, password)
def why_cant_user_login(self, user):
"""
@ -156,7 +161,7 @@ class AuthenticationView(APIView):
data = self.request.json_body
# first make sure "current" password is accurate
if not authenticate_user(Session(), self.request.user, data['current_password']):
if not self.authenticate_user(self.request.user, data['current_password']):
return {'error': "The current/old password you provided is incorrect"}
# okay then, set new password

View file

@ -93,6 +93,11 @@ def set_session_timeout(request, timeout):
class TailboneAuthorizationPolicy(object):
def permits(self, context, principals, permission):
config = context.request.rattail_config
model = config.get_model()
app = config.get_app()
auth = app.get_auth_handler()
for userid in principals:
if userid not in (Everyone, Authenticated):
if context.request.user and context.request.user.uuid == userid:
@ -100,10 +105,6 @@ class TailboneAuthorizationPolicy(object):
else:
# this is pretty rare, but can happen in dev after
# re-creating the database, which means new user uuids.
config = context.request.rattail_config
model = config.get_model()
app = config.get_app()
auth = app.get_auth_handler()
# TODO: the odds of this query returning a user in that
# case, are probably nil, and we should just skip this bit?
user = Session.query(model.User).get(userid)
@ -111,7 +112,7 @@ class TailboneAuthorizationPolicy(object):
if auth.has_permission(Session(), user, permission):
return True
if Everyone in principals:
return has_permission(Session(), None, permission)
return auth.has_permission(Session(), None, permission)
return False
def principals_allowed_by_permission(self, context, permission):

View file

@ -91,12 +91,13 @@ def new_request(event):
auth = app.get_auth_handler()
request.tailbone_cached_permissions = auth.cache_permissions(
Session(), request.user)
else:
# TODO: not sure why this would really work, or even be
# needed, if there was no rattail config?
from rattail.db.auth import cache_permissions
request.tailbone_cached_permissions = cache_permissions(
Session(), request.user)
# TODO: until we know otherwise, let's assume this is not needed
# else:
# # TODO: not sure why this would really work, or even be
# # needed, if there was no rattail config?
# from rattail.db.auth import cache_permissions
# request.tailbone_cached_permissions = cache_permissions(
# Session(), request.user)
def before_render(event):

View file

@ -50,9 +50,12 @@ class UserLogin(colander.MappingSchema):
@colander.deferred
def current_password_correct(node, kw):
request = kw['request']
app = request.rattail_config.get_app()
auth = app.get_auth_handler()
user = kw['user']
def validate(node, value):
if not authenticate_user(Session(), user.username, value):
if not auth.authenticate_user(Session(), user.username, value):
raise colander.Invalid(node, "The password is incorrect")
return validate
@ -175,7 +178,7 @@ class AuthenticationView(View):
return self.redirect(self.request.get_referrer())
use_buefy = self.get_use_buefy()
schema = ChangePassword().bind(user=self.request.user)
schema = ChangePassword().bind(user=self.request.user, request=self.request)
form = forms.Form(schema=schema, request=self.request, use_buefy=use_buefy)
if form.validate(newstyle=True):
set_user_password(self.request.user, form.validated['new_password'])

View file

@ -28,7 +28,6 @@ from __future__ import unicode_literals, absolute_import
import copy
from rattail.db.auth import has_permission
from rattail.core import Object
from rattail.util import OrderedDict
@ -144,6 +143,9 @@ class PermissionsRenderer(Object):
return self.render()
def render(self):
app = self.request.rattail_config.get_app()
auth = app.get_handler()
principal = self.principal
html = ''
for groupkey in sorted(self.permissions, key=lambda k: self.permissions[k]['label'].lower()):
@ -151,7 +153,7 @@ class PermissionsRenderer(Object):
perms = self.permissions[groupkey]['perms']
rendered = False
for key in sorted(perms, key=lambda p: perms[p]['label'].lower()):
checked = has_permission(Session(), principal, key,
checked = auth.has_permission(Session(), principal, key,
include_guest=self.include_guest,
include_authenticated=self.include_authenticated)
if checked:

View file

@ -33,8 +33,7 @@ from sqlalchemy import orm
from openpyxl.styles import Font, PatternFill
from rattail.db import model
from rattail.db.auth import (has_permission, grant_permission, revoke_permission,
administrator_role, guest_role, authenticated_role)
from rattail.db.auth import administrator_role, guest_role, authenticated_role
from rattail.excel import ExcelWriter
import colander
@ -158,6 +157,8 @@ class RoleView(PrincipalMasterView):
super(RoleView, self).configure_form(f)
role = f.model_instance
use_buefy = self.get_use_buefy()
app = self.get_rattail_app()
auth = app.get_auth_handler()
# name
f.set_validator('name', self.unique_name)
@ -194,7 +195,8 @@ class RoleView(PrincipalMasterView):
# permissions
self.tailbone_permissions = self.get_available_permissions()
f.set_renderer('permissions', PermissionsRenderer(permissions=self.tailbone_permissions))
f.set_renderer('permissions', PermissionsRenderer(request=self.request,
permissions=self.tailbone_permissions))
f.set_node('permissions', colander.Set())
f.set_widget('permissions', PermissionsWidget(
permissions=self.tailbone_permissions,
@ -203,7 +205,9 @@ class RoleView(PrincipalMasterView):
granted = []
for groupkey in self.tailbone_permissions:
for key in self.tailbone_permissions[groupkey]['perms']:
if has_permission(self.Session(), role, key, include_guest=False, include_authenticated=False):
if auth.has_permission(self.Session(), role, key,
include_guest=False,
include_authenticated=False):
granted.append(key)
f.set_default('permissions', granted)
elif self.deleting:
@ -309,13 +313,16 @@ class RoleView(PrincipalMasterView):
permissions, but rather each "available" permission (depends on current
user) will be examined individually, and updated as needed.
"""
app = self.get_rattail_app()
auth = app.get_auth_handler()
available = self.tailbone_permissions
for gkey, group in six.iteritems(available):
for pkey, perm in six.iteritems(group['perms']):
if pkey in permissions:
grant_permission(role, pkey)
auth.grant_permission(role, pkey)
else:
revoke_permission(role, pkey)
auth.revoke_permission(role, pkey)
def template_kwargs_view(self, **kwargs):
role = kwargs['instance']
@ -364,13 +371,16 @@ class RoleView(PrincipalMasterView):
return self.redirect(self.request.get_referrer(default=self.request.route_url('roles')))
def find_principals_with_permission(self, session, permission):
app = self.get_rattail_app()
auth = app.get_auth_handler()
# TODO: this should search Permission table instead, and work backward to Role?
all_roles = session.query(model.Role)\
.order_by(model.Role.name)\
.options(orm.joinedload(model.Role._permissions))
roles = []
for role in all_roles:
if has_permission(session, role, permission, include_guest=False):
if auth.has_permission(session, role, permission, include_guest=False):
roles.append(role)
return roles
@ -379,6 +389,9 @@ class RoleView(PrincipalMasterView):
View which renders the complete role / permissions matrix data into an
Excel spreadsheet, and returns that file.
"""
app = self.get_rattail_app()
auth = app.get_auth_handler()
roles = self.Session.query(model.Role)\
.order_by(model.Role.name)\
.all()
@ -427,7 +440,8 @@ class RoleView(PrincipalMasterView):
# and show an 'X' for any role which has this perm
for col, role in enumerate(roles, 2):
if has_permission(self.Session(), role, key, include_guest=False):
if auth.has_permission(self.Session(), role, key,
include_guest=False):
sheet.cell(row=writing_row, column=col, value="X")
writing_row += 1

View file

@ -32,7 +32,8 @@ import six
from sqlalchemy import orm
from rattail.db import model
from rattail.db.auth import administrator_role, guest_role, authenticated_role, set_user_password, has_permission
from rattail.db.auth import (administrator_role, guest_role,
authenticated_role, set_user_password)
import colander
from deform import widget as dfwidget
@ -239,7 +240,8 @@ class UserView(PrincipalMasterView):
if self.viewing:
permissions = self.request.registry.settings.get('tailbone_permissions', {})
f.append('permissions')
f.set_renderer('permissions', PermissionsRenderer(permissions=permissions,
f.set_renderer('permissions', PermissionsRenderer(request=self.request,
permissions=permissions,
include_guest=True,
include_authenticated=True))
@ -389,6 +391,9 @@ class UserView(PrincipalMasterView):
]
def find_principals_with_permission(self, session, permission):
app = self.get_rattail_app()
auth = app.get_auth_handler()
# TODO: this should search Permission table instead, and work backward to User?
all_users = session.query(model.User)\
.filter(model.User.active == True)\
@ -398,7 +403,7 @@ class UserView(PrincipalMasterView):
.joinedload(model.Role._permissions))
users = []
for user in all_users:
if has_permission(session, user, permission):
if auth.has_permission(session, user, permission):
users.append(user)
return users