enhancement for the common policy enforce
Now the magnum.common.policy just support an "enforce" method to wsgi policy check. And this "enforce" method should be inline the body of wsgi method. Such as: from magnum.common import policy class BaysController(rest.RestController): .... @wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) def delete(self, bay_ident): ... doc string ... policy.enforce(pecan.request.context, "bay:create") .... common stuff .... This inline style is ugly. Now this patch is improving it. This patch uses a decorator for policy check. With this decorator we can do the policy check as follow: from magnum.common import policy class BaysController(rest.RestController): .... @policy.enforce_wsgi("bay", "delete") @wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204) def delete(self, bay_ident): ... Here: This decorator MUST appear first (the outermost decorator) on an API method for it to work correctly. The decorator use functools.wraps to decorator the wsgi function. A common decorator(without functools.wraps) replaces the original function with an new one, that means it will lose the information about the original function, it would be a serious problem for pcen wsgi. That's why we have functools.wraps. This takes a function used in a decorator and adds the functionality of copying over the function name, docstring, arguments list, etc. ref: http://stackoverflow.com/questions/308999/what-does-functools-wraps-do Co-Authored-By: yuntongjin <yuntong.jin@intel.com> Change-Id: I9a7baf9559ff924ca4e261db2961b9d3c8763325 Partial-implements: blueprint policy-enforce
This commit is contained in:
parent
1c78cd834b
commit
e8a77b6e1b
@ -15,8 +15,10 @@
|
||||
|
||||
"""Policy Engine For magnum."""
|
||||
|
||||
import functools
|
||||
from oslo_config import cfg
|
||||
from oslo_policy import policy
|
||||
import pecan
|
||||
|
||||
|
||||
_ENFORCER = None
|
||||
@ -88,3 +90,30 @@ def enforce(context, action=None, target=None,
|
||||
'user_id': context.user_id}
|
||||
return enforcer.enforce(action, target, credentials,
|
||||
do_raise=do_raise, exc=exc, *args, **kwargs)
|
||||
|
||||
|
||||
# NOTE(Shaohe Feng): This decorator MUST appear first (the outermost
|
||||
# decorator) on an API method for it to work correctly
|
||||
def enforce_wsgi(api_name, act=None):
|
||||
"""This is a decorator to simplify wsgi action policy rule check.
|
||||
:param api_name: The collection name to be evaluate.
|
||||
:param act: The function name of wsgi action.
|
||||
|
||||
example:
|
||||
from magnum.common import policy
|
||||
class BaysController(rest.RestController):
|
||||
....
|
||||
@policy.enforce_wsgi("bay", "delete")
|
||||
@wsme_pecan.wsexpose(None, types.uuid_or_name, status_code=204)
|
||||
def delete(self, bay_ident):
|
||||
...
|
||||
"""
|
||||
def wraper(fn):
|
||||
action = "%s:%s" % (api_name, (act or fn.func_name))
|
||||
|
||||
@functools.wraps(fn)
|
||||
def handle(self, *args, **kwargs):
|
||||
enforce(pecan.request.context, action, None)
|
||||
return fn(self, *args, **kwargs)
|
||||
return handle
|
||||
return wraper
|
||||
|
Loading…
Reference in New Issue
Block a user