diff --git a/src/phi/async_ldap/model.py b/src/phi/async_ldap/model.py index 2558302..0da6ae4 100644 --- a/src/phi/async_ldap/model.py +++ b/src/phi/async_ldap/model.py @@ -140,6 +140,17 @@ class Hackers(Entry): self._hackers = build_heritage(self, User) raise + async def get_by_attr(self, attr, value): + async with self.client.connect(is_async=True) as conn: + res = await conn.search("{}={},{}".format(attr, value, self.dn), 0) + if len(res) == 0: + return None + return [User(r["uid"][0], self.client) for r in res] + + async def get_by_uid(self, uid): + res = await self.get_by_attr("uid", uid) + return res[0] + class Robots(Entry): """ diff --git a/test/test_async_ldap_model.py b/test/test_async_ldap_model.py index afe5544..193abb8 100644 --- a/test/test_async_ldap_model.py +++ b/test/test_async_ldap_model.py @@ -27,6 +27,17 @@ BASE_DN = "dc=test,dc=abbiamoundominio,dc=org" USER_LIST = [{"uid": ["conte_mascetti"]}, {"uid": ["perozzi"]}, {"uid": ["necchi"]}] SERVICE_LIST = [{"uid": ["phi"]}, {"uid": ["irc"]}] GROUP_LIST = [{"cn": ["amici_miei"]}, {"cn": ["antani"]}] +EXISTING_USER = [ + { + "dn": f"uid=existing_user,{BASE_DN}>", + "objectClass": ["inetOrgPerson", "organizationalPerson", "person", "top"], + "cn": ["exists"], + "sn": ["Existing User"], + "mail": ["existing@mail.org"], + "uid": ["existing_user"], + "userPassword": ["{SHA}oLY7P6V+DWAMJ9ix7vbMYGIfA+E="], + } +] class MockClient: @@ -47,9 +58,20 @@ class MockClient: return SERVICE_LIST elif "Groups" in self.args: return GROUP_LIST - return USER_LIST + elif "Users" in self.args or f"None=Entry,{BASE_DN}" in args: + return USER_LIST + if f"uid=existing_user,ou=Hackers,{BASE_DN}" in args: + return EXISTING_USER + elif f"uid=not_existing,ou=Hackers,{BASE_DN}" in args: + return [] conn.search = _search + + async def _add(*args, **kwargs): + return + + conn.add = _add + yield conn @@ -61,7 +83,7 @@ def client_fixture(): @pytest.fixture def client_fixture_multi(): res = Namespace() - res.users = MockClient(BASE_DN) + res.users = MockClient(BASE_DN, "Users") res.services = MockClient(BASE_DN, "Services") res.groups = MockClient(BASE_DN, "Groups") return res @@ -244,6 +266,34 @@ def test_Hackers_children(client_fixture_multi): assert USER_LIST == h.children +@pytest.mark.asyncio +async def test_Hackers_get_by_attr(client_fixture): + h = Hackers(client_fixture) + + res = await h.get_by_attr("uid", "existing_user") + + assert len(res) == 1 + assert res[0] is User("existing_user", client_fixture) + + +@pytest.mark.asyncio +async def test_Hackers_get_by_attr_empty(client_fixture): + h = Hackers(client_fixture) + + res = await h.get_by_attr("uid", "not_existing") + + assert res is None + + +@pytest.mark.asyncio +async def test_Hackers_get_by_uid(client_fixture): + h = Hackers(client_fixture) + + res = await h.get_by_uid("existing_user") + + assert res is User("existing_user", client_fixture) + + def test_Robots(client_fixture_multi): r = Robots(client_fixture_multi.services)