Comment 2 for bug 347162

Revision history for this message
Martin Aspeli (optilude) wrote :

Hi Sylvain,

I came across this again and did some more debugging.

Is your test using a browser view? If so, it wouldn't trigger the error, because it probably only happens in protected code.

Basically, I think the problem is this:

 - The expression does exists:portal/++resource++foo.bar/some-stylesheet.css
 - This finds the ZopeTwoDirectoryResource for ++resource++foo.bar
 - It then tries to traverse to some-stylesheet.css, which calls restrictedTraverse() on the ZopeTwoDirectoryResource
 - This ends up calling validate() on the security manager
 - This ends up here, in AccessControl.ImplPython:

            p = Containers(type(container), None)
            if p is None:
                p = getattr(container,
                            '__allow_access_to_unprotected_subobjects__',
                            None)

            if p is not None:
                if not isinstance(p, int): # catches bool too
                    if isinstance(p, dict):
                        if isinstance(name, basestring):
                            p = p.get(name)
                        else:
                            p = 1
                    else:
                        p = p(name, value)

            if not p:
                if self._verbose:
                    raiseVerbose(
                        'The container has no security assertions',
                        accessed, container, name, value, context)
                raise Unauthorized(name, value)

The variables are:

(Pdb) pp accessed, container, name, value, context
(<five.grok.components.ZopeTwoDirectoryResource object at 0x6dd48b0>,
 <five.grok.components.ZopeTwoDirectoryResource object at 0x6dd48b0>,
 None,
 <Products.Five.browser.resource.FileResource object at 0x6dd4910>,
 <AccessControl.SecurityManagement.SecurityContext instance at 0x6da51e8>)

As you can see from this code, it's trying to determine if you're allowed to access an item in a container. For that to be allowed, you need to set __allow_access_to_unprotected_subobjects__ to True (or to a method that returns True when called with the sub-item name).

Therefore, adding this to ZopeTwoDirectoryResource seems to do the trick:

class ZopeTwoDirectoryResource(resource.DirectoryResource):
    __allow_access_to_unprotected_subobjects__ = True

Do you agree with this?

Cheers,
Martin