Commit 8de2ccb2 authored by Tres Seaver's avatar Tres Seaver

Protect names from interface superclasses.

o See http://www.zope.org/Collectors/Zope/2333
parent 600bdaef
...@@ -97,6 +97,9 @@ Zope Changes ...@@ -97,6 +97,9 @@ Zope Changes
Bugs Fixed Bugs Fixed
- Five.browser.metaconfigure.page didn't protect names from interface
superclasses (http://www.zope.org/Collectors/Zope/2333)
- Fixed bug in ZPublisher.BaseRequest with persistent site managers. - Fixed bug in ZPublisher.BaseRequest with persistent site managers.
An EndRequestEvent was thrown after the ZODB connection was already An EndRequestEvent was thrown after the ZODB connection was already
closed and thus the site manager not being available anymore. closed and thus the site manager not being available anymore.
......
...@@ -60,7 +60,7 @@ def page(_context, name, permission, for_, ...@@ -60,7 +60,7 @@ def page(_context, name, permission, for_,
allowed_attributes = [] allowed_attributes = []
if allowed_interface is not None: if allowed_interface is not None:
for interface in allowed_interface: for interface in allowed_interface:
allowed_attributes.extend(interface.names()) allowed_attributes.extend(interface.names(all=True))
if attribute != '__call__': if attribute != '__call__':
if template: if template:
......
...@@ -22,9 +22,21 @@ if __name__ == '__main__': ...@@ -22,9 +22,21 @@ if __name__ == '__main__':
from zope.interface import Interface, implements from zope.interface import Interface, implements
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
class IDummy(Interface): class ISuperDummy(Interface):
"""
"""
def superMethod():
"""
"""
class IDummy(ISuperDummy):
"""Just a marker interface""" """Just a marker interface"""
def foo():
"""
"""
class Dummy1: class Dummy1:
implements(IDummy) implements(IDummy)
def foo(self): pass def foo(self): pass
...@@ -32,6 +44,7 @@ class Dummy1: ...@@ -32,6 +44,7 @@ class Dummy1:
def baz(self): pass def baz(self): pass
def keg(self): pass def keg(self): pass
def wot(self): pass def wot(self): pass
def superMethod(self): pass
class Dummy2(Dummy1): class Dummy2(Dummy1):
security = ClassSecurityInfo() security = ClassSecurityInfo()
...@@ -136,6 +149,78 @@ def test_security_equivalence(): ...@@ -136,6 +149,78 @@ def test_security_equivalence():
>>> tearDown() >>> tearDown()
""" """
def test_allowed_interface():
"""This test demonstrates that allowed_interface security declarations work
as expected.
>>> from zope.app.testing.placelesssetup import setUp, tearDown
>>> setUp()
Before we can make security declarations through ZCML, we need to
register the directive and the permission:
>>> import Products.Five
>>> from Products.Five import zcml
>>> zcml.load_config('meta.zcml', Products.Five)
>>> import Products.Five.browser
>>> zcml.load_config('meta.zcml', Products.Five.browser)
>>> zcml.load_config('permissions.zcml', Products.Five)
Now we provide some ZCML declarations for ``Dummy1``:
>>> configure_zcml = '''
... <configure xmlns="http://namespaces.zope.org/zope"
... xmlns:browser="http://namespaces.zope.org/browser">
... <browser:page
... for="*"
... name="testview"
... permission="zope2.ViewManagementScreens"
... class="Products.Five.tests.test_security.Dummy1"
... allowed_interface="Products.Five.tests.test_security.IDummy" />
... </configure>
... '''
>>> zcml.load_string(configure_zcml)
We are going to check that roles are correctly setup, so we need getRoles.
>>> from AccessControl.ZopeSecurityPolicy import getRoles
>>> from AccessControl import ACCESS_PRIVATE
Due to the nasty voodoo involved in Five's handling of view classes,
browser:page doesn't apply security to Dummy1, but rather to the "magic"
view class that is created at ZCML parse time. That means we can't just
instanciate with Dummy1() directly and expect a security-aware instance :(.
Instead, we'll have to actually lookup the view. The view was declared for
"*", so we just use an instance of Dummy1 ;-).
Instanciate a Dummy1 object to test with.
>>> from Products.Five.tests.test_security import Dummy1
>>> dummy1 = Dummy1()
>>> from zope.component import getMultiAdapter
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> view = getMultiAdapter((dummy1, request), name="testview")
As 'foo' is defined in IDummy, it should have the 'Manager' role.
>>> getRoles(view, 'foo', view.foo, ('Def',))
('Manager',)
As 'wot' is not defined in IDummy, it should be private.
>>> getRoles(view, 'wot', view.wot, ('Def',)) is ACCESS_PRIVATE
True
But 'superMethod' is defined on IDummy by inheritance from ISuperDummy, and
so should have the 'Manager' role setup.
>>> getRoles(view, 'superMethod', view.superMethod, ('Def',))
('Manager',)
>>> tearDown()
"""
def test_checkPermission(): def test_checkPermission():
""" """
Test checkPermission Test checkPermission
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment