[z3-checkins] r5175 - in z3/Five/trunk: . demo/FiveViewsDemo
directives handlers security tests
dreamcatcher at codespeak.net
dreamcatcher at codespeak.net
Sun Jun 20 05:28:09 MEST 2004
Author: dreamcatcher
Date: Sun Jun 20 05:28:07 2004
New Revision: 5175
Added:
z3/Five/trunk/directives/
z3/Five/trunk/directives/__init__.py (contents, props changed)
z3/Five/trunk/directives/content.py (contents, props changed)
z3/Five/trunk/handlers/
z3/Five/trunk/handlers/__init__.py (contents, props changed)
z3/Five/trunk/handlers/content.py (contents, props changed)
z3/Five/trunk/permissions.zcml
z3/Five/trunk/security/
z3/Five/trunk/security/__init__.py (contents, props changed)
z3/Five/trunk/security/fields.py (contents, props changed)
z3/Five/trunk/security/interfaces.py (contents, props changed)
z3/Five/trunk/security/permission.py (contents, props changed)
z3/Five/trunk/tests/__init__.py (contents, props changed)
z3/Five/trunk/tests/test_security.py (contents, props changed)
Modified:
z3/Five/trunk/demo/FiveViewsDemo/browser.py
z3/Five/trunk/demo/FiveViewsDemo/configure.zcml
z3/Five/trunk/demo/FiveViewsDemo/interfaces.py
z3/Five/trunk/five.zcml
z3/Five/trunk/fivedirectives.py
z3/Five/trunk/meta.zcml
z3/Five/trunk/metaconfigure.py
z3/Five/trunk/metadirectives.py
z3/Five/trunk/tests/test_five.py
Log:
Implementation of z3-like zcml 'content' directive for z2 security. Pending tests.
Modified: z3/Five/trunk/demo/FiveViewsDemo/browser.py
==============================================================================
--- z3/Five/trunk/demo/FiveViewsDemo/browser.py (original)
+++ z3/Five/trunk/demo/FiveViewsDemo/browser.py Sun Jun 20 05:28:07 2004
@@ -1,31 +1,20 @@
-from AccessControl import ClassSecurityInfo
-from Globals import InitializeClass
from Products.Five.api import BrowserView
class SimpleContentView(BrowserView):
"""More docstring. Please Zope"""
- security = ClassSecurityInfo()
- security.declareProtected('View Management Screens', 'eagle')
def eagle(self):
"""Docstring"""
return "The eagle has landed"
-
-InitializeClass(SimpleContentView)
class SimpleFolderView(BrowserView):
- security = ClassSecurityInfo()
- security.declarePublic('eagle')
def eagle(self):
"""Test
"""
return "The eagle has landed: %s" % self.context.objectIds()
- security.declareProtected('View management screens', 'mydefault')
def mydefault(self):
"""Test
"""
return "This is default view for %s" % self.context.absolute_url()
-
-InitializeClass(SimpleFolderView)
Modified: z3/Five/trunk/demo/FiveViewsDemo/configure.zcml
==============================================================================
--- z3/Five/trunk/demo/FiveViewsDemo/configure.zcml (original)
+++ z3/Five/trunk/demo/FiveViewsDemo/configure.zcml Sun Jun 20 05:28:07 2004
@@ -1,7 +1,7 @@
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five">
- <five:page
+ <five:page
for=".interfaces.ISimpleContent"
class=".browser.SimpleContentView"
attribute="eagle"
@@ -14,7 +14,7 @@
/>
<five:viewable
- class="OFS.Folder.Folder"
+ class="OFS.Folder.Folder"
/>
<five:page
@@ -23,5 +23,27 @@
attribute="eagle"
name="eagle.txt"
/>
-
+
+ <five:content class=".browser.SimpleContentView">
+
+ <five:require attributes="eagle"
+ permission="zope.ViewManagementScreens"
+ />
+
+ </five:content>
+
+ <five:content class=".browser.SimpleFolderView">
+
+ <implements interface=".interfaces.ISimpleFolderView"
+ />
+
+ <require interface=".interfaces.IWriteSimpleFolderView"
+ permission="zope.ViewManagementScreens"
+ />
+
+ <allow interface=".interfaces.IReadSimpleFolderView"
+ />
+
+ </five:content>
+
</configure>
Modified: z3/Five/trunk/demo/FiveViewsDemo/interfaces.py
==============================================================================
--- z3/Five/trunk/demo/FiveViewsDemo/interfaces.py (original)
+++ z3/Five/trunk/demo/FiveViewsDemo/interfaces.py Sun Jun 20 05:28:07 2004
@@ -7,3 +7,17 @@
class IFolder(Interface):
pass
+
+
+class IReadSimpleFolderView(Interface):
+
+ def eagle():
+ """Just a sample method"""
+
+class IWriteSimpleFolderView(Interface):
+
+ def mydefault():
+ """Just a sample method"""
+
+class ISimpleFolderView(IReadSimpleFolderView, IWriteSimpleFolderView):
+ """Interface for SimpleFolderView"""
Added: z3/Five/trunk/directives/__init__.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/directives/__init__.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1 @@
+# import this
Added: z3/Five/trunk/directives/content.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/directives/content.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,94 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: metadirectives.py 25177 2004-06-02 13:17:31Z jim $
+"""
+from zope.interface import Interface
+from zope.configuration.fields import GlobalObject, Tokens, \
+ PythonIdentifier, MessageID
+from zope.schema import TextLine, Id
+
+from Products.Five.security.fields import Permission
+
+class IContentDirective(Interface):
+ """
+ Make statements about a content class
+ """
+
+ class_ = GlobalObject(
+ title=u"Class",
+ required=True
+ )
+
+class IImplementsSubdirective(Interface):
+ """
+ Declare that the class given by the content directive's class
+ attribute implements a given interface
+ """
+
+ interface = Tokens(
+ title=u"One or more interfaces",
+ required=True,
+ value_type=GlobalObject()
+ )
+
+class IRequireSubdirective(Interface):
+ """
+ Indicate that the a specified list of names or the names in a
+ given Interface require a given permission for access.
+ """
+
+ permission = Permission(
+ title=u"Permission",
+ description=u"""
+ Specifies the permission by id that will be required to
+ access or mutate the attributes and methods specified.""",
+ required=False
+ )
+
+ attributes = Tokens(
+ title=u"Attributes and methods",
+ description=u"""
+ This is a list of attributes and methods that can be accessed.""",
+ required=False,
+ value_type=PythonIdentifier()
+ )
+
+ interface = Tokens(
+ title=u"Interfaces",
+ description=u"""
+ The listed interfaces' methods and attributes can be accessed.""",
+ required=False,
+ value_type=GlobalObject()
+ )
+
+class IAllowSubdirective(Interface):
+ """
+ Declare a part of the class to be publicly viewable (that is,
+ requires the zope.Public permission). Only one of the following
+ two attributes may be used.
+ """
+
+ attributes = Tokens(
+ title=u"Attributes",
+ required=False,
+ value_type=PythonIdentifier()
+ )
+
+ interface = Tokens(
+ title=u"Interface",
+ required=False,
+ value_type=GlobalObject()
+ )
+
Modified: z3/Five/trunk/five.zcml
==============================================================================
--- z3/Five/trunk/five.zcml (original)
+++ z3/Five/trunk/five.zcml Sun Jun 20 05:28:07 2004
@@ -1,12 +1,13 @@
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five">
-
+
<include file="meta.zcml" />
<include file="services.zcml" />
+ <include file="permissions.zcml" />
<!-- do 'traditional' traversing for ZPT by default -->
- <adapter
+ <adapter
for="*"
factory="zope.app.traversing.adapters.DefaultTraversable"
provides="zope.app.traversing.interfaces.ITraversable" />
Modified: z3/Five/trunk/fivedirectives.py
==============================================================================
--- z3/Five/trunk/fivedirectives.py (original)
+++ z3/Five/trunk/fivedirectives.py Sun Jun 20 05:28:07 2004
@@ -7,7 +7,7 @@
"""
This is the basic information for all views.
"""
-
+
for_ = Tokens(
title=u"Specifications of the objects to be viewed",
description=u"""This should be a list of interfaces or classes
@@ -119,7 +119,7 @@
title=u"Class",
required=True
)
-
+
class ILayerDirective(Interface):
"""
Register a layer
Added: z3/Five/trunk/handlers/__init__.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/handlers/__init__.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1 @@
+# import this
Added: z3/Five/trunk/handlers/content.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/handlers/content.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Register class directive.
+
+$Id: contentdirective.py 25177 2004-06-02 13:17:31Z jim $
+"""
+from types import ModuleType
+from zope.interface import classImplements
+from zope.configuration.exceptions import ConfigurationError
+from zope.component import getUtility
+
+# Zope 2 stuff
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass
+from Products.Five.metaconfigure import interface as provideInterface
+from Products.Five.security.interfaces import IPermission
+from Products.Five.security.permission import CheckerPublic
+
+def dottedName(klass):
+ if klass is None:
+ return 'None'
+ return klass.__module__ + '.' + klass.__name__
+
+class ProtectionDeclarationException(Exception):
+ """Security-protection-specific exceptions."""
+ pass
+
+class ContentDirective:
+
+ def __init__(self, _context, class_):
+ self.__id = dottedName(class_)
+ self.__class = class_
+ if isinstance(self.__class, ModuleType):
+ raise ConfigurationError('Content class attribute must be a class')
+ # not used yet
+ #self.__name = class_
+ #self.__normalized_name = _context.getNormalizedName(class_)
+ self.__context = _context
+
+ def implements(self, _context, interface):
+ for interface in interface:
+ _context.action(
+ discriminator = (
+ 'five::directive:content', self.__class, object()),
+ callable = classImplements,
+ args = (self.__class, interface),
+ )
+ provideInterface(_context, interface)
+
+ def require(self, _context, permission=None,
+ attributes=None, interface=None):
+ """Require a the permission to access a specific aspect"""
+
+ if not (interface or attributes):
+ raise ConfigurationError("Nothing required")
+
+ if interface:
+ for i in interface:
+ if i:
+ self.__protectByInterface(i, permission)
+ if attributes:
+ self.__protectNames(attributes, permission)
+
+ def allow(self, _context, attributes=None, interface=None):
+ """Like require, but with permission_id zope.Public"""
+ return self.require(_context, CheckerPublic, attributes, interface)
+
+
+ def __protectByInterface(self, interface, permission_id):
+ "Set a permission on names in an interface."
+ for n, d in interface.namesAndDescriptions(1):
+ self.__protectName(n, permission_id)
+ provideInterface(self.__context, interface)
+
+ def __protectName(self, name, permission_id):
+ "Set a permission on a particular name."
+ self.__context.action(
+ discriminator = ('protectName', self.__class, name),
+ callable = protectName,
+ args = (self.__class, name, permission_id)
+ )
+
+ def __protectNames(self, names, permission_id):
+ "Set a permission on a bunch of names."
+ for name in names:
+ self.__protectName(name, permission_id)
+
+ def __call__(self):
+ "Handle empty/simple declaration."
+ return self.__context.action(
+ discriminator = ('five:initialize:class', self.__class),
+ callable = initializeClass,
+ args = (self.__class,)
+ )
+
+
+def initializeClass(klass):
+ print 'Initializing class %r' % klass
+ InitializeClass(klass)
+
+def _getSecurity(klass):
+ info = vars(klass)
+ for k, v in info.items():
+ if hasattr(v, '__security_info__'):
+ return v
+ security = ClassSecurityInfo()
+ setattr(klass, '__security__', security)
+ return security
+
+def protectName(klass, name, permission_id):
+ print klass, name, permission_id
+ security = _getSecurity(klass)
+ if permission_id == CheckerPublic:
+ security.declarePublic(name)
+ else:
+ permission = getUtility(IPermission, name=permission_id)
+ security.declareProtected(permission.title, name)
+
Modified: z3/Five/trunk/meta.zcml
==============================================================================
--- z3/Five/trunk/meta.zcml (original)
+++ z3/Five/trunk/meta.zcml Sun Jun 20 05:28:07 2004
@@ -5,6 +5,11 @@
<meta:directives namespace="http://namespaces.zope.org/zope">
<meta:directive
+ name="permission"
+ schema=".metadirectives.IDefinePermissionDirective"
+ handler=".metaconfigure.definePermission" />
+
+ <meta:directive
name="interface"
schema=".metadirectives.IInterfaceDirective"
handler=".metaconfigure.interface"
@@ -27,7 +32,7 @@
schema=".metadirectives.IServiceTypeDirective"
handler=".metaconfigure.serviceType"
/>
-
+
<meta:directive
name="service"
schema=".metadirectives.IServiceDirective"
@@ -37,13 +42,13 @@
</meta:directives>
<meta:directives namespace="http://namespaces.zope.org/five">
-
+
<meta:directive
name="page"
schema=".fivedirectives.IPageDirective"
handler=".fiveconfigure.page"
/>
-
+
<meta:directive
name="layer"
schema=".fivedirectives.ILayerDirective"
@@ -62,6 +67,33 @@
handler=".fiveconfigure.defaultSkin"
/>
+
+ <!-- This is a simplified version of z3's content directive, -->
+ <!-- to accomodate the fact that z2's security is not as powerful -->
+
+ <meta:complexDirective
+ name="content"
+ schema=".directives.content.IContentDirective"
+ handler=".handlers.content.ContentDirective"
+ >
+
+ <meta:subdirective
+ name="implements"
+ schema=".directives.content.IImplementsSubdirective"
+ />
+
+ <meta:subdirective
+ name="require"
+ schema=".directives.content.IRequireSubdirective"
+ />
+
+ <meta:subdirective
+ name="allow"
+ schema=".directives.content.IAllowSubdirective"
+ />
+
+ </meta:complexDirective>
+
<!-- specific to Five -->
<meta:directive
name="implements"
Modified: z3/Five/trunk/metaconfigure.py
==============================================================================
--- z3/Five/trunk/metaconfigure.py (original)
+++ z3/Five/trunk/metaconfigure.py Sun Jun 20 05:28:07 2004
@@ -18,6 +18,8 @@
from zope.component import getService, getServices
from zope.component.servicenames import Adapters
from provideinterface import provideInterface
+from Products.Five.security.permission import Permission
+from Products.Five.security.interfaces import IPermission
def handler(serviceName, methodName, *args, **kwargs):
method=getattr(getService(serviceName), methodName)
@@ -126,3 +128,7 @@
callable = provideInterface,
args = (provides.__module__ + '.' + provides.getName(), provides)
)
+
+def definePermission(_context, id, title, description=''):
+ permission = Permission(id, title, description)
+ utility(_context, IPermission, permission, name=id)
Modified: z3/Five/trunk/metadirectives.py
==============================================================================
--- z3/Five/trunk/metadirectives.py (original)
+++ z3/Five/trunk/metadirectives.py Sun Jun 20 05:28:07 2004
@@ -32,22 +32,22 @@
)
class IServiceTypeDirective(Interface):
-
+
id = TextLine(
title=u"ID of the service type",
required=True
)
-
+
interface = GlobalObject(
title=u"Interface of the service type",
required=True
)
-
+
class IServiceDirective(IBasicComponentInformation):
"""
Register a service
"""
-
+
serviceType = TextLine(
title=u"ID of service type",
required=True
@@ -57,7 +57,7 @@
"""
Define an interface
"""
-
+
interface = GlobalObject(
title=u"Interface",
required=True
@@ -118,3 +118,25 @@
required=False
)
+class IBaseDefineDirective(Interface):
+ """Define a new security object."""
+
+ id = Id(
+ title=u"Id",
+ description=u"Id as which this object will be known and used.",
+ required=True)
+
+ title = MessageID(
+ title=u"Title",
+ description=u"Provides a title for the object.",
+ required=True)
+
+ description = MessageID(
+ title=u"Description",
+ description=u"Provides a description for the object.",
+ required=False)
+
+
+class IDefinePermissionDirective(IBaseDefineDirective):
+ """Define a new permission."""
+
Added: z3/Five/trunk/permissions.zcml
==============================================================================
--- (empty file)
+++ z3/Five/trunk/permissions.zcml Sun Jun 20 05:28:07 2004
@@ -0,0 +1,9 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="Five">
+
+ <permission
+ id="zope.ViewManagementScreens"
+ title="View Management Screens"
+ />
+
+</configure>
Added: z3/Five/trunk/security/__init__.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/security/__init__.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1 @@
+# import this
Added: z3/Five/trunk/security/fields.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/security/fields.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Security related configuration fields.
+
+$Id: fields.py 25253 2004-06-04 15:20:26Z jim $
+"""
+from zope import schema
+from zope.interface import implements
+from zope.schema.interfaces import IFromUnicode
+
+from Products.Five.security.permission import checkPermission
+
+class Permission(schema.Id):
+ r"""This field describes a permission.
+
+ Let's look at an example:
+
+ >>> class FauxContext:
+ ... permission_mapping = {'zope.ManageCode':'zope.private'}
+ ... _actions = []
+ ... def action(self, **kws):
+ ... self._actions.append(kws)
+ >>> context = FauxContext()
+ >>> field = Permission().bind(context)
+
+ Let's test the fromUnicode method:
+
+ >>> field.fromUnicode(u'zope.foo')
+ 'zope.foo'
+ >>> field.fromUnicode(u'zope.ManageCode')
+ 'zope.private'
+
+ Now let's see whether validation works alright
+
+ >>> field._validate('zope.ManageCode')
+ >>> context._actions[0]['args']
+ (None, 'zope.foo')
+ >>> field._validate('3 foo')
+ Traceback (most recent call last):
+ ...
+ InvalidId: 3 foo
+
+ zope.Public is always valid
+ >>> field._validate('zope.Public')
+ """
+ implements(IFromUnicode)
+
+ def fromUnicode(self, u):
+ u = super(Permission, self).fromUnicode(u)
+
+ map = getattr(self.context, 'permission_mapping', {})
+ return map.get(u, u)
+
+ def _validate(self, value):
+ super(Permission, self)._validate(value)
+
+ if value != 'zope.Public':
+ self.context.action(
+ discriminator = None,
+ callable = checkPermission,
+ args = (None, value),
+
+ # Delay execution till end. This is an
+ # optimization. We don't want to intersperse utility
+ # lookup, done when checking permissions, with utility
+ # definitions. Utility lookup is expensive after
+ # utility definition, as extensive caches have to be
+ # rebuilt.
+ order=9999999,
+ )
+
Added: z3/Five/trunk/security/interfaces.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/security/interfaces.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,21 @@
+from zope.interface import Interface
+from zope.schema import TextLine, Text
+
+class IPermission(Interface):
+ """A permission object."""
+
+ id = TextLine(
+ title=u"Id",
+ description=u"Id as which this permission will be known and used.",
+ readonly=True,
+ required=True)
+
+ title = TextLine(
+ title=u"Title",
+ description=u"Provides a title for the permission.",
+ required=True)
+
+ description = Text(
+ title=u"Description",
+ description=u"Provides a description for the permission.",
+ required=False)
Added: z3/Five/trunk/security/permission.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/security/permission.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,35 @@
+from zope.interface import implements
+from zope.component import queryUtility
+from Products.Five.security.interfaces import IPermission
+
+CheckerPublic = 'zope.Public'
+
+def checkPermission(context, permission_id):
+ """Check whether a given permission exists in the provided context.
+
+ >>> from zope.app.tests.placelesssetup import setUp, tearDown
+ >>> setUp()
+
+ >>> from zope.app.tests.ztapi import provideUtility
+ >>> provideUtility(IPermission, Permission('x'), 'x')
+
+ >>> checkPermission(None, 'x')
+ >>> checkPermission(None, 'y')
+ Traceback (most recent call last):
+ ...
+ ValueError: ('Undefined permission id', 'y')
+
+ >>> tearDown()
+ """
+ if permission_id == CheckerPublic:
+ return
+ if not queryUtility(IPermission, permission_id, context=context):
+ raise ValueError("Undefined permission id", permission_id)
+
+class Permission(object):
+ implements(IPermission)
+
+ def __init__(self, id, title="", description=""):
+ self.id = id
+ self.title = title
+ self.description = description
Added: z3/Five/trunk/tests/__init__.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/tests/__init__.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1 @@
+# import this
Modified: z3/Five/trunk/tests/test_five.py
==============================================================================
--- z3/Five/trunk/tests/test_five.py (original)
+++ z3/Five/trunk/tests/test_five.py Sun Jun 20 05:28:07 2004
@@ -1,11 +1,22 @@
import os, sys
+from os import curdir
+from os.path import join, abspath, dirname, split
+
+try:
+ __file__
+except NameError:
+ # Test was called directly, so no __file__ global exists.
+ _prefix = abspath(curdir)
+else:
+ # Test was called by another test.
+ _prefix = abspath(dirname(__file__))
if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py'))
# XXX hack but no other way to initialize options apparently
from Zope.Startup.run import configure
-configure('../../../etc/zope.conf')
+configure(join(_prefix, '..', '..', '..', 'etc', 'zope.conf'))
from Testing import ZopeTestCase
@@ -35,7 +46,7 @@
"Adapted: The method",
adapted.adaptedMethod())
- def test_attribute_view(self):
+ def test_attribute_view(self):
self.root.manage_addProduct['FiveTest'].manage_addSimpleContent(
'testoid', 'Testoid')
test = self.root.testoid
@@ -67,7 +78,7 @@
'testoid', 'Testoid')
view = self.root.unrestrictedTraverse('testoid/flamingo2.html')
self.assertEquals(u'<p>Hello world</p>\n', view())
-
+
def test_view_backwards_compatibility(self):
self.root.manage_addProduct['FiveTest'].manage_addSimpleContent(
'testoid', 'Testoid')
@@ -84,13 +95,13 @@
<p>Hello world</p>
"""
self.assertEquals(expected, view())
-
-
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(FiveTestCase))
+ return suite
+
if __name__ == '__main__':
framework()
-else:
- import unittest
- def test_suite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(FiveTestCase))
- return suite
+
Added: z3/Five/trunk/tests/test_security.py
==============================================================================
--- (empty file)
+++ z3/Five/trunk/tests/test_security.py Sun Jun 20 05:28:07 2004
@@ -0,0 +1,73 @@
+import os, sys
+from os import curdir
+from os.path import join, abspath, dirname, split
+
+try:
+ __file__
+except NameError:
+ # Test was called directly, so no __file__ global exists.
+ _prefix = abspath(curdir)
+else:
+ # Test was called by another test.
+ _prefix = abspath(dirname(__file__))
+
+if __name__ == '__main__':
+ execfile(os.path.join(sys.path[0], 'framework.py'))
+
+# XXX hack but no other way to initialize options apparently
+from Zope.Startup.run import configure
+configure(join(_prefix, '..', '..', '..', 'etc', 'zope.conf'))
+
+import unittest
+from Testing import ZopeTestCase
+
+ZopeTestCase.installProduct('Five')
+
+from AccessControl import ClassSecurityInfo
+
+class Dummy:
+
+ def foo(self): pass
+ def bar(self): pass
+ def baz(self): pass
+ def keg(self): pass
+ def wot(self): pass
+
+class Dummy1(Dummy):
+
+ security = ClassSecurityInfo()
+ security.declareProtected('View', 'foo')
+
+class Dummy2(Dummy):
+
+ security = ClassSecurityInfo()
+ security.declarePublic('foo')
+ security.declareProtected('View', 'bar')
+ security.declarePrivate('baz')
+ security.declareProtected('Edit', 'keg')
+
+
+class SecurityTestCase(ZopeTestCase.ZopeTestCase):
+
+ def test_require(self):
+ # Need to use xmlconfig() to run a
+ # small zcml snippet and then check
+ # the class __ac_permissions__ to see
+ # if the declaration took effect.
+ pass
+
+ def test_allow(self):
+ pass
+
+ def test_initialize(self):
+ pass
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(SecurityTestCase))
+ return suite
+
+if __name__ == '__main__':
+ framework()
+
More information about the z3-checkins
mailing list