feat: add permission checks for menus, view routes
This commit is contained in:
parent
675b51cac2
commit
e3942ce65e
11 changed files with 537 additions and 40 deletions
|
@ -3,20 +3,15 @@
|
|||
from unittest import TestCase
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from wuttjamaican.conf import WuttaConfig
|
||||
|
||||
from pyramid import testing
|
||||
|
||||
from wuttaweb import menus as mod
|
||||
from tests.util import WebTestCase
|
||||
|
||||
|
||||
class TestMenuHandler(TestCase):
|
||||
class TestMenuHandler(WebTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.config = WuttaConfig()
|
||||
self.app = self.config.get_app()
|
||||
self.setup_web()
|
||||
self.handler = mod.MenuHandler(self.config)
|
||||
self.request = testing.DummyRequest()
|
||||
|
||||
def test_make_admin_menu(self):
|
||||
menus = self.handler.make_admin_menu(self.request)
|
||||
|
@ -27,7 +22,27 @@ class TestMenuHandler(TestCase):
|
|||
self.assertIsInstance(menus, list)
|
||||
|
||||
def test_is_allowed(self):
|
||||
# TODO: this should test auth/perm handling
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
|
||||
# user with perms
|
||||
barney = model.User(username='barney')
|
||||
self.session.add(barney)
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
barney.roles.append(blokes)
|
||||
auth.grant_permission(blokes, 'appinfo.list')
|
||||
self.request.user = barney
|
||||
|
||||
# perm not granted to user
|
||||
item = {'perm': 'appinfo.configure'}
|
||||
self.assertFalse(self.handler._is_allowed(self.request, item))
|
||||
|
||||
# perm *is* granted to user
|
||||
item = {'perm': 'appinfo.list'}
|
||||
self.assertTrue(self.handler._is_allowed(self.request, item))
|
||||
|
||||
# perm not required
|
||||
item = {}
|
||||
self.assertTrue(self.handler._is_allowed(self.request, item))
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import json
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from wuttjamaican.conf import WuttaConfig
|
||||
|
||||
|
@ -210,6 +210,137 @@ class TestNewRequestSetUser(TestCase):
|
|||
self.assertTrue(self.request.is_admin)
|
||||
self.assertTrue(self.request.is_root)
|
||||
|
||||
def test_user_permissions(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
event = MagicMock(request=self.request)
|
||||
|
||||
# anonymous user
|
||||
self.assertFalse(hasattr(self.request, 'user_permissions'))
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertEqual(self.request.user_permissions, set())
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
|
||||
# add user to role with perms
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
auth.grant_permission(blokes, 'appinfo.list')
|
||||
self.user.roles.append(blokes)
|
||||
self.session.commit()
|
||||
|
||||
# authenticated user, with perms
|
||||
self.request.user = self.user
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertEqual(self.request.user_permissions, {'appinfo.list'})
|
||||
|
||||
def test_has_perm(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
event = MagicMock(request=self.request)
|
||||
|
||||
# anonymous user
|
||||
self.assertFalse(hasattr(self.request, 'has_perm'))
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertFalse(self.request.has_perm('appinfo.list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
|
||||
# add user to role with perms
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
auth.grant_permission(blokes, 'appinfo.list')
|
||||
self.user.roles.append(blokes)
|
||||
self.session.commit()
|
||||
|
||||
# authenticated user, with perms
|
||||
self.request.user = self.user
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertTrue(self.request.has_perm('appinfo.list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
|
||||
# drop user from role, no more perms
|
||||
self.user.roles.remove(blokes)
|
||||
self.session.commit()
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertFalse(self.request.has_perm('appinfo.list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
del self.request.is_admin
|
||||
del self.request.is_root
|
||||
|
||||
# root user always has perms
|
||||
admin = auth.get_role_administrator(self.session)
|
||||
self.user.roles.append(admin)
|
||||
self.session.commit()
|
||||
self.request.session['is_root'] = True
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertTrue(self.request.has_perm('appinfo.list'))
|
||||
|
||||
def test_has_any_perm(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
event = MagicMock(request=self.request)
|
||||
|
||||
# anonymous user
|
||||
self.assertFalse(hasattr(self.request, 'has_any_perm'))
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertFalse(self.request.has_any_perm('appinfo.list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
|
||||
# add user to role with perms
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
auth.grant_permission(blokes, 'appinfo.list')
|
||||
self.user.roles.append(blokes)
|
||||
self.session.commit()
|
||||
|
||||
# authenticated user, with perms
|
||||
self.request.user = self.user
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertTrue(self.request.has_any_perm('appinfo.list', 'appinfo.view'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
|
||||
# drop user from role, no more perms
|
||||
self.user.roles.remove(blokes)
|
||||
self.session.commit()
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertFalse(self.request.has_any_perm('appinfo.list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
del self.request.has_perm
|
||||
del self.request.has_any_perm
|
||||
del self.request.is_admin
|
||||
del self.request.is_root
|
||||
|
||||
# root user always has perms
|
||||
admin = auth.get_role_administrator(self.session)
|
||||
self.user.roles.append(admin)
|
||||
self.session.commit()
|
||||
self.request.session['is_root'] = True
|
||||
subscribers.new_request_set_user(event, db_session=self.session)
|
||||
self.assertTrue(self.request.has_any_perm('appinfo.list'))
|
||||
|
||||
|
||||
class TestBeforeRender(TestCase):
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class WebTestCase(DataTestCase):
|
|||
|
||||
def setup_web(self):
|
||||
self.setup_db()
|
||||
self.request = testing.DummyRequest()
|
||||
self.request = self.make_request()
|
||||
self.pyramid_config = testing.setUp(request=self.request, settings={
|
||||
'wutta_config': self.config,
|
||||
'mako.directories': ['wuttaweb:templates'],
|
||||
|
@ -78,6 +78,9 @@ class WebTestCase(DataTestCase):
|
|||
testing.tearDown()
|
||||
self.teardown_db()
|
||||
|
||||
def make_request(self):
|
||||
return testing.DummyRequest()
|
||||
|
||||
|
||||
class NullMenuHandler(MenuHandler):
|
||||
"""
|
||||
|
|
|
@ -331,6 +331,64 @@ class TestMasterView(WebTestCase):
|
|||
# support methods
|
||||
##############################
|
||||
|
||||
def test_has_perm(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_name='Setting'):
|
||||
view = self.make_view()
|
||||
|
||||
# anonymous user
|
||||
self.assertFalse(view.has_perm('list'))
|
||||
self.assertFalse(self.request.has_perm('list'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
|
||||
# make user with perms
|
||||
barney = model.User(username='barney')
|
||||
self.session.add(barney)
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
barney.roles.append(blokes)
|
||||
auth.grant_permission(blokes, 'settings.list')
|
||||
self.session.commit()
|
||||
|
||||
# this user has perms
|
||||
self.request.user = barney
|
||||
self.assertTrue(view.has_perm('list'))
|
||||
self.assertTrue(self.request.has_perm('settings.list'))
|
||||
|
||||
def test_has_any_perm(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_name='Setting'):
|
||||
view = self.make_view()
|
||||
|
||||
# anonymous user
|
||||
self.assertFalse(view.has_any_perm('list', 'view'))
|
||||
self.assertFalse(self.request.has_any_perm('settings.list', 'settings.view'))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
|
||||
# make user with perms
|
||||
barney = model.User(username='barney')
|
||||
self.session.add(barney)
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
barney.roles.append(blokes)
|
||||
auth.grant_permission(blokes, 'settings.view')
|
||||
self.session.commit()
|
||||
|
||||
# this user has perms
|
||||
self.request.user = barney
|
||||
self.assertTrue(view.has_any_perm('list', 'view'))
|
||||
self.assertTrue(self.request.has_any_perm('settings.list', 'settings.view'))
|
||||
|
||||
def test_render_to_response(self):
|
||||
self.pyramid_config.include('wuttaweb.views.common')
|
||||
self.pyramid_config.include('wuttaweb.views.auth')
|
||||
|
@ -387,6 +445,28 @@ class TestMasterView(WebTestCase):
|
|||
grid = view.make_model_grid(session=self.session)
|
||||
self.assertIs(grid.model_class, model.Setting)
|
||||
|
||||
# no actions by default
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
grid = view.make_model_grid(session=self.session)
|
||||
self.assertEqual(grid.actions, [])
|
||||
|
||||
# now let's test some more actions logic
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting,
|
||||
viewable=True,
|
||||
editable=True,
|
||||
deletable=True):
|
||||
|
||||
# should have 3 actions now, but for lack of perms
|
||||
grid = view.make_model_grid(session=self.session)
|
||||
self.assertEqual(len(grid.actions), 0)
|
||||
|
||||
# but root user has perms, so gets 3 actions
|
||||
with patch.object(self.request, 'is_root', new=True):
|
||||
grid = view.make_model_grid(session=self.session)
|
||||
self.assertEqual(len(grid.actions), 3)
|
||||
|
||||
def test_get_grid_data(self):
|
||||
model = self.app.model
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
|
@ -468,6 +548,57 @@ class TestMasterView(WebTestCase):
|
|||
self.request.matchdict = {'name': 'blarg'}
|
||||
self.assertRaises(HTTPNotFound, view.get_instance, session=self.session)
|
||||
|
||||
def test_get_action_url_view(self):
|
||||
model = self.app.model
|
||||
setting = model.Setting(name='foo', value='bar')
|
||||
self.session.add(setting)
|
||||
self.session.commit()
|
||||
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
master.MasterView.defaults(self.pyramid_config)
|
||||
view = self.make_view()
|
||||
url = view.get_action_url_view(setting, 0)
|
||||
self.assertEqual(url, self.request.route_url('settings.view', name='foo'))
|
||||
|
||||
def test_get_action_url_edit(self):
|
||||
model = self.app.model
|
||||
setting = model.Setting(name='foo', value='bar')
|
||||
self.session.add(setting)
|
||||
self.session.commit()
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
master.MasterView.defaults(self.pyramid_config)
|
||||
view = self.make_view()
|
||||
|
||||
# typical
|
||||
url = view.get_action_url_edit(setting, 0)
|
||||
self.assertEqual(url, self.request.route_url('settings.edit', name='foo'))
|
||||
|
||||
# but null if instance not editable
|
||||
with patch.object(view, 'is_editable', return_value=False):
|
||||
url = view.get_action_url_edit(setting, 0)
|
||||
self.assertIsNone(url)
|
||||
|
||||
def test_get_action_url_delete(self):
|
||||
model = self.app.model
|
||||
setting = model.Setting(name='foo', value='bar')
|
||||
self.session.add(setting)
|
||||
self.session.commit()
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
master.MasterView.defaults(self.pyramid_config)
|
||||
view = self.make_view()
|
||||
|
||||
# typical
|
||||
url = view.get_action_url_delete(setting, 0)
|
||||
self.assertEqual(url, self.request.route_url('settings.delete', name='foo'))
|
||||
|
||||
# but null if instance not deletable
|
||||
with patch.object(view, 'is_deletable', return_value=False):
|
||||
url = view.get_action_url_delete(setting, 0)
|
||||
self.assertIsNone(url)
|
||||
|
||||
def test_make_model_form(self):
|
||||
model = self.app.model
|
||||
|
||||
|
|
|
@ -31,6 +31,42 @@ class TestRoleView(WebTestCase):
|
|||
view.configure_grid(grid)
|
||||
self.assertTrue(grid.is_linked('name'))
|
||||
|
||||
def test_is_editable(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
blokes = model.Role(name="Blokes")
|
||||
self.session.add(blokes)
|
||||
self.session.commit()
|
||||
view = self.make_view()
|
||||
|
||||
admin = auth.get_role_administrator(self.session)
|
||||
authed = auth.get_role_authenticated(self.session)
|
||||
anon = auth.get_role_anonymous(self.session)
|
||||
|
||||
# editable by default
|
||||
self.assertTrue(view.is_editable(blokes))
|
||||
|
||||
# built-in roles not editable by default
|
||||
self.assertFalse(view.is_editable(admin))
|
||||
self.assertFalse(view.is_editable(authed))
|
||||
self.assertFalse(view.is_editable(anon))
|
||||
|
||||
# reset
|
||||
del self.request.user_permissions
|
||||
|
||||
barney = model.User(username='barney')
|
||||
self.session.add(barney)
|
||||
barney.roles.append(blokes)
|
||||
auth.grant_permission(blokes, 'roles.edit_builtin')
|
||||
self.session.commit()
|
||||
|
||||
# user with perms can edit *some* built-in
|
||||
self.request.user = barney
|
||||
self.assertTrue(view.is_editable(authed))
|
||||
self.assertTrue(view.is_editable(anon))
|
||||
# nb. not this one yet
|
||||
self.assertFalse(view.is_editable(admin))
|
||||
|
||||
def test_is_deletable(self):
|
||||
model = self.app.model
|
||||
auth = self.app.get_auth_handler()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue