Merge "Move default policy target"
This commit is contained in:
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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):
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user