This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
|
||||
import secrets
|
||||
from functools import lru_cache
|
||||
from typing import Optional
|
||||
|
||||
from .types import TokenType
|
||||
|
||||
@@ -16,7 +15,7 @@ class BaseTokenManager:
|
||||
|
||||
@staticmethod
|
||||
@lru_cache(maxsize=1000)
|
||||
def _make_token_key(token_type: TokenType, identifier: str, token: Optional[str] = None) -> str:
|
||||
def _make_token_key(token_type: TokenType, identifier: str, token: str | None = None) -> str:
|
||||
"""
|
||||
Создает унифицированный ключ для токена с кэшированием
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from auth.jwtcodec import JWTCodec
|
||||
from services.redis import redis as redis_adapter
|
||||
@@ -54,7 +54,7 @@ class BatchTokenOperations(BaseTokenManager):
|
||||
token_keys = []
|
||||
valid_tokens = []
|
||||
|
||||
for token, payload in zip(token_batch, decoded_payloads):
|
||||
for token, payload in zip(token_batch, decoded_payloads, strict=False):
|
||||
if isinstance(payload, Exception) or payload is None:
|
||||
results[token] = False
|
||||
continue
|
||||
@@ -80,12 +80,12 @@ class BatchTokenOperations(BaseTokenManager):
|
||||
await pipe.exists(key)
|
||||
existence_results = await pipe.execute()
|
||||
|
||||
for token, exists in zip(valid_tokens, existence_results):
|
||||
for token, exists in zip(valid_tokens, existence_results, strict=False):
|
||||
results[token] = bool(exists)
|
||||
|
||||
return results
|
||||
|
||||
async def _safe_decode_token(self, token: str) -> Optional[Any]:
|
||||
async def _safe_decode_token(self, token: str) -> Any | None:
|
||||
"""Безопасное декодирование токена"""
|
||||
try:
|
||||
return JWTCodec.decode(token)
|
||||
@@ -190,7 +190,7 @@ class BatchTokenOperations(BaseTokenManager):
|
||||
await pipe.exists(session_key)
|
||||
results = await pipe.execute()
|
||||
|
||||
for token, exists in zip(tokens, results):
|
||||
for token, exists in zip(tokens, results, strict=False):
|
||||
if exists:
|
||||
active_tokens.append(token)
|
||||
else:
|
||||
|
||||
@@ -48,7 +48,7 @@ class TokenMonitoring(BaseTokenManager):
|
||||
count_tasks = [self._count_keys_by_pattern(pattern) for pattern in patterns.values()]
|
||||
counts = await asyncio.gather(*count_tasks)
|
||||
|
||||
for (stat_name, _), count in zip(patterns.items(), counts):
|
||||
for (stat_name, _), count in zip(patterns.items(), counts, strict=False):
|
||||
stats[stat_name] = count
|
||||
|
||||
# Получаем информацию о памяти Redis
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
import json
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from services.redis import redis as redis_adapter
|
||||
from utils.logger import root_logger as logger
|
||||
@@ -23,9 +22,9 @@ class OAuthTokenManager(BaseTokenManager):
|
||||
user_id: str,
|
||||
provider: str,
|
||||
access_token: str,
|
||||
refresh_token: Optional[str] = None,
|
||||
expires_in: Optional[int] = None,
|
||||
additional_data: Optional[TokenData] = None,
|
||||
refresh_token: str | None = None,
|
||||
expires_in: int | None = None,
|
||||
additional_data: TokenData | None = None,
|
||||
) -> bool:
|
||||
"""Сохраняет OAuth токены"""
|
||||
try:
|
||||
@@ -79,7 +78,7 @@ class OAuthTokenManager(BaseTokenManager):
|
||||
logger.info(f"Создан {token_type} токен для пользователя {user_id}, провайдер {provider}")
|
||||
return token_key
|
||||
|
||||
async def get_token(self, user_id: int, provider: str, token_type: TokenType) -> Optional[TokenData]:
|
||||
async def get_token(self, user_id: int, provider: str, token_type: TokenType) -> TokenData | None:
|
||||
"""Получает токен"""
|
||||
if token_type.startswith("oauth_"):
|
||||
return await self._get_oauth_data_optimized(token_type, str(user_id), provider)
|
||||
@@ -87,7 +86,7 @@ class OAuthTokenManager(BaseTokenManager):
|
||||
|
||||
async def _get_oauth_data_optimized(
|
||||
self, token_type: TokenType, user_id: str, provider: str
|
||||
) -> Optional[TokenData]:
|
||||
) -> TokenData | None:
|
||||
"""Оптимизированное получение OAuth данных"""
|
||||
if not user_id or not provider:
|
||||
error_msg = "OAuth токены требуют user_id и provider"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import json
|
||||
import time
|
||||
from typing import Any, List, Optional, Union
|
||||
from typing import Any, List
|
||||
|
||||
from auth.jwtcodec import JWTCodec
|
||||
from services.redis import redis as redis_adapter
|
||||
@@ -22,9 +22,9 @@ class SessionTokenManager(BaseTokenManager):
|
||||
async def create_session(
|
||||
self,
|
||||
user_id: str,
|
||||
auth_data: Optional[dict] = None,
|
||||
username: Optional[str] = None,
|
||||
device_info: Optional[dict] = None,
|
||||
auth_data: dict | None = None,
|
||||
username: str | None = None,
|
||||
device_info: dict | None = None,
|
||||
) -> str:
|
||||
"""Создает токен сессии"""
|
||||
session_data = {}
|
||||
@@ -75,7 +75,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
logger.info(f"Создан токен сессии для пользователя {user_id}")
|
||||
return session_token
|
||||
|
||||
async def get_session_data(self, token: str, user_id: Optional[str] = None) -> Optional[TokenData]:
|
||||
async def get_session_data(self, token: str, user_id: str | None = None) -> TokenData | None:
|
||||
"""Получение данных сессии"""
|
||||
if not user_id:
|
||||
# Извлекаем user_id из JWT
|
||||
@@ -97,7 +97,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
token_data = results[0] if results else None
|
||||
return dict(token_data) if token_data else None
|
||||
|
||||
async def validate_session_token(self, token: str) -> tuple[bool, Optional[TokenData]]:
|
||||
async def validate_session_token(self, token: str) -> tuple[bool, TokenData | None]:
|
||||
"""
|
||||
Проверяет валидность токена сессии
|
||||
"""
|
||||
@@ -163,7 +163,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
|
||||
return len(tokens)
|
||||
|
||||
async def get_user_sessions(self, user_id: Union[int, str]) -> List[TokenData]:
|
||||
async def get_user_sessions(self, user_id: int | str) -> List[TokenData]:
|
||||
"""Получение сессий пользователя"""
|
||||
try:
|
||||
user_tokens_key = self._make_user_tokens_key(str(user_id), "session")
|
||||
@@ -180,7 +180,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
await pipe.hgetall(self._make_token_key("session", str(user_id), token_str))
|
||||
results = await pipe.execute()
|
||||
|
||||
for token, session_data in zip(tokens, results):
|
||||
for token, session_data in zip(tokens, results, strict=False):
|
||||
if session_data:
|
||||
token_str = token if isinstance(token, str) else str(token)
|
||||
session_dict = dict(session_data)
|
||||
@@ -193,7 +193,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
logger.error(f"Ошибка получения сессий пользователя: {e}")
|
||||
return []
|
||||
|
||||
async def refresh_session(self, user_id: int, old_token: str, device_info: Optional[dict] = None) -> Optional[str]:
|
||||
async def refresh_session(self, user_id: int, old_token: str, device_info: dict | None = None) -> str | None:
|
||||
"""
|
||||
Обновляет сессию пользователя, заменяя старый токен новым
|
||||
"""
|
||||
@@ -226,7 +226,7 @@ class SessionTokenManager(BaseTokenManager):
|
||||
logger.error(f"Ошибка обновления сессии: {e}")
|
||||
return None
|
||||
|
||||
async def verify_session(self, token: str) -> Optional[Any]:
|
||||
async def verify_session(self, token: str) -> Any | None:
|
||||
"""
|
||||
Проверяет сессию по токену для совместимости с TokenStorage
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Простой интерфейс для системы токенов
|
||||
"""
|
||||
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
|
||||
from .batch import BatchTokenOperations
|
||||
from .monitoring import TokenMonitoring
|
||||
@@ -29,18 +29,18 @@ class _TokenStorageImpl:
|
||||
async def create_session(
|
||||
self,
|
||||
user_id: str,
|
||||
auth_data: Optional[dict] = None,
|
||||
username: Optional[str] = None,
|
||||
device_info: Optional[dict] = None,
|
||||
auth_data: dict | None = None,
|
||||
username: str | None = None,
|
||||
device_info: dict | None = None,
|
||||
) -> str:
|
||||
"""Создание сессии пользователя"""
|
||||
return await self._sessions.create_session(user_id, auth_data, username, device_info)
|
||||
|
||||
async def verify_session(self, token: str) -> Optional[Any]:
|
||||
async def verify_session(self, token: str) -> Any | None:
|
||||
"""Проверка сессии по токену"""
|
||||
return await self._sessions.verify_session(token)
|
||||
|
||||
async def refresh_session(self, user_id: int, old_token: str, device_info: Optional[dict] = None) -> Optional[str]:
|
||||
async def refresh_session(self, user_id: int, old_token: str, device_info: dict | None = None) -> str | None:
|
||||
"""Обновление сессии пользователя"""
|
||||
return await self._sessions.refresh_session(user_id, old_token, device_info)
|
||||
|
||||
@@ -76,20 +76,20 @@ class TokenStorage:
|
||||
@staticmethod
|
||||
async def create_session(
|
||||
user_id: str,
|
||||
auth_data: Optional[dict] = None,
|
||||
username: Optional[str] = None,
|
||||
device_info: Optional[dict] = None,
|
||||
auth_data: dict | None = None,
|
||||
username: str | None = None,
|
||||
device_info: dict | None = None,
|
||||
) -> str:
|
||||
"""Создание сессии пользователя"""
|
||||
return await _token_storage.create_session(user_id, auth_data, username, device_info)
|
||||
|
||||
@staticmethod
|
||||
async def verify_session(token: str) -> Optional[Any]:
|
||||
async def verify_session(token: str) -> Any | None:
|
||||
"""Проверка сессии по токену"""
|
||||
return await _token_storage.verify_session(token)
|
||||
|
||||
@staticmethod
|
||||
async def refresh_session(user_id: int, old_token: str, device_info: Optional[dict] = None) -> Optional[str]:
|
||||
async def refresh_session(user_id: int, old_token: str, device_info: dict | None = None) -> str | None:
|
||||
"""Обновление сессии пользователя"""
|
||||
return await _token_storage.refresh_session(user_id, old_token, device_info)
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import json
|
||||
import secrets
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from services.redis import redis as redis_adapter
|
||||
from utils.logger import root_logger as logger
|
||||
@@ -24,7 +23,7 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
user_id: str,
|
||||
verification_type: str,
|
||||
data: TokenData,
|
||||
ttl: Optional[int] = None,
|
||||
ttl: int | None = None,
|
||||
) -> str:
|
||||
"""Создает токен подтверждения"""
|
||||
token_data = {"verification_type": verification_type, **data}
|
||||
@@ -41,7 +40,7 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
return await self._create_verification_token(user_id, token_data, ttl)
|
||||
|
||||
async def _create_verification_token(
|
||||
self, user_id: str, token_data: TokenData, ttl: int, token: Optional[str] = None
|
||||
self, user_id: str, token_data: TokenData, ttl: int, token: str | None = None
|
||||
) -> str:
|
||||
"""Оптимизированное создание токена подтверждения"""
|
||||
verification_token = token or secrets.token_urlsafe(32)
|
||||
@@ -61,12 +60,12 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
logger.info(f"Создан токен подтверждения {verification_type} для пользователя {user_id}")
|
||||
return verification_token
|
||||
|
||||
async def get_verification_token_data(self, token: str) -> Optional[TokenData]:
|
||||
async def get_verification_token_data(self, token: str) -> TokenData | None:
|
||||
"""Получает данные токена подтверждения"""
|
||||
token_key = self._make_token_key("verification", "", token)
|
||||
return await redis_adapter.get_and_deserialize(token_key)
|
||||
|
||||
async def validate_verification_token(self, token_str: str) -> tuple[bool, Optional[TokenData]]:
|
||||
async def validate_verification_token(self, token_str: str) -> tuple[bool, TokenData | None]:
|
||||
"""Проверяет валидность токена подтверждения"""
|
||||
token_key = self._make_token_key("verification", "", token_str)
|
||||
token_data = await redis_adapter.get_and_deserialize(token_key)
|
||||
@@ -74,7 +73,7 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
return True, token_data
|
||||
return False, None
|
||||
|
||||
async def confirm_verification_token(self, token_str: str) -> Optional[TokenData]:
|
||||
async def confirm_verification_token(self, token_str: str) -> TokenData | None:
|
||||
"""Подтверждает и использует токен подтверждения (одноразовый)"""
|
||||
token_data = await self.get_verification_token_data(token_str)
|
||||
if token_data:
|
||||
@@ -106,7 +105,7 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
await pipe.get(key)
|
||||
results = await pipe.execute()
|
||||
|
||||
for key, data in zip(keys, results):
|
||||
for key, data in zip(keys, results, strict=False):
|
||||
if data:
|
||||
try:
|
||||
token_data = json.loads(data)
|
||||
@@ -141,7 +140,7 @@ class VerificationTokenManager(BaseTokenManager):
|
||||
results = await pipe.execute()
|
||||
|
||||
# Проверяем какие токены нужно удалить
|
||||
for key, data in zip(keys, results):
|
||||
for key, data in zip(keys, results, strict=False):
|
||||
if data:
|
||||
try:
|
||||
token_data = json.loads(data)
|
||||
|
||||
Reference in New Issue
Block a user