Views accessible via url even if user doesn't match policy rules

When a user doesn't match the policy rules of a panel then the panel tab
is removed from the menu of the left, but panel views are still
accessible using directly the url (ex /admin/flavors/).

In most of the case, views won't work correctly because of the lack of
right in the backend, but it may cause trouble when you play with
policies.

I think it could be more elegant to return directly a "You are not
authorized to access this page" from the frontend when user try to
access a view of a panel (via url) without matching the policy rules.

Change-Id: I7bc93fed29568adfc14d5bcadfc8728d3b5cf633
Closes-Bug: #1741051
This commit is contained in:
David Gutman 2018-01-03 14:25:46 +01:00 committed by Akihiro Motoki
parent 02119d8562
commit 3f585d3b1e
3 changed files with 31 additions and 0 deletions

View File

@ -43,6 +43,7 @@ import six
from horizon import conf
from horizon.decorators import _current_component
from horizon.decorators import require_auth
from horizon.decorators import require_component_access
from horizon.decorators import require_perms
from horizon import loaders
from horizon.utils import settings as utils_settings
@ -320,6 +321,8 @@ class Panel(HorizonComponent):
# Apply access controls to all views in the patterns
permissions = getattr(self, 'permissions', [])
_decorate_urlconf(urlpatterns, require_perms, permissions)
_decorate_urlconf(
urlpatterns, require_component_access, component=self)
_decorate_urlconf(urlpatterns, _current_component, panel=self)
# Return the three arguments to django.conf.urls.include

View File

@ -90,3 +90,26 @@ def require_perms(view_func, required):
return dec
else:
return view_func
def require_component_access(view_func, component):
"""Perform component can_access check to access the view.
:param component containing the view (panel or dashboard).
Raises a :exc:`~horizon.exceptions.NotAuthorized` exception if the
user cannot access the component containing the view.
By example the check of component policy rules will be applied to its
views.
"""
from horizon.exceptions import NotAuthorized
@functools.wraps(view_func, assigned=available_attrs(view_func))
def dec(request, *args, **kwargs):
if not component.can_access({'request': request}):
raise NotAuthorized(_("You are not authorized to access %s")
% request.path)
return view_func(request, *args, **kwargs)
return dec

View File

@ -297,6 +297,11 @@ TEST_GLOBAL_MOCKS_ON_PANELS = {
'.aggregates.panel.Aggregates.can_access'),
'return_value': True,
},
'domains': {
'method': ('openstack_dashboard.dashboards.identity'
'.domains.panel.Domains.can_access'),
'return_value': True,
},
'trunk-project': {
'method': ('openstack_dashboard.dashboards.project'
'.trunks.panel.Trunks.can_access'),