Coverage for src/lexigram/admin/rbac/protocols.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 23:39 +0800

1"""Protocols for the RBAC admin subsystem (roles management).""" 

2 

3from __future__ import annotations 

4 

5from typing import Protocol 

6 

7from lexigram.admin.rbac.errors import ( 

8 AdminRoleError, 

9 RoleDuplicateError, 

10 RoleNotFoundError, 

11 SystemRoleError, 

12) 

13from lexigram.contracts.auth import RoleDefinition 

14from lexigram.result import Result 

15 

16 

17class AdminRoleStoreProtocol(Protocol): 

18 """Persistence for admin roles (``admin_roles`` table).""" 

19 

20 async def ensure_schema(self) -> None: 

21 """Create the roles table if it does not exist (idempotent).""" 

22 ... 

23 

24 async def list_roles(self) -> list[RoleDefinition]: 

25 """Return all roles ordered by name.""" 

26 ... 

27 

28 async def get_role(self, name: str) -> RoleDefinition | None: 

29 """Return one role by name, or ``None`` when missing.""" 

30 ... 

31 

32 async def create_role(self, role: RoleDefinition) -> None: 

33 """Insert a new role. Raises on duplicate name.""" 

34 ... 

35 

36 async def update_role(self, role: RoleDefinition) -> None: 

37 """Update an existing role by name.""" 

38 ... 

39 

40 async def delete_role(self, name: str) -> bool: 

41 """Delete a role by name; ``True`` when a row was removed.""" 

42 ... 

43 

44 

45class AdminRoleServiceProtocol(Protocol): 

46 """Role CRUD orchestration with authorization-sync and audit.""" 

47 

48 async def list_roles(self) -> list[RoleDefinition]: 

49 """Return all roles ordered by name.""" 

50 ... 

51 

52 async def create_role( 

53 self, 

54 name: str, 

55 description: str, 

56 permissions: list[str], 

57 inherits: list[str], 

58 ) -> Result[RoleDefinition, RoleDuplicateError | AdminRoleError]: 

59 """Create a role and mirror it into the authorizer.""" 

60 ... 

61 

62 async def update_role( 

63 self, 

64 name: str, 

65 description: str, 

66 permissions: list[str], 

67 inherits: list[str], 

68 ) -> Result[RoleDefinition, RoleNotFoundError | SystemRoleError | AdminRoleError]: 

69 """Update a role (system roles may not be renamed).""" 

70 ... 

71 

72 async def delete_role( 

73 self, name: str 

74 ) -> Result[None, RoleNotFoundError | SystemRoleError | AdminRoleError]: 

75 """Delete a role (system roles may not be deleted).""" 

76 ... 

77 

78 

79__all__ = [ 

80 "AdminRoleServiceProtocol", 

81 "AdminRoleStoreProtocol", 

82]