Pylons / pyramid_rpc

RPC plugins for pyramid. XML-RPC, JSON-RPC, etc.
https://docs.pylonsproject.org/projects/pyramid-rpc/en/latest/
Other
27 stars 19 forks source link

remove the route predicate and add a pattern for security #37

Open mmerickel opened 9 years ago

mmerickel commented 9 years ago

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

mmerickel commented 9 years ago

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.

mmerickel commented 9 years ago

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.

tflorac commented 9 years ago

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...

mmerickel commented 9 years ago

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.

tflorac commented 9 years ago

I don't know Pyramid internals enough to be able to have a good point of view about that... :-/