Skip to content

Commit

Permalink
Implement the suggestion of @davisagli.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed May 27, 2019
1 parent ce327e3 commit 3ebdd45
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
28 changes: 23 additions & 5 deletions src/Products/Five/browser/metaconfigure.py
Expand Up @@ -25,6 +25,7 @@
import zope.browserpage.metaconfigure
import zope.browserpage.simpleviewclass
import zope.publisher.browser
from AccessControl import ClassSecurityInfo
from AccessControl.class_init import InitializeClass
from AccessControl.security import CheckerPrivateId
from AccessControl.security import getSecurityInfo
Expand Down Expand Up @@ -459,6 +460,27 @@ def __call__(self):
return getattr(self, attr)


class DeferredAttrAuthProxy(object):
"""Proxy to defer the authorization from traversal to object access."""

security = ClassSecurityInfo()

def __init__(self, context, name):
self.context = context
self.name = name

@security.public
def __call__(self, *args, **kw):
try:
attr = guarded_getattr(self.context, self.name)
except (AttributeError, Unauthorized):
raise NotFound(self.context, self.name)
return attr(*args, **kw)


InitializeClass(DeferredAttrAuthProxy)


@zope.interface.implementer(IPublishTraverse)
@zope.component.adapter(simple, IBrowserRequest)
class SimplePublishTraverse(object):
Expand All @@ -469,11 +491,7 @@ def __init__(self, context, request):
self.request = request

def publishTraverse(self, request, name):
try:
return guarded_getattr(self.context, name)
except Unauthorized:
# attribute exists but is not published, so hide it from access:
raise AttributeError(name)
return DeferredAttrAuthProxy(self.context, name)


class ViewMixinForTemplates(zope.browserpage.simpleviewclass.simple):
Expand Down
2 changes: 1 addition & 1 deletion src/Products/Five/browser/tests/test_pages.py
Expand Up @@ -110,7 +110,7 @@ def test_publishTraverse_to_allowed_name(self):

self.browser.open(
'http://localhost/test_folder_1_/testoid/eagle.method/eagle')
self.assertEqual('The eagle has landed', browser.contents)
self.assertEqual('The eagle has landed', self.browser.contents)

def test_publishTraverse_to_not_allowed_name(self):
# The ``eagle.method`` view has a method ``mouse`` but it is not
Expand Down

0 comments on commit 3ebdd45

Please sign in to comment.