use page 1 metadata for allowed methods
Right now we have a request.allow method that raises 405 if the method isn't in *args. What if we did this declaratively in page 1 rather than programmatically in page 2?
allowed_methods = ['GET', 'HEAD']
[---]
[---]
That would be the default, meaning simplates would have to explicitly opt in to non-idempotent methods. That smells more secure to me, along the lines of explicitly exporting variables from page 2 into the page 3 template context (#165).
It also moves us in the direction of using metadata in page 1 to influence request handling. I like that direction, somehow.
I like the idea - it puts control where it should be, in the page.
What I don't like is More Magic Names. Can we namespace it somehow? what about putting all this stuff on something called 'self' ? (thus referring to the simplate/endpoint)
self.allowed_methods = [ 'GET', 'HEAD' ]
Actually seems clearer to me than without the 'self'.
Would self point to the resource object representing the simplate?
And would we call it self or could we call it resource?
We already have resource in the simplate context.
So it sounds like we would use resource.allowed_methods for this.
A simple variable was my original idea too (https://github.com/liberapay/liberapay.com/issues/116), but that wouldn't alert the developer if they type the name wrong. The simplest solution to that would be to do:
+resource.allow('GET', 'POST')
[---]
-request.allow('GET', 'POST')
But there's another issue: should the above disallow HEAD? Currently it does because request.allow() doesn't treat HEAD specially. We could automatically allow HEAD when GET is allowed, but what if you really want to disallow HEAD for some crazy reason?
I guess the simplest solution to that would be to have two methods, e.g. also_allow and only_allow.
that wouldn't alert the developer if they type the name wrong.
It could, right?
for method in allowed_methods:
if method not in ALL_METHODS:
raise Warning('Unusual verb')
:D I meant the name of the variable, not the HTTP methods.
🐭
Another question just came to me: do we want this to be in Pando, or in Aspen? I guess it would be better in Aspen because then the Django and Flask plugins could benefit from it. Note that Aspen currently doesn't have access to the method, we would need to put it in the state dict.
Is there a way that Aspen can delegate to the framework/plugin, so that it doesn't need to know the method? (Is the Resource object in Pando or Aspen? ... looks like that's duplicated?)
Is there a way that Aspen can delegate to the framework/plugin, so that it doesn't need to know the method?
I suppose Aspen could provide an algorithm function that isn't in its own algorithm by default but instead is meant to be inserted into it by Pando and others. That would avoid the code duplication without actually requiring that the method be passed to Aspen.
(Is the
Resourceobject in Pando or Aspen? ... looks like that's duplicated?)
The latter doesn't exist anymore on the use-aspen branch.
The latter doesn't exist anymore on the
use-aspenbranch.
Okay, so resource remains as part of Aspen. I suspect we'll hit this question a few times as the new architecture shakes out: how to manage the boundary between Aspen and the frameworks. I say go for whatever right now and we can reassess when we have more experience.