Coverage for src/taipanstack/security/types.py: 100%
34 statements
« prev ^ index » next coverage.py v7.15.1, created at 2026-10-13 20:52 +0000
« prev ^ index » next coverage.py v7.15.1, created at 2026-10-13 20:52 +0000
1"""
2Pydantic-compatible security types.
4Provide ``Annotated`` type aliases that integrate TaipanStack's
5runtime security guards with Pydantic v2 validation, enabling
6declarative, type-safe input validation inside ``BaseModel``
7definitions.
8"""
10from typing import Annotated
12from pydantic.functional_validators import AfterValidator
14from taipanstack.core.result import Ok
15from taipanstack.security.guards import (
16 SecurityError,
17 guard_command_injection,
18 guard_path_traversal,
19 guard_ssrf,
20)
21from taipanstack.security.validators import (
22 validate_project_name,
23 validate_url,
24)
27def _validate_safe_url(url: str) -> str:
28 """Validate a URL is safe from SSRF attacks.
30 Args:
31 url: The URL string to validate.
33 Returns:
34 The validated URL.
36 Raises:
37 ValueError: If the URL fails SSRF validation.
39 """
40 result = guard_ssrf(url)
41 if isinstance(result, Ok):
42 return result.ok_value
43 raise ValueError(str(result.err_value)) from result.err_value
46def _validate_safe_path(path: str) -> str:
47 """Validate a path is safe from traversal attacks.
49 Args:
50 path: The path string to validate.
52 Returns:
53 The validated path string.
55 Raises:
56 ValueError: If path traversal is detected.
58 """
59 try:
60 guard_path_traversal(path)
61 except SecurityError as exc:
62 raise ValueError(str(exc)) from exc
63 return path
66def _validate_safe_command(command: str) -> str:
67 """Validate a command string is safe from injection attacks.
69 Args:
70 command: The command string to validate.
72 Returns:
73 The validated command string.
75 Raises:
76 ValueError: If command injection is detected.
78 """
79 try:
80 guard_command_injection([command])
81 except SecurityError as exc:
82 raise ValueError(str(exc)) from exc
83 return command
86def _validate_safe_project_name(name: str) -> str:
87 """Validate a project name conforms to safe naming rules.
89 Args:
90 name: The project name to validate.
92 Returns:
93 The validated project name.
95 Raises:
96 ValueError: If the name is invalid.
98 """
99 return validate_project_name(name)
102def _validate_safe_url_format(url: str) -> str:
103 """Validate a URL has a correct format and allowed scheme.
105 Args:
106 url: The URL string to validate.
108 Returns:
109 The validated URL.
111 Raises:
112 ValueError: If the URL format is invalid.
114 """
115 return validate_url(url)
118SafeUrl = Annotated[
119 str,
120 AfterValidator(_validate_safe_url_format),
121 AfterValidator(_validate_safe_url),
122]
123"""A URL validated for correct format and safe from SSRF attacks."""
125SafePath = Annotated[str, AfterValidator(_validate_safe_path)]
126"""A filesystem path validated against path-traversal attacks."""
128SafeCommand = Annotated[str, AfterValidator(_validate_safe_command)]
129"""A command string validated against shell-injection attacks."""
131SafeProjectName = Annotated[str, AfterValidator(_validate_safe_project_name)]
132"""A project name validated for safe naming conventions."""