AD: поиск по нескольким OU (AD_BASES)
- config.py: AD_BASE -> AD_BASES (кортеж OU) - utils/ad_search.py: новая утилита для поиска по всем OU - utils/ad_checker.py: использовать ad_search - utils/otp_service.py: использовать ad_search - lk/handlers.py: использовать ad_search - transcription_bot/handlers.py: использовать ad_search - service_desk/handlers.py: использовать ad_search - instruct/handlers.py: использовать ad_search - photo_bot/ad_helper.py: использовать ad_search - photo_bot/check_ad_photo.py: использовать ad_search - check_ad_2fa.py: использовать ad_search - debug_ad_filter.py: обновить для AD_BASES - lk/test_lk_payslip.py: обновить для AD_BASES
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# /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 []
|
||||
Reference in New Issue
Block a user