# DRF Rack # Библиотека классов расширений для Django REST Framework # # Автор: Николай В. Анохин # Все права защищены. Лицензия: MIT """ Описание класса SessionManager """ from typing import Type from django.apps import apps from environ import ImproperlyConfigured from net.xeaf.rack.managers import ConfigurationManager from net.xeaf.rack.managers import CryptoManager from net.xeaf.rack.models import AccountModel from net.xeaf.rack.models import SessionModel class SessionManager[T:SessionModel]: """ Реализует методы работы с Сессиями """ DEFAULT_SESSION_TTL = 3600 """ Время жизни сессии по умолчанию """ @classmethod def authenticate(cls, username: str, password: str) -> SessionModel: """ Авторизует новую сессию :param username: Имя пользователя :param password: Пароль :return: Объект данных сессии """ pass @classmethod def find_by_token(cls, token: str) -> SessionModel | None: """ Возвращает объект данных сессии по токену :param token: Токен :return: Объект данных сессии или None, если не найдена или просрочена """ session = SessionModel.objects.filter(token__exact=token).first() if session is not None and not session.is_expired(): return session return None @classmethod def open_session(cls, account: AccountModel, actual_account: AccountModel, device_id: str | None = None) -> T: """ Открывает сессию для аккаунта :param account: Модель данных Аккаунта пользователя :param actual_account: Актуальный Аккаунт пользователя :param device_id: Идентификатор устройства :return: Информация о сессии """ session = cls._create_session_model(account, actual_account) session.device_id = device_id cls.renew_session(session) return session @classmethod def renew_session(cls, session: SessionModel) -> None: """ Обновляет время существование сессии :param session: Модель данных сессии """ ttl = ConfigurationManager.get_int("SESSION_TTL", cls.DEFAULT_SESSION_TTL) session.renew(ttl, save=True) @classmethod def close_session(cls, session: SessionModel) -> None: """ Закрывает сессию пользователя :param session: Модель данных сессии """ session.expire(save=True) @classmethod def _create_session_model(cls, account: AccountModel, actual_account: AccountModel) -> T: """ Создает новую модель Сессии :param account: Аккаунт пользователя :param actual_account: Актуальный Аккаунт пользователя """ model = cls._get_session_model_class() return model.objects.create( token=CryptoManager.gen_token(), account=account, actual_account=actual_account ) @classmethod def _get_session_model_class(cls) -> Type[T]: """ Возвращает класс модели данных сессии :return: Класс модели данных сессии """ model_path = ConfigurationManager.get_string("AUTH_SESSION_MODEL", "net_xeaf_rack.AccountModel") app_label, model_name = model_path.split(".") result = apps.get_model(app_label, model_name) # Нет класса if not result: raise ImproperlyConfigured("AUTH_SESSION_MODEL must be set in settings.py") # Некорректный класс if not issubclass(result, SessionModel): raise ImproperlyConfigured(f"AUTH_SESSION_MODEL must be a subclass of {SessionModel.__name__}") return result