backoffice: refactor check of backoffice access rights (#6726)
This commit is contained in:
parent
7ef5152323
commit
f95e3361e8
|
@ -33,12 +33,14 @@ def pub(request):
|
|||
|
||||
return pub
|
||||
|
||||
def create_superuser(pub):
|
||||
global user1
|
||||
def create_user(pub, is_admin=True):
|
||||
if pub.user_class.select(lambda x: x.name == 'admin'):
|
||||
user1 = pub.user_class.select(lambda x: x.name == 'admin')[0]
|
||||
user1.is_admin = is_admin
|
||||
user1.store()
|
||||
return
|
||||
user1 = pub.user_class(name='admin')
|
||||
user1.is_admin = True
|
||||
user1.is_admin = is_admin
|
||||
user1.store()
|
||||
|
||||
account1 = PasswordAccount(id='admin')
|
||||
|
@ -53,6 +55,7 @@ def create_superuser(pub):
|
|||
user1.roles = [role.id]
|
||||
user1.store()
|
||||
|
||||
|
||||
def create_environment(set_receiver=True):
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
|
@ -100,19 +103,43 @@ def teardown_module(module):
|
|||
clean_temporary_pub()
|
||||
|
||||
def test_backoffice_unlogged(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
resp = get_app(pub).get('/backoffice/', status=302)
|
||||
resp = resp.follow()
|
||||
assert resp.location == 'http://example.net/login/'
|
||||
|
||||
def test_backoffice_home(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/')
|
||||
assert 'Management' in resp.body
|
||||
assert 'Forms Workshop' in resp.body
|
||||
assert 'Workflows Workshop' in resp.body
|
||||
|
||||
def test_backoffice_role_user(pub):
|
||||
create_user(pub, is_admin=False)
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/')
|
||||
assert 'Management' in resp.body
|
||||
assert not 'Forms Workshop' in resp.body
|
||||
assert not 'Workflows Workshop' in resp.body
|
||||
|
||||
pub.cfg['admin-permissions'] = {'forms': [x.id for x in Role.select()]}
|
||||
pub.write_cfg()
|
||||
resp = app.get('/backoffice/')
|
||||
assert 'Management' in resp.body
|
||||
assert 'Forms Workshop' in resp.body
|
||||
assert not 'Workflows Workshop' in resp.body
|
||||
|
||||
pub.cfg['admin-permissions'] = {'workflows': [x.id for x in Role.select()]}
|
||||
pub.write_cfg()
|
||||
resp = app.get('/backoffice/')
|
||||
assert 'Management' in resp.body
|
||||
assert not 'Forms Workshop' in resp.body
|
||||
assert 'Workflows Workshop' in resp.body
|
||||
|
||||
def test_backoffice_forms(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment(set_receiver=False)
|
||||
|
||||
# 1st time with user not handling those forms
|
||||
|
@ -131,7 +158,7 @@ def test_backoffice_forms(pub):
|
|||
assert '17 open on 50' in resp.body
|
||||
|
||||
def test_backoffice_listing(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -159,7 +186,7 @@ def test_backoffice_listing(pub):
|
|||
assert resp.body.count('data-link') == 33
|
||||
|
||||
def test_backoffice_columns(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -171,7 +198,7 @@ def test_backoffice_columns(pub):
|
|||
assert resp.body.count('FOO BAR') == 0 # no field 1 column
|
||||
|
||||
def test_backoffice_filter(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -197,7 +224,7 @@ def test_backoffice_filter(pub):
|
|||
assert resp.body.count('<td>baz</td>') == 8
|
||||
|
||||
def test_backoffice_csv(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -212,7 +239,7 @@ def test_backoffice_csv(pub):
|
|||
assert len(resp.body.splitlines()) == 51
|
||||
|
||||
def test_backoffice_ods(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -222,7 +249,7 @@ def test_backoffice_ods(pub):
|
|||
assert resp.body[:2] == 'PK' # ods has a zip container
|
||||
|
||||
def test_backoffice_statistics(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -240,7 +267,7 @@ def test_backoffice_statistics(pub):
|
|||
assert 'Total number of records: 0' in resp.body
|
||||
|
||||
def test_backoffice_statistics_status_filter(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -270,7 +297,7 @@ def test_backoffice_statistics_status_filter(pub):
|
|||
assert 'Total number of records: 50' in resp.body
|
||||
|
||||
def test_backoffice_statistics_status_select(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/form-title/')
|
||||
|
@ -291,7 +318,7 @@ def test_backoffice_statistics_status_select(pub):
|
|||
assert 'Total number of records: 13' in resp.body
|
||||
|
||||
def test_backoffice_handling(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
form_class = FormDef.get_by_urlname('form-title').data_class()
|
||||
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0].id
|
||||
|
@ -306,7 +333,7 @@ def test_backoffice_handling(pub):
|
|||
assert 'HELLO WORLD' in resp.body
|
||||
|
||||
def test_global_statisticspub(pub):
|
||||
create_superuser(pub)
|
||||
create_user(pub)
|
||||
create_environment()
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/')
|
||||
|
|
|
@ -32,7 +32,6 @@ from qommon.afterjobs import AfterJob
|
|||
from qommon import errors
|
||||
from qommon import ods
|
||||
from qommon.form import *
|
||||
from qommon.admin.menu import is_accessible
|
||||
from qommon.storage import Equal, NotEqual, LessOrEqual, GreaterOrEqual, Or
|
||||
|
||||
from wcs.forms.common import FormStatusPage
|
||||
|
@ -239,6 +238,38 @@ class RootDirectory(BackofficeRootDirectory):
|
|||
('/', N_('WCS Form Server'))
|
||||
]
|
||||
|
||||
def _q_traverse(self, path):
|
||||
get_response().add_javascript(['jquery.js'])
|
||||
return super(RootDirectory, self)._q_traverse(path)
|
||||
|
||||
@classmethod
|
||||
def is_accessible(cls, subdirectory):
|
||||
# check a backoffice directory is accessible to the current user
|
||||
if not get_request().user:
|
||||
if get_publisher().user_class.count() == 0:
|
||||
# setting up the site, access is granted to settings and users
|
||||
# sections
|
||||
return subdirectory in ('settings', 'users')
|
||||
if getattr(get_response(), 'filter', {}) and get_response().filter.get('admin_for_all'):
|
||||
# if admin for all is set, access is granted to everything
|
||||
return True
|
||||
return False
|
||||
|
||||
user_roles = set(get_request().user.roles or [])
|
||||
authorised_roles = set(get_cfg('admin-permissions', {}).get(subdirectory) or [])
|
||||
if authorised_roles:
|
||||
# access is governed by roles set in the settings panel
|
||||
return user_roles.intersection(authorised_roles)
|
||||
|
||||
# for some subdirectories, the user needs to be part of a role allowed
|
||||
# to go in the backoffice
|
||||
if subdirectory in ('management',):
|
||||
return get_request().user.can_go_in_backoffice()
|
||||
|
||||
# for the other directories, an extra level is required, the user needs
|
||||
# to be marked as admin
|
||||
return get_request().user.can_go_in_admin()
|
||||
|
||||
def _q_access(self):
|
||||
get_response().breadcrumb.append( ('backoffice/', _('Back Office')) )
|
||||
req = get_request()
|
||||
|
@ -519,7 +550,7 @@ class RootDirectory(BackofficeRootDirectory):
|
|||
|
||||
def _q_lookup(self, component):
|
||||
if component in [str(x[0]).strip('/') for x in self.menu_items]:
|
||||
if not is_accessible(component):
|
||||
if not self.is_accessible(component):
|
||||
raise errors.AccessForbiddenError()
|
||||
return getattr(self, component)
|
||||
return FormPage(component)
|
||||
|
@ -541,7 +572,7 @@ class RootDirectory(BackofficeRootDirectory):
|
|||
continue
|
||||
if display_function and not display_function(slug):
|
||||
continue
|
||||
if not is_accessible(slug):
|
||||
if not self.is_accessible(slug):
|
||||
continue
|
||||
if callable(v):
|
||||
label = v()
|
||||
|
|
|
@ -153,13 +153,12 @@ class Category(XmlStorableObject):
|
|||
return '%s/%s/' % (base_url, self.url_name)
|
||||
|
||||
def get_description_html_text(self, editable=True):
|
||||
from qommon.admin.menu import is_accessible
|
||||
if not self.description:
|
||||
return None
|
||||
text = self.description
|
||||
if text[0] != '<':
|
||||
text = '<p>%s</p>' % text
|
||||
if editable and is_accessible('categories'):
|
||||
if editable and get_publisher().get_backoffice_root().is_accessible('categories'):
|
||||
root_url = get_publisher().get_root_url()
|
||||
get_response().add_javascript(['jquery.js', 'jquery-ui.js',
|
||||
'ckeditor/ckeditor.js', 'qommon.wysiwyg.js',
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
from quixote import get_publisher, get_response, get_request, get_session
|
||||
from quixote.html import TemplateIO, htmltext
|
||||
|
||||
from qommon.misc import is_user_admin
|
||||
from qommon import get_cfg
|
||||
import re
|
||||
|
||||
|
@ -179,18 +178,3 @@ def error_page(section, error):
|
|||
r += htmltext('<a href="%s">%s</a>') % (get_request().get_url(), _('Back'))
|
||||
r += htmltext('</div>')
|
||||
return r.getvalue()
|
||||
|
||||
def is_accessible(key):
|
||||
if not get_request().user:
|
||||
if get_publisher().user_class.count() == 0:
|
||||
return key in ('settings', 'users')
|
||||
if getattr(get_response(), 'filter', {}) and get_response().filter.get('admin_for_all'):
|
||||
return True
|
||||
return False
|
||||
|
||||
user_roles = set(get_request().user.roles or [])
|
||||
authorised_roles = set(get_cfg('admin-permissions', {}).get(key) or [])
|
||||
if not authorised_roles:
|
||||
return is_user_admin()
|
||||
|
||||
return user_roles.intersection(authorised_roles)
|
||||
|
|
|
@ -24,7 +24,6 @@ from quixote.directory import Directory
|
|||
from qommon.form import *
|
||||
from qommon import misc, get_cfg, ezt
|
||||
from qommon.backoffice.menu import html_top
|
||||
from qommon.admin.menu import is_accessible
|
||||
|
||||
|
||||
class TextsDirectory(Directory):
|
||||
|
@ -56,7 +55,8 @@ class TextsDirectory(Directory):
|
|||
text_template.generate(fd, subst_vars)
|
||||
text = fd.getvalue()
|
||||
|
||||
if is_accessible('settings'):
|
||||
if get_publisher().get_backoffice_root() and \
|
||||
get_publisher().get_backoffice_root().is_accessible('settings'):
|
||||
root_url = get_publisher().get_root_url()
|
||||
get_response().add_javascript(['jquery.js', 'jquery-ui.js',
|
||||
'ckeditor/ckeditor.js', 'qommon.wysiwyg.js',
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
from quixote import get_response, get_request, get_publisher, get_session
|
||||
|
||||
from qommon import get_cfg
|
||||
from qommon.misc import is_user_admin
|
||||
from quixote.html import htmltext, TemplateIO
|
||||
|
||||
def generate_header_menu(selected = None):
|
||||
|
|
|
@ -271,20 +271,6 @@ def http_get_page(url, headers={}, timeout=None):
|
|||
def http_post_request(url, body=None, headers={}, timeout=None):
|
||||
return _http_request(url, 'POST', body, headers, timeout=timeout)
|
||||
|
||||
def is_user_admin():
|
||||
session = get_session()
|
||||
if not session:
|
||||
return False
|
||||
user = session.get_user_object()
|
||||
if not user:
|
||||
return False
|
||||
if callable(user.is_admin):
|
||||
if user.is_admin():
|
||||
return True
|
||||
elif user.is_admin:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_variadic_url(url, variables, encode_query=True):
|
||||
# substitution in an URL : try to be safe
|
||||
|
||||
|
|
Loading…
Reference in New Issue