common_lib/common_lib/utils/validators.py
2025-10-23 04:24:32 +03:00

91 lines
3.8 KiB
Python
Raw 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.

import re
def validate_username(value: str,
field_name: str = "login",
need_back=False,
is_bot=False,
min_length=3,
max_length=32) -> str:
"""
Username validator:
- checks for length
- no spaces
- no leading underscore
- no consecutive underscores
- only [A-Za-z0-9_]
"""
# Проверка типа и длины
if not isinstance(value, str) or not (min_length <= len(value) <= max_length):
msg = f"{field_name.capitalize()} must be between {min_length} and {max_length} characters long"
return (False, msg) if need_back else False
# Пробелы
if any(c.isspace() for c in value):
msg = f"{field_name.capitalize()} must not contain whitespace characters"
return (False, msg) if need_back else False
# Начинается с подчеркивания
if value.startswith('_'):
msg = f"{field_name.capitalize()} must not start with an underscore"
return (False, msg) if need_back else False
# Двойные подчеркивания
if '__' in value:
msg = f"{field_name.capitalize()} must not contain consecutive underscores"
return (False, msg) if need_back else False
# Только допустимые символы
if not re.fullmatch(r'[A-Za-z0-9_]+', value):
msg = f"{field_name.capitalize()} must contain only English letters, digits, and underscores"
return (False, msg) if need_back else False
val_lower = value.lower()
# Проверка окончания имени в зависимости от is_bot
if is_bot and not val_lower.endswith("bot"):
msg = f"{field_name.capitalize()} must end with 'bot' for bot accounts"
return (False, msg) if need_back else False
if not is_bot and val_lower.endswith("bot"):
msg = f"{field_name.capitalize()} must not end with 'bot' for non-bot accounts"
return (False, msg) if need_back else False
# Если заканчивается на 'bot', то перед ним должно быть >=3 символов (кроме '_')
if val_lower.endswith("bot"):
prefix = re.sub(r'_+', '', val_lower[:-3]) # убираем все подчёркивания
if len(prefix) < 3:
msg = f"{field_name.capitalize()} must contain at least 3 non-underscore characters before 'bot'"
return (False, msg) if need_back else False
return (True, val_lower) if need_back else val_lower
def validate_password(value: str,
field_name: str = "password",
need_back=False,
min_length=8,
max_length=128) -> str:
"""
Validates password length and (optionally) other rules.
Supports HTTPException raising if `with_httpexception=True`.
Returns (True, value) or raises ValueError.
"""
# Проверка типа и длины
if not isinstance(value, str) or not (min_length <= len(value) <= max_length):
msg = f"{field_name.capitalize()} must be between {min_length} and {max_length} characters long"
return (False, msg) if need_back else False
# if any(c.isspace() for c in value):
# raise ValueError(f"{field_name.capitalize()} must not contain whitespace characters")
# if not re.search(r'[A-Z]', value):
# raise ValueError(f"{field_name.capitalize()} must contain at least one uppercase letter")
# if not re.search(r'\d', value):
# raise ValueError(f"{field_name.capitalize()} must contain at least one digit")
# if not re.search(r'[!@#$%^&*()\-_=+\[\]{};:\'",.<>?/|\\]', value):
# raise ValueError(f"{field_name.capitalize()} must contain at least one special character")
return (True, value) if need_back else value