def test_multiple_search_ids(self, mock_bind, mock_unbind): """verify ldapresolver supports search for multiple names to support for example the login with sAMAccountName and userPrincipalName. The test verifies that the login name will be expanded into the search filter multiple times, replacing all %s occurrences in the resolver.filter string. """ # 1. setup the test environment uid_type = "üid" bindresult = Bindresult(uid_type=uid_type) mock_bind.return_value = bindresult mock_unbind.return_value = None resolver = LDAPResolver() resolver.filter = ( "(&(|(sAMAccountName=%s)(userPrincipalName=%s))(objectClass=user))" ) resolver.uidType = uid_type login_name = "*****@*****.**" # 2. finally trigger the call getUserId userid = resolver.getUserId(loginname=login_name) # 3. verify that the login name occurs multiple times in the filter assert bindresult._filter_str.count(login_name) == 2
def test_bind_with_failover(self): """ test the failover in the bind handling """ # ------------------------------------------------------------------ -- # setup the ldap fake resolver, which requires: # - an mocked connect # - an mocked bindpw, which in normal case would contain the # crypted data # the mocked resolver loads the derived mocked ResouceSchduler with # the mocked Registry so that we can access the calling data myldap = LDAPResolver() myldap.ldapuri = ("ldap://fail_bind1.psw.de, " "ldap://fail_bind2.psw.de, " "ldap://ok_bind3.psw.de, " "ldap://ok_bind4.psw.de, ") myldap.bindpw = MockedBindPW("geheim1") # ------------------------------------------------------------------ -- # run the bind test myldap.bind() # ------------------------------------------------------------------ -- # evaluate the result: how often called called = FakeLdapResolver.called assert len(called) == 2 * TRIES + 1 assert "ldap://ok_bind4.psw.de" not in called # ------------------------------------------------------------------ -- # evaluate the result: failed should be blocked, other not registry = MockedResourceRegistry.registry for key, val in list(registry.items()): value, _b_ind, _b_count = val if "fail" in key: assert value is not None else: assert value is None # ------------------------------------------------------------------ -- # verify that the 4th entry was never evaluated assert "ldap://ok_bind4.psw.de" not in registry return
class LDAPResolverTest(unittest.TestCase): def setUp(self): self.ldap_y = LDAPResolver() ldap_config = { 'LDAPFILTER': '(&(cn=%s))', 'LDAPSEARCHFILTER': '(cn=*)', 'LOGINNAMEATTRIBUTE': 'cn', 'USERINFO': ('{"username":"******", ' '"description":"",' '"phone" : "telephoneNumber",' '"groups" : "o",' '"mobile" : "mobile",' '"email" : "email",' '"surname" : "sn",' '"givenname" : "givenName",' '"gender" : "" } '), 'LDAPURI': 'ldap://*****:*****@mock.patch.object(LDAPResolver, 'bind', autospec=True) def mocked_ldap_getuserid(self, user, retvalue, mock_bind): ''' Request search for a user, and return the result. Use mock to avoid external LDAP call ''' mock_bind.return_value.search_ext.return_value = 1 mock_bind.return_value.result.return_value = [ldap.RES_SEARCH_ENTRY, retvalue] res = self.ldap_y.getUserId(user) return res
def setUp(self): self.ldap_y = LDAPResolver() ldap_config = { 'LDAPFILTER': '(&(cn=%s))', 'LDAPSEARCHFILTER': '(cn=*)', 'LOGINNAMEATTRIBUTE': 'cn', 'USERINFO': ('{"username":"******", ' '"description":"",' '"phone" : "telephoneNumber",' '"groups" : "o",' '"mobile" : "mobile",' '"email" : "email",' '"surname" : "sn",' '"givenname" : "givenName",' '"gender" : "" } '), 'LDAPURI': 'ldap://localhost:1389', 'LDAPBASE': 'o=linotp,c=org', 'BINDDN': '', 'BINDPW': '', 'TIMEOUT': '5', 'SIZELIMIT': '10', 'linotp.certificates.use_system_certificates': False, } self.ldap_y.loadConfig(ldap_config)
def test_getUserId(self, mock_bind, mock_unbind): """ test for absence of non-utf-8 encoded strings the ldap library used by the python ldap library requires all data encoded in utf-8, which has not been the case for the uidType """ class Bindresult(object): def search_ext(self, base, scope_subtree, filterstr=None, sizelimit=None, attrlist=None, timeout=None): if attrlist: for attr in attrlist: # check if attribute is not a python unicode str if isinstance(attr, unicode): raise Exception('Unicode character recieved') # invalid utf-8 will raise an exception too attr.decode('utf-8') return True def result(self, l_id, all=1): return [[], [('cn=Wolfgang Amadeus Mozart,ou=people,dc=blackdog,' 'dc=corp,dc=lsexperts,dc=de', { 'entryUUID': ['f4450c88-1df9-1033-90e8-713823084e1f'] })]] bindresult = Bindresult() mock_bind.return_value = bindresult mock_unbind.return_value = None resolver = LDAPResolver() resolver.filter = u'(&(uid=%s)(objectClass=inetOrgPerson))' resolver.uidType = u'entryUUIDä' # finally trigger the call to run the test _userid = resolver.getUserId(u'mozart')
def setUp(self): self.ldap_y = LDAPResolver() ldap_config = { "LDAPFILTER": "(&(cn=%s))", "LDAPSEARCHFILTER": "(cn=*)", "LOGINNAMEATTRIBUTE": "cn", "USERINFO": ('{"username":"******", ' '"description":"",' '"phone" : "telephoneNumber",' '"groups" : "o",' '"mobile" : "mobile",' '"email" : "email",' '"surname" : "sn",' '"givenname" : "givenName",' '"gender" : "" } '), "LDAPURI": "ldap://localhost:1389", "LDAPBASE": "o=linotp,c=org", "BINDDN": "", "BINDPW": "", "TIMEOUT": "5", "SIZELIMIT": "10", "linotp.certificates.use_system_certificates": False, } self.ldap_y.loadConfig(ldap_config)
def test_getUserId(self, mock_bind, mock_unbind): """ test for absence of non-utf-8 encoded strings the ldap library used by the python ldap library requires all data encoded in utf-8, which has not been the case for the uidType """ uid_type = u'üid' class Bindresult(object): def search_ext(self, base, scope_subtree, filterstr=None, sizelimit=None, attrlist=None, timeout=None): if attrlist: for attr in attrlist: # check if attribute is not a python unicode str if isinstance(attr, unicode): raise Exception('Unicode character recieved') # invalid utf-8 will raise an exception too attr.decode('utf-8') # check if filterstr is not a python unicode str if isinstance(filterstr, unicode): raise Exception('Unicode character recieved') # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted back from utf-8 it is ensured # that we have the correct encoding filterstr.decode('utf-8') return True def result(self, l_id, all=1): return [ [], [('cn=Wolfgang Amadeus Mözart,ou=people,dc=blackdog,' 'dc=corp,dc=lsexperts,dc=de', {uid_type: ['f4450c88-1df9-1033-90e8-Wolfgang Amadeus Mözart']})]] # ------------------------------------------------------------------ -- # setup the test environment bindresult = Bindresult() mock_bind.return_value = bindresult mock_unbind.return_value = None resolver = LDAPResolver() resolver.filter = u'(&(uid=%s)(objectClass=inetOrgPerson))' resolver.uidType = uid_type # ------------------------------------------------------------------ -- # finally trigger the call to run the test userid = resolver.getUserId(u'mözart') # check if attribute is a python unicode str if not isinstance(userid, unicode): raise Exception('non Unicode character recieved') # if unicode could be converted to utf-8 and back userid.encode('utf-8').decode('utf-8') # ------------------------------------------------------------------ -- # extend the test to verify as well the getUserLDAPInfo and getUserInfo userLdapInfo = resolver.getUserLDAPInfo(u'Üßalad') for key, val_list in userLdapInfo.items(): # check if attribute is a python unicode str if not isinstance(key, unicode) and not isinstance(key, str): raise Exception('Non Unicode character recieved') # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding key.encode('utf-8').decode('utf-8') val = val_list[0] # check if attribute is a python unicode str if not isinstance(val, unicode) and not isinstance(key, str): raise Exception('Non Unicode character recieved') # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding val.encode('utf-8').decode('utf-8') # ------------------------------------------------------------------ -- userInfo = resolver.getUserInfo(u'Üßalad') for key, val in userInfo.items(): if not isinstance(key, str): # check if attribute is a python unicode str if not isinstance(key, unicode): raise Exception('Non Unicode character recieved') # key could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding key.encode('utf-8').decode('utf-8') # check if attribute is a python unicode str if not isinstance(val, unicode): raise Exception('Non Unicode character recieved') # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding val.encode('utf-8').decode('utf-8') return
class LDAPResolverTest(unittest.TestCase): def setUp(self): self.ldap_y = LDAPResolver() ldap_config = { 'LDAPFILTER': '(&(cn=%s))', 'LDAPSEARCHFILTER': '(cn=*)', 'LOGINNAMEATTRIBUTE': 'cn', 'USERINFO': ('{"username":"******", ' '"description":"",' '"phone" : "telephoneNumber",' '"groups" : "o",' '"mobile" : "mobile",' '"email" : "email",' '"surname" : "sn",' '"givenname" : "givenName",' '"gender" : "" } '), 'LDAPURI': 'ldap://*****:*****@mock.patch.object(LDAPResolver, 'bind', autospec=True) def mocked_ldap_getuserid(self, user, retvalue, mock_bind): ''' Request search for a user, and return the result. Use mock to avoid external LDAP call ''' mock_bind.return_value.search_ext.return_value = 1 mock_bind.return_value.result.return_value = [ ldap.RES_SEARCH_ENTRY, retvalue ] res = self.ldap_y.getUserId(user) return res
def test_bind_with_fail(self): """ test the failover in the bind handling """ # ------------------------------------------------------------------ -- # setup the ldap fake resolver, which requires: # - an mocked connect # - an mocked bindpw, which in normal case would contain the # crypted data # the mocked resolver loads the derived mocked ResouceSchduler with # the mocked Registry so that we can access the calling data myldap = LDAPResolver() myldap.ldapuri = ("ldap://fail_bind1.psw.de, " "ldap://fail_bind2.psw.de, " "ldap://fail_bind3.psw.de, " "ldap://fail_bind4.psw.de, ") myldap.binddn = "Heinz" myldap.bindpw = MockedBindPW("geheim1") # ------------------------------------------------------------------ -- # run the bin test with freeze_time("2012-01-14 12:00:00"): with pytest.raises(ResolverNotAvailable): myldap.bind() # -------------------------------------------------------------- -- # evaluate the result: how often called called = FakeLdapResolver.called assert len(called) == 4 * TRIES assert "ldap://fail_bind4.psw.de" in called # -------------------------------------------------------------- -- # evaluate the result: failed should be blocked, other not registry = MockedResourceRegistry.registry for key, value in list(registry.items()): assert value is not None # -------------------------------------------------------------- -- # verify that the 4th entry was evaluated assert "ldap://fail_bind4.psw.de" in registry # -------------------------------------------------------------- -- # now reset the calle registration FakeLdapResolver.called = [] # # -------------------------------------------------------------- -- # and re-run the bind with pytest.raises(ResolverNotAvailable): myldap.bind() # -------------------------------------------------------------- -- # now all resources are marked as blocked and # none will be called called = FakeLdapResolver.called assert len(called) == 0 assert "ldap://fail_bind1.psw.de" not in called with freeze_time("2012-01-14 12:01:00"): # -------------------------------------------------------------- -- # one minute later re-run the bind myldap.ldapuri = ("ldap://fail_bind1.psw.de, " "ldap://fail_bind2.psw.de, " "ldap://go_bind3.psw.de, " "ldap://go_bind4.psw.de, ") myldap.bind() # -------------------------------------------------------------- -- # evaluate the result: how often called called = FakeLdapResolver.called assert len(called) == 2 * TRIES + 1 assert "ldap://go_bind4.psw.de" not in called # -------------------------------------------------------------- -- # evaluate the result: failed should be blocked, other not registry = MockedResourceRegistry.registry for key, val in list(registry.items()): value, _b_ind, _b_count = val if "fail" in key: assert value is not None else: assert value is None # -------------------------------------------------------------- -- # verify that the 4th entry was never evaluated assert "ldap://go_bind4.psw.de" not in registry return
def test_getUserId(self, mock_bind, mock_unbind): """ test for absence of non-utf-8 encoded strings the ldap library used by the python ldap library requires all data encoded in utf-8, which has not been the case for the uidType """ uid_type = "üid" # ------------------------------------------------------------------ -- # setup the test environment bindresult = Bindresult(uid_type=uid_type) mock_bind.return_value = bindresult mock_unbind.return_value = None resolver = LDAPResolver() resolver.filter = "(&(uid=%s)(objectClass=inetOrgPerson))" resolver.uidType = uid_type # ------------------------------------------------------------------ -- # finally trigger the call to run the test userid = resolver.getUserId("mözart") # check if attribute is a python unicode str if not isinstance(userid, str): raise Exception("non Unicode character recieved") # if unicode could be converted to utf-8 and back userid.encode("utf-8").decode("utf-8") # ------------------------------------------------------------------ -- # extend the test to verify as well the getUserLDAPInfo and getUserInfo userLdapInfo = resolver.getUserLDAPInfo("Üßalad") for key, val_list in list(userLdapInfo.items()): # check if attribute is a python unicode str if not isinstance(key, str) and not isinstance(key, str): raise Exception("Non Unicode character recieved") # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding key.encode("utf-8").decode("utf-8") val = val_list[0] # check if attribute is a python unicode str if not isinstance(val, str) and not isinstance(key, str): raise Exception("Non Unicode character recieved") # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding val.encode("utf-8").decode("utf-8") # ------------------------------------------------------------------ -- userInfo = resolver.getUserInfo("Üßalad") for key, val in list(userInfo.items()): if not isinstance(key, str): # check if attribute is a python unicode str if not isinstance(key, str): raise Exception("Non Unicode character recieved") # key could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding key.encode("utf-8").decode("utf-8") # check if attribute is a python unicode str if not isinstance(val, str): raise Exception("Non Unicode character recieved") # val could be str with ascii or non ascii (str.encode(utf-8). # If the str could converted to utf-8 and back it is ensured # that we have the correct encoding val.encode("utf-8").decode("utf-8") return
class LDAPResolverTest(unittest.TestCase): def setUp(self): self.ldap_y = LDAPResolver() ldap_config = { "LDAPFILTER": "(&(cn=%s))", "LDAPSEARCHFILTER": "(cn=*)", "LOGINNAMEATTRIBUTE": "cn", "USERINFO": ('{"username":"******", ' '"description":"",' '"phone" : "telephoneNumber",' '"groups" : "o",' '"mobile" : "mobile",' '"email" : "email",' '"surname" : "sn",' '"givenname" : "givenName",' '"gender" : "" } '), "LDAPURI": "ldap://*****:*****@mock.patch.object(LDAPResolver, "bind", autospec=True) def mocked_ldap_getuserid(self, user, retvalue, mock_bind): """ Request search for a user, and return the result. Use mock to avoid external LDAP call """ mock_bind.return_value.search_ext.return_value = 1 mock_bind.return_value.result.return_value = [ ldap.RES_SEARCH_ENTRY, retvalue, ] res = self.ldap_y.getUserId(user) return res