Source code for satorbis_kit.auth.token_store
import base64
import json
import time
from dataclasses import dataclass, field
from typing import Optional
[docs]
@dataclass
class TokenStore:
access_token: Optional[str] = field(default=None, repr=False)
refresh_token: Optional[str] = field(default=None, repr=False)
id_token: Optional[str] = field(default=None, repr=False)
token_type: str = "Bearer"
expires_at: Optional[float] = None
@property
def is_empty(self):
return self.access_token is None
@property
def is_expired(self):
if self.expires_at is None:
return True
return time.time() >= self.expires_at - 60
[docs]
def update_from_raw(self, raw: dict):
self.access_token = raw["access_token"]
self.refresh_token = raw.get("refresh_token", self.refresh_token)
self.id_token = raw.get("id_token", self.id_token)
self.token_type = raw.get("token_type", "Bearer")
self.expires_at = raw.get("expires_at") or (
time.time() + raw.get("expires_in", 3600)
)
[docs]
@staticmethod
def decode_jwt_payload_str(token_str: str) -> dict:
"""Base64-decode a JWT payload without verifying the signature."""
try:
parts = token_str.split(".")
if len(parts) != 3:
return {}
padding = 4 - len(parts[1]) % 4
padded = parts[1] + "=" * (padding % 4)
return json.loads(base64.urlsafe_b64decode(padded))
except Exception:
return {}
[docs]
def decode_jwt_payload(self) -> dict:
"""Decode the access token's JWT payload without signature verification."""
if not self.access_token:
return {}
return self.decode_jwt_payload_str(self.access_token)