From a685a0ef40919bf5b57488c530dcfd0bbf97a6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Thu, 8 Oct 2015 09:03:03 +0200 Subject: [PATCH] general: don't allow admins to get into new areas, unless authorized (#8562) --- extra/auquotidien.py | 31 +++++-------------------------- extra/modules/announces_ui.py | 8 ++++++-- extra/modules/backoffice.py | 25 +++++++++++++++++++++++++ extra/modules/events_ui.py | 8 ++++++-- extra/modules/links_ui.py | 8 ++++++-- extra/modules/payments_ui.py | 8 ++++++-- extra/modules/strongbox_ui.py | 8 ++++++-- tests/test_admin_pages.py | 43 ++++++++++++++++++++++++++++++++++++++----- 8 files changed, 98 insertions(+), 41 deletions(-) diff --git a/extra/auquotidien.py b/extra/auquotidien.py index 7b13dc7..2e4b9b9 100644 --- a/extra/auquotidien.py +++ b/extra/auquotidien.py @@ -28,45 +28,24 @@ get_publisher_class().backoffice_feed_url = { } -def check_visibility(target): - user = get_request().user - if not user: - return False - target = target.strip('/') - if target == 'management': - target = 'forms' - if target == 'strongbox': - if not get_publisher().has_site_option(target): - # strongbox disabled in site-options.cfg - return False - if not get_cfg('misc', {}).get('aq-strongbox'): - # strongbox disabled in settings panel - return False - admin_role = get_cfg('aq-permissions', {}).get(target, None) - if not admin_role: - return False - if not (user.is_admin or admin_role in (user.roles or [])): - return False - return True - rdb = get_publisher_class().backoffice_directory_class rdb.items = [] rdb.register_directory('announces', modules.announces_ui.AnnouncesDirectory()) -rdb.register_menu_item('announces/', _('Announces'), check_visibility) +rdb.register_menu_item('announces/', _('Announces')) rdb.register_directory('links', modules.links_ui.LinksDirectory()) -rdb.register_menu_item('links/', _('Links'), check_visibility) +rdb.register_menu_item('links/', _('Links')) rdb.register_directory('events', modules.events_ui.EventsDirectory()) -rdb.register_menu_item('events/', _('Events'), check_visibility) +rdb.register_menu_item('events/', _('Events')) rdb.register_directory('payments', modules.payments_ui.PaymentsDirectory()) -rdb.register_menu_item('payments/', _('Payments'), check_visibility) +rdb.register_menu_item('payments/', _('Payments')) rdb.register_directory('strongbox', modules.strongbox_ui.StrongboxDirectory()) -rdb.register_menu_item('strongbox/', _('Strongbox'), check_visibility) +rdb.register_menu_item('strongbox/', _('Strongbox')) rdb.register_directory('settings', modules.admin.SettingsDirectory()) rdb.register_directory('categories', modules.categories_admin.CategoriesDirectory()) diff --git a/extra/modules/announces_ui.py b/extra/modules/announces_ui.py index 7b5df33..fac236c 100644 --- a/extra/modules/announces_ui.py +++ b/extra/modules/announces_ui.py @@ -320,12 +320,16 @@ class AnnouncesDirectory(AccessControlled, Directory): subscriptions = SubscriptionsDirectory() + def is_accessible(self, user): + from .backoffice import check_visibility + return check_visibility('announces', user) + def _q_access(self): user = get_request().user if not user: raise errors.AccessUnauthorizedError() - admin_role = get_cfg('aq-permissions', {}).get('announces', None) - if not (user.is_admin or admin_role in (user.roles or [])): + + if not self.is_accessible(user): raise errors.AccessForbiddenError( public_msg = _('You are not allowed to access Announces Management'), location_hint = 'backoffice') diff --git a/extra/modules/backoffice.py b/extra/modules/backoffice.py index 06069a0..03cffd2 100644 --- a/extra/modules/backoffice.py +++ b/extra/modules/backoffice.py @@ -14,6 +14,31 @@ from wcs.formdef import FormDef from qommon import get_cfg, errors from qommon.form import * +CURRENT_USER = object() + +def check_visibility(target, user=CURRENT_USER): + if user is CURRENT_USER: + user = get_request().user + if not user: + return False + target = target.strip('/') + if target == 'management': + target = 'forms' + if target == 'strongbox': + if not get_publisher().has_site_option(target): + # strongbox disabled in site-options.cfg + return False + if not get_cfg('misc', {}).get('aq-strongbox'): + # strongbox disabled in settings panel + return False + admin_role = get_cfg('aq-permissions', {}).get(target, None) + if not admin_role: + return False + if not (user.is_admin or admin_role in (user.roles or [])): + return False + return True + + class BackofficeRootDirectory(wcs.backoffice.root.RootDirectory): def _q_access(self): super(BackofficeRootDirectory, self)._q_access() diff --git a/extra/modules/events_ui.py b/extra/modules/events_ui.py index 47f296e..63875f9 100644 --- a/extra/modules/events_ui.py +++ b/extra/modules/events_ui.py @@ -304,12 +304,16 @@ class EventsDirectory(AccessControlled, Directory): remote = RemoteCalendarsDirectory() + def is_accessible(self, user): + from .backoffice import check_visibility + return check_visibility('events', user) + def _q_access(self): user = get_request().user if not user: raise errors.AccessUnauthorizedError() - admin_role = get_cfg('aq-permissions', {}).get('events', None) - if not (user.is_admin or admin_role in (user.roles or [])): + + if not self.is_accessible(user): raise errors.AccessForbiddenError( public_msg = _('You are not allowed to access Events Management'), location_hint = 'backoffice') diff --git a/extra/modules/links_ui.py b/extra/modules/links_ui.py index c2a2c67..2822fc0 100644 --- a/extra/modules/links_ui.py +++ b/extra/modules/links_ui.py @@ -101,12 +101,16 @@ class LinksDirectory(AccessControlled, Directory): _q_exports = ['', 'new', 'listing', 'update_order'] label = N_('Links') + def is_accessible(self, user): + from .backoffice import check_visibility + return check_visibility('links', user) + def _q_access(self): user = get_request().user if not user: raise errors.AccessUnauthorizedError() - admin_role = get_cfg('aq-permissions', {}).get('links', None) - if not (user.is_admin or admin_role in (user.roles or [])): + + if not self.is_accessible(user): raise errors.AccessForbiddenError( public_msg = _('You are not allowed to access Links Management'), location_hint = 'backoffice') diff --git a/extra/modules/payments_ui.py b/extra/modules/payments_ui.py index 6ddd0ac..4d79456 100644 --- a/extra/modules/payments_ui.py +++ b/extra/modules/payments_ui.py @@ -524,12 +524,16 @@ class PaymentsDirectory(AccessControlled, Directory): regie = RegiesDirectory() + def is_accessible(self, user): + from .backoffice import check_visibility + return check_visibility('payments', user) + def _q_access(self): user = get_request().user if not user: raise errors.AccessUnauthorizedError() - admin_role = get_cfg('aq-permissions', {}).get('payments', None) - if not (user.is_admin or admin_role in (user.roles or [])): + + if not self.is_accessible(user): raise errors.AccessForbiddenError( public_msg = _('You are not allowed to access Payments Management'), location_hint = 'backoffice') diff --git a/extra/modules/strongbox_ui.py b/extra/modules/strongbox_ui.py index 776ed9d..6becdd2 100644 --- a/extra/modules/strongbox_ui.py +++ b/extra/modules/strongbox_ui.py @@ -147,12 +147,16 @@ class StrongboxDirectory(AccessControlled, Directory): types = StrongboxTypesDirectory() + def is_accessible(self, user): + from .backoffice import check_visibility + return check_visibility('strongbox', user) + def _q_access(self): user = get_request().user if not user: raise errors.AccessUnauthorizedError() - admin_role = get_cfg('aq-permissions', {}).get('strongbox', None) - if not (user.is_admin or admin_role in (user.roles or [])): + + if not self.is_accessible(user): raise errors.AccessForbiddenError( public_msg = _('You are not allowed to access Strongbox Management'), location_hint = 'backoffice') diff --git a/tests/test_admin_pages.py b/tests/test_admin_pages.py index 54bf939..fadf177 100644 --- a/tests/test_admin_pages.py +++ b/tests/test_admin_pages.py @@ -72,11 +72,6 @@ def test_with_superuser(): # this makes sure the extension loaded properly assert 'Publik' in resp.body -def test_directory_registration(): - create_superuser() - app = login(get_app(pub)) - resp = app.get('/backoffice/links/') - def test_general_admin_permissions(): create_superuser() app = login(get_app(pub)) @@ -96,3 +91,41 @@ def test_aq_permissions_panel(): resp = app.get('/backoffice/settings/') assert 'aq/permissions' in resp.body resp = app.get('/backoffice/settings/aq/permissions') + +def test_menu_items(): + create_superuser() + role = create_role() + + for area in ('links', 'announces', 'events', 'links', 'payments'): + pub.cfg['aq-permissions'] = {area: None} + pub.write_cfg() + + user1.is_admin = True + user1.roles = [] + user1.store() + + app = login(get_app(pub)) + resp = app.get('/backoffice/') + assert not '/%s/' % area in resp.body + resp = app.get('/backoffice/%s/' % area, status=403) + + pub.cfg['aq-permissions'] = {area: 'XXX'} + pub.write_cfg() + + resp = app.get('/backoffice/') + assert '/%s/' % area in resp.body + resp = app.get('/backoffice/%s/' % area, status=200) + + user1.is_admin = False + user1.roles = [role.id] + user1.store() + resp = app.get('/backoffice/') + assert not '/%s/' % area in resp.body + resp = app.get('/backoffice/%s/' % area, status=403) + + user1.is_admin = False + user1.roles = [role.id, 'XXX'] + user1.store() + resp = app.get('/backoffice/') + assert '/%s/' % area in resp.body + resp = app.get('/backoffice/%s/' % area, status=200) -- 2.6.1