# /opt/trueconf_bot/utils/ad_checker.py # Проверка членства пользователя в группах Active Directory from ldap3 import Server, Connection, ALL def _get_ad_connection(): """Создать соединение с AD.""" from config.config import AD_SERVER, AD_USER, AD_PASSWORD, AD_BASE # noqa: E501 server = Server(AD_SERVER, get_info=ALL) return Connection(server, user=AD_USER, password=AD_PASSWORD, auto_bind=True), AD_BASE def get_user_groups(cn: str) -> list[str] | None: """ Найти пользователя по CN и вернуть список групп. Возвращает None если пользователь не найден. """ conn, ad_base = _get_ad_connection() try: conn.search( search_base=ad_base, search_filter=f"(cn={cn})", attributes=["cn", "sAMAccountName", "memberOf"], ) if not conn.entries: return None entry = conn.entries[0] return [str(g) for g in entry.memberOf] except Exception as e: print(f"❌ Ошибка AD при поиске {cn}: {e}") return None def check_group_membership(cn: str, group_pattern: str = "2FA") -> dict: """ Проверить членство пользователя в группе. Args: cn: CN пользователя (например 'Krivochenko_Denis_Sergeevich') group_pattern: подстрока для поиска в имени группы (по умолчанию '2FA') Returns: dict с полями: found: bool — найден ли пользователь cn: str | None — CN пользователя sam: str | None — sAMAccountName in_group: bool — в группе ли groups: list[str] — все группы matching_groups: list[str] — группы с паттерном """ groups = get_user_groups(cn) if groups is None: return { "found": False, "cn": None, "sam": None, "in_group": False, "groups": [], "matching_groups": [], } matching = [g for g in groups if group_pattern.upper() in g.upper()] return { "found": True, "cn": cn, "sam": groups[0].split(",")[0].split("=")[-1], # грубо из DN "in_group": len(matching) > 0, "groups": groups, "matching_groups": matching, }