backoffice: check category permissions for export/statistics views (#53667)
This commit is contained in:
parent
7225537069
commit
5783fd8f0a
|
@ -1500,6 +1500,67 @@ def test_backoffice_statistics(pub):
|
|||
assert 'End: 2013-01-01' in resp.text
|
||||
|
||||
|
||||
def test_backoffice_form_category_permissions(pub):
|
||||
user = create_user(pub)
|
||||
create_environment(pub)
|
||||
|
||||
formdef = FormDef.get_by_urlname('form-title')
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' in resp.text
|
||||
assert 'Statistics' in resp.text
|
||||
|
||||
cat1 = Category(name='cat1')
|
||||
cat1.store()
|
||||
formdef.category_id = cat1.id
|
||||
formdef.store()
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' in resp.text
|
||||
assert 'Statistics' in resp.text
|
||||
|
||||
role = pub.role_class(name='limited perms')
|
||||
role.store()
|
||||
cat1.export_roles = [role]
|
||||
cat1.store()
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' not in resp.text
|
||||
assert 'Statistics' in resp.text
|
||||
|
||||
cat1.statistics_roles = [role]
|
||||
cat1.store()
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' not in resp.text
|
||||
assert 'Statistics' not in resp.text
|
||||
app.get('/backoffice/management/form-title/stats', status=403)
|
||||
app.get('/backoffice/management/form-title/export-spreadsheet', status=403)
|
||||
app.get('/backoffice/management/form-title/csv', status=403)
|
||||
app.get('/backoffice/management/form-title/ods', status=403)
|
||||
|
||||
# check it's ok for admins
|
||||
user.is_admin = True
|
||||
user.store()
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' in resp.text
|
||||
assert 'Statistics' in resp.text
|
||||
app.get('/backoffice/management/form-title/stats', status=200)
|
||||
app.get('/backoffice/management/form-title/export-spreadsheet', status=200)
|
||||
app.get('/backoffice/management/form-title/csv', status=200)
|
||||
app.get('/backoffice/management/form-title/ods', status=200)
|
||||
|
||||
# check it's ok for agents with roles
|
||||
user.is_admin = False
|
||||
user.roles.append(role.id)
|
||||
user.store()
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert 'Export a Spreadsheet' in resp.text
|
||||
assert 'Statistics' in resp.text
|
||||
app.get('/backoffice/management/form-title/stats', status=200)
|
||||
app.get('/backoffice/management/form-title/export-spreadsheet', status=200)
|
||||
app.get('/backoffice/management/form-title/csv', status=200)
|
||||
app.get('/backoffice/management/form-title/ods', status=200)
|
||||
|
||||
|
||||
def test_backoffice_multi_actions(pub):
|
||||
create_superuser(pub)
|
||||
create_environment(pub)
|
||||
|
|
|
@ -1183,16 +1183,20 @@ class FormPage(Directory):
|
|||
|
||||
def get_formdata_sidebar_actions(self, qs=''):
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext(
|
||||
' <li><a rel="popup" data-base-href="export-spreadsheet" data-autoclose-dialog="true" '
|
||||
'href="export-spreadsheet%s">%s</a></li>'
|
||||
) % (
|
||||
qs,
|
||||
_('Export a Spreadsheet'),
|
||||
)
|
||||
if not self.formdef.category or self.formdef.category.has_permission('export', get_request().user):
|
||||
r += htmltext(
|
||||
' <li><a rel="popup" data-base-href="export-spreadsheet" data-autoclose-dialog="true" '
|
||||
'href="export-spreadsheet%s">%s</a></li>'
|
||||
) % (
|
||||
qs,
|
||||
_('Export a Spreadsheet'),
|
||||
)
|
||||
if self.formdef.geolocations:
|
||||
r += htmltext(' <li><a data-base-href="map" href="map%s">%s</a></li>') % (qs, _('Plot on a Map'))
|
||||
if 'stats' in self._q_exports:
|
||||
if 'stats' in self._q_exports and (
|
||||
not self.formdef.category
|
||||
or self.formdef.category.has_permission('statistics', get_request().user)
|
||||
):
|
||||
r += htmltext(' <li class="stats"><a href="stats">%s</a></li>') % _('Statistics')
|
||||
return r.getvalue()
|
||||
|
||||
|
@ -2140,6 +2144,8 @@ class FormPage(Directory):
|
|||
|
||||
def export_spreadsheet(self):
|
||||
self.check_access()
|
||||
if self.formdef.category and not self.formdef.category.has_permission('export', get_request().user):
|
||||
raise errors.AccessForbiddenError()
|
||||
form = Form()
|
||||
form.add_hidden('query_string', get_request().get_query())
|
||||
form.add(
|
||||
|
@ -2175,6 +2181,8 @@ class FormPage(Directory):
|
|||
|
||||
def csv(self):
|
||||
self.check_access()
|
||||
if self.formdef.category and not self.formdef.category.has_permission('export', get_request().user):
|
||||
raise errors.AccessForbiddenError()
|
||||
fields = self.get_fields_from_query()
|
||||
selected_filter = self.get_filter_from_query()
|
||||
user = get_request().user
|
||||
|
@ -2227,6 +2235,8 @@ class FormPage(Directory):
|
|||
if get_request().has_anonymised_data_api_restriction():
|
||||
# api/ will let this pass but we don't want that.
|
||||
raise errors.AccessForbiddenError()
|
||||
if self.formdef.category and not self.formdef.category.has_permission('export', get_request().user):
|
||||
raise errors.AccessForbiddenError()
|
||||
fields = self.get_fields_from_query()
|
||||
selected_filter = self.get_filter_from_query()
|
||||
user = get_user_from_api_query_string() or get_request().user
|
||||
|
@ -2476,6 +2486,10 @@ class FormPage(Directory):
|
|||
|
||||
def stats(self):
|
||||
self.check_access()
|
||||
if self.formdef.category and not self.formdef.category.has_permission(
|
||||
'statistics', get_request().user
|
||||
):
|
||||
raise errors.AccessForbiddenError()
|
||||
get_logger().info('backoffice - form %s - stats' % self.formdef.name)
|
||||
html_top('management', '%s - %s' % (_('Form'), self.formdef.name))
|
||||
r = TemplateIO(html=True)
|
||||
|
|
|
@ -124,6 +124,15 @@ class Category(XmlStorableObject):
|
|||
text = '<p>%s</p>' % text
|
||||
return htmltext(text)
|
||||
|
||||
def has_permission(self, permission_name, user):
|
||||
if user.is_admin:
|
||||
return True
|
||||
permission_roles = getattr(self, '%s_roles' % permission_name, None) or []
|
||||
if not permission_roles:
|
||||
return True
|
||||
user_roles = set(user.get_roles()) if user else set()
|
||||
return bool(user_roles.intersection([x.id for x in permission_roles]))
|
||||
|
||||
|
||||
class CardDefCategory(Category):
|
||||
_names = 'carddef_categories'
|
||||
|
|
Loading…
Reference in New Issue