"""Storage and service contracts for gnexus-gauth."""
from __future__ import annotations
from abc import ABC, abstractmethod
from datetime import datetime
from typing import Any
from gnexus_gauth.dto import (
AuthenticatedUser,
TokenSet,
VerifiedWebhook,
WebhookEvent,
)
class StateStoreInterface(ABC):
"""Authorization state storage contract."""
@abstractmethod
def put(self, state: str, expires_at: datetime, context: dict | None = None) -> None:
"""Persist authorization state with optional context."""
@abstractmethod
def has(self, state: str) -> bool:
"""Check if state exists and is not expired."""
@abstractmethod
def get_context(self, state: str) -> dict:
"""Retrieve context for the given state."""
@abstractmethod
def forget(self, state: str) -> None:
"""Remove the state."""
class PkceStoreInterface(ABC):
"""PKCE verifier storage contract."""
@abstractmethod
def put(self, state: str, verifier: str, expires_at: datetime) -> None:
"""Persist PKCE verifier by state."""
@abstractmethod
def get(self, state: str) -> str | None:
"""Retrieve PKCE verifier for callback exchange."""
@abstractmethod
def forget(self, state: str) -> None:
"""Remove consumed verifier."""
class TokenStoreInterface(ABC):
"""Optional token set persistence contract."""
@abstractmethod
def put(self, key: str, token_set: TokenSet) -> None:
"""Persist token set."""
@abstractmethod
def get(self, key: str) -> TokenSet | None:
"""Retrieve token set."""
@abstractmethod
def forget(self, key: str) -> None:
"""Delete token set on logout/revoke."""
class ClockInterface(ABC):
"""Clock abstraction for deterministic testing."""
@abstractmethod
def now(self) -> datetime:
"""Return current time."""
class TokenEndpointInterface(ABC):
"""Token endpoint operations."""
@abstractmethod
def exchange_authorization_code(self, code: str, pkce_verifier: str) -> TokenSet:
"""Exchange authorization code for tokens."""
@abstractmethod
def refresh_token(self, refresh_token: str) -> TokenSet:
"""Refresh access token."""
@abstractmethod
def revoke_token(self, token: str, token_type_hint: str | None = None) -> None:
"""Revoke a token."""
class RuntimeUserProviderInterface(ABC):
"""Runtime user data provider."""
@abstractmethod
def fetch_user(self, access_token: str) -> AuthenticatedUser:
"""Fetch authenticated user data from runtime API."""
class WebhookVerifierInterface(ABC):
"""Webhook signature verifier."""
@abstractmethod
def verify(self, raw_body: str, headers: dict[str, Any], secret: str) -> VerifiedWebhook:
"""Verify webhook signature."""
class WebhookParserInterface(ABC):
"""Webhook payload parser."""
@abstractmethod
def parse(self, raw_body: str) -> WebhookEvent:
"""Parse webhook payload into structured event."""