backoffice: refactor check of backoffice access rights (#6726)

This commit is contained in:
Frédéric Péters 2015-05-06 22:10:21 +02:00
parent d85ca517cf
commit 0c71152a89
7 changed files with 69 additions and 41 deletions

View File

@ -33,12 +33,14 @@ def pub(request):
return pub
def create_superuser(pub):
global user1
def create_user(pub, is_admin=False):
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,9 @@ def create_superuser(pub):
user1.roles = [role.id]
user1.store()
def create_superuser(pub):
create_user(pub, is_admin=True)
def create_environment(set_receiver=True):
FormDef.wipe()
formdef = FormDef()
@ -110,6 +115,30 @@ def test_backoffice_home(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)
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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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