from fooder.controller.base import ControllerBase from fooder.context import Context from fooder.utils.jwt import Token, AccessToken, RefreshToken from typing import Type, TypeVar from datetime import datetime T = TypeVar("T", bound=Token) class TokenController(ControllerBase): def __init__(self, ctx: Context, entity_id: int) -> None: super().__init__(ctx) self.entity_id = entity_id @classmethod def from_token(cls, ctx: Context, token_str: str, token_cls: Type[T]) -> "TokenController": token = token_cls.decode(token_str) return cls(ctx, token.sub) @classmethod def from_refresh_token(cls, ctx: Context, token_str: str) -> "TokenController": return cls.from_token(ctx, token_str, RefreshToken) @classmethod def from_access_token(cls, ctx: Context, token_str: str) -> "TokenController": return cls.from_token(ctx, token_str, AccessToken) def generate_token(self, token_cls: Type[T], now: datetime) -> T: return token_cls(exp=token_cls.calculate_exp(now), sub=self.entity_id) def generate_refresh_token(self, now: datetime) -> RefreshToken: return self.generate_token(RefreshToken, now) def generate_access_token(self, now: datetime) -> AccessToken: return self.generate_token(AccessToken, now) def generate_token_pair(self, now: datetime) -> tuple[AccessToken, RefreshToken]: return (self.generate_access_token(now), self.generate_refresh_token(now))