Revisit exported policy module
The primary goal of the library policy module is to support the context module during the enforcement of service and admin rules, and as such an enforcer is needed. Incidentally the enforcer is stored in a global variable whose name is the same as the enforcer's used by neutron's policy engine. To avoid confusion, this patch revises some parts of the library's policy module to make sure the cut of responsibilities is better defined. It finally makes the policy module private to avoid any danger of mixing up the enforcer instances. Change-Id: Ie55d557aa3e24678aed2fb3b5c590485f54fe792
This commit is contained in:
parent
6d5e550446
commit
1902e2adf6
@ -14,26 +14,11 @@ from oslo_config import cfg
|
|||||||
from oslo_policy import policy
|
from oslo_policy import policy
|
||||||
|
|
||||||
|
|
||||||
_ENFORCER = None
|
_ROLE_ENFORCER = None
|
||||||
_ADMIN_CTX_POLICY = 'context_is_admin'
|
_ADMIN_CTX_POLICY = 'context_is_admin'
|
||||||
_ADVSVC_CTX_POLICY = 'context_is_advsvc'
|
_ADVSVC_CTX_POLICY = 'context_is_advsvc'
|
||||||
|
|
||||||
|
|
||||||
def reset():
|
|
||||||
"""Reset the global enforcer.
|
|
||||||
|
|
||||||
Resets the global enforcer thereby deleting any rules and state associated
|
|
||||||
with it. Subsequent calls to this modules API will trigger a
|
|
||||||
re-initialization of the global enforcer as necessary.
|
|
||||||
|
|
||||||
:returns: None.
|
|
||||||
"""
|
|
||||||
global _ENFORCER
|
|
||||||
if _ENFORCER:
|
|
||||||
_ENFORCER.clear()
|
|
||||||
_ENFORCER = None
|
|
||||||
|
|
||||||
|
|
||||||
def init(conf=cfg.CONF, policy_file=None):
|
def init(conf=cfg.CONF, policy_file=None):
|
||||||
"""Initialize the global enforcer if not already initialized.
|
"""Initialize the global enforcer if not already initialized.
|
||||||
|
|
||||||
@ -47,32 +32,19 @@ def init(conf=cfg.CONF, policy_file=None):
|
|||||||
:returns: None.
|
:returns: None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
global _ENFORCER
|
global _ROLE_ENFORCER
|
||||||
if not _ENFORCER:
|
if not _ROLE_ENFORCER:
|
||||||
_ENFORCER = policy.Enforcer(conf, policy_file=policy_file)
|
_ROLE_ENFORCER = policy.Enforcer(conf, policy_file=policy_file)
|
||||||
_ENFORCER.load_rules(True)
|
_ROLE_ENFORCER.load_rules(True)
|
||||||
|
|
||||||
|
|
||||||
def refresh(policy_file=None):
|
|
||||||
"""Reset the global enforcer and re-initialize it.
|
|
||||||
|
|
||||||
Reset the global policy and re-initialize it optionally using the said
|
|
||||||
policy file.
|
|
||||||
|
|
||||||
:param policy_file: The policy file to initialize the global enforcer with.
|
|
||||||
:returns: None.
|
|
||||||
"""
|
|
||||||
reset()
|
|
||||||
init(policy_file=policy_file)
|
|
||||||
|
|
||||||
|
|
||||||
def _check_rule(context, rule):
|
def _check_rule(context, rule):
|
||||||
init()
|
init()
|
||||||
# the target is user-self
|
# the target is user-self
|
||||||
credentials = context.to_policy_values()
|
credentials = context.to_policy_values()
|
||||||
if rule not in _ENFORCER.rules:
|
if rule not in _ROLE_ENFORCER.rules:
|
||||||
return False
|
return False
|
||||||
return _ENFORCER.enforce(rule, credentials, credentials)
|
return _ROLE_ENFORCER.enforce(rule, credentials, credentials)
|
||||||
|
|
||||||
|
|
||||||
def check_is_admin(context):
|
def check_is_admin(context):
|
@ -19,8 +19,8 @@ from oslo_context import context as oslo_context
|
|||||||
from oslo_db.sqlalchemy import enginefacade
|
from oslo_db.sqlalchemy import enginefacade
|
||||||
|
|
||||||
# TODO(HenryG): replace db/_api.py with the real db/api.py
|
# TODO(HenryG): replace db/_api.py with the real db/api.py
|
||||||
|
from neutron_lib import _policy as policy
|
||||||
from neutron_lib.db import _api as db_api
|
from neutron_lib.db import _api as db_api
|
||||||
from neutron_lib import policy
|
|
||||||
|
|
||||||
|
|
||||||
class ContextBase(oslo_context.RequestContext):
|
class ContextBase(oslo_context.RequestContext):
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from neutron_lib import _policy as policy
|
||||||
from neutron_lib import context
|
from neutron_lib import context
|
||||||
from neutron_lib import policy
|
|
||||||
|
|
||||||
from neutron_lib.tests import _base as base
|
from neutron_lib.tests import _base as base
|
||||||
|
|
||||||
@ -22,17 +22,13 @@ from neutron_lib.tests import _base as base
|
|||||||
class TestPolicyEnforcer(base.BaseTestCase):
|
class TestPolicyEnforcer(base.BaseTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPolicyEnforcer, self).setUp()
|
super(TestPolicyEnforcer, self).setUp()
|
||||||
# Isolate one _ENFORCER per test case
|
# Isolate one _ROLE_ENFORCER per test case
|
||||||
mock.patch.object(policy, '_ENFORCER', None).start()
|
mock.patch.object(policy, '_ROLE_ENFORCER', None).start()
|
||||||
|
|
||||||
def test_init_reset_refresh(self):
|
def test_init_reset(self):
|
||||||
self.assertIsNone(policy._ENFORCER)
|
self.assertIsNone(policy._ROLE_ENFORCER)
|
||||||
policy.init()
|
policy.init()
|
||||||
self.assertIsNotNone(policy._ENFORCER)
|
self.assertIsNotNone(policy._ROLE_ENFORCER)
|
||||||
policy.reset()
|
|
||||||
self.assertIsNone(policy._ENFORCER)
|
|
||||||
policy.refresh()
|
|
||||||
self.assertIsNotNone(policy._ENFORCER)
|
|
||||||
|
|
||||||
def test_check_user_is_not_admin(self):
|
def test_check_user_is_not_admin(self):
|
||||||
ctx = context.Context('me', 'my_project')
|
ctx = context.Context('me', 'my_project')
|
7
releasenotes/notes/policy-redux-25c26836219fd02d.yaml
Normal file
7
releasenotes/notes/policy-redux-25c26836219fd02d.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
deprecations:
|
||||||
|
- |
|
||||||
|
``policy.refresh()`` and ``policy.reset()`` have been removed. The library
|
||||||
|
policy module is not meant for public consumption, and it should be
|
||||||
|
considered in practice a private component of the library. If you use it,
|
||||||
|
you will do so at your own risk, as it has been marked as a private module.
|
Loading…
Reference in New Issue
Block a user