From 706f109faf2ec2df28cc5e6c65e7fdf2794891a8 Mon Sep 17 00:00:00 2001 From: Blallo Date: Sun, 30 Jun 2019 21:26:27 +0200 Subject: [PATCH] Create, sync, modify and remove User. --- .../test_async_ldap_model.py | 0 src/phi/async_ldap/model.py | 63 +++++++++++++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) rename {test => async_tests}/test_async_ldap_model.py (100%) diff --git a/test/test_async_ldap_model.py b/async_tests/test_async_ldap_model.py similarity index 100% rename from test/test_async_ldap_model.py rename to async_tests/test_async_ldap_model.py diff --git a/src/phi/async_ldap/model.py b/src/phi/async_ldap/model.py index 0da6ae4..9c6be8e 100644 --- a/src/phi/async_ldap/model.py +++ b/src/phi/async_ldap/model.py @@ -4,6 +4,7 @@ import asyncio import logging import typing as T +from bonsai import LDAPEntry, LDAPModOp from phi.logging import get_logger @@ -204,6 +205,16 @@ class Congregations(Entry): raise +async def create_new_(self, **kwargs): + entry = LDAPEntry(self.dn) + entry["objectClass"] = self.object_class + for k, w in kwargs.items(): + entry[k] = w + async with self.client.connect(is_async=True) as conn: + await conn.add(entry) + return entry + + class User(Hackers): """ This class models a user. Users may have attributes @@ -212,6 +223,7 @@ class User(Hackers): kind = "uid" _instances: T.Dict[str, Entry] = dict() + object_class = ["inetOrgPerson", "organizationalPerson", "person", "top"] def __new__(cls, name, client, *args, **kwargs): _name = f"{name}-{id(client)}" @@ -221,7 +233,8 @@ class User(Hackers): def __init__(self, name, client, *args, **kwargs): super().__init__(client, *args, **kwargs) - self.name = name + self._name = name + self._entry = LDAPEntry(self.dn) def __repr__(self): return f"<{get_class(self).__name__}({self.name}) {self.dn}>" @@ -235,7 +248,43 @@ class User(Hackers): @name.setter def name(self, name): - self._name = name + raise RuntimeError("Name property is not modifiable.") + + async def create(self, mail, sn=None, cn=None): + async with self.client.connect(is_async=True) as conn: + res = await conn.search(self.dn, 0) + if len(res) > 0: + raise PhiUserExists + _sn = sn if sn is not None else self.name + _cn = cn if cn is not None else self.name + self._entry = await create_new_(self, uid=self.name, mail=mail, sn=_sn, cn=_cn) + + async def sync(self): + async with self.client.connect(is_async=True) as conn: + res = await conn.search(self.dn, 0) + alog.debug("[%s] sync -> res: %s", self.name, res) + if len(res) == 0: + raise PhiUserDoesNotExist(self.dn) + for k, v in res[0].items(): + self._entry[k] = v + + async def modify(self, key, value): + async with self.client.connect(is_async=True) as conn: + self._entry.connection = conn + await self._entry.change_attribute(key, LDAPModOp.REPLACE, value) + + async def remove(self): + async with self.client.connect(is_async=True) as conn: + self._entry.connection = conn + await self._entry.delete() + + +class PhiUserExists(Exception): + pass + + +class PhiUserDoesNotExist(Exception): + pass class Service(Robots): @@ -247,6 +296,7 @@ class Service(Robots): kind = "uid" _instances: T.Dict[str, Entry] = dict() + object_class = ["account", "top", "simpleSecurityObject"] def __new__(cls, name, client, *args, **kwargs): _name = f"{name}-{id(client)}" @@ -256,7 +306,7 @@ class Service(Robots): def __init__(self, name, *args, **kwargs): super().__init__(*args, **kwargs) - self.name = name + self._name = name def __repr__(self): return f"<{get_class(self).__name__}({self.name}) {self.dn}>" @@ -270,7 +320,7 @@ class Service(Robots): @name.setter def name(self, name): - self._name = name + raise RuntimeError("Name property is not modifiable.") class Group(Congregations): @@ -281,6 +331,7 @@ class Group(Congregations): kind = "cn" _instances: T.Dict[str, Entry] = dict() + object_class = ["groupOfNames", "top"] def __new__(cls, name, client, *args, **kwargs): _name = f"{name}-{id(client)}" @@ -290,7 +341,7 @@ class Group(Congregations): def __init__(self, name, *args, **kwargs): super().__init__(*args, **kwargs) - self.name = name + self._name = name def __repr__(self): return f"<{get_class(self).__name__}({self.name}) {self.dn}>" @@ -304,4 +355,4 @@ class Group(Congregations): @name.setter def name(self, name): - self._name = name + raise RuntimeError("Name property is not modifiable.")