74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
# /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,
|
||
}
|