general: don't allow admins to get into new areas, unless authorized (#8562)

This commit is contained in:
Frédéric Péters 2015-10-08 09:03:03 +02:00
parent c8b78b6f0c
commit a685a0ef40
8 changed files with 98 additions and 41 deletions

View File

@ -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())

View File

@ -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')

View File

@ -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()

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -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')

View File

@ -72,11 +72,6 @@ def test_with_superuser():
# this makes sure the extension loaded properly
assert '<span id="applabel">Publik</span>' 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)