My Mojolicious application has some custom authentication mechanism, which I implement in a routing condition called auth_permission
:
$app->add_condition(auth_permission => sub {
return is_user_allowed(...) ? 1 : 0;
});
So my routes look something like this:
my $r = $app->routes;
$r->get('/prefs')
# no permission necessary here
->to(...);
$r->get('/objects')
->over(auth_permission => 'view objects')
->to(...);
$r->get('/objects/delete/:id')
->over(auth_permission => 'delete objects')
->to(...);
The to()
clauses are handled correctly: GET /objects
gives me the object list, and GET /objects/delete/42
deletes object 42.
The problem is that the permission view objects
is checked for both requests, even though the second route should check the permission delete objects
.
The reason seems to be that /objects/delete/42
is a path below /objects
. The same problem does not occur with the route /prefs
, which does not have a common base with the other routes.
My current workaround is to place the rule for /objects
below the one for /objects/delete/:id
, but that's a) unelegant and is b) going to break when another developer edits the file. Can I explicitly disable the nesting behavior seen in this case?
The Mojolicious docs seem to indicate that you should be building the extended route off the object that handles the shorter one. See the Nested Routes Section of the docs.
This means you have a $objects route, and a $objects_delete route derived from it. Eliminates ordering problems (other than having to declare the shorter route first).