Coverage for src / lexigram / contracts / exceptions / security.py: 0%
32 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Security exception classes for the Lexigram Framework.
3Defines the exception hierarchy for the security subsystem,
4covering guard denials, input sanitization failures, and CORS violations.
5"""
7from __future__ import annotations
9from typing import Any
11from lexigram.contracts.exceptions.base import LexigramError
14class SecurityError(LexigramError):
15 """Base security error for the Lexigram security subsystem."""
17 _code = "LEX_ERR_SEC_001"
19 def __init__(self, message: str = "Security error", **kwargs: Any) -> None:
20 super().__init__(message, **kwargs)
23class GuardDeniedError(SecurityError):
24 """Raised when a GuardChain denies the request.
26 Attributes:
27 guard: The name or type of the guard that triggered the denial.
28 reason: Human-readable reason for the denial, if provided.
29 """
31 _code = "LEX_ERR_SEC_002"
33 def __init__(
34 self,
35 message: str = "Access denied by guard",
36 guard: str | None = None,
37 reason: str | None = None,
38 **kwargs: Any,
39 ) -> None:
40 super().__init__(message, **kwargs)
41 self.guard = guard
42 self.reason = reason
45class InputSanitizationError(SecurityError):
46 """Raised when sanitization fails due to unrecoverable input structure."""
48 _code = "LEX_ERR_SEC_003"
50 def __init__(
51 self, message: str = "Input sanitization failed", **kwargs: Any
52 ) -> None:
53 super().__init__(message, **kwargs)
56class CORSViolationError(SecurityError):
57 """Raised when a request violates the configured CORS policy.
59 Attributes:
60 origin: The request origin that was rejected.
61 """
63 _code = "LEX_ERR_SEC_004"
65 def __init__(
66 self,
67 message: str = "CORS policy violation",
68 origin: str | None = None,
69 **kwargs: Any,
70 ) -> None:
71 super().__init__(message, **kwargs)
72 self.origin = origin
75class SecretAccessError(SecurityError):
76 """Raised when the caller lacks permission to access or modify a secret.
78 Attributes:
79 secret_name: Name of the secret that was denied access.
80 operation: The operation that was denied (read, write, delete, etc.).
81 """
83 _code = "LEX_ERR_SEC_005"
85 def __init__(
86 self,
87 secret_name: str,
88 operation: str = "read",
89 **kwargs: Any,
90 ) -> None:
91 details = kwargs.get("details", {})
92 details["secret_name"] = secret_name
93 details["operation"] = operation
94 super().__init__(
95 message=f"Access denied: cannot {operation} secret '{secret_name}'",
96 details=details,
97 **kwargs,
98 )
99 self.secret_name = secret_name
100 self.operation = operation
103__all__ = [
104 "CORSViolationError",
105 "GuardDeniedError",
106 "InputSanitizationError",
107 "SecretAccessError",
108 "SecurityError",
109]