feat: add repository Protocol interfaces for User, Credential, MagicLink

This commit is contained in:
Johan Lundberg 2026-02-12 14:56:20 +01:00
parent b22325588a
commit fd8c8cbf39
No known key found for this signature in database
GPG key ID: A6C152738D03C7D1
2 changed files with 66 additions and 0 deletions

View file

@ -0,0 +1,53 @@
from typing import Protocol, runtime_checkable
from fastapi_oidc_op.models import (
MagicLink,
PasswordCredential,
User,
WebAuthnCredential,
)
@runtime_checkable
class UserRepository(Protocol):
async def create(self, user: User) -> User: ...
async def get_by_userid(self, userid: str) -> User | None: ...
async def get_by_username(self, username: str) -> User | None: ...
async def update(self, user: User) -> User: ...
async def list_users(self, offset: int = 0, limit: int = 100) -> list[User]: ...
async def delete(self, userid: str) -> bool: ...
@runtime_checkable
class CredentialRepository(Protocol):
async def create_webauthn(self, credential: WebAuthnCredential) -> WebAuthnCredential: ...
async def create_password(self, credential: PasswordCredential) -> PasswordCredential: ...
async def get_webauthn_by_user(self, user_id: str) -> list[WebAuthnCredential]: ...
async def get_webauthn_by_credential_id(self, credential_id: bytes) -> WebAuthnCredential | None: ...
async def get_password_by_user(self, user_id: str) -> PasswordCredential | None: ...
async def update_webauthn(self, credential: WebAuthnCredential) -> WebAuthnCredential: ...
async def delete_webauthn(self, user_id: str, credential_id: bytes) -> bool: ...
async def delete_password(self, user_id: str) -> bool: ...
@runtime_checkable
class MagicLinkRepository(Protocol):
async def create(self, link: MagicLink) -> MagicLink: ...
async def get_by_token(self, token: str) -> MagicLink | None: ...
async def mark_used(self, token: str) -> bool: ...
async def delete_expired(self) -> int: ...

View file

@ -0,0 +1,13 @@
from typing import runtime_checkable
from fastapi_oidc_op.store.protocols import (
CredentialRepository,
MagicLinkRepository,
UserRepository,
)
def test_protocols_are_runtime_checkable() -> None:
assert runtime_checkable(UserRepository) # type: ignore[arg-type]
assert runtime_checkable(CredentialRepository) # type: ignore[arg-type]
assert runtime_checkable(MagicLinkRepository) # type: ignore[arg-type]