mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2024-11-05 11:03:12 +00:00
62 lines
1.7 KiB
Python
62 lines
1.7 KiB
Python
"""
|
|
Recovery key used to obtain access token.
|
|
|
|
Recovery key has a token string, date of creation, optional date of expiration and optional count of uses left.
|
|
"""
|
|
from datetime import datetime, timezone
|
|
import secrets
|
|
from typing import Optional
|
|
from pydantic import BaseModel
|
|
from mnemonic import Mnemonic
|
|
|
|
from selfprivacy_api.models.tokens.time import is_past, ensure_timezone
|
|
|
|
|
|
class RecoveryKey(BaseModel):
|
|
"""
|
|
Recovery key used to obtain access token.
|
|
|
|
Recovery key has a key string, date of creation, optional date of expiration and optional count of uses left.
|
|
"""
|
|
|
|
key: str
|
|
created_at: datetime
|
|
expires_at: Optional[datetime]
|
|
uses_left: Optional[int]
|
|
|
|
def is_valid(self) -> bool:
|
|
"""
|
|
Check if the recovery key is valid.
|
|
"""
|
|
if self.expires_at is not None and is_past(self.expires_at):
|
|
return False
|
|
if self.uses_left is not None and self.uses_left <= 0:
|
|
return False
|
|
return True
|
|
|
|
def as_mnemonic(self) -> str:
|
|
"""
|
|
Get the recovery key as a mnemonic.
|
|
"""
|
|
return Mnemonic(language="english").to_mnemonic(bytes.fromhex(self.key))
|
|
|
|
@staticmethod
|
|
def generate(
|
|
expiration: Optional[datetime],
|
|
uses_left: Optional[int],
|
|
) -> "RecoveryKey":
|
|
"""
|
|
Factory to generate a random token.
|
|
If passed naive time as expiration, assumes utc
|
|
"""
|
|
creation_date = datetime.now(timezone.utc)
|
|
if expiration is not None:
|
|
expiration = ensure_timezone(expiration)
|
|
key = secrets.token_bytes(24).hex()
|
|
return RecoveryKey(
|
|
key=key,
|
|
created_at=creation_date,
|
|
expires_at=expiration,
|
|
uses_left=uses_left,
|
|
)
|