3fa7543477
search_by_user_id: or_filter был '(...)' вместо '(|...)' — LDAP требовал OR-оператор
74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
# /opt/trueconf_bot/utils/ad_search.py
|
||
# Универсальный поиск пользователей по нескольким OU в AD.
|
||
# Каждая функция принимает user_id/email/логин и ищет по всем OU из AD_BASES.
|
||
# Возвращает первую найденную запись (ldap3 Entry) или None.
|
||
|
||
from ldap3 import Server, Connection, ALL
|
||
from ldap3.utils.conv import escape_filter_chars
|
||
import config.config as config
|
||
|
||
|
||
def _get_conn():
|
||
"""Создать соединение с AD."""
|
||
server = Server(config.AD_SERVER, get_info=ALL)
|
||
return Connection(server, user=config.AD_USER, password=config.AD_PASSWORD, auto_bind=True)
|
||
|
||
|
||
def search_by_login(login: str, attributes: list[str] | None = None) -> list:
|
||
"""
|
||
Найти пользователя по sAMAccountName во всех OU из AD_BASES.
|
||
Возвращает список Entry (обычно 0 или 1).
|
||
"""
|
||
attrs = attributes or ["cn", "sAMAccountName"]
|
||
conn = _get_conn()
|
||
for base in config.AD_BASES:
|
||
conn.search(
|
||
search_base=base,
|
||
search_filter="({}={})".format("sAMAccountName", login),
|
||
attributes=attrs,
|
||
)
|
||
if conn.entries:
|
||
return list(conn.entries)
|
||
return []
|
||
|
||
|
||
def search_by_user_id(user_id: str, attributes: list[str] | None = None) -> list:
|
||
"""
|
||
Найти пользователя по email/UPN/sAMAccountName во всех OU из AD_BASES.
|
||
Возвращает список Entry (обычно 0 или 1).
|
||
"""
|
||
attrs = attributes or ["cn", "sAMAccountName", "mail", "userPrincipalName", "extensionAttribute2"]
|
||
safe_id = escape_filter_chars(user_id)
|
||
short_username = user_id.split("@")[0] if "@" in user_id else user_id
|
||
safe_sam = escape_filter_chars(short_username)
|
||
|
||
# Строим LDAP filter: (&(objectClass=user)(|(mail=...)(userPrincipalName=...)(sAMAccountName=...)))
|
||
or_parts = [
|
||
"(mail={})".format(safe_id),
|
||
"(userPrincipalName={})".format(safe_id),
|
||
"(userPrincipalName={})".format(short_username + "@sibcem.ru"),
|
||
"(sAMAccountName={})".format(safe_sam),
|
||
]
|
||
or_filter = "(|{})".format("".join(or_parts))
|
||
search_filter = "(&{}{})".format("(objectClass=user)", or_filter)
|
||
|
||
conn = _get_conn()
|
||
for base in config.AD_BASES:
|
||
conn.search(search_base=base, search_filter=search_filter, attributes=attrs)
|
||
if conn.entries:
|
||
return list(conn.entries)
|
||
return []
|
||
|
||
|
||
def search_by_filter(search_filter: str, attributes: list[str]) -> list:
|
||
"""
|
||
Найти по произвольному LDAP-фильтру во всех OU из AD_BASES.
|
||
Возвращает список Entry.
|
||
"""
|
||
conn = _get_conn()
|
||
for base in config.AD_BASES:
|
||
conn.search(search_base=base, search_filter=search_filter, attributes=attributes)
|
||
if conn.entries:
|
||
return list(conn.entries)
|
||
return []
|