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