diff options
author | David Gutman <david.gutman@thalesgroup.com> | 2018-01-03 14:25:46 +0100 |
---|---|---|
committer | David Gutman <david.gutman@thalesgroup.com> | 2018-02-09 15:18:11 +0100 |
commit | 1870b536e20213b89122c5eded9ce0d40e572cfd (patch) | |
tree | 452578888229c77bd16728ed9344d739687ae967 | |
parent | 2785a60bb41002a187289138302d55b6d419658e (diff) | |
download | horizon-1870b536e20213b89122c5eded9ce0d40e572cfd.tar.gz |
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
(cherry picked from commit 3f585d3b1efca1b2379d6c0a80246fd6e5a87640)
-rw-r--r-- | horizon/base.py | 3 | ||||
-rw-r--r-- | horizon/decorators.py | 23 | ||||
-rw-r--r-- | openstack_dashboard/test/settings.py | 5 |
3 files changed, 31 insertions, 0 deletions
diff --git a/horizon/base.py b/horizon/base.py index 0b2ef870b..e2c2a830a 100644 --- a/horizon/base.py +++ b/horizon/base.py @@ -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 diff --git a/horizon/decorators.py b/horizon/decorators.py index 7be22ef44..dd4fe776b 100644 --- a/horizon/decorators.py +++ b/horizon/decorators.py @@ -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 diff --git a/openstack_dashboard/test/settings.py b/openstack_dashboard/test/settings.py index 8b36dfda9..d1ff532a9 100644 --- a/openstack_dashboard/test/settings.py +++ b/openstack_dashboard/test/settings.py @@ -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': { 'method': ('openstack_dashboard.dashboards.project' '.trunks.panel.Trunks.can_access'), |