Spaces:
Sleeping
Sleeping
File size: 3,976 Bytes
494c89b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | """
Authentication Strategy Pattern
Поддерживает разные методы авторизации:
- AutomatedStrategy: DrissionPage (старый метод, работает для некоторых)
- WebViewStrategy: Реальный браузер с ручным вводом (новый, anti-ban)
- DeviceFlowStrategy: Device flow OAuth (для headless серверов)
"""
from abc import ABC, abstractmethod
from typing import Optional, Dict, Any
from dataclasses import dataclass
@dataclass
class AuthResult:
"""Результат авторизации"""
success: bool
access_token: Optional[str] = None
refresh_token: Optional[str] = None
expires_in: Optional[int] = None
profile_arn: Optional[str] = None
csrf_token: Optional[str] = None
error: Optional[str] = None
metadata: Optional[Dict[str, Any]] = None
class AuthStrategy(ABC):
"""Базовый класс для стратегий авторизации"""
@abstractmethod
def authenticate(self, email: str, password: str, **kwargs) -> AuthResult:
"""
Выполнить авторизацию
Args:
email: Email для авторизации
password: Пароль
**kwargs: Дополнительные параметры (зависят от стратегии)
Returns:
AuthResult с токенами или ошибкой
"""
pass
@abstractmethod
def get_name(self) -> str:
"""Название стратегии"""
pass
@abstractmethod
def requires_manual_input(self) -> bool:
"""Требует ли стратегия ручного ввода от пользователя"""
pass
@abstractmethod
def supports_headless(self) -> bool:
"""Поддерживает ли headless режим"""
pass
def get_ban_risk(self) -> str:
"""Оценка риска бана (low/medium/high)"""
return "unknown"
def cleanup(self):
"""Очистка ресурсов"""
pass
class RegistrationStrategy(ABC):
"""Базовый класс для стратегий регистрации"""
@abstractmethod
def register(self, email: str, name: Optional[str] = None,
password: Optional[str] = None, **kwargs) -> Dict[str, Any]:
"""
Выполнить регистрацию
Args:
email: Email для регистрации
name: Имя пользователя (генерируется если не указано)
password: Пароль (генерируется если не указан)
**kwargs: Дополнительные параметры
Returns:
Dict с результатом регистрации
"""
pass
@abstractmethod
def get_name(self) -> str:
"""Название стратегии"""
pass
@abstractmethod
def requires_manual_input(self) -> bool:
"""Требует ли стратегия ручного ввода от пользователя"""
pass
@abstractmethod
def supports_headless(self) -> bool:
"""Поддерживает ли headless режим"""
pass
def get_ban_risk(self) -> str:
"""Оценка риска бана (low/medium/high)"""
return "unknown"
def supports_immediate_quota_check(self) -> bool:
"""
Поддерживает ли стратегия немедленную проверку quota после регистрации.
Для anti-ban стратегий должно быть False!
"""
return True
def cleanup(self):
"""Очистка ресурсов"""
pass
|