2026-09-07 19:43:48 +03:00

126 lines
3.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Утилиты для обработки текста и экранирования.
Функции для транслитерации, экранирования LDAP-значений и нормализации текста.
"""
from typing import Optional
from ldap3.utils.conv import escape_filter_chars
# Словарь для транслитерации русских символов в латиницу
_RU2LAT = {
"а": "a",
"б": "b",
"в": "v",
"г": "g",
"д": "d",
"е": "e",
"ё": "e",
"ж": "zh",
"з": "z",
"и": "i",
"й": "i",
"к": "k",
"л": "l",
"м": "m",
"н": "n",
"о": "o",
"п": "p",
"р": "r",
"с": "s",
"т": "t",
"у": "u",
"ф": "f",
"х": "kh",
"ц": "ts",
"ч": "ch",
"ш": "sh",
"щ": "shch",
"ъ": "",
"ы": "y",
"ь": "",
"э": "e",
"ю": "yu",
"я": "ya",
}
def translit_to_ascii(text: str) -> str:
"""Транслитерирует строку в ascii: [a-z0-9], нижний регистр.
Args:
text (str): Входная строка.
Returns:
str: Нормализованная ASCII-строка.
Raises:
TypeError: Если text не строка.
"""
if not isinstance(text, str):
raise TypeError("text должен быть строкой")
s = (text or "").strip().lower()
out: list[str] = []
for ch in s:
if "a" <= ch <= "z" or "0" <= ch <= "9":
out.append(ch)
continue
if ch in (" ", ".", "_", "-"):
continue
if ch in _RU2LAT:
out.append(_RU2LAT[ch])
continue
return "".join(out)
def esc_filter(value: Optional[str]) -> str:
"""Экранирует строку для подстановки в LDAP-фильтры (RFC4515).
Args:
value (Optional[str]): Исходная строка.
Returns:
str: Экранированная строка.
"""
s = (value or "").strip()
try:
return escape_filter_chars(s)
except Exception:
# Fallback если ldap3 не сработал
return (
s.replace("\\", r"\5c")
.replace("*", r"\2a")
.replace("(", r"\28")
.replace(")", r"\29")
.replace("\x00", r"\00")
)
def esc_rdn(text: str) -> str:
"""Экранирует RDN-компонент Distinguished Name.
Args:
text (str): RDN-значение (например, "John, Doe").
Returns:
str: Экранированная строка (например, "John\\, Doe").
"""
return (
text.replace("\\", "\\\\")
.replace(",", "\\,")
.replace("+", "\\+")
.replace(";", "\\;")
.replace("=", "\\=")
.replace("<", "\\<")
.replace(">", "\\>")
.replace("#", "\\#")
.replace('"', '\\"')
)
__all__ = [
"translit_to_ascii",
"esc_filter",
"esc_rdn",
]