Support policy checks in the Tab base class
Many tabs are populated via API calls; we should have a way to check if those calls will fail before displaying the tab. Change-Id: I2968f611b2ae49bfb66d74e32dc9729eaa447f4c
This commit is contained in:
parent
a4cea370d4
commit
4aa00e8f54
|
@ -23,6 +23,7 @@ from django.utils import module_loading
|
|||
|
||||
from horizon import exceptions
|
||||
from horizon.utils import html
|
||||
from horizon.utils import settings as utils_settings
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -307,8 +308,9 @@ class Tab(html.HTMLElement):
|
|||
preload = True
|
||||
_active = None
|
||||
permissions = []
|
||||
policy_rules = None
|
||||
|
||||
def __init__(self, tab_group, request=None):
|
||||
def __init__(self, tab_group, request=None, policy_rules=None):
|
||||
super().__init__()
|
||||
# Priority: constructor, class-defined, fallback
|
||||
if not self.name:
|
||||
|
@ -321,6 +323,7 @@ class Tab(html.HTMLElement):
|
|||
self._allowed = self.allowed(request) and (
|
||||
self._has_permissions(request))
|
||||
self._enabled = self.enabled(request)
|
||||
self.policy_rules = policy_rules or []
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %s>" % (self.__class__.__name__, self.slug)
|
||||
|
@ -437,9 +440,14 @@ class Tab(html.HTMLElement):
|
|||
|
||||
Tab instances can override this method to specify conditions under
|
||||
which this tab should not be shown at all by returning ``False``.
|
||||
|
||||
The default behavior is to return ``True`` for all cases.
|
||||
"""
|
||||
if not self.policy_rules:
|
||||
return True
|
||||
|
||||
policy_check = utils_settings.import_setting("POLICY_CHECK_FUNCTION")
|
||||
|
||||
if policy_check:
|
||||
return policy_check(self.policy_rules, request)
|
||||
return True
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
|
|
@ -65,9 +65,16 @@ class TabDisallowed(BaseTestTab):
|
|||
return False
|
||||
|
||||
|
||||
class TabWithPolicy(BaseTestTab):
|
||||
slug = "tab_with_policy"
|
||||
name = "tab only visible to admin"
|
||||
template_name = "_tab.html"
|
||||
policy_rules = (("compute", "role:admin"),)
|
||||
|
||||
|
||||
class Group(horizon_tabs.TabGroup):
|
||||
slug = "tab_group"
|
||||
tabs = (TabOne, TabDelayed, TabDisabled, TabDisallowed)
|
||||
tabs = (TabOne, TabDelayed, TabDisabled, TabDisallowed, TabWithPolicy)
|
||||
sticky = True
|
||||
|
||||
def tabs_not_available(self):
|
||||
|
@ -126,15 +133,19 @@ class TabWithTableView(horizon_tabs.TabbedTableView):
|
|||
|
||||
|
||||
class TabTests(test.TestCase):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=lambda *args: True)
|
||||
def test_tab_group_basics(self):
|
||||
tg = Group(self.request)
|
||||
|
||||
# Test tab instantiation/attachment to tab group, and get_tabs method
|
||||
tabs = tg.get_tabs()
|
||||
# "tab_disallowed" should NOT be in this list.
|
||||
# "tab_with_policy" should be present, since our policy check
|
||||
# always passes
|
||||
self.assertQuerysetEqual(tabs, ['<TabOne: tab_one>',
|
||||
'<TabDelayed: tab_delayed>',
|
||||
'<TabDisabled: tab_disabled>'])
|
||||
'<TabDisabled: tab_disabled>',
|
||||
'<TabWithPolicy: tab_with_policy>'])
|
||||
# Test get_id
|
||||
self.assertEqual("tab_group", tg.get_id())
|
||||
# get_default_classes
|
||||
|
@ -149,6 +160,19 @@ class TabTests(test.TestCase):
|
|||
# Test get_selected_tab is None w/o GET input
|
||||
self.assertIsNone(tg.get_selected_tab())
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=lambda *args: False)
|
||||
def test_failed_tab_policy(self):
|
||||
tg = Group(self.request)
|
||||
|
||||
# Test tab instantiation/attachment to tab group, and get_tabs method
|
||||
tabs = tg.get_tabs()
|
||||
# "tab_disallowed" should NOT be in this list, it's not allowed
|
||||
# "tab_with_policy" should also not be present as its
|
||||
# policy check failed
|
||||
self.assertQuerysetEqual(tabs, ['<TabOne: tab_one>',
|
||||
'<TabDelayed: tab_delayed>',
|
||||
'<TabDisabled: tab_disabled>'])
|
||||
|
||||
@test.update_settings(
|
||||
HORIZON_CONFIG={'extra_tabs': {
|
||||
'horizon.test.unit.tabs.test_tabs.GroupWithConfig': (
|
||||
|
@ -251,7 +275,7 @@ class TabTests(test.TestCase):
|
|||
# tab group
|
||||
output = tg.render()
|
||||
res = http.HttpResponse(output.strip())
|
||||
self.assertContains(res, "<li", 3)
|
||||
self.assertContains(res, "<li", 4)
|
||||
|
||||
# stickiness
|
||||
self.assertContains(res, 'data-sticky-tabs="sticky"', 1)
|
||||
|
|
Loading…
Reference in New Issue