You've already forked RekomenciBackend
fast init
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
from abc import abstractmethod
|
||||
from typing import Protocol
|
||||
|
||||
from template_project.application.access_token.entity import AccessTokenId
|
||||
|
||||
|
||||
type RawAccessToken = str
|
||||
|
||||
|
||||
class AccessTokenCryptographer(Protocol):
|
||||
@abstractmethod
|
||||
def crypto(self, access_token_id: AccessTokenId) -> RawAccessToken:
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def decrypto(self, raw_access_token: RawAccessToken) -> AccessTokenId:
|
||||
raise NotImplementedError
|
||||
@@ -0,0 +1,10 @@
|
||||
from abc import abstractmethod
|
||||
from typing import Protocol
|
||||
|
||||
from template_project.application.access_token.entity import AccessToken, AccessTokenId
|
||||
|
||||
|
||||
class AccessTokenDataGateway(Protocol):
|
||||
@abstractmethod
|
||||
async def load_with_id(self, access_token_id: AccessTokenId) -> AccessToken | None:
|
||||
raise NotImplementedError
|
||||
@@ -0,0 +1,49 @@
|
||||
from datetime import UTC, datetime, timedelta
|
||||
from typing import NewType, Self
|
||||
from uuid import UUID
|
||||
|
||||
from uuid_utils.compat import uuid7
|
||||
|
||||
from template_project.application.access_token.errors import AccessTokenExpiredError
|
||||
from template_project.application.common.entity import Entity, to_entity
|
||||
from template_project.application.user.entity import UserId
|
||||
|
||||
AccessTokenId = NewType("AccessTokenId", UUID)
|
||||
|
||||
@to_entity
|
||||
class AccessToken(Entity[AccessTokenId]):
|
||||
user_id: UserId
|
||||
revoked: bool
|
||||
expires_in: datetime
|
||||
|
||||
@classmethod
|
||||
def factory(
|
||||
cls,
|
||||
user_id: UserId,
|
||||
expires_in: timedelta,
|
||||
) -> Self:
|
||||
current_date_time = datetime.now(tz=UTC)
|
||||
|
||||
return cls(
|
||||
id=AccessTokenId(uuid7()),
|
||||
created_at=current_date_time,
|
||||
user_id=user_id,
|
||||
expires_in=current_date_time + expires_in,
|
||||
revoked=False,
|
||||
)
|
||||
|
||||
|
||||
def ensure_expired(self) -> None:
|
||||
if self.expired_predicate():
|
||||
raise AccessTokenExpiredError(id_=self.id)
|
||||
|
||||
def expired_predicate(self) -> bool:
|
||||
return (
|
||||
(self.expires_in < datetime.now(tz=UTC))
|
||||
or self.revoked
|
||||
or self.deleted_at is not None
|
||||
)
|
||||
|
||||
def revoke(self) -> None:
|
||||
self.revoked = True
|
||||
self.deleted_at = datetime.now(tz=UTC)
|
||||
@@ -0,0 +1,11 @@
|
||||
from abc import abstractmethod
|
||||
from typing import Protocol
|
||||
|
||||
from template_project.application.access_token.entity import AccessToken
|
||||
from template_project.application.user.entity import UserId
|
||||
|
||||
|
||||
class AccessTokenFactory(Protocol):
|
||||
@abstractmethod
|
||||
def execute(self, user_id: UserId) -> AccessToken:
|
||||
raise NotImplementedError
|
||||
@@ -0,0 +1,13 @@
|
||||
from typing import override
|
||||
|
||||
from template_project.application.access_token.entity import AccessTokenId
|
||||
from template_project.application.common.errors import ApplicationError, to_error
|
||||
|
||||
|
||||
@to_error
|
||||
class AccessTokenExpiredError(ApplicationError):
|
||||
id_: AccessTokenId
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return f"Access token id={self.id_!r} expried"
|
||||
Reference in New Issue
Block a user