Merge "Specify POLICY_CHECK_FUNCTION as a string"
This commit is contained in:
commit
c789a7aba5
@ -45,6 +45,7 @@ from horizon.decorators import _current_component # noqa
|
|||||||
from horizon.decorators import require_auth # noqa
|
from horizon.decorators import require_auth # noqa
|
||||||
from horizon.decorators import require_perms # noqa
|
from horizon.decorators import require_perms # noqa
|
||||||
from horizon import loaders
|
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.
|
# 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'])
|
return self._can_access(context['request'])
|
||||||
|
|
||||||
def _can_access(self, 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
|
# this check is an OR check rather than an AND check that is the
|
||||||
# default in the policy engine, so calling each rule individually
|
# default in the policy engine, so calling each rule individually
|
||||||
|
@ -33,6 +33,7 @@ import six
|
|||||||
from horizon import messages
|
from horizon import messages
|
||||||
from horizon.utils import functions
|
from horizon.utils import functions
|
||||||
from horizon.utils import html
|
from horizon.utils import html
|
||||||
|
from horizon.utils import settings as utils_settings
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -129,7 +130,7 @@ class BaseAction(html.HTMLElement):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def _allowed(self, request, datum):
|
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:
|
if policy_check and self.policy_rules:
|
||||||
target = self.get_policy_target(request, datum)
|
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 mox3.mox import IsA # noqa
|
||||||
|
|
||||||
from horizon.workflows import views
|
from horizon.workflows import views
|
||||||
from openstack_auth import policy as policy_backend
|
|
||||||
|
|
||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.dashboards.identity.projects import workflows
|
from openstack_dashboard.dashboards.identity.projects import workflows
|
||||||
@ -100,7 +99,7 @@ class TenantsViewTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
|
|
||||||
class ProjectsViewNonAdminTests(test.TestCase):
|
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',
|
@test.create_stubs({api.keystone: ('tenant_list',
|
||||||
'domain_lookup')})
|
'domain_lookup')})
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
from django.conf import settings
|
from horizon.utils import settings as utils_settings
|
||||||
|
|
||||||
|
|
||||||
def check(actions, request, target=None):
|
def check(actions, request, target=None):
|
||||||
"""Wrapper of the configurable policy method."""
|
"""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:
|
if policy_check:
|
||||||
return policy_check(actions, request, target)
|
return policy_check(actions, request, target)
|
||||||
|
@ -305,14 +305,7 @@ THEME_COLLECTION_DIR = 'themes'
|
|||||||
# Theme Cookie Name
|
# Theme Cookie Name
|
||||||
THEME_COOKIE_NAME = 'theme'
|
THEME_COOKIE_NAME = 'theme'
|
||||||
|
|
||||||
|
POLICY_CHECK_FUNCTION = 'openstack_auth.policy.check'
|
||||||
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
|
|
||||||
|
|
||||||
CSRF_COOKIE_AGE = None
|
CSRF_COOKIE_AGE = None
|
||||||
|
|
||||||
|
@ -617,7 +617,7 @@ class NeutronApiTests(test.APITestCase):
|
|||||||
|
|
||||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||||
True},
|
True},
|
||||||
POLICY_CHECK_FUNCTION=policy.check)
|
POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||||
@test.create_stubs({api.neutron: ('is_extension_supported',)})
|
@test.create_stubs({api.neutron: ('is_extension_supported',)})
|
||||||
def _test_get_dvr_permission_with_policy_check(self, policy_check_allowed,
|
def _test_get_dvr_permission_with_policy_check(self, policy_check_allowed,
|
||||||
operation):
|
operation):
|
||||||
@ -655,7 +655,7 @@ class NeutronApiTests(test.APITestCase):
|
|||||||
|
|
||||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||||
True},
|
True},
|
||||||
POLICY_CHECK_FUNCTION=policy.check)
|
POLICY_CHECK_FUNCTION='openstack_auth.policy.check')
|
||||||
def test_get_dvr_permission_dvr_unsupported_operation(self):
|
def test_get_dvr_permission_dvr_unsupported_operation(self):
|
||||||
self.assertRaises(ValueError,
|
self.assertRaises(ValueError,
|
||||||
api.neutron.get_feature_permission,
|
api.neutron.get_feature_permission,
|
||||||
@ -675,7 +675,7 @@ class NeutronApiTests(test.APITestCase):
|
|||||||
# above. l3-ha check only checks l3-ha specific code.
|
# above. l3-ha check only checks l3-ha specific code.
|
||||||
|
|
||||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_ha_router': True},
|
@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', )})
|
@test.create_stubs({api.neutron: ('is_extension_supported', )})
|
||||||
def _test_get_router_ha_permission_with_policy_check(self, ha_enabled):
|
def _test_get_router_ha_permission_with_policy_check(self, ha_enabled):
|
||||||
self.mox.StubOutWithMock(policy, 'check')
|
self.mox.StubOutWithMock(policy, 'check')
|
||||||
|
@ -11,46 +11,45 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from django.test.utils import override_settings # noqa
|
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.api.rest import policy
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
|
||||||
class PolicyRestTestCase(test.TestCase):
|
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": []}'):
|
def test_policy(self, body='{"rules": []}'):
|
||||||
request = self.mock_rest_request(body=body)
|
request = self.mock_rest_request(body=body)
|
||||||
response = policy.Policy().post(request)
|
response = policy.Policy().post(request)
|
||||||
self.assertStatusCode(response, 200)
|
self.assertStatusCode(response, 200)
|
||||||
self.assertEqual({"allowed": True}, response.json)
|
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):
|
def test_rule_alone(self):
|
||||||
body = '{"rules": [["compute", "compute:get_all" ]]}'
|
body = '{"rules": [["compute", "compute:get_all" ]]}'
|
||||||
self.test_policy(body)
|
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):
|
def test_multiple_rule(self):
|
||||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||||
' ["compute", "compute:start"]]}'
|
' ["compute", "compute:start"]]}'
|
||||||
self.test_policy(body)
|
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):
|
def test_rule_with_empty_target(self):
|
||||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||||
' ["compute", "compute:start"]],' \
|
' ["compute", "compute:start"]],' \
|
||||||
' "target": {}}'
|
' "target": {}}'
|
||||||
self.test_policy(body)
|
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):
|
def test_rule_with_target(self):
|
||||||
body = '{"rules": [["compute", "compute:get_all"],' \
|
body = '{"rules": [["compute", "compute:get_all"],' \
|
||||||
' ["compute", "compute:start"]],' \
|
' ["compute", "compute:start"]],' \
|
||||||
' "target": {"project_id": "1"}}'
|
' "target": {"project_id": "1"}}'
|
||||||
self.test_policy(body)
|
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):
|
def test_policy_fail(self):
|
||||||
# admin only rule, default test case user should fail
|
# admin only rule, default test case user should fail
|
||||||
request = self.mock_rest_request(
|
request = self.mock_rest_request(
|
||||||
@ -59,7 +58,7 @@ class PolicyRestTestCase(test.TestCase):
|
|||||||
self.assertStatusCode(response, 200)
|
self.assertStatusCode(response, 200)
|
||||||
self.assertEqual({"allowed": False}, response.json)
|
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):
|
def test_policy_error(self):
|
||||||
# admin only rule, default test case user should fail
|
# admin only rule, default test case user should fail
|
||||||
request = self.mock_rest_request(
|
request = self.mock_rest_request(
|
||||||
@ -69,7 +68,7 @@ class PolicyRestTestCase(test.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class AdminPolicyRestTestCase(test.BaseAdminViewTests):
|
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):
|
def test_rule_with_target(self):
|
||||||
body = '{"rules": [["compute", "compute:unlock_override"]]}'
|
body = '{"rules": [["compute", "compute:unlock_override"]]}'
|
||||||
request = self.mock_rest_request(body=body)
|
request = self.mock_rest_request(body=body)
|
||||||
|
@ -12,14 +12,13 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from openstack_auth import policy as policy_backend
|
|
||||||
|
|
||||||
from openstack_dashboard import policy
|
from openstack_dashboard import policy
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
|
||||||
|
|
||||||
class PolicyTestCase(test.TestCase):
|
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):
|
def test_policy_check_set(self):
|
||||||
value = policy.check((("identity", "admin_required"),),
|
value = policy.check((("identity", "admin_required"),),
|
||||||
request=self.request)
|
request=self.request)
|
||||||
@ -33,7 +32,7 @@ class PolicyTestCase(test.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
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):
|
def test_policy_check_set_admin(self):
|
||||||
value = policy.check((("identity", "admin_required"),),
|
value = policy.check((("identity", "admin_required"),),
|
||||||
request=self.request)
|
request=self.request)
|
||||||
|
@ -31,14 +31,14 @@ class PolicyBackendTestCase(test.TestCase):
|
|||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
self.assertIsNone(policy_backend._ENFORCER)
|
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):
|
def test_check_admin_required_false(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "admin_required"),),
|
value = policy.check((("identity", "admin_required"),),
|
||||||
request=self.request)
|
request=self.request)
|
||||||
self.assertFalse(value)
|
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):
|
def test_check_identity_rule_not_found_false(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "i_dont_exist"),),
|
value = policy.check((("identity", "i_dont_exist"),),
|
||||||
@ -47,14 +47,14 @@ class PolicyBackendTestCase(test.TestCase):
|
|||||||
# identity is admin_required
|
# identity is admin_required
|
||||||
self.assertFalse(value)
|
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):
|
def test_check_nova_context_is_admin_false(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("compute", "context_is_admin"),),
|
value = policy.check((("compute", "context_is_admin"),),
|
||||||
request=self.request)
|
request=self.request)
|
||||||
self.assertFalse(value)
|
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):
|
def test_compound_check_false(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "admin_required"),
|
value = policy.check((("identity", "admin_required"),
|
||||||
@ -62,7 +62,7 @@ class PolicyBackendTestCase(test.TestCase):
|
|||||||
request=self.request)
|
request=self.request)
|
||||||
self.assertFalse(value)
|
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):
|
def test_scope_not_found(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("dummy", "default"),),
|
value = policy.check((("dummy", "default"),),
|
||||||
@ -71,14 +71,14 @@ class PolicyBackendTestCase(test.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
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):
|
def test_check_admin_required_true(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "admin_required"),),
|
value = policy.check((("identity", "admin_required"),),
|
||||||
request=self.request)
|
request=self.request)
|
||||||
self.assertTrue(value)
|
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):
|
def test_check_identity_rule_not_found_true(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "i_dont_exist"),),
|
value = policy.check((("identity", "i_dont_exist"),),
|
||||||
@ -87,7 +87,7 @@ class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
|||||||
# identity is admin_required
|
# identity is admin_required
|
||||||
self.assertTrue(value)
|
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):
|
def test_compound_check_true(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("identity", "admin_required"),
|
value = policy.check((("identity", "admin_required"),
|
||||||
@ -95,7 +95,7 @@ class PolicyBackendTestCaseAdmin(test.BaseAdminViewTests):
|
|||||||
request=self.request)
|
request=self.request)
|
||||||
self.assertTrue(value)
|
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):
|
def test_check_nova_context_is_admin_true(self):
|
||||||
policy_backend.reset()
|
policy_backend.reset()
|
||||||
value = policy.check((("compute", "context_is_admin"),),
|
value = policy.check((("compute", "context_is_admin"),),
|
||||||
|
Loading…
Reference in New Issue
Block a user