[Checkins] SVN: Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/ Tests for login_transform on PAS.

Maurits van Rees cvs-admin at zope.org
Thu Jan 3 12:48:06 UTC 2013


Log message for revision 128991:
  Tests for login_transform on PAS.

Changed:
  U   Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/PluggableAuthService.py
  U   Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/tests/test_PluggableAuthService.py

-=-
Modified: Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/PluggableAuthService.py	2013-01-03 10:42:26 UTC (rev 128990)
+++ Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/PluggableAuthService.py	2013-01-03 12:48:05 UTC (rev 128991)
@@ -1082,8 +1082,8 @@
             return value
         transform = getattr(self, login_transform.strip(), None)
         if transform is None:
-            LOG.debug("Transform method %r not found in plugin %r.",
-                      self.login_transform, self)
+            logger.debug("Transform method %r not found in plugin %r.",
+                         self.login_transform, self)
             return value
         return transform(value)
 

Modified: Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/tests/test_PluggableAuthService.py
===================================================================
--- Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/tests/test_PluggableAuthService.py	2013-01-03 10:42:26 UTC (rev 128990)
+++ Products.PluggableAuthService/branches/maurits-login-transform/Products/PluggableAuthService/tests/test_PluggableAuthService.py	2013-01-03 12:48:05 UTC (rev 128991)
@@ -935,8 +935,89 @@
         finally:
             PluggableAuthService.emergency_user = old_eu
 
+    def test__extractUserIds_transform( self ):
 
+        from Products.PluggableAuthService.interfaces.plugins \
+            import IExtractionPlugin, IAuthenticationPlugin
 
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+
+        login = DummyPlugin()
+        directlyProvides( login, IExtractionPlugin, IAuthenticationPlugin )
+        login.extractCredentials = _extractLogin
+        login.authenticateCredentials = _authLogin
+        zcuf._setObject( 'login', login )
+        # Make login names lowercase.  User ids are not affected, but
+        # our dummy _authLogin simply reports a tuple with twice the
+        # login name.
+        zcuf.login_transform = 'lower'
+
+        plugins = zcuf._getOb( 'plugins' )
+        plugins.activatePlugin( IExtractionPlugin, 'login' )
+        plugins.activatePlugin( IAuthenticationPlugin, 'login' )
+
+        # Mixed case here.
+        request = self._makeRequest( form={ 'login' : 'Foo'
+                                          , 'password' : 'Bar' } )
+
+        user_ids = zcuf._extractUserIds( request=request
+                                       , plugins=zcuf.plugins
+                                       )
+
+        self.assertEqual( len( user_ids ), 1 )
+        # Lower case here.
+        self.assertEqual( user_ids[0][0], 'foo' )
+
+    def test__extractUserIds_emergency_user_always_wins_in_transform( self ):
+
+        from Products.PluggableAuthService.interfaces.plugins \
+            import IExtractionPlugin, IAuthenticationPlugin
+
+        from AccessControl.User import UnrestrictedUser
+
+        from Products.PluggableAuthService import PluggableAuthService
+
+        old_eu = PluggableAuthService.emergency_user
+
+        # Mixed case here.  We want to test if an emergency user with
+        # mixed (or upper) case login name is found also when the
+        # login_transform is to lower case the login.
+        eu = UnrestrictedUser( 'Foo', 'Bar', ( 'manage', ), () )
+
+        PluggableAuthService.emergency_user = eu
+
+        try:
+            plugins = self._makePlugins()
+            zcuf = self._makeOne( plugins )
+
+            login = DummyPlugin()
+            directlyProvides( login, IExtractionPlugin, IAuthenticationPlugin )
+            login.extractCredentials = lambda req: {'login': 'baz', 'password': ''}
+            login.authenticateCredentials = _authLogin
+
+            zcuf._setObject( 'login', login )
+            zcuf.login_transform = 'lower'
+
+            plugins = zcuf._getOb( 'plugins' )
+
+            plugins.activatePlugin( IExtractionPlugin, 'login' )
+            plugins.activatePlugin( IAuthenticationPlugin, 'login' )
+
+            request = self._makeRequest( form={ 'login' : eu.getUserName()
+                                              , 'password' : eu._getPassword() } )
+
+            # This should authenticate the emergency user and not 'baz'
+            user_ids = zcuf._extractUserIds( request=request
+                                           , plugins=zcuf.plugins
+                                           )
+
+            self.assertEqual( len( user_ids ), 1 )
+            self.assertEqual( user_ids[0][0], 'Foo' )
+        finally:
+            PluggableAuthService.emergency_user = old_eu
+
+
     def _isNotCompetent_test( self, decisions, result):
         from Products.PluggableAuthService.interfaces.plugins \
             import INotCompetentPlugin
@@ -1224,7 +1305,67 @@
                          None)
         self.assertEqual(zcuf._verifyUser(plugins), None)
 
+    def test__verifyUser_login_transform_lower( self ):
 
+        from Products.PluggableAuthService.interfaces.plugins \
+             import IUserEnumerationPlugin
+
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+        zcuf.login_transform = 'lower'
+
+        enumerator = DummyMultiUserEnumerator(
+            'enumerator',
+            {'id': 'Foo', 'login': 'foobar'},
+            {'id': 'Bar', 'login': 'BAR'})
+        directlyProvides( enumerator, IUserEnumerationPlugin )
+        zcuf._setObject( 'enumerator', enumerator )
+
+        plugins = zcuf._getOb( 'plugins' )
+
+        plugins.activatePlugin( IUserEnumerationPlugin, 'enumerator' )
+
+        # No matter what we try as login parameter, it is always lower
+        # cased before verifying a user.
+        self.failIf(zcuf._verifyUser(plugins, login='BAR'))
+        self.failIf(zcuf._verifyUser(plugins, login='Bar'))
+        self.failIf(zcuf._verifyUser(plugins, login='bar'))
+        self.failUnless(
+            zcuf._verifyUser(plugins, login='FOOBAR')['id'] == 'Foo')
+        self.failUnless(
+            zcuf._verifyUser(plugins, login='Foobar')['id'] == 'Foo')
+        self.failUnless(
+            zcuf._verifyUser(plugins, login='foobar')['id'] == 'Foo')
+
+    def test__verifyUser_login_transform_upper( self ):
+
+        from Products.PluggableAuthService.interfaces.plugins \
+             import IUserEnumerationPlugin
+
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+        zcuf.login_transform = 'upper'
+
+        enumerator = DummyMultiUserEnumerator(
+            'enumerator',
+            {'id': 'Foo', 'login': 'foobar'},
+            {'id': 'Bar', 'login': 'BAR'})
+        directlyProvides( enumerator, IUserEnumerationPlugin )
+        zcuf._setObject( 'enumerator', enumerator )
+
+        plugins = zcuf._getOb( 'plugins' )
+
+        plugins.activatePlugin( IUserEnumerationPlugin, 'enumerator' )
+
+        # No matter what we try as login parameter, it is always upper
+        # cased before verifying a user.
+        self.failUnless(zcuf._verifyUser(plugins, login='BAR')['id'] == 'Bar')
+        self.failUnless(zcuf._verifyUser(plugins, login='Bar')['id'] == 'Bar')
+        self.failUnless(zcuf._verifyUser(plugins, login='bar')['id'] == 'Bar')
+        self.failIf(zcuf._verifyUser(plugins, login='FOOBAR'))
+        self.failIf(zcuf._verifyUser(plugins, login='Foobar'))
+        self.failIf(zcuf._verifyUser(plugins, login='foobar'))
+
     def test__findUser_no_plugins( self ):
 
         plugins = self._makePlugins()
@@ -1289,6 +1430,42 @@
 
         self.failUnless( faux_user.__class__ is FauxUser )
 
+    def test__findUser_with_userfactory_plugin_and_transform( self ):
+
+        from Products.PluggableAuthService.interfaces.plugins \
+            import IUserFactoryPlugin
+
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+        zcuf.login_transform = 'lower'
+
+        bar = DummyPlugin()
+        directlyProvides( bar, IUserFactoryPlugin )
+
+        def _makeUser( user_id, name ):
+            user = FauxUser( user_id )
+            user._name = name
+            return user
+
+        bar.createUser = _makeUser
+
+        zcuf._setObject( 'bar', bar )
+
+        plugins = zcuf._getOb( 'plugins' )
+
+        real_user = zcuf._findUser( plugins, 'Mixed', 'Case' )
+        self.failIf( real_user.__class__ is FauxUser )
+
+        plugins.activatePlugin( IUserFactoryPlugin , 'bar' )
+
+        faux_user = zcuf._findUser( plugins, 'Mixed', 'Case' )
+
+        self.assertEqual( faux_user.getId(), 'Mixed' )
+        # This is lower case:
+        self.assertEqual( faux_user.getUserName(), 'case' )
+
+        self.failUnless( faux_user.__class__ is FauxUser )
+
     def test__findUser_with_plugins( self ):
 
         from Products.PluggableAuthService.interfaces.plugins \
@@ -1608,6 +1785,35 @@
         self.assertEqual( user2.getId(), 'bar/bar')
         self.assertEqual( user2.getUserName(), 'bar at example.com' )
 
+    def test_getUser_login_transform( self ):
+        from Products.PluggableAuthService.interfaces.plugins \
+             import IUserEnumerationPlugin
+
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+        zcuf.login_transform = 'lower'
+
+        # The login_transform is applied in PAS, so we need to lower
+        # case the login ourselves in this test when passing it to a
+        # plugin.
+        bar = self._makeUserEnumerator( 'bar', 'bar at example.com' )
+        bar.identifier = 'bar/'
+        zcuf._setObject( 'bar', bar )
+
+        zcuf.plugins.activatePlugin(IUserEnumerationPlugin, 'bar')
+        # Fetch the new user by ID and name, and check we get the same.
+        user = zcuf.getUserById('bar/bar')
+        self.assertEqual( user.getId(), 'bar/bar')
+        self.assertEqual( user.getUserName(), 'bar at example.com' )
+
+        user2 = zcuf.getUser('bar at example.com')
+        self.assertEqual( user2.getId(), 'bar/bar')
+        self.assertEqual( user2.getUserName(), 'bar at example.com' )
+
+        user3 = zcuf.getUser('Bar at Example.Com')
+        self.assertEqual( user3.getId(), 'bar/bar')
+        self.assertEqual( user3.getUserName(), 'bar at example.com' )
+
     def test_simple_getUserGroups_with_Groupplugin(self):
 
         from Products.PluggableAuthService.interfaces.plugins \
@@ -1779,6 +1985,60 @@
         validated = wrapped.validate( request )
         self.assertEqual( validated.getUserName(), 'olivier' )
 
+    def test_validate_simple_authenticated_transform( self ):
+
+        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 )
+        # Lower case all logins.
+        zcuf.login_transform = 'lower'
+
+        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' )
+
+        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'
+                                          }
+                                   )
+
+
+        wrapped = zcuf.__of__( root )
+
+        validated = wrapped.validate( request )
+        self.assertEqual( validated.getUserName(), 'olivier' )
+
     def test_validate_with_anonymous_factory( self ):
 
         from Products.PluggableAuthService.interfaces.plugins \
@@ -2035,7 +2295,45 @@
         self.failUnless(
             len( zcuf.searchPrincipals(id='group')) == 1 )
 
+    def test_searchPrincipals_transform( self ):
 
+        from Products.PluggableAuthService.interfaces.plugins \
+             import IUserEnumerationPlugin
+        from Products.PluggableAuthService.interfaces.plugins \
+             import IGroupEnumerationPlugin
+
+        plugins = self._makePlugins()
+        zcuf = self._makeOne( plugins )
+        zcuf.login_transform = 'lower'
+
+        foo = self._makeUserEnumerator( 'foo' )
+        zcuf._setObject( 'foo', foo )
+        foobar = self._makeGroupEnumerator( 'Foobar' )
+        zcuf._setObject( 'foobar', foobar )
+
+        plugins = zcuf._getOb( 'plugins' )
+        plugins.activatePlugin( IUserEnumerationPlugin, 'foo' )
+        plugins.activatePlugin( IGroupEnumerationPlugin, 'foobar' )
+
+        self.failIf( zcuf.searchPrincipals( name='zope' ) )
+        # Note that groups are never found by name, only by id.
+        self.failUnless( len( zcuf.searchPrincipals( name='foo' ) ) == 1 )
+        user1 = zcuf.searchPrincipals( name='foo' )[0]
+        self.assertEqual(user1['principal_type'], 'user')
+        self.assertEqual(user1['id'], 'foo')
+        self.assertEqual(user1['login'], 'foo')
+
+        # Search for mixed case.
+        self.failUnless( len( zcuf.searchPrincipals( name='Foo' ) ) == 1 )
+        user2 = zcuf.searchPrincipals( name='Foo' )[0]
+        self.assertEqual(user1, user2)
+
+        # Search for upper case.
+        self.failUnless( len( zcuf.searchPrincipals( name='FOO' ) ) == 1 )
+        user3 = zcuf.searchPrincipals( name='FOO' )[0]
+        self.assertEqual(user1, user3)
+
+
     def test_no_challenger(self):
         # make sure that the response's _unauthorized gets propogated
         # if no challengers exist (or have fired)
@@ -2223,6 +2521,32 @@
         extracted = creds_store.extractCredentials(request)
         self.failUnless(len(extracted.keys()) == 0)
 
+    def test_applyTransform( self ):
+        zcuf = self._makeOne()
+        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
+        zcuf.login_transform =  'lower'
+        self.assertEqual(zcuf.applyTransform(' User '), 'user')
+        self.assertEqual(zcuf.applyTransform(u' User '), u'user')
+        self.assertEqual(zcuf.applyTransform(''), '')
+        self.assertEqual(zcuf.applyTransform(None), None)
+        self.assertRaises(AttributeError, zcuf.applyTransform, 123)
+        self.assertRaises(AttributeError, zcuf.applyTransform, ['User'])
+        zcuf.login_transform =  'upper'
+        self.assertEqual(zcuf.applyTransform(' User '), 'USER')
+        # Let's not fail just because a user has accidentally left a
+        # space at the end of the login_transform name.  That could
+        # lead to hard-to-debug behaviour.
+        zcuf.login_transform =  ' upper  '
+        self.assertEqual(zcuf.applyTransform(' User '), 'USER')
+        # We would want to test what happens when the login_transform
+        # attribute is not there, but the following only removes it
+        # from the instance, not the class.  Oh well.
+        del zcuf.login_transform
+        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
+        zcuf.login_transform =  'nonexisting'
+        self.assertEqual(zcuf.applyTransform(' User '), ' User ')
+
+
 if __name__ == "__main__":
     unittest.main()
 



More information about the checkins mailing list