From ab8e9d19f4fdcdb5b0af729f6e75823707851ca3 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 17 Jul 2019 16:47:15 +0200 Subject: [PATCH 1/2] data: delegate permission checking to mellon when available If a page requires roles the user doesn't currently have, we let them be redirected by the middleware. In the case of a cell, we display a link to the appropriate authentication page instead of the cell content. --- combo/data/models.py | 38 +++++++++++++++++++++++++++----------- combo/settings.py | 1 + 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/combo/data/models.py b/combo/data/models.py index 86f9502..fd9d416 100644 --- a/combo/data/models.py +++ b/combo/data/models.py @@ -59,27 +59,32 @@ from .library import register_cell_class, get_cell_classes, get_cell_class from combo import utils from combo.utils import NothingInCacheException +if 'mellon' in settings.INSTALLED_APPS: + from mellon.utils import user_has_roles, get_role_request_url + from mellon.exceptions import RolesNotInSession +else: + def user_has_roles(request, roles): + return len(set(page_groups).intersection(request.user.groups.all())) > 0 + class PostException(Exception): pass -def element_is_visible(element, user=None): +def element_is_visible(element, request=None): if element.public: if getattr(element, 'restricted_to_unlogged', None) is True: - return (user is None or user.is_anonymous()) + return (request is None or request.user.is_anonymous()) return True - if user is None or user.is_anonymous(): + if request is None or request.user.is_anonymous(): return False - if user.is_superuser: - return True page_groups = element.groups.all() if not page_groups: groups_ok = True else: - groups_ok = len(set(page_groups).intersection(user.groups.all())) > 0 + groups_ok = user_has_roles(request, page_groups) if getattr(element, 'restricted_to_unlogged', None) is True: - return not(groups_ok) + return request.user.is_superuser or not(groups_ok) return groups_ok @@ -338,8 +343,8 @@ class Page(models.Model): return _('Public') return _('Private (%s)') % ', '.join([x.name for x in self.groups.all()]) - def is_visible(self, user=None): - return element_is_visible(self, user=user) + def is_visible(self, request=None): + return element_is_visible(self, request=request) def get_cells(self): return CellBase.get_cells(page=self) @@ -669,8 +674,12 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)): def get_extra_manager_context(self): return {} - def is_visible(self, user=None): - return element_is_visible(self, user=user) + def is_visible(self, request=None): + try: + return element_is_visible(self, request=request) + except RolesNotInSession as e: + self.missing_roles = e.roles + return True def is_relevant(self, context): '''Return whether it's relevant to render this cell in the page @@ -689,6 +698,13 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)): return {'cell': self} def render(self, context): + if getattr(self, 'missing_roles', None): + # je vois un context.get('request') plus bas, mais il faudrait que je sache + # dans quel cas ca arrive avant de pouvoir le gerer proprement ici + context['url'] = get_role_request_url(context['request'], self.missing_roles) + context['title'] = _('Some permissions are missing in order to view this cell.') + tmpl = template.loader.get_template('combo/link-cell.html') + return tmpl.render(context, context['request']) context.update(self.get_cell_extra_context(context)) template_names = ['combo/' + self._meta.model_name + '.html'] base_template_name = self._meta.model_name + '.html' diff --git a/combo/settings.py b/combo/settings.py index 5b6025e..c2a0a34 100644 --- a/combo/settings.py +++ b/combo/settings.py @@ -239,6 +239,7 @@ if mellon is not None: 'mellon.backends.SAMLBackend', 'django.contrib.auth.backends.ModelBackend', ) + MIDDLEWARE_CLASSES += ('mellon.middleware.RolesRequestMiddleware',) LOGIN_URL = '/login/' LOGIN_REDIRECT_URL = '/' -- 2.20.1