@@ -0,0 +1,3232 @@
+import time%0Afrom ldaptor.protocols import pureldap%0Afrom ldaptor.protocols.ldap import ldaperrors%0Afrom ldaptor.protocols.ldap.ldapsyntax import LDAPEntry%0Afrom twisted.internet import defer%0A%0Afrom pi_ldapproxy.test.util import ProxyTestCase%0A%0A%0Aclass TestProxyUserBind(ProxyTestCase):%0A    privacyidea_credentials = %7B%0A        'hugo@default': 'secret',%0A    %7D%0A%0A    additional_config = %7B%0A        'bind-cache': %7B%0A            'enabled': True,%0A            'timeout': 2,%0A        %7D%0A    %7D%0A%0A    @defer.inlineCallbacks%0A    def test_simple_bind_succeeds(self):%0A        dn = 'uid=hugo,cn=users,dc=test,dc=local'%0A        server, client = self.create_server_and_client()%0A        yield client.bind(dn, 'secret')%0A        self.assertEqual(self.privacyidea.authentication_requests,%0A                         %5B('hugo', 'default', 'secret', True)%5D)%0A        time.sleep(3) # clean bind cache%0A%0A    @defer.inlineCallbacks%0A    def test_subsequent_binds_succeed(self):%0A        dn = 'uid=hugo,cn=users,dc=test,dc=local'%0A        server, client = self.create_server_and_client(%5B%0A            pureldap.LDAPBindResponse(resultCode=0), # for service account%0A        %5D,%0A        %5B%0A            pureldap.LDAPBindResponse(resultCode=0),  # for service account%0A        %5D,%0A        )%0A        yield client.bind(dn, 'secret')%0A        time.sleep(0.5)%0A        yield client.bind(dn, 'secret')%0A        # but only one authentication request to privacyIDEA!%0A        self.assertEqual(self.privacyidea.authentication_requests,%0A                         %5B('hugo', 'default', 'secret', True)%5D)%0A        time.sleep(2) # to clean the reactor%0A%0A    @defer.inlineCallbacks%0A    def test_bind_cache_cleared(self):%0A        dn = 'uid=hugo,cn=users,dc=test,dc=local'%0A        server, client = self.create_server_and_client(%5B%0A            pureldap.LDAPBindResponse(resultCode=0), # for service account%0A        %5D,%0A        %5B%0A            pureldap.LDAPBindResponse(resultCode=0),  # for service account%0A        %5D,%0A        )%0A        yield client.bind(dn, 'secret')%0A        time.sleep(3) # which cleans the bind cache%0A        yield client.bind(dn, 'secret')%0A        # two authentication requests to privacyIDEA!%0A        self.assertEqual(self.privacyidea.authentication_requests,%0A                         %5B('hugo', 'default', 'secret', True),%0A                          ('hugo', 'default', 'secret', True)%5D)%0A        time.sleep(2) # to clean the reactor%0A%0A    @defer.inlineCallbacks%0A    def test_bind_cache_different_password(self):%0A        dn = 'uid=hugo,cn=users,dc=test,dc=local'%0A        server, client = self.create_server_and_client(%5B%0A            pureldap.LDAPBindResponse(resultCode=0), # for service account%0A        %5D,%0A        %5B%0A            pureldap.LDAPBindResponse(resultCode=0),  # for service account%0A        %5D,%0A        )%0A        yield client.bind(dn, 'secret')%0A        time.sleep(0.5)%0A        d = client.bind(dn, 'something-else')%0A        yield self.assertFailure(d, ldaperrors.LDAPInvalidCredentials)%0A        # two authentication requests to privacyIDEA!%0A        self.assertEqual(self.privacyidea.authentication_requests,%0A                         %5B('hugo', 'default', 'secret', True),%0A                          ('hugo', 'default', 'something-else', False)%5D)%0A        time.sleep(2) # to clean the reactor%0A%0A%0A

Add unit tests for the bind cache