Coverage for src/lexigram/admin/auth/user.py: 88%

17 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-21 14:26 +0800

1"""Admin module user record. 

2 

3Provides a lightweight user dataclass for the admin subsystem that satisfies 

4the :class:`lexigram.contracts.auth.AuthenticatedUserProtocol` protocol without 

5importing from ``lexigram-auth``. 

6 

7Cross-extension communication uses contracts only; the concrete ``User`` 

8from ``lexigram-auth`` must not be imported here. 

9""" 

10 

11from __future__ import annotations 

12 

13from dataclasses import dataclass, field 

14 

15 

16@dataclass 

17class AdminUserRecord: 

18 """User record for the admin module. 

19 

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 """ 

26 

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 

35 

36 def has_role(self, role: str) -> bool: 

37 """Return True if the user has the given role. 

38 

39 Args: 

40 role: Role name to check. 

41 

42 Returns: 

43 True when the role is present in :attr:`roles`. 

44 """ 

45 return role in self.roles 

46 

47 def has_permission(self, permission: str) -> bool: 

48 """Return True if the user has the given permission. 

49 

50 Args: 

51 permission: Permission name to check. 

52 

53 Returns: 

54 True when the permission is present in :attr:`permissions`. 

55 """ 

56 return permission in self.permissions 

57 

58 

59__all__ = ["AdminUserRecord"]