Coverage for src / lexigram / contracts / auth / blacklist.py: 100%

7 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-19 05:41 +0800

1"""Token blacklist protocol. 

2 

3Defines the contract for token blacklist implementations used to 

4invalidate JWT tokens before their natural expiration time. 

5""" 

6 

7from __future__ import annotations 

8 

9from typing import Protocol, runtime_checkable 

10 

11 

12@runtime_checkable 

13class TokenBlacklistProtocol(Protocol): 

14 """Protocol for token blacklist implementations. 

15 

16 Implementations must support blacklisting tokens and checking whether 

17 a token has been blacklisted. Concrete implementations may persist 

18 entries in Redis (via CacheBackendProtocol) or keep them in-process for 

19 environments that do not require distributed invalidation. 

20 

21 Example:: 

22 

23 class RedisTokenBlacklist: 

24 async def blacklist(self, token: str, ttl: int | None = None) -> None: 

25 token_hash = hashlib.sha256(token.encode()).hexdigest() 

26 await self._cache.set(f"jwt:blacklist:{token_hash}", "1", ttl=ttl) 

27 

28 async def is_blacklisted(self, token: str) -> bool: 

29 token_hash = hashlib.sha256(token.encode()).hexdigest() 

30 return await self._cache.exists(f"jwt:blacklist:{token_hash}") 

31 """ 

32 

33 async def blacklist(self, token: str, ttl: int | None = None) -> None: 

34 """Add a token to the blacklist. 

35 

36 Args: 

37 token: The raw token string to blacklist. 

38 ttl: Time-to-live in seconds. If None the entry persists 

39 indefinitely (only appropriate for in-memory stores). 

40 """ 

41 ... 

42 

43 async def is_blacklisted(self, token: str) -> bool: 

44 """Check whether a token is blacklisted. 

45 

46 Args: 

47 token: The raw token string to check. 

48 

49 Returns: 

50 ``True`` if the token is blacklisted, ``False`` otherwise. 

51 """ 

52 ... 

53 

54 

55__all__ = ["TokenBlacklistProtocol"]