Coverage for src/lexigram/admin/auth/user.py: 35%
17 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
1"""Admin module user record.
3Provides a lightweight user dataclass for the admin subsystem that satisfies
4the :class:`lexigram.contracts.auth.AuthenticatedUserProtocol` protocol without
5importing from ``lexigram-auth``.
7Cross-extension communication uses contracts only; the concrete ``User``
8from ``lexigram-auth`` must not be imported here.
9"""
11from __future__ import annotations
13from dataclasses import dataclass, field
16@dataclass
17class AdminUserRecord:
18 """User record for the admin module.
20 A plain dataclass that satisfies the ``AuthenticatedUserProtocol`` protocol from
21 ``lexigram.contracts.auth``. Instances are constructed locally within
22 ``lexigram-admin`` (e.g. from ``AdminUserEntity.to_user()`` or from
23 config-backed in-memory stores) and must never be imported from
24 ``lexigram-auth``.
25 """
27 user_id: str
28 email: str
29 name: str = ""
30 hashed_password: str | None = None
31 roles: list[str] = field(default_factory=list)
32 permissions: list[str] = field(default_factory=list)
33 is_active: bool = True
34 is_verified: bool = True
36 def has_role(self, role: str) -> bool:
37 """Return True if the user has the given role.
39 Args:
40 role: Role name to check.
42 Returns:
43 True when the role is present in :attr:`roles`.
44 """
45 return role in self.roles
47 def has_permission(self, permission: str) -> bool:
48 """Return True if the user has the given permission.
50 Args:
51 permission: Permission name to check.
53 Returns:
54 True when the permission is present in :attr:`permissions`.
55 """
56 return permission in self.permissions
59__all__ = ["AdminUserRecord"]