backoffice: only display datasource custom views to admins (#77191) #299
|
@ -6,6 +6,7 @@ from quixote import get_publisher
|
|||
|
||||
from wcs import fields
|
||||
from wcs.carddef import CardDef
|
||||
from wcs.categories import CardDefCategory
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.qommon.ident.password_accounts import PasswordAccount
|
||||
|
@ -1239,3 +1240,64 @@ def test_item_options_in_dynamic_view(pub):
|
|||
'a3',
|
||||
'{}',
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('user_perms', ['admin', 'category_admin', 'category_not_admin', 'agent'])
|
||||
def test_backoffice_hidden_data_source_custom_view(pub, user_perms):
|
||||
pub.user_class.wipe()
|
||||
|
||||
CardDefCategory.wipe()
|
||||
cat = CardDefCategory(name='Foo')
|
||||
cat.store()
|
||||
|
||||
if user_perms == 'admin':
|
||||
user = create_superuser(pub)
|
||||
elif user_perms == 'category_admin':
|
||||
user = create_user(pub)
|
||||
cat.management_roles = [pub.role_class.get(user.roles[0])]
|
||||
cat.store()
|
||||
else:
|
||||
user = create_user(pub)
|
||||
|
||||
pub.custom_view_class.wipe()
|
||||
CardDef.wipe()
|
||||
carddef = CardDef()
|
||||
carddef.name = 'foo'
|
||||
carddef.fields = [
|
||||
fields.StringField(id='1', label='Test', type='string', varname='foo'),
|
||||
]
|
||||
carddef.backoffice_submission_roles = user.roles
|
||||
carddef.workflow_roles = {'_editor': user.roles[0]}
|
||||
carddef.digest_templates = {
|
||||
'default': 'plop',
|
||||
'custom-view:custom-test-view': 'FOO {{ form_var_foo }}',
|
||||
'custom-view:datasource-view': '{{ form_var_foo }}',
|
||||
}
|
||||
if user_perms in ('category_admin', 'category_not_admin'):
|
||||
carddef.category = cat
|
||||
carddef.store()
|
||||
|
||||
custom_view = pub.custom_view_class()
|
||||
custom_view.title = 'custom test view'
|
||||
custom_view.formdef = carddef
|
||||
custom_view.visibility = 'any'
|
||||
custom_view.columns = {'list': [{'id': 'id'}]}
|
||||
custom_view.filters = {}
|
||||
custom_view.store()
|
||||
|
||||
custom_view = pub.custom_view_class()
|
||||
custom_view.title = 'datasource view'
|
||||
custom_view.formdef = carddef
|
||||
custom_view.visibility = 'datasource'
|
||||
custom_view.columns = {'list': [{'id': 'id'}]}
|
||||
custom_view.filters = {}
|
||||
custom_view.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/data/foo/')
|
||||
visible_views = {x.attrib['href'] for x in resp.pyquery('#sidebar-custom-views a')}
|
||||
|
||||
if user_perms in ('admin', 'category_admin'):
|
||||
assert visible_views == {'datasource-view/', 'custom-test-view/'}
|
||||
else:
|
||||
assert visible_views == {'custom-test-view/'}
|
||||
|
|
|
@ -1856,7 +1856,7 @@ class FormsDirectory(AccessControlled, Directory):
|
|||
|
||||
def _q_lookup(self, component):
|
||||
directory = self.formdef_page_class(component)
|
||||
if not directory.formdef.has_user_access(get_request().user):
|
||||
if not directory.formdef.has_admin_access(get_request().user):
|
||||
raise AccessForbiddenError()
|
||||
return directory
|
||||
|
||||
|
|
|
@ -2129,7 +2129,7 @@ class WorkflowsDirectory(Directory):
|
|||
directory = WorkflowPage(component)
|
||||
if directory.workflow.id in ('_default', '_carddef_default'):
|
||||
return directory
|
||||
if not directory.workflow.has_user_access(get_request().user):
|
||||
if not directory.workflow.has_admin_access(get_request().user):
|
||||
raise errors.AccessForbiddenError()
|
||||
return directory
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ class ApiCardPage(ApiFormPageMixin, BackofficeCardPage):
|
|||
return super().check_access(api_name=api_name)
|
||||
|
||||
def schema(self):
|
||||
if is_url_signed() or self.formdef.has_user_access(get_user_from_api_query_string()):
|
||||
if is_url_signed() or self.formdef.has_admin_access(get_user_from_api_query_string()):
|
||||
get_response().set_content_type('application/json')
|
||||
return self.formdef.export_to_json(with_user_fields=True)
|
||||
raise AccessForbiddenError()
|
||||
|
@ -563,7 +563,7 @@ class ApiFormdefDirectory(Directory):
|
|||
self.formdef = formdef
|
||||
|
||||
def schema(self):
|
||||
if is_url_signed() or self.formdef.has_user_access(get_user_from_api_query_string()):
|
||||
if is_url_signed() or self.formdef.has_admin_access(get_user_from_api_query_string()):
|
||||
get_response().set_content_type('application/json')
|
||||
return self.formdef.export_to_json()
|
||||
raise AccessForbiddenError()
|
||||
|
|
|
@ -879,12 +879,12 @@ class FormPage(FormdefDirectoryBase):
|
|||
):
|
||||
r += htmltext(' <li class="stats"><a href="stats">%s</a></li>') % _('Statistics')
|
||||
|
||||
if self.formdef.has_user_access(get_request().user):
|
||||
if self.formdef.has_admin_access(get_request().user):
|
||||
r += htmltext(' <li><a href="%s">%s</a></li>') % (
|
||||
self.formdef.get_admin_url(),
|
||||
self.formdef_view_label,
|
||||
)
|
||||
if self.formdef.workflow.has_user_access(get_request().user):
|
||||
if self.formdef.workflow.has_admin_access(get_request().user):
|
||||
r += htmltext(' <li><a href="%s">%s</a></li>') % (
|
||||
self.formdef.workflow.get_admin_url(),
|
||||
_('View Workflow'),
|
||||
|
@ -896,7 +896,10 @@ class FormPage(FormdefDirectoryBase):
|
|||
r += htmltext('<ul id="sidebar-actions">')
|
||||
r += self.get_formdata_sidebar_actions(qs=qs)
|
||||
r += htmltext('</ul>')
|
||||
views = list(self.get_custom_views())
|
||||
criterias = []
|
||||
if not self.formdef.has_admin_access(get_request().user):
|
||||
criterias = [NotEqual('visibility', 'datasource')]
|
||||
views = list(self.get_custom_views(criterias))
|
||||
if views:
|
||||
r += htmltext('<h3>%s</h3>') % _('Custom Views')
|
||||
r += htmltext('<ul id="sidebar-custom-views">')
|
||||
|
@ -3677,8 +3680,8 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
return v
|
||||
|
||||
access_to_admin_forms = get_publisher().get_backoffice_root().is_global_accessible('forms')
|
||||
access_to_formdef = self.formdef.has_user_access(get_request().user)
|
||||
access_to_workflow = self.formdef.workflow.has_user_access(get_request().user)
|
||||
access_to_formdef = self.formdef.has_admin_access(get_request().user)
|
||||
access_to_workflow = self.formdef.workflow.has_admin_access(get_request().user)
|
||||
|
||||
for k in sorted(substvars.get_flat_keys()):
|
||||
if not k.startswith('form_'):
|
||||
|
|
|
@ -364,7 +364,9 @@ class FormDef(StorableObject):
|
|||
break
|
||||
return '%s%s' % (direction, order_by)
|
||||
|
||||
def has_user_access(self, user):
|
||||
def has_admin_access(self, user):
|
||||
# return True if user 1/ is global administrator for this type of object, or
|
||||
# 2/ has one of the management roles defined in its category.
|
||||
if get_publisher().get_backoffice_root().is_global_accessible(self.backoffice_section):
|
||||
return True
|
||||
if not user:
|
||||
|
|
|
@ -1341,7 +1341,7 @@ class Workflow(StorableObject):
|
|||
criterias = [st.Contains('slug', slugs)]
|
||||
return list(MailTemplate.select(criterias, order_by='name'))
|
||||
|
||||
def has_user_access(self, user):
|
||||
def has_admin_access(self, user):
|
||||
if get_publisher().get_backoffice_root().is_global_accessible('workflows'):
|
||||
return True
|
||||
if not user:
|
||||
|
|
Loading…
Reference in New Issue