Back to index

plone3  3.1.7
test_DynamicGroupsPlugin.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE.
00013 #
00014 ##############################################################################
00015 """ Unit tests for DynamicGroupsPlugin
00016 
00017 $Id: test_DynamicGroupsPlugin.py 73968 2007-04-01 20:13:59Z alecm $
00018 """
00019 import unittest
00020 
00021 from Products.PluggableAuthService.tests.conformance \
00022     import IGroupsPlugin_conformance
00023 from Products.PluggableAuthService.tests.conformance \
00024     import IGroupEnumerationPlugin_conformance
00025 from Products.PluggableAuthService.tests.utils import _setUpDefaultTraversable
00026 
00027 from Products.PluggableAuthService.plugins.tests.helpers \
00028      import makeRequestAndResponse
00029 
00030 class FauxScript:
00031 
00032 
00033     def __init__( self, id, return_value=0 ):
00034 
00035         self._id = id
00036         self.return_value = return_value
00037 
00038     def __call__( self, *args, **kw ):
00039 
00040         return self.return_value
00041 
00042 class FauxPrincipal:
00043 
00044     __allow_access_to_unprotected_subobjects__ = 1
00045 
00046     def __init__( self, id ):
00047         self._id = id
00048 
00049     def getId( self ):
00050         return self._id
00051 
00052 class DynamicGroupsPlugin( unittest.TestCase
00053                          , IGroupsPlugin_conformance
00054                          , IGroupEnumerationPlugin_conformance
00055                          ):
00056 
00057     def _getTargetClass( self ):
00058 
00059         from Products.PluggableAuthService.plugins.DynamicGroupsPlugin \
00060             import DynamicGroupsPlugin
00061 
00062         return DynamicGroupsPlugin
00063 
00064     def _makeOne( self, id='test', *args, **kw ):
00065 
00066         return self._getTargetClass()( id, *args, **kw )
00067 
00068     def test_empty( self ):
00069 
00070         dpg = self._makeOne( 'empty' )
00071 
00072         self.assertEqual( len( dpg.listGroupIds() ), 0 )
00073         self.assertEqual( len( dpg.listGroupInfo() ), 0 )
00074         self.assertEqual( len( dpg.enumerateGroups() ), 0 )
00075 
00076     def test_addGroup_simple( self ):
00077 
00078         dpg = self._makeOne( 'adding' )
00079 
00080         dpg.addGroup( 'everyone', 'python:True', 'title', 'description', True )
00081 
00082         self.assertEqual( len( dpg.listGroupIds() ), 1 )
00083         self.failUnless( 'everyone' in dpg.listGroupIds() )
00084 
00085         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00086         info = dpg.listGroupInfo()[0]
00087 
00088         self.assertEqual( info[ 'id' ], 'everyone' )
00089         self.assertEqual( info[ 'title' ], 'title' )
00090         self.assertEqual( info[ 'description' ], 'description' )
00091         self.assertEqual( info[ 'predicate' ], 'python:True' )
00092         self.assertEqual( info[ 'active' ], True )
00093 
00094     def test_addGroup_duplicate( self ):
00095 
00096         dpg = self._makeOne( 'adding_duplicate' )
00097 
00098         dpg.addGroup( 'everyone', 'python:True', 'title', 'description', True )
00099 
00100         self.assertRaises( KeyError
00101                          , dpg.addGroup
00102                          , 'everyone'
00103                          , 'python:False'
00104                          , 'other title'
00105                          , 'other descripton'
00106                          , False )
00107 
00108         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00109         info = dpg.listGroupInfo()[0]
00110 
00111         self.assertEqual( info[ 'id' ], 'everyone' )
00112         self.assertEqual( info[ 'predicate' ], 'python:True' )
00113         self.assertEqual( info[ 'title' ], 'title' )
00114         self.assertEqual( info[ 'description' ], 'description' )
00115         self.assertEqual( info[ 'active' ], True )
00116 
00117     def test_removeGroup_nonesuch( self ):
00118 
00119         dpg = self._makeOne( 'removing_nonesuch' )
00120 
00121         self.assertRaises( KeyError, dpg.removeGroup, 'everyone' )
00122 
00123     def test_removeGroup( self ):
00124 
00125         dpg = self._makeOne( 'removing' )
00126 
00127         dpg.addGroup( 'everyone', predicate='python:True' )
00128         dpg.addGroup( 'beast', predicate='python:666' )
00129         dpg.addGroup( 'noone', predicate='python:False' )
00130 
00131         self.assertEqual( len( dpg.listGroupIds() ), 3 )
00132         self.failUnless( 'everyone' in dpg.listGroupIds() )
00133         self.failUnless( 'beast' in dpg.listGroupIds() )
00134         self.failUnless( 'noone' in dpg.listGroupIds() )
00135 
00136         info_list = dpg.listGroupInfo()
00137         self.assertEqual( len( info_list ), 3 )
00138 
00139         ids = [ x[ 'id' ] for x in info_list ]
00140         self.failUnless( 'everyone' in ids )
00141         self.failUnless( 'beast' in ids )
00142         self.failUnless( 'noone' in ids )
00143 
00144         dpg.removeGroup( 'beast' )
00145 
00146         self.assertEqual( len( dpg.listGroupIds() ), 2 )
00147         self.failUnless( 'everyone' in dpg.listGroupIds() )
00148         self.failIf( 'beast' in dpg.listGroupIds() )
00149         self.failUnless( 'noone' in dpg.listGroupIds() )
00150 
00151         info_list = dpg.listGroupInfo()
00152         self.assertEqual( len( info_list ), 2 )
00153 
00154         ids = [ x[ 'id' ] for x in info_list ]
00155         self.failUnless( 'everyone' in ids )
00156         self.failIf( 'beast' in ids )
00157         self.failUnless( 'noone' in ids )
00158 
00159     def test_updateGroup_nonesuch( self ):
00160 
00161         dpg = self._makeOne( 'updating_nonesuch' )
00162 
00163         self.assertRaises( KeyError, dpg.updateGroup
00164                          , 'everyone', 'title', True )
00165 
00166     def test_updateGroup_simple( self ):
00167 
00168         dpg = self._makeOne( 'updating_simple' )
00169 
00170         dpg.addGroup( 'noone', predicate='python:False' )
00171 
00172         self.assertEqual( len( dpg.listGroupIds() ), 1 )
00173         self.failUnless( 'noone' in dpg.listGroupIds() )
00174 
00175         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00176         info = dpg.listGroupInfo()[0]
00177 
00178         self.assertEqual( info[ 'id' ], 'noone' )
00179         self.assertEqual( info[ 'predicate' ], 'python:False' )
00180         self.assertEqual( info[ 'title' ], '' )
00181         self.assertEqual( info[ 'description' ], '' )
00182         self.assertEqual( info[ 'active' ], True )
00183 
00184         dpg.updateGroup( 'noone', 'python:True', 'title', 'description', False )
00185 
00186         self.assertEqual( len( dpg.listGroupIds() ), 1 )
00187         self.failUnless( 'noone' in dpg.listGroupIds() )
00188 
00189         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00190         info = dpg.listGroupInfo()[0]
00191 
00192         self.assertEqual( info[ 'id' ], 'noone' )
00193         self.assertEqual( info[ 'predicate' ], 'python:True' )
00194         self.assertEqual( info[ 'title' ], 'title' )
00195         self.assertEqual( info[ 'description' ], 'description' )
00196         self.assertEqual( info[ 'active' ], False )
00197 
00198     def test_updateGroup_partial( self ):
00199 
00200         dpg = self._makeOne( 'updating_partial' )
00201 
00202         dpg.addGroup( 'everyone', 'python:True', 'title', 'description', True )
00203 
00204         self.assertEqual( len( dpg.listGroupIds() ), 1 )
00205         self.failUnless( 'everyone' in dpg.listGroupIds() )
00206 
00207         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00208         info = dpg.listGroupInfo()[0]
00209 
00210         self.assertEqual( info[ 'id' ], 'everyone' )
00211         self.assertEqual( info[ 'predicate' ], 'python:True' )
00212         self.assertEqual( info[ 'title' ], 'title' )
00213         self.assertEqual( info[ 'description' ], 'description' )
00214         self.assertEqual( info[ 'active' ], True )
00215 
00216         dpg.updateGroup( 'everyone', predicate='python:False' )
00217 
00218         self.assertEqual( len( dpg.listGroupIds() ), 1 )
00219         self.failUnless( 'everyone' in dpg.listGroupIds() )
00220 
00221         self.assertEqual( len( dpg.listGroupInfo() ), 1 )
00222         info = dpg.listGroupInfo()[0]
00223 
00224         self.assertEqual( info[ 'id' ], 'everyone' )
00225         self.assertEqual( info[ 'predicate' ], 'python:False' )
00226         self.assertEqual( info[ 'title' ], 'title' )
00227         self.assertEqual( info[ 'description' ], 'description' )
00228         self.assertEqual( info[ 'active' ], True )
00229 
00230     def test_enumerateGroups_all( self ):
00231 
00232         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00233             import FauxRoot
00234 
00235         root = FauxRoot()
00236         dpg = self._makeOne( 'enumerating' ).__of__( root )
00237 
00238         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00239         dpg.addGroup( 'noone', 'python:False', active=True )
00240         dpg.addGroup( 'hohum', 'nothing', active=True )
00241 
00242         info_list = dpg.enumerateGroups()
00243 
00244         self.assertEqual( len( info_list ), 3 )
00245 
00246         ids = [ x[ 'id' ] for x in info_list ]
00247 
00248         self.failUnless( 'everyone' in ids )
00249         self.failUnless( 'noone' in ids )
00250         self.failUnless( 'hohum' in ids )
00251 
00252     def test_enumerateGroups_exact_list( self ):
00253 
00254         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00255             import FauxRoot
00256 
00257         root = FauxRoot()
00258         dpg = self._makeOne( 'enumerating' ).__of__( root )
00259 
00260         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00261         dpg.addGroup( 'noone', 'python:False', active=True )
00262         dpg.addGroup( 'hohum', 'nothing', active=True )
00263 
00264         ID_LIST = ( 'everyone', 'noone' )
00265 
00266         info_list = dpg.enumerateGroups( id=ID_LIST, exact_match=True )
00267 
00268         self.assertEqual( len( info_list ), len( ID_LIST ) )
00269 
00270         ids = [ x[ 'id' ] for x in info_list ]
00271 
00272         for id in ID_LIST:
00273             self.failUnless( id in ids )
00274 
00275     def test_enumerateGroups_exact_one( self ):
00276 
00277         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00278             import FauxRoot
00279 
00280         root = FauxRoot()
00281         dpg = self._makeOne( 'enumerating' ).__of__( root )
00282 
00283         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00284         dpg.addGroup( 'noone', 'python:False', active=True )
00285         dpg.addGroup( 'hohum', 'nothing', active=True )
00286 
00287         info_list = dpg.enumerateGroups( id='noone', exact_match=True )
00288 
00289         self.assertEqual( len( info_list ), 1 )
00290         info = info_list[ 0 ]
00291 
00292         self.assertEqual( info[ 'id' ], 'noone' )
00293         self.assertEqual( info[ 'title' ], '' )
00294         self.assertEqual( info[ 'description' ], '' )
00295         self.assertEqual( info[ 'active' ], True )
00296         self.assertEqual( info[ 'predicate' ], 'python:False' )
00297         self.assertEqual( info[ 'pluginid' ], 'enumerating' )
00298 
00299         # Because teher is no proper REQUEST, the properties_url will be incorrect
00300         # It should normally be  '/enumerating/noone/manage_propertiesForm'
00301         # But it will be '//noone/manage_propertiesForm'
00302         URL = '//noone/manage_propertiesForm'
00303         self.assertEqual( info[ 'properties_url' ], URL )
00304         self.assertEqual( info[ 'members_url' ], URL )
00305 
00306     def test_enumerateGroups_skip_inactive( self ):
00307 
00308         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00309             import FauxRoot
00310 
00311         root = FauxRoot()
00312         dpg = self._makeOne( 'enumerating' ).__of__( root )
00313 
00314         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00315         dpg.addGroup( 'noone', 'python:False', active=True )
00316         dpg.addGroup( 'inactive', 'nothing', active=False )
00317 
00318         info_list = dpg.enumerateGroups()
00319 
00320         self.assertEqual( len( info_list ), 2 )
00321 
00322         ids = [ x[ 'id' ] for x in info_list ]
00323 
00324         self.failUnless( 'everyone' in ids )
00325         self.failUnless( 'noone' in ids )
00326         self.failIf( 'inactive' in ids )
00327 
00328     def test_getGroupsForPrincipal_empty( self ):
00329 
00330         dpg = self._makeOne( 'ggp_request' )
00331         principal = FauxPrincipal( 'faux' )
00332 
00333         groups = dpg.getGroupsForPrincipal( principal )
00334 
00335         self.assertEqual( len( groups ), 0 )
00336 
00337     def test_getGroupsForPrincipal_principal( self ):
00338 
00339         dpg = self._makeOne( 'ggp_principal' )
00340         principal = FauxPrincipal( 'faux' )
00341 
00342         dpg.addGroup( 'effable', 'python:principal.getId().startswith("f")' )
00343         groups = dpg.getGroupsForPrincipal( principal, {} )
00344         self.assertEqual( len( groups ), 1 )
00345         self.failUnless( 'effable' in groups )
00346 
00347     def test_getGroupsForPrincipal_python( self ):
00348 
00349         dpg = self._makeOne( 'ggp_python' )
00350         principal = FauxPrincipal( 'faux' )
00351 
00352         dpg.addGroup( 'everyone', 'python:1' )
00353         groups = dpg.getGroupsForPrincipal( principal, {} )
00354         self.assertEqual( len( groups ), 1 )
00355         self.failUnless( 'everyone' in groups )
00356 
00357     def test_getGroupsForPrincipal_request( self ):
00358 
00359         _setUpDefaultTraversable()
00360         dpg = self._makeOne( 'ggp_request' )
00361         principal = FauxPrincipal( 'faux' )
00362 
00363         dpg.addGroup( 'local', 'request/is_local | nothing' )
00364 
00365         groups = dpg.getGroupsForPrincipal( principal, {} )
00366 
00367         self.assertEqual( len( groups ), 0 )
00368 
00369         groups = dpg.getGroupsForPrincipal( principal, { 'is_local' : 0 } )
00370 
00371         self.assertEqual( len( groups ), 0 )
00372 
00373         groups = dpg.getGroupsForPrincipal( principal, { 'is_local' : 1 } )
00374 
00375         self.assertEqual( len( groups ), 1 )
00376         self.failUnless( 'local' in groups )
00377 
00378     def test_getGroupsForPrincipal_group( self ):
00379 
00380         _setUpDefaultTraversable()
00381         dpg = self._makeOne( 'ggp_group' )
00382         principal = FauxPrincipal( 'faux' )
00383 
00384         dpg.addGroup( 'willing', 'group/willing' )
00385         dpg.willing._setProperty( 'willing', type='boolean', value=0 )
00386 
00387         groups = dpg.getGroupsForPrincipal( principal, {} )
00388         self.assertEqual( len( groups ), 0 )
00389 
00390         dpg.willing._updateProperty( 'willing', 1 )
00391         groups = dpg.getGroupsForPrincipal( principal, {} )
00392         self.assertEqual( len( groups ), 1 )
00393         self.failUnless( 'willing' in groups )
00394 
00395     def test_getGroupsForPrincipal_plugin_nope( self ):
00396 
00397         dpg = self._makeOne( 'ggp_plugin' )
00398         principal = FauxPrincipal( 'faux' )
00399 
00400         dpg.addGroup( 'scripted', 'python: plugin.callme(request)' )
00401         callme = FauxScript( 'callme', 0 )
00402         dpg._setOb( 'callme', callme )
00403 
00404         groups = dpg.getGroupsForPrincipal( principal, {} )
00405         self.assertEqual( len( groups ), 0 )
00406 
00407     def test_getGroupsForPrincipal_plugin_ok( self ):
00408 
00409         dpg = self._makeOne( 'ggp_plugin' )
00410         principal = FauxPrincipal( 'faux' )
00411 
00412         dpg.addGroup( 'scripted', 'python: plugin.callme(request)' )
00413         callme = FauxScript( 'callme', 1 )
00414         dpg._setOb( 'callme', callme )
00415 
00416         groups = dpg.getGroupsForPrincipal( principal, {} )
00417         self.assertEqual( len( groups ), 1 )
00418         self.failUnless( 'scripted' in groups )
00419 
00420     def test_enumerateGroups_matching_with_optional_prefix( self ):
00421 
00422         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00423             import FauxRoot
00424 
00425         root = FauxRoot()
00426         dpg = self._makeOne( 'enumerating' ).__of__( root )
00427         dpg.prefix = 'enumerating_'
00428 
00429         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00430         dpg.addGroup( 'noone', 'python:False', active=True )
00431         dpg.addGroup( 'hohum', 'nothing', active=True )
00432 
00433         ID_LIST = ( 'enumerating_everyone', )
00434 
00435         info_list = dpg.enumerateGroups( id=ID_LIST, exact_match=True )
00436 
00437         self.assertEqual( len( info_list ), len( ID_LIST ) )
00438 
00439         ids = [ x[ 'id' ] for x in info_list ]
00440 
00441         for id in ID_LIST:
00442             self.failUnless( id in ids )
00443 
00444     def test_enumerateGroups_enumerating_with_optional_prefix( self ):
00445 
00446         from Products.PluggableAuthService.tests.test_PluggableAuthService \
00447             import FauxRoot
00448 
00449         root = FauxRoot()
00450         dpg = self._makeOne( 'enumerating' ).__of__( root )
00451         dpg.prefix = 'enumerating_'
00452 
00453         dpg.addGroup( 'everyone', 'python:True', 'Everyone', '', True )
00454         dpg.addGroup( 'noone', 'python:False', active=True )
00455         dpg.addGroup( 'hohum', 'nothing', active=True )
00456 
00457         ID_LIST = ( 'enumerating_everyone', 'enumerating_noone',
00458                     'enumerating_hohum' )
00459 
00460         info_list = dpg.enumerateGroups()
00461 
00462         self.assertEqual( len( info_list ), len( ID_LIST ) )
00463 
00464         ids = [ x[ 'id' ] for x in info_list ]
00465 
00466         for id in ID_LIST:
00467             self.failUnless( id in ids )
00468 
00469     def test_getGroupsForPrincipal_optional_prefix( self ):
00470 
00471         dpg = self._makeOne( 'ggp_prefixed' )
00472         dpg.prefix = 'ggp_'
00473 
00474         principal = FauxPrincipal( 'faux' )
00475 
00476         dpg.addGroup( 'effable', 'python:principal.getId().startswith("f")' )
00477         groups = dpg.getGroupsForPrincipal( principal, {} )
00478         self.assertEqual( len( groups ), 1 )
00479         self.failUnless( 'ggp_effable' in groups )
00480 
00481     def testPOSTProtections(self):
00482         from zExceptions import Forbidden
00483 
00484         GROUP_ID = 'testgroup'
00485 
00486         dpg = self._makeOne( 'adding' )
00487 
00488         dpg.addGroup( GROUP_ID, 'python:True', 'title', 'description', True )
00489 
00490         req, res = makeRequestAndResponse()
00491 
00492         req.set('REQUEST_METHOD', 'GET')
00493 
00494         # Fails with a GET
00495         # test removeGroup
00496         req.set('REQUEST_METHOD', 'GET')
00497         self.assertRaises(Forbidden, dpg.removeGroup,
00498                           GROUP_ID, REQUEST=req)
00499         # Works with a POST
00500         req.set('REQUEST_METHOD', 'POST')
00501         dpg.removeGroup(GROUP_ID, REQUEST=req)
00502 
00503 if __name__ == "__main__":
00504     unittest.main()
00505 
00506 def test_suite():
00507     return unittest.TestSuite((
00508         unittest.makeSuite( DynamicGroupsPlugin ),
00509         ))