Merge "Move default policy target"

This commit is contained in:
Zuul
2019-07-27 00:32:20 +00:00
committed by Gerrit Code Review
4 changed files with 22 additions and 14 deletions

View File

@@ -228,9 +228,8 @@ class RequestContext(context.RequestContext):
:param action: string representing the action to be checked. :param action: string representing the action to be checked.
:param target: dictionary representing the object of the action :param target: dictionary representing the object of the action
for object creation this should be a dictionary representing the for object creation this should be a dictionary representing the
location of the object e.g. ``{'project_id': context.project_id}``. location of the object
If None, then this default target will be considered: e.g. ``{'project_id': instance.project_id}``.
{'project_id': self.project_id, 'user_id': self.user_id}
:param fatal: if False, will return False when an exception.Forbidden :param fatal: if False, will return False when an exception.Forbidden
occurs. occurs.
@@ -240,9 +239,6 @@ class RequestContext(context.RequestContext):
:return: returns a non-False value (not necessarily "True") if :return: returns a non-False value (not necessarily "True") if
authorized and False if not authorized and fatal is False. authorized and False if not authorized and fatal is False.
""" """
if target is None:
target = self.default_target()
try: try:
return policy.authorize(self, action, target) return policy.authorize(self, action, target)
except exception.Forbidden: except exception.Forbidden:
@@ -250,9 +246,6 @@ class RequestContext(context.RequestContext):
raise raise
return False return False
def default_target(self):
return {'project_id': self.project_id, 'user_id': self.user_id}
def to_policy_values(self): def to_policy_values(self):
policy = super(RequestContext, self).to_policy_values() policy = super(RequestContext, self).to_policy_values()
policy['is_admin'] = self.is_admin policy['is_admin'] = self.is_admin

View File

@@ -122,7 +122,7 @@ def set_rules(rules, overwrite=True, use_conf=False):
_ENFORCER.set_rules(rules, overwrite, use_conf) _ENFORCER.set_rules(rules, overwrite, use_conf)
def authorize(context, action, target, do_raise=True, exc=None): def authorize(context, action, target=None, do_raise=True, exc=None):
"""Verifies that the action is valid on the target in this context. """Verifies that the action is valid on the target in this context.
:param context: nova context :param context: nova context
@@ -133,7 +133,9 @@ def authorize(context, action, target, do_raise=True, exc=None):
``volume:attach_volume`` ``volume:attach_volume``
:param target: dictionary representing the object of the action :param target: dictionary representing the object of the action
for object creation this should be a dictionary representing the for object creation this should be a dictionary representing the
location of the object e.g. ``{'project_id': context.project_id}`` location of the object e.g. ``{'project_id': instance.project_id}``
If None, then this default target will be considered:
{'project_id': self.project_id, 'user_id': self.user_id}
:param do_raise: if True (the default), raises PolicyNotAuthorized; :param do_raise: if True (the default), raises PolicyNotAuthorized;
if False, returns False if False, returns False
:param exc: Class of the exception to raise if the check fails. :param exc: Class of the exception to raise if the check fails.
@@ -154,6 +156,12 @@ def authorize(context, action, target, do_raise=True, exc=None):
credentials = context.to_policy_values() credentials = context.to_policy_values()
if not exc: if not exc:
exc = exception.PolicyNotAuthorized exc = exception.PolicyNotAuthorized
# Legacy fallback for emtpy target from context.can()
# should be removed once we improve testing and scope checks
if target is None:
target = default_target(context)
try: try:
result = _ENFORCER.authorize(action, target, credentials, result = _ENFORCER.authorize(action, target, credentials,
do_raise=do_raise, exc=exc, action=action) do_raise=do_raise, exc=exc, action=action)
@@ -168,6 +176,10 @@ def authorize(context, action, target, do_raise=True, exc=None):
return result return result
def default_target(context):
return {'project_id': context.project_id, 'user_id': context.user_id}
def check_is_admin(context): def check_is_admin(context):
"""Whether or not roles contains 'admin' role according to policy setting. """Whether or not roles contains 'admin' role according to policy setting.
@@ -176,7 +188,7 @@ def check_is_admin(context):
init() init()
# the target is user-self # the target is user-self
credentials = context.to_policy_values() credentials = context.to_policy_values()
target = context.default_target() target = default_target(context)
return _ENFORCER.authorize('context_is_admin', target, credentials) return _ENFORCER.authorize('context_is_admin', target, credentials)

View File

@@ -216,8 +216,7 @@ class ContextTestCase(test.NoDBTestCase):
self.assertTrue(result) self.assertTrue(result)
mock_authorize.assert_called_once_with( mock_authorize.assert_called_once_with(
ctxt, mock.sentinel.rule, ctxt, mock.sentinel.rule, None)
{'project_id': ctxt.project_id, 'user_id': ctxt.user_id})
@mock.patch.object(context.policy, 'authorize') @mock.patch.object(context.policy, 'authorize')
def test_can_fatal(self, mock_authorize): def test_can_fatal(self, mock_authorize):

View File

@@ -134,6 +134,10 @@ class PolicyTestCase(test.NoDBTestCase):
target_not_mine = {'project_id': 'another'} target_not_mine = {'project_id': 'another'}
action = "example:my_file" action = "example:my_file"
policy.authorize(self.context, action, target_mine) policy.authorize(self.context, action, target_mine)
# check we fallback to context.project_id
# TODO(johngarbutt): longer term we need to remove this and make
# the target a required param.
policy.authorize(self.context, action)
self.assertRaises(exception.PolicyNotAuthorized, policy.authorize, self.assertRaises(exception.PolicyNotAuthorized, policy.authorize,
self.context, action, target_not_mine) self.context, action, target_not_mine)