Coverage for src / lexigram / admin / auth / store / protocols.py: 100%
12 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-13 22:14 +0800
1"""Admin user store protocol.
3Defines the formal contract for admin panel user store implementations.
4Any class that satisfies these method signatures is a valid implementation.
5"""
7from __future__ import annotations
9from typing import Any, Protocol, runtime_checkable
12@runtime_checkable
13class AdminUserStoreProtocol(Protocol):
14 """Protocol for admin panel user store operations.
16 This is the single authoritative contract for anything that stores and
17 manages admin-panel user accounts (distinct from the application's own
18 user store managed by lexigram-auth).
20 Implementations:
21 - :class:`~lexigram.admin.auth.store.direct_sql.DirectSQLAdminUserStore`
22 — production SQL backend (``admin_users`` table)
23 - :class:`~lexigram.admin.auth.store.memory.MemoryAdminUserStore`
24 — in-memory store for testing
25 """
27 async def get_admin_count(self) -> int:
28 """Return the total number of admin-panel accounts.
30 Used by :class:`~lexigram.admin.middleware.setup.SetupMiddleware` to
31 decide whether to redirect to the first-run setup wizard.
33 Returns:
34 Non-negative integer count of admin users.
35 """
36 ...
38 async def create_user(
39 self,
40 name: str,
41 email: str,
42 hashed_password: str,
43 roles: list[str] | None = None,
44 permissions: list[str] | None = None,
45 **kwargs: Any,
46 ) -> Any:
47 """Create (or upsert) an admin-panel user account.
49 Args:
50 name: Display name.
51 email: Unique email address — used as the login identifier.
52 hashed_password: Pre-hashed credential.
53 roles: Optional list of role strings (e.g. ``["superadmin"]``).
54 permissions: Optional list of explicit permission strings.
55 **kwargs: Implementation-specific extras (ignored if unsupported).
57 Returns:
58 A lightweight object exposing at least ``user_id``, ``name``, and
59 ``email`` attributes.
60 """
61 ...
63 async def get_user_by_email(self, email: str) -> Any | None:
64 """Look up an admin user by email address.
66 Args:
67 email: Email to search for.
69 Returns:
70 User object or ``None`` when no match exists.
71 """
72 ...
74 async def get_user_by_id(self, user_id: str) -> Any | None:
75 """Look up an admin user by primary key.
77 Args:
78 user_id: Unique identifier (UUID string).
80 Returns:
81 User object or ``None`` when no match exists.
82 """
83 ...
85 async def update_user(self, user: Any) -> None:
86 """Persist changes to an existing admin user.
88 Args:
89 user: User object carrying updated field values. Must expose at
90 least ``user_id``, ``name``, ``email``, ``roles``,
91 ``permissions``, ``hashed_password``, and ``is_active``.
92 """
93 ...
95 async def delete_user(self, user_id: str) -> None:
96 """Permanently remove an admin user account.
98 Args:
99 user_id: Unique identifier of the user to delete.
100 """
101 ...
103 async def authenticate(self, email: str, password: str) -> Any | None:
104 """Authenticate an admin user by email and password.
106 Args:
107 email: Email address to look up.
108 password: Plain-text password to verify.
110 Returns:
111 User object when credentials are valid and account is active,
112 ``None`` otherwise.
113 """
114 ...
117__all__ = ["AdminUserStoreProtocol"]