Specify POLICY_CHECK_FUNCTION as a string
We don't want code in our settings.py and local_settings.py, and in particular we don't want to have to import Python objects from all over to set them as setting values -- instead, we can specify those as import path strings. This also solves problems with importing order and loops. This change is backwards-compatible, in the sense that you can still import the objects directly and set them as the setting values. Partially-Implements: blueprint ini-based-configuration Change-Id: I8a346e55bb98e4e22e0c14a614c45d493d20feb4
This commit is contained in:
parent
11f6e3de48
commit
f5685ebe46
@ -45,6 +45,7 @@ from horizon.decorators import _current_component # noqa
|
||||
from horizon.decorators import require_auth # noqa
|
||||
from horizon.decorators import require_perms # noqa
|
||||
from horizon import loaders
|
||||
from horizon.utils import settings as utils_settings
|
||||
|
||||
|
||||
# Name of the panel group for panels to be displayed without a group.
|
||||
@ -144,7 +145,7 @@ class HorizonComponent(object):
|
||||
return self._can_access(context['request'])
|
||||
|
||||
def _can_access(self, request):
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
policy_check = utils_settings.import_setting("POLICY_CHECK_FUNCTION")
|
||||
|
||||
# this check is an OR check rather than an AND check that is the
|
||||
# default in the policy engine, so calling each rule individually
|
||||
|
@ -33,6 +33,7 @@ import six
|
||||
from horizon import messages
|
||||
from horizon.utils import functions
|
||||
from horizon.utils import html
|
||||
from horizon.utils import settings as utils_settings
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -129,7 +130,7 @@ class BaseAction(html.HTMLElement):
|
||||
return True
|
||||
|
||||
def _allowed(self, request, datum):
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
policy_check = utils_settings.import_setting("POLICY_CHECK_FUNCTION")
|
||||
|
||||
if policy_check and self.policy_rules:
|
||||
target = self.get_policy_target(request, datum)
|
||||
|
28
horizon/utils/settings.py
Normal file
28
horizon/utils/settings.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.module_loading import import_string
|
||||
|
||||
|
||||
def import_object(name_or_object):
|
||||
if isinstance(name_or_object, six.string_types):
|
||||
return import_string(name_or_object)
|
||||
return name_or_object
|
||||
|
||||
|
||||
def import_setting(name):
|
||||
"""Imports an object specified either directly or as a module path."""
|
||||
value = getattr(settings, name, None)
|
||||
return import_object(value)
|
@ -27,7 +27,6 @@ from mox3.mox import IgnoreArg # noqa
|
||||
from mox3.mox import IsA # noqa
|
||||
|
||||
from horizon.workflows import views
|
||||
from openstack_auth import policy as policy_backend
|
||||
|
||||
from openstack_dashboard import api
|
||||
from openstack_dashboard.dashboards.identity.projects import workflows
|
||||
@ -100,7 +99,7 @@ class TenantsViewTests(test.BaseAdminViewTests):
|
||||
|
||||
|
||||
class ProjectsViewNonAdminTests(test.TestCase):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
@test.create_stubs({api.keystone: ('tenant_list',
|
||||
'domain_lookup')})
|
||||
def test_index(self):
|
||||
|
@ -12,13 +12,13 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
from horizon.utils import settings as utils_settings
|
||||
|
||||
|
||||
def check(actions, request, target=None):
|
||||
"""Wrapper of the configurable policy method."""
|
||||
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
policy_check = utils_settings.import_setting("POLICY_CHECK_FUNCTION")
|
||||
|
||||
if policy_check:
|
||||
return policy_check(actions, request, target)
|
||||
|
@ -305,14 +305,7 @@ THEME_COLLECTION_DIR = 'themes'
|
||||
# Theme Cookie Name
|
||||
THEME_COOKIE_NAME = 'theme'
|
||||
|
||||
|
||||
def check(actions, request, target=None):
|
||||
# Note(Itxaka): This is to prevent circular dependencies and apps not ready
|
||||
# If you do django imports in your settings, you are gonna have a bad time
|
||||
from openstack_auth import policy
|
||||
return policy.check(actions, request, target)
|
||||
|
||||
POLICY_CHECK_FUNCTION = check
|
||||
POLICY_CHECK_FUNCTION = 'openstack_auth.policy.check'
|
||||
|
||||
CSRF_COOKIE_AGE = None
|
||||
|
||||
|
@ -617,7 +617,7 @@ class NeutronApiTests(test.APITestCase):
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||
True},
|
||||
POLICY_CHECK_FUNCTION=policy.check)
|
||||
POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
@test.create_stubs({api.neutron: ('is_extension_supported',)})
|
||||
def _test_get_dvr_permission_with_policy_check(self, policy_check_allowed,
|
||||
operation):
|
||||
@ -655,7 +655,7 @@ class NeutronApiTests(test.APITestCase):
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||
True},
|
||||
POLICY_CHECK_FUNCTION=policy.check)
|
||||
POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_get_dvr_permission_dvr_unsupported_operation(self):
|
||||
self.assertRaises(ValueError,
|
||||
api.neutron.get_feature_permission,
|
||||
@ -675,7 +675,7 @@ class NeutronApiTests(test.APITestCase):
|
||||
# above. l3-ha check only checks l3-ha specific code.
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_ha_router': True},
|
||||
POLICY_CHECK_FUNCTION=policy.check)
|
||||
POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
@test.create_stubs({api.neutron: ('is_extension_supported', )})
|
||||
def _test_get_router_ha_permission_with_policy_check(self, ha_enabled):
|
||||
self.mox.StubOutWithMock(policy, 'check')
|
||||
|
@ -11,46 +11,45 @@
|
||||
# limitations under the License.
|
||||
|
||||
from django.test.utils import override_settings # noqa
|
||||
from openstack_auth import policy as policy_backend
|
||||
|
||||
from openstack_dashboard.api.rest import policy
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class PolicyRestTestCase(test.TestCase):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_policy(self, body='{"rules": []}'):
|
||||
request = self.mock_rest_request(body=body)
|
||||
response = policy.Policy().post(request)
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertEqual({"allowed": True}, response.json)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_rule_alone(self):
|
||||
body = '{"rules": [["compute", "compute:get_all" ]]}'
|
||||
self.test_policy(body)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_multiple_rule(self):
|
||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||
' ["compute", "compute:start"]]}'
|
||||
self.test_policy(body)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_rule_with_empty_target(self):
|
||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||
' ["compute", "compute:start"]],' \
|
||||
' "target": {}}'
|
||||
self.test_policy(body)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_rule_with_target(self):
|
||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||
' ["compute", "compute:start"]],' \
|
||||
' "target": {"project_id": "1"}}'
|
||||
self.test_policy(body)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_policy_fail(self):
|
||||
# admin only rule, default test case user should fail
|
||||
request = self.mock_rest_request(
|
||||
@ -59,7 +58,7 @@ class PolicyRestTestCase(test.TestCase):
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertEqual({"allowed": False}, response.json)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_policy_error(self):
|
||||
# admin only rule, default test case user should fail
|
||||
request = self.mock_rest_request(
|
||||
@ -69,7 +68,7 @@ class PolicyRestTestCase(test.TestCase):
|
||||
|
||||
|
||||
class AdminPolicyRestTestCase(test.BaseAdminViewTests):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_rule_with_target(self):
|
||||
body = '{"rules": [["compute", "compute:unlock_override"]]}'
|
||||
request = self.mock_rest_request(body=body)
|
||||
|
@ -12,14 +12,13 @@
|
||||
# under the License.
|
||||
|
||||
from django.test.utils import override_settings
|
||||
from openstack_auth import policy as policy_backend
|
||||
|
||||
from openstack_dashboard import policy
|
||||
from openstack_dashboard.test import helpers as test
|
||||
|
||||
|
||||
class PolicyTestCase(test.TestCase):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_policy_check_set(self):
|
||||
value = policy.check((("identity", "admin_required"),),
|
||||
request=self.request)
|
||||
@ -33,7 +32,7 @@ class PolicyTestCase(test.TestCase):
|
||||
|
||||
|
||||
class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_policy_check_set_admin(self):
|
||||
value = policy.check((("identity", "admin_required"),),
|
||||
request=self.request)
|
||||
|
@ -31,14 +31,14 @@ class PolicyBackendTestCase(test.TestCase):
|
||||
policy_backend.reset()
|
||||
self.assertIsNone(policy_backend._ENFORCER)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_admin_required_false(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "admin_required"),),
|
||||
request=self.request)
|
||||
self.assertFalse(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_identity_rule_not_found_false(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "i_dont_exist"),),
|
||||
@ -47,14 +47,14 @@ class PolicyBackendTestCase(test.TestCase):
|
||||
# identity is admin_required
|
||||
self.assertFalse(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_nova_context_is_admin_false(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("compute", "context_is_admin"),),
|
||||
request=self.request)
|
||||
self.assertFalse(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_compound_check_false(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "admin_required"),
|
||||
@ -62,7 +62,7 @@ class PolicyBackendTestCase(test.TestCase):
|
||||
request=self.request)
|
||||
self.assertFalse(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_scope_not_found(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("dummy", "default"),),
|
||||
@ -71,14 +71,14 @@ class PolicyBackendTestCase(test.TestCase):
|
||||
|
||||
|
||||
class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_admin_required_true(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "admin_required"),),
|
||||
request=self.request)
|
||||
self.assertTrue(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_identity_rule_not_found_true(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "i_dont_exist"),),
|
||||
@ -87,7 +87,7 @@ class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
||||
# identity is admin_required
|
||||
self.assertTrue(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_compound_check_true(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("identity", "admin_required"),
|
||||
@ -95,7 +95,7 @@ class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
||||
request=self.request)
|
||||
self.assertTrue(value)
|
||||
|
||||
@override_settings(POLICY_CHECK_FUNCTION=policy_backend.check)
|
||||
@override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||
def test_check_nova_context_is_admin_true(self):
|
||||
policy_backend.reset()
|
||||
value = policy.check((("compute", "context_is_admin"),),
|
||||
|
Loading…
Reference in New Issue
Block a user