Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#4018 defect closed invalid (invalid)

NoSuchResource when accessing a protected leaf resource

Reported by: unshift Owned by:
Priority: normal Milestone:
Component: web Keywords:
Cc: Branch:
Author: Launchpad Bug:

Description

When protecting a Site object which consists of a root Resource and multiple leaf resources, accessing a leaf node will result in a NoSuchResource exception.

For example, if I guard my root object, and then add to it /foo/die, then accessing /foo/die will try to render /. Setting a breakpoint on getChildWithDefault shows that self.children has "foo" in it (meaning / is being rendered) -- there's no traversal mechanism there.

This might be the way it's supposed to work (and the unit tests only really test this case, as far as I can tell from a quick look), but the documentation notes that the auth mechanism is supposed to be a drop-in solution, so either the code or doc is mistaken.

Attachments (1)

4018.py (1.5 KB) - added by unshift 5 years ago.

Download all attachments as: .zip

Change History (5)

Changed 5 years ago by unshift

comment:1 Changed 5 years ago by unshift

I think I tracked this one down.

resource.getChildForRequest is called to find the node that should be used to handle the request:

def getChildForRequest(resource, request):
    """Traverse resource tree to find who will handle the request."""
    while request.postpath and not resource.isLeaf:
        pathElement = request.postpath.pop(0)
        request.prepath.append(pathElement)
        resource = resource.getChildWithDefault(pathElement, request)
    return resource

Eventually resource will be a ResourceWrapper.

ResourceWrapper.getChildWithDefault is a pass-through straight to the wrapped resource's getChildWithDefault method. With authentication enabled, the wrapped resource is going to be whatever the guard was set on -- in the example above and in the attached code, the guard was set on /, but really getChildWithDefault should be called on the Resource representing /foo. In that case, the child node ("die") that *should* go back to getChildForRequest won't be there, and a NoSuchResource will be returned.

It seems this is a fundamental issue with the authentication strategy in general, since the notion of wrapping a sub-tree means either breaking the simple abstraction and putting node search code into getChildWithDefault, or changing the way that logins are handled. Since the HTTPAuthSessionWrapper's login code just gets the avatar from the realm, and the avatar is an entire tree, there's no concise way to get the desired node directly from the avatar. Not without being fancy on the caller's side, anyway.

comment:2 Changed 5 years ago by unshift

  • Resolution set to invalid
  • Status changed from new to closed

This shows up in 8.2 but seems fixed as of r27323

comment:3 Changed 5 years ago by unshift

It's worth noting, the fix may have come from the fix to #3679

comment:4 Changed 4 years ago by <automation>

  • Owner jknight deleted
Note: See TracTickets for help on using tickets.