Coverage for src/local_deep_research/security/__init__.py: 100%

28 statements  

« prev     ^ index     » next       coverage.py v7.15.1, created at 2026-07-19 23:35 +0000

1"""Security utilities for Local Deep Research.""" 

2 

3from .data_sanitizer import ( 

4 DataSanitizer, 

5 filter_research_metadata, 

6 redact_data, 

7 sanitize_data, 

8 strip_settings_snapshot, 

9) 

10from .egress.audit_hook import ( 

11 active_egress_context, 

12 clear_active_context, 

13 get_active_context, 

14 install_audit_hook, 

15 is_installed as is_audit_hook_installed, 

16 set_active_context, 

17) 

18from .security_settings import get_security_default 

19from .file_integrity import FileIntegrityManager, FAISSIndexVerifier 

20from .notification_validator import ( 

21 NotificationURLValidator, 

22 NotificationURLValidationError, 

23) 

24from .safe_requests import safe_get, safe_post, SafeSession 

25from .security_headers import SecurityHeaders 

26from .ssrf_validator import ( 

27 assert_base_url_safe, 

28 get_safe_url, 

29 is_ip_blocked, 

30 redact_url_for_log, 

31 validate_url, 

32) 

33from .url_validator import URLValidator 

34from .account_lockout import AccountLockoutManager, get_account_lockout_manager 

35from .password_validator import PasswordValidator 

36from .log_sanitizer import ( 

37 redact_secrets, 

38 sanitize_error_details, 

39 sanitize_error_for_client, 

40 sanitize_error_message, 

41 sanitize_for_log, 

42 scrub_error, 

43 strip_control_chars, 

44) 

45from .filename_sanitizer import sanitize_filename, UnsafeFilenameError 

46from .module_whitelist import ( 

47 get_safe_module_class, 

48 ModuleNotAllowedError, 

49 ALLOWED_MODULES, 

50) 

51 

52# PathValidator requires werkzeug (Flask dependency), import conditionally 

53try: 

54 from .path_validator import PathValidator 

55 

56 _has_path_validator = True 

57except ImportError: 

58 PathValidator = None # type: ignore 

59 _has_path_validator = False 

60 

61# FileUploadValidator requires pdfplumber, import conditionally 

62try: 

63 from .file_upload_validator import FileUploadValidator 

64 

65 _has_file_upload_validator = True 

66except ImportError: 

67 FileUploadValidator = None # type: ignore 

68 _has_file_upload_validator = False 

69 

70__all__ = [ 

71 "PathValidator", 

72 "DataSanitizer", 

73 "active_egress_context", 

74 "clear_active_context", 

75 "get_active_context", 

76 "install_audit_hook", 

77 "is_audit_hook_installed", 

78 "set_active_context", 

79 "sanitize_data", 

80 "redact_data", 

81 "filter_research_metadata", 

82 "strip_settings_snapshot", 

83 "get_security_default", 

84 "FileIntegrityManager", 

85 "FAISSIndexVerifier", 

86 "FileUploadValidator", 

87 "NotificationURLValidator", 

88 "NotificationURLValidationError", 

89 "SecurityHeaders", 

90 "URLValidator", 

91 "safe_get", 

92 "safe_post", 

93 "SafeSession", 

94 "validate_url", 

95 "get_safe_url", 

96 "is_ip_blocked", 

97 "assert_base_url_safe", 

98 "redact_url_for_log", 

99 "get_safe_module_class", 

100 "ModuleNotAllowedError", 

101 "ALLOWED_MODULES", 

102 "AccountLockoutManager", 

103 "get_account_lockout_manager", 

104 "PasswordValidator", 

105 "redact_secrets", 

106 "sanitize_error_details", 

107 "sanitize_error_for_client", 

108 "sanitize_error_message", 

109 "sanitize_for_log", 

110 "scrub_error", 

111 "strip_control_chars", 

112 "sanitize_filename", 

113 "UnsafeFilenameError", 

114] 

115 

116# Install the process-wide socket.connect audit hook after all imports 

117# resolve. The hook is a no-op until a worker thread calls 

118# ``set_active_context(ctx)`` — importing this module has zero 

119# behavioral effect on code that does not opt in. Idempotent: subsequent 

120# imports do not re-install. 

121install_audit_hook()