Enable authZ checks for member actions
Blueprint make-authz-orthogonal This implements work item #1 of the blueprint. This patch enables authZ checks for 'member actions' in the base controller and removes explicit checks from l3_db. This patch also addresses a small glitch in the policy engine which was assuming the request always had a body. Change-Id: I7e0f386eedcfff24ea1fee7294bbadd6c5ec781c
This commit is contained in:
@@ -12,8 +12,6 @@
|
|||||||
|
|
||||||
"extension:router:view": "rule:regular_user",
|
"extension:router:view": "rule:regular_user",
|
||||||
"extension:router:set": "rule:admin_only",
|
"extension:router:set": "rule:admin_only",
|
||||||
"extension:router:add_router_interface": "rule:admin_or_owner",
|
|
||||||
"extension:router:remove_router_interface": "rule:admin_or_owner",
|
|
||||||
|
|
||||||
"extension:port_binding:view": "rule:admin_only",
|
"extension:port_binding:view": "rule:admin_only",
|
||||||
"extension:port_binding:set": "rule:admin_only",
|
"extension:port_binding:set": "rule:admin_only",
|
||||||
|
@@ -141,13 +141,25 @@ class Controller(object):
|
|||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if name in self._member_actions:
|
if name in self._member_actions:
|
||||||
def _handle_action(request, id, **kwargs):
|
def _handle_action(request, id, **kwargs):
|
||||||
if 'body' in kwargs:
|
arg_list = [request.context, id]
|
||||||
body = kwargs.pop('body')
|
# Fetch the resource and verify if the user can access it
|
||||||
return getattr(self._plugin, name)(request.context, id,
|
try:
|
||||||
body, **kwargs)
|
resource = self._item(request, id, True)
|
||||||
else:
|
except exceptions.PolicyNotAuthorized:
|
||||||
return getattr(self._plugin, name)(request.context, id,
|
raise webob.exc.HTTPNotFound()
|
||||||
**kwargs)
|
body = kwargs.pop('body', None)
|
||||||
|
# Explicit comparison with None to distinguish from {}
|
||||||
|
if body is not None:
|
||||||
|
arg_list.append(body)
|
||||||
|
# TODO(salvatore-orlando): bp/make-authz-ortogonal
|
||||||
|
# The body of the action request should be included
|
||||||
|
# in the info passed to the policy engine
|
||||||
|
# Enforce policy, if any, for this action
|
||||||
|
# It is ok to raise a 403 because accessibility to the
|
||||||
|
# object was checked earlier in this method
|
||||||
|
policy.enforce(request.context, name, resource,
|
||||||
|
plugin=self._plugin)
|
||||||
|
return getattr(self._plugin, name)(*arg_list, **kwargs)
|
||||||
return _handle_action
|
return _handle_action
|
||||||
else:
|
else:
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
|
@@ -310,19 +310,10 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def add_router_interface(self, context, router_id, interface_info):
|
def add_router_interface(self, context, router_id, interface_info):
|
||||||
# make sure router exists
|
|
||||||
router = self._get_router(context, router_id)
|
|
||||||
if not interface_info:
|
if not interface_info:
|
||||||
msg = _("Either subnet_id or port_id must be specified")
|
msg = _("Either subnet_id or port_id must be specified")
|
||||||
raise q_exc.BadRequest(resource='router', msg=msg)
|
raise q_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
|
||||||
try:
|
|
||||||
policy.enforce(context,
|
|
||||||
"extension:router:add_router_interface",
|
|
||||||
self._make_router_dict(router))
|
|
||||||
except q_exc.PolicyNotAuthorized:
|
|
||||||
raise l3.RouterNotFound(router_id=router_id)
|
|
||||||
|
|
||||||
if 'port_id' in interface_info:
|
if 'port_id' in interface_info:
|
||||||
if 'subnet_id' in interface_info:
|
if 'subnet_id' in interface_info:
|
||||||
msg = _("Cannot specify both subnet-id and port-id")
|
msg = _("Cannot specify both subnet-id and port-id")
|
||||||
@@ -394,15 +385,6 @@ class L3_NAT_db_mixin(l3.RouterPluginBase):
|
|||||||
router_id=router_id, subnet_id=subnet_id)
|
router_id=router_id, subnet_id=subnet_id)
|
||||||
|
|
||||||
def remove_router_interface(self, context, router_id, interface_info):
|
def remove_router_interface(self, context, router_id, interface_info):
|
||||||
# make sure router exists
|
|
||||||
router = self._get_router(context, router_id)
|
|
||||||
try:
|
|
||||||
policy.enforce(context,
|
|
||||||
"extension:router:remove_router_interface",
|
|
||||||
self._make_router_dict(router))
|
|
||||||
except q_exc.PolicyNotAuthorized:
|
|
||||||
raise l3.RouterNotFound(router_id=router_id)
|
|
||||||
|
|
||||||
if not interface_info:
|
if not interface_info:
|
||||||
msg = _("Either subnet_id or port_id must be specified")
|
msg = _("Either subnet_id or port_id must be specified")
|
||||||
raise q_exc.BadRequest(resource='router', msg=msg)
|
raise q_exc.BadRequest(resource='router', msg=msg)
|
||||||
|
@@ -174,6 +174,9 @@ def check(context, action, target, plugin=None):
|
|||||||
:return: Returns True if access is permitted else False.
|
:return: Returns True if access is permitted else False.
|
||||||
"""
|
"""
|
||||||
init()
|
init()
|
||||||
|
# Compare with None to distinguish case in which target is {}
|
||||||
|
if target is None:
|
||||||
|
target = {}
|
||||||
real_target = _build_target(action, target, plugin, context)
|
real_target = _build_target(action, target, plugin, context)
|
||||||
match_rule = _build_match_rule(action, real_target)
|
match_rule = _build_match_rule(action, real_target)
|
||||||
credentials = context.to_dict()
|
credentials = context.to_dict()
|
||||||
@@ -196,6 +199,9 @@ def enforce(context, action, target, plugin=None):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
init()
|
init()
|
||||||
|
# Compare with None to distinguish case in which target is {}
|
||||||
|
if target is None:
|
||||||
|
target = {}
|
||||||
real_target = _build_target(action, target, plugin, context)
|
real_target = _build_target(action, target, plugin, context)
|
||||||
match_rule = _build_match_rule(action, real_target)
|
match_rule = _build_match_rule(action, real_target)
|
||||||
credentials = context.to_dict()
|
credentials = context.to_dict()
|
||||||
|
Reference in New Issue
Block a user