pyramid_rpc
pyramid_rpc copied to clipboard
remove the route predicate and add a pattern for security
I prefer to think of the parsing as a custom factory
on the route that can setup the request after matching the route. We can then pass the request into a custom factory if the user specified one, and return the context. Imagine:
class AddUser(object):
def __init__(self, request):
pass
def __acl__(self):
return [
(Allow, 'admin', 'create_users'),
]
def jsonrpc_factory(request):
if request.method == 'addUser':
return AddUser(request)
config.add_jsonrpc_endpoint('jsonrpc', '/jsonrpc', factory=jsonrpc_factory)
@jsonrpc_method(endpoint='jsonrpc', permission='create_users')
def addUser(request):
# add a user
related: #31, #36
Doing the parsing in a factory is also a great way to provide support for a full-traversal application.
Consider the public api pyramid_rpc.jsonrpc.JSONRPCRootFactory
which would be the replacement for the predicate.
def myFactory(request):
if request.rpc_method == 'addUser':
return AddUser(request)
config.set_root_factory(JSONRPCRootFactory(myFactory))
@jsonrpc_method(context=AddUser, permission='create_users')
def addUser(request):
# add a user
Note that myFactory
could be a full-traversal app that did something. We just made the jsonrpc_method
work without an endpoint but is still dependent on a (context, name, rpc_method)
for view lookup.
Removing the endpoint concept is a little hairy because parts of it are used to pass settings to jsonrpc_method
but this could probably be solved by config.set_default_jsonrpc_endpoint_options()
or something. I haven't thought through those details yet but this gets us to the point where we can parse the request at least.
From a "user" point of view, what I would like is to be able to declare a JSON-RPC or XML-RPC view like a common Pyramid view, using traversal... For example :
@jsonrpc_method(context=IMyContext, permission='create_users') def my_jsonrpc_method(request): """Request should receive a context attribute..."""
Calling URL required to access this method should use common objects traversal : /object1/object2/my_context, and method name is the name of the function...
I understand but in order to dispatch on the method it's necessary to parse the body. Using the JSONRPCRootFactory
(or currently the route predicate) allows this to happen. Alternatively I could have it be completely lazy and only parse it during view lookup but that feels a little weird to me.
I don't know Pyramid internals enough to be able to have a good point of view about that... :-/