[Checkins] SVN: Products.PluggableAuthService/trunk/ Merge Dieter Maurer's 'not-compenetent plugin' branch.
Tres Seaver
cvs-admin at zope.org
Fri May 25 18:19:21 UTC 2012
Log message for revision 126497:
Merge Dieter Maurer's 'not-compenetent plugin' branch.
See: https://bugs.launchpad.net/bugs/649596
Changed:
_U Products.PluggableAuthService/trunk/
U Products.PluggableAuthService/trunk/Products/PluggableAuthService/PluggableAuthService.py
U Products.PluggableAuthService/trunk/Products/PluggableAuthService/__init__.py
U Products.PluggableAuthService/trunk/Products/PluggableAuthService/interfaces/plugins.py
A Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/NotCompetentHelper.py
A Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/tests/test_NotCompetentHelper.py
A Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/www/ncbrAdd.zpt
U Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/conformance.py
U Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/test_PluggableAuthService.py
-=-
Modified: Products.PluggableAuthService/trunk/Products/PluggableAuthService/PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/PluggableAuthService.py 2012-05-25 14:48:51 UTC (rev 126496)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/PluggableAuthService.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -62,6 +62,7 @@
from .interfaces.plugins import IGroupEnumerationPlugin
from .interfaces.plugins import IRoleEnumerationPlugin
from .interfaces.plugins import IRoleAssignerPlugin
+from .interfaces.plugins import INotCompetentPlugin
from .interfaces.plugins import IChallengeProtocolChooser
from .interfaces.plugins import IRequestTypeSniffer
from .permissions import SearchPrincipals
@@ -223,6 +224,10 @@
plugins = self._getOb( 'plugins' )
is_top = self._isTop()
+ if not is_top and self._isNotCompetent( request, plugins ):
+ # this user folder should not try to authenticate this request
+ return None
+
user_ids = self._extractUserIds(request, plugins)
( accessed
, container
@@ -521,6 +526,32 @@
#
# Helper methods
#
+ security.declarePrivate( '_isNotCompetent' )
+ def _isNotCompetent( self, request, plugins ):
+
+ """ return true when this user folder should not try authentication.
+
+ Never called for top level user folder.
+ """
+ try:
+ not_competents = plugins.listPlugins( INotCompetentPlugin )
+ except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
+ logger.debug('NotCompetent plugin listing error', exc_info=True)
+ not_competents = ()
+
+ for not_competent_id, not_competent in not_competents:
+ try:
+ if not_competent.isNotCompetentToAuthenticate(request):
+ return True
+ except _SWALLOWABLE_PLUGIN_EXCEPTIONS:
+ reraise(not_competent)
+ logger.debug( 'NotCompetentPlugin %s error' % not_competent_id
+ , exc_info=True
+ )
+ continue
+ return False
+
+
security.declarePrivate( '_extractUserIds' )
def _extractUserIds( self, request, plugins ):
@@ -1273,6 +1304,15 @@
, 'request_type_sniffer'
, "Request Type Sniffer plugins detect the type of an incoming request."
)
+ , ( INotCompetentPlugin
+ , 'INotCompetentPlugin'
+ , 'notcompetent'
+ , "Not-Competent plugins check whether this user folder should not "
+ "authenticate the current request. "
+ "These plugins are not used for a top level user folder. "
+ "They are typically used to prevent shaddowing of authentications by "
+ "higher level user folders."
+ )
)
def addPluggableAuthService( dispatcher
Modified: Products.PluggableAuthService/trunk/Products/PluggableAuthService/__init__.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/__init__.py 2012-05-25 14:48:51 UTC (rev 126496)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/__init__.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -44,6 +44,7 @@
from plugins import DynamicGroupsPlugin as DGP
from plugins import ChallengeProtocolChooser as CPC
from plugins import RequestTypeSniffer as RTS
+from plugins import NotCompetentHelper as NCH
registerMultiPlugin(HBAH.HTTPBasicAuthHelper.meta_type)
registerMultiPlugin(IAH.InlineAuthHelper.meta_type)
@@ -61,6 +62,7 @@
registerMultiPlugin(DGP.DynamicGroupsPlugin.meta_type)
registerMultiPlugin(CPC.ChallengeProtocolChooser.meta_type)
registerMultiPlugin(RTS.RequestTypeSniffer.meta_type)
+registerMultiPlugin(NCH.NotCompetent_byRoles.meta_type)
try:
from Products.GenericSetup import profile_registry
@@ -257,6 +259,14 @@
, icon='plugins/www/DelegatingMultiPlugin.png'
)
+ context.registerClass( NCH.NotCompetent_byRoles
+ , permission=ManageUsers
+ , constructors=(
+ NCH.manage_addNotCompetent_byRolesForm,
+ NCH.manage_addNotCompetent_byRoles, )
+ , visibility=None
+ )
+
if profile_registry is not None:
context.registerClass( PluggableAuthService.PluggableAuthService
Modified: Products.PluggableAuthService/trunk/Products/PluggableAuthService/interfaces/plugins.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/interfaces/plugins.py 2012-05-25 14:48:51 UTC (rev 126496)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/interfaces/plugins.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -479,3 +479,18 @@
# has two different algorithms, based on whether or not the
# context object implements IPlacelessSecurity.
#
+
+
+class INotCompetentPlugin( Interface ):
+
+ """check whether this user folder is not competent to authenticate.
+
+ Never used for a top level user folder;
+ primarily used to prevent shaddowing of authentications by higher level
+ user folders.
+ """
+
+ def isNotCompetentToAuthenticate(request):
+
+ """return true if this user folder should not authenticate *request*.
+ """
Added: Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/NotCompetentHelper.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/NotCompetentHelper.py (rev 0)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/NotCompetentHelper.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -0,0 +1,143 @@
+##############################################################################
+#
+# Copyright (c) 2012 Zope Foundation and Contributors
+#
+# 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.
+#
+##############################################################################
+""" NotCompetentHelper `INotCompetent` plugin utilities
+
+`INotCompetent` plugins are usually used to prevent shaddowing of users
+authenticated by higher level user folders. This module provides
+an `INotCompetent` plugin base class which can check for authentications
+by higher level user folders and the class `NotCompetent_byRoles`
+to prevent shaddowing of higher level authentications with
+specified roles.
+"""
+# General Zope imports
+from Acquisition import aq_inner, aq_parent, aq_base
+from AccessControl import ClassSecurityInfo
+from AccessControl.Permissions import manage_users
+from AccessControl.User import nobody
+from ZPublisher.BaseRequest import UNSPECIFIED_ROLES
+from ZPublisher.Response import Response
+from OFS.PropertyManager import PropertyManager
+
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+
+# PluggableAuthService imports
+from Products.PluggableAuthService.interfaces.plugins import \
+ INotCompetentPlugin
+from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
+from Products.PluggableAuthService.utils import classImplements
+
+
+class HigherLevelUserFolderAccessMixin( object ):
+ """mixin class for access to higher level user folders
+
+ requires to be mixed with a `BasePlugin`.
+ """
+ def _generateHigherLevelUserFolders( self ):
+ folder = aq_parent( aq_inner( self._getPAS( ) ) )
+ while True:
+ folder = aq_parent( aq_inner( folder ) )
+ if folder is None: return
+ uf = getattr( folder, "__allow_groups__", None )
+ validate = getattr( aq_base( uf ), "validate", None )
+ if validate is not None:
+ yield uf
+
+ def _getHigherLevelUser( self, request, roles=None ):
+ if roles:
+ accessed = self._getPAS( )._getObjectContext(
+ request[ "PUBLISHED" ], request
+ ) [ 1 ]
+ req_roles = request.roles
+ auth = request._auth
+ # save response and install new one to prevent side effects
+ saved_response = request.response
+ try:
+ request.response = Response()
+ for uf in self._generateHigherLevelUserFolders( ):
+ if req_roles is UNSPECIFIED_ROLES:
+ u = uf.validate( request, auth )
+ else:
+ u = uf.validate( request, auth, req_roles )
+ if u is None or u is nobody:
+ continue
+ # this user folder has authenticated a user able to perform
+ # the request
+ if roles:
+ # check in addition that is has one of *roles*
+ if not u.allowed(accessed, roles):
+ # reject this user
+ continue
+ return u
+ finally:
+ request.response = saved_response
+
+
+class NotCompetentBase( BasePlugin, HigherLevelUserFolderAccessMixin ):
+ """abstract `INotCompententPlugin` base class.
+
+ with access to higher level user folders.
+ """
+
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(manage_users)
+
+ def __init__( self, id, title='' ):
+ self.id = id
+ self.title = title
+
+ security.declarePrivate( 'isNotCompetentToAuthenticate' )
+ def isNotCompetentToAuthenticate( self, request ):
+ raise NotImplementedError( )
+
+classImplements(NotCompetentBase, INotCompetentPlugin)
+
+
+class NotCompetent_byRoles( NotCompetentBase ):
+ """`INotCompetentPlugin` to prevent authentication shaddowing by roles.
+ """
+
+ meta_type = "prevent authentication shaddowing by roles"
+
+ _properties = (
+ PropertyManager._properties +
+ (
+ dict( id="roles", label="roles (empty means all roles)",
+ type="lines", mode="rw",
+ ),
+ )
+ )
+ roles = ()
+
+ manage_options = (
+ ( NotCompetentBase.manage_options[ 0 ], )
+ + PropertyManager.manage_options
+ + NotCompetentBase.manage_options[ 1:-1 ]
+ )
+
+ def isNotCompetentToAuthenticate( self, request ):
+ return self._getHigherLevelUser( request, self.roles ) is not None
+
+
+manage_addNotCompetent_byRolesForm = PageTemplateFile(
+ 'www/ncbrAdd', globals(), __name__='manage_addNotCompetent_byRolesForm' )
+
+def manage_addNotCompetent_byRoles(self, id, title='', REQUEST=None):
+ """ Factory method to instantiate a NotCompetent_byRoles """
+ obj = NotCompetent_byRoles(id, title=title)
+ self._setObject(id, obj)
+
+ if REQUEST is not None:
+ qs = 'manage_tabs_message=NotCompetent_byRoles+added.'
+ my_url = self.absolute_url()
+ REQUEST['RESPONSE'].redirect('%s/manage_workspace?%s' % (my_url, qs))
Added: Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/tests/test_NotCompetentHelper.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/tests/test_NotCompetentHelper.py (rev 0)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/tests/test_NotCompetentHelper.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -0,0 +1,129 @@
+##############################################################################
+#
+# Copyright (c) 2012 Zope Foundation and Contributors
+#
+# 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.
+#
+##############################################################################
+import unittest
+
+from ZPublisher.BaseRequest import UNSPECIFIED_ROLES
+
+from Products.PluggableAuthService.tests.conformance \
+ import INotCompetentPlugin_conformance
+from Products.PluggableAuthService.tests.test_PluggableAuthService \
+ import PluggableAuthServiceTests
+
+
+
+class _WrapPluggableAuthServiceTests( PluggableAuthServiceTests ):
+ """auxiliary wrapper class to allow for instantiation."""
+
+ def __init__(self, *args, **kw): pass
+
+
+
+class NotCompetentHelperTests( unittest.TestCase
+ , INotCompetentPlugin_conformance
+ ):
+
+ def _getTargetClass( self ):
+
+ from Products.PluggableAuthService.plugins.NotCompetentHelper \
+ import NotCompetent_byRoles
+
+ return NotCompetent_byRoles
+
+ def _makeOne( self, id='test', *args, **kw ):
+
+ return self._getTargetClass()( id=id, *args, **kw )
+
+ def setUp( self ):
+ # we use `PluggableAuthServiceTests` to set up a structure
+ # with two pas instances: one at the root set up for
+ # authentications, the other further down with a
+ # `NotCompetent_byRoles` plugin.
+ past = _WrapPluggableAuthServiceTests( )
+ root_pas, request = past._setup_for_authentication( )
+ request.roles = UNSPECIFIED_ROLES
+ request._auth = None
+ request.response = None
+ root = request[ "PARENTS" ][ -1 ]
+ root._setObject(root_pas.getId(), root_pas)
+ test_pas = past._makeOne( past._makePlugins( ) )
+ folder = request[ "PARENTS" ][ -2 ]
+ folder._setObject(test_pas.getId(), test_pas)
+ test_pas = folder._getOb( test_pas.getId( ) ) # ac wrap
+ nc = self._getTargetClass()( "nc" )
+ test_pas._setObject( nc.getId(), nc )
+ self.plugin, self.request = test_pas._getOb( nc.getId( ) ), request
+
+ def test__generateHigherLevelUserFolders( self ):
+ plugin = self.plugin
+ self.assertEqual( len( list( plugin._generateHigherLevelUserFolders( ) ) ), 1)
+
+ def test__getHigherLevelUser( self ):
+ plugin, request = self.plugin, self.request
+ hlu = plugin._getHigherLevelUser( request )
+ self.assertEqual( hlu.getUserName( ), "olivier" )
+
+ def test__getHigherLevelUser_asHamlet( self ):
+ plugin, request = self.plugin, self.request
+ hlu = plugin._getHigherLevelUser( request, ( "Hamlet", ) )
+ self.assertEqual( hlu.getUserName( ), "olivier" )
+
+ def test__getHigherLevelUser_asManager( self ):
+ plugin, request = self.plugin, self.request
+ hlu = plugin._getHigherLevelUser( request, ( "Manager", ) )
+ self.assertEqual( hlu, None)
+
+ def test__getHigherLevelUser_requiresHamlet( self ):
+ plugin, request = self.plugin, self.request
+ request.roles = ( "Hamlet", )
+ hlu = plugin._getHigherLevelUser( request )
+ self.assertEqual( hlu.getUserName( ), "olivier" )
+
+ def test__getHigherLevelUser_requiresManager( self ):
+ plugin, request = self.plugin, self.request
+ request.roles = ( "Manager", )
+ hlu = plugin._getHigherLevelUser( request )
+ self.assertEqual( hlu, None)
+
+ def test_isNotCompetent_any( self ):
+ plugin, request = self.plugin, self.request
+ self.assertEqual( plugin.isNotCompetentToAuthenticate( request ),
+ True
+ )
+
+ def test_isNotCompetent_Hamlet( self ):
+ plugin, request = self.plugin, self.request
+ plugin.manage_changeProperties( roles=( "Hamlet", ) )
+ self.assertEqual( plugin.isNotCompetentToAuthenticate( request ),
+ True
+ )
+
+ def test_isNotCompetent_Manager( self ):
+ plugin, request = self.plugin, self.request
+ plugin.manage_changeProperties( roles=( "Manager", ) )
+ self.assertEqual( plugin.isNotCompetentToAuthenticate( request ),
+ False
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite( NotCompetentHelperTests ),
+ ))
+
+
+
+
Added: Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/www/ncbrAdd.zpt
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/www/ncbrAdd.zpt (rev 0)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/plugins/www/ncbrAdd.zpt 2012-05-25 18:19:18 UTC (rev 126497)
@@ -0,0 +1,47 @@
+<h1 tal:replace="structure here/manage_page_header">Header</h1>
+
+<h2 tal:define="form_title string:Not-Compentent by roles"
+ tal:replace="structure here/manage_form_title">Form Title</h2>
+
+<p class="form-help">
+The plugin prevents this user folder to shaddow higher level authentications with given roles.
+</p>
+
+<form action="manage_addNotCompetent_byRoles" method="post"
+ enctype="multipart/form-data">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="id" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="title" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit"
+ value=" Add " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
+
Modified: Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/conformance.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/conformance.py 2012-05-25 14:48:51 UTC (rev 126496)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/conformance.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -347,3 +347,21 @@
verifyClass( IPropertySheet, self._getTargetClass() )
+
+class INotCompetentPlugin_conformance:
+
+ def test_INotCompetentPlugin_conformance( self ):
+
+ from Products.PluggableAuthService.interfaces.plugins \
+ import INotCompetentPlugin
+
+ verifyClass( INotCompetentPlugin, self._getTargetClass() )
+
+ def test_INotCompetentPlugin_listInterfaces(self):
+
+ from Products.PluggableAuthService.interfaces.plugins \
+ import INotCompetentPlugin
+
+ listed = self._makeOne().listInterfaces()
+ self.failUnless(INotCompetentPlugin.__name__ in listed)
+
Modified: Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/test_PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/test_PluggableAuthService.py 2012-05-25 14:48:51 UTC (rev 126496)
+++ Products.PluggableAuthService/trunk/Products/PluggableAuthService/tests/test_PluggableAuthService.py 2012-05-25 18:19:18 UTC (rev 126497)
@@ -22,6 +22,8 @@
from zExceptions import Unauthorized, Redirect
from Products.PluggableAuthService.utils import directlyProvides
+from zope.interface import implements
+from ..interfaces.plugins import INotCompetentPlugin
from conformance import IUserFolder_conformance
@@ -217,6 +219,20 @@
self.count += 1
return True
+class DummyNotCompetentPlugin( DummyPlugin ):
+ implements( INotCompetentPlugin )
+
+ def __init__( self, id, type ):
+ self.id, self.type = id, type
+
+ def getId( self ): return id
+
+ def isNotCompetentToAuthenticate( self, request ):
+ if self.type is None:
+ raise KeyError("purposeful `KeyError` by `isNotCompetentToAuthenticate`")
+ return self.type
+
+
class FauxRequest( object ):
form = property(lambda self: self)
@@ -924,6 +940,46 @@
finally:
PluggableAuthService.emergency_user = old_eu
+
+
+ def _isNotCompetent_test( self, decisions, result):
+ from Products.PluggableAuthService.interfaces.plugins \
+ import INotCompetentPlugin
+
+ plugins = self._makePlugins( )
+ zcuf = self._makeOne( plugins )
+ plugins = zcuf._getOb("plugins") # acquisition wrap
+
+ for i, decision in enumerate( decisions ):
+ pid = "nc_%d" % i
+ p = DummyNotCompetentPlugin( pid, decision )
+ zcuf._setObject( pid, p )
+ plugins.activatePlugin( INotCompetentPlugin, pid )
+
+ self.assertEqual( zcuf._isNotCompetent( None, plugins ), result )
+
+ def test__isNotCompetent_empty( self ):
+ self._isNotCompetent_test( (), False )
+
+ def test__isNotCompetent_False( self ):
+ self._isNotCompetent_test( (False,), False )
+
+ def test__isNotCompetent_True( self ):
+ self._isNotCompetent_test( (True,), True )
+
+ def test__isNotCompetent_True_False( self ):
+ self._isNotCompetent_test( (True, False), True )
+
+ def test__isNotCompetent_False_True( self ):
+ self._isNotCompetent_test( (False, True), True )
+
+ def test__isNotCompetent_Broken( self ):
+ self._isNotCompetent_test( (None,), False )
+
+ def test__isNotCompetent_Broken_True( self ):
+ self._isNotCompetent_test( (None, True), True )
+
+
def test__getObjectContext_no_steps( self ):
zcuf = self._makeOne()
@@ -1773,6 +1829,82 @@
self.assertEqual( root_validated.getGroups()
, [ 'All People Everywhere Ever' ] )
+ def _setup_for_authentication( self ):
+ """return pas set up for authentication and associated request."""
+
+
+ from Products.PluggableAuthService.interfaces.plugins \
+ import IExtractionPlugin, \
+ IAuthenticationPlugin, \
+ IUserEnumerationPlugin, \
+ IRolesPlugin
+
+ plugins = self._makePlugins()
+ zcuf = self._makeOne( plugins )
+
+ login = DummyPlugin()
+ directlyProvides( login, IExtractionPlugin, IAuthenticationPlugin )
+ login.extractCredentials = _extractLogin
+ login.authenticateCredentials = _authLogin
+ zcuf._setObject( 'login', login )
+
+ nc = DummyNotCompetentPlugin( 'nc', True )
+ zcuf._setObject( 'nc', nc )
+
+ olivier = DummyPlugin()
+ directlyProvides( olivier, IUserEnumerationPlugin, IRolesPlugin )
+ olivier.enumerateUsers = lambda id: id == 'foo' or None
+ olivier.getRolesForPrincipal = lambda user, req: (
+ user.getId() == 'olivier' and ( 'Hamlet', ) or () )
+
+ zcuf._setObject( 'olivier', olivier )
+
+ plugins = zcuf._getOb( 'plugins' )
+ plugins.activatePlugin( IExtractionPlugin, 'login' )
+ plugins.activatePlugin( IAuthenticationPlugin, 'login' )
+ plugins.activatePlugin( IUserEnumerationPlugin, 'olivier' )
+ plugins.activatePlugin( IRolesPlugin, 'olivier' )
+ plugins.activatePlugin( INotCompetentPlugin, 'nc' )
+
+ rc, root, folder, object = self._makeTree()
+
+ index = FauxObject( 'index_html' )
+ index.__roles__ = ( 'Hamlet', )
+ acquired_index = index.__of__( root ).__of__( object )
+
+ request = self._makeRequest( ( 'folder', 'object', 'index_html' )
+ , RESPONSE=FauxResponse()
+ , PARENTS=[ object, folder, root ]
+ , PUBLISHED=acquired_index.__of__( object )
+ , form={ 'login' : 'olivier'
+ , 'password' : 'arras'
+ }
+ )
+
+ return zcuf, request
+
+
+ def _NotCompetent_validate_check( self, is_top ):
+
+ zcuf, request = self._setup_for_authentication( )
+ folder, root = request[ "PARENTS" ][ -2: ]
+
+ wrapped = zcuf.__of__( is_top and root or folder )
+
+ return wrapped.validate( request )
+
+ def test_validate_NotCompetent_isTop( self ):
+ self.assertEqual(
+ self._NotCompetent_validate_check( True ).getUserName(),
+ 'olivier'
+ )
+
+ def test_validate_NotCompetent_not_isTop( self ):
+ self.assertEqual(
+ self._NotCompetent_validate_check( False ),
+ None
+ )
+
def testAllowGroupsAttribute(self):
# Verify that __allow_groups__ gets set and removed
from OFS.Folder import Folder
More information about the checkins
mailing list