exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. exonware/__init__.py +2 -1
  2. exonware/conf.py +2 -2
  3. exonware/xwsystem/__init__.py +115 -43
  4. exonware/xwsystem/base.py +30 -0
  5. exonware/xwsystem/caching/__init__.py +39 -13
  6. exonware/xwsystem/caching/base.py +24 -6
  7. exonware/xwsystem/caching/bloom_cache.py +2 -2
  8. exonware/xwsystem/caching/cache_manager.py +2 -1
  9. exonware/xwsystem/caching/conditional.py +2 -2
  10. exonware/xwsystem/caching/contracts.py +85 -139
  11. exonware/xwsystem/caching/decorators.py +6 -19
  12. exonware/xwsystem/caching/defs.py +2 -1
  13. exonware/xwsystem/caching/disk_cache.py +2 -1
  14. exonware/xwsystem/caching/distributed.py +2 -1
  15. exonware/xwsystem/caching/errors.py +2 -1
  16. exonware/xwsystem/caching/events.py +110 -27
  17. exonware/xwsystem/caching/eviction_strategies.py +2 -2
  18. exonware/xwsystem/caching/external_caching_python.py +701 -0
  19. exonware/xwsystem/caching/facade.py +253 -0
  20. exonware/xwsystem/caching/factory.py +300 -0
  21. exonware/xwsystem/caching/fluent.py +14 -12
  22. exonware/xwsystem/caching/integrity.py +21 -6
  23. exonware/xwsystem/caching/lfu_cache.py +2 -1
  24. exonware/xwsystem/caching/lfu_optimized.py +18 -6
  25. exonware/xwsystem/caching/lru_cache.py +7 -4
  26. exonware/xwsystem/caching/memory_bounded.py +2 -2
  27. exonware/xwsystem/caching/metrics_exporter.py +2 -2
  28. exonware/xwsystem/caching/observable_cache.py +2 -2
  29. exonware/xwsystem/caching/pluggable_cache.py +2 -2
  30. exonware/xwsystem/caching/rate_limiter.py +2 -2
  31. exonware/xwsystem/caching/read_through.py +2 -2
  32. exonware/xwsystem/caching/secure_cache.py +81 -28
  33. exonware/xwsystem/caching/serializable.py +9 -7
  34. exonware/xwsystem/caching/stats.py +2 -2
  35. exonware/xwsystem/caching/tagging.py +2 -2
  36. exonware/xwsystem/caching/ttl_cache.py +4 -3
  37. exonware/xwsystem/caching/two_tier_cache.py +6 -3
  38. exonware/xwsystem/caching/utils.py +30 -12
  39. exonware/xwsystem/caching/validation.py +2 -2
  40. exonware/xwsystem/caching/warming.py +6 -3
  41. exonware/xwsystem/caching/write_behind.py +15 -6
  42. exonware/xwsystem/config/__init__.py +11 -17
  43. exonware/xwsystem/config/base.py +5 -5
  44. exonware/xwsystem/config/contracts.py +93 -153
  45. exonware/xwsystem/config/defaults.py +3 -2
  46. exonware/xwsystem/config/defs.py +3 -2
  47. exonware/xwsystem/config/errors.py +2 -5
  48. exonware/xwsystem/config/logging.py +12 -8
  49. exonware/xwsystem/config/logging_setup.py +3 -2
  50. exonware/xwsystem/config/performance.py +1 -46
  51. exonware/xwsystem/config/performance_modes.py +9 -8
  52. exonware/xwsystem/config/version_manager.py +1 -0
  53. exonware/xwsystem/config.py +27 -0
  54. exonware/xwsystem/console/__init__.py +53 -0
  55. exonware/xwsystem/console/base.py +133 -0
  56. exonware/xwsystem/console/cli/__init__.py +61 -0
  57. exonware/xwsystem/{cli → console/cli}/args.py +27 -24
  58. exonware/xwsystem/{cli → console/cli}/base.py +18 -87
  59. exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
  60. exonware/xwsystem/console/cli/console.py +98 -0
  61. exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
  62. exonware/xwsystem/console/cli/defs.py +87 -0
  63. exonware/xwsystem/console/cli/encoding.py +69 -0
  64. exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
  65. exonware/xwsystem/console/cli/event_logger.py +166 -0
  66. exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
  67. exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
  68. exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
  69. exonware/xwsystem/console/contracts.py +113 -0
  70. exonware/xwsystem/console/defs.py +154 -0
  71. exonware/xwsystem/console/errors.py +34 -0
  72. exonware/xwsystem/console/event_logger.py +385 -0
  73. exonware/xwsystem/console/writer.py +132 -0
  74. exonware/xwsystem/contracts.py +28 -0
  75. exonware/xwsystem/data_structures/__init__.py +23 -0
  76. exonware/xwsystem/data_structures/trie.py +34 -0
  77. exonware/xwsystem/data_structures/union_find.py +144 -0
  78. exonware/xwsystem/defs.py +17 -0
  79. exonware/xwsystem/errors.py +23 -0
  80. exonware/xwsystem/facade.py +62 -0
  81. exonware/xwsystem/http_client/__init__.py +22 -1
  82. exonware/xwsystem/http_client/advanced_client.py +8 -5
  83. exonware/xwsystem/http_client/base.py +3 -2
  84. exonware/xwsystem/http_client/client.py +7 -4
  85. exonware/xwsystem/http_client/contracts.py +42 -56
  86. exonware/xwsystem/http_client/defs.py +2 -1
  87. exonware/xwsystem/http_client/errors.py +2 -1
  88. exonware/xwsystem/http_client/facade.py +156 -0
  89. exonware/xwsystem/io/__init__.py +22 -3
  90. exonware/xwsystem/io/archive/__init__.py +8 -2
  91. exonware/xwsystem/io/archive/archive.py +1 -1
  92. exonware/xwsystem/io/archive/archive_files.py +4 -7
  93. exonware/xwsystem/io/archive/archivers.py +120 -10
  94. exonware/xwsystem/io/archive/base.py +4 -5
  95. exonware/xwsystem/io/archive/codec_integration.py +1 -2
  96. exonware/xwsystem/io/archive/compression.py +1 -2
  97. exonware/xwsystem/io/archive/facade.py +263 -0
  98. exonware/xwsystem/io/archive/formats/__init__.py +2 -3
  99. exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
  100. exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
  101. exonware/xwsystem/io/archive/formats/rar.py +11 -5
  102. exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
  103. exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
  104. exonware/xwsystem/io/archive/formats/tar.py +52 -7
  105. exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
  106. exonware/xwsystem/io/archive/formats/zip.py +1 -2
  107. exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
  108. exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
  109. exonware/xwsystem/io/base.py +119 -115
  110. exonware/xwsystem/io/codec/__init__.py +4 -2
  111. exonware/xwsystem/io/codec/base.py +19 -13
  112. exonware/xwsystem/io/codec/contracts.py +59 -2
  113. exonware/xwsystem/io/codec/registry.py +67 -21
  114. exonware/xwsystem/io/common/__init__.py +1 -1
  115. exonware/xwsystem/io/common/atomic.py +29 -16
  116. exonware/xwsystem/io/common/base.py +11 -10
  117. exonware/xwsystem/io/common/lock.py +6 -5
  118. exonware/xwsystem/io/common/path_manager.py +2 -1
  119. exonware/xwsystem/io/common/watcher.py +1 -2
  120. exonware/xwsystem/io/contracts.py +301 -433
  121. exonware/xwsystem/io/contracts_1.py +1180 -0
  122. exonware/xwsystem/io/data_operations.py +19 -20
  123. exonware/xwsystem/io/defs.py +4 -3
  124. exonware/xwsystem/io/errors.py +3 -2
  125. exonware/xwsystem/io/facade.py +87 -61
  126. exonware/xwsystem/io/file/__init__.py +1 -1
  127. exonware/xwsystem/io/file/base.py +8 -9
  128. exonware/xwsystem/io/file/conversion.py +2 -3
  129. exonware/xwsystem/io/file/file.py +61 -18
  130. exonware/xwsystem/io/file/paged_source.py +8 -8
  131. exonware/xwsystem/io/file/paging/__init__.py +1 -2
  132. exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
  133. exonware/xwsystem/io/file/paging/line_paging.py +2 -3
  134. exonware/xwsystem/io/file/paging/record_paging.py +2 -3
  135. exonware/xwsystem/io/file/paging/registry.py +1 -2
  136. exonware/xwsystem/io/file/source.py +13 -17
  137. exonware/xwsystem/io/filesystem/__init__.py +1 -1
  138. exonware/xwsystem/io/filesystem/base.py +1 -2
  139. exonware/xwsystem/io/filesystem/local.py +3 -4
  140. exonware/xwsystem/io/folder/__init__.py +1 -1
  141. exonware/xwsystem/io/folder/base.py +1 -2
  142. exonware/xwsystem/io/folder/folder.py +16 -7
  143. exonware/xwsystem/io/indexing/__init__.py +14 -0
  144. exonware/xwsystem/io/indexing/facade.py +443 -0
  145. exonware/xwsystem/io/path_parser.py +98 -0
  146. exonware/xwsystem/io/serialization/__init__.py +21 -3
  147. exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
  148. exonware/xwsystem/io/serialization/base.py +84 -34
  149. exonware/xwsystem/io/serialization/contracts.py +50 -73
  150. exonware/xwsystem/io/serialization/defs.py +2 -1
  151. exonware/xwsystem/io/serialization/errors.py +2 -1
  152. exonware/xwsystem/io/serialization/flyweight.py +154 -7
  153. exonware/xwsystem/io/serialization/format_detector.py +15 -14
  154. exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
  155. exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
  156. exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
  157. exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
  158. exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
  159. exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
  160. exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
  161. exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
  162. exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
  163. exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
  164. exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
  165. exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
  166. exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
  167. exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
  168. exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
  169. exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
  170. exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
  171. exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
  172. exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
  173. exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
  174. exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
  175. exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
  176. exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
  177. exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
  178. exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
  179. exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
  180. exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
  181. exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
  182. exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
  183. exonware/xwsystem/io/serialization/parsers/base.py +6 -5
  184. exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
  185. exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
  186. exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
  187. exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
  188. exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
  189. exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
  190. exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
  191. exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
  192. exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
  193. exonware/xwsystem/io/serialization/registry.py +4 -4
  194. exonware/xwsystem/io/serialization/serializer.py +168 -79
  195. exonware/xwsystem/io/serialization/universal_options.py +367 -0
  196. exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
  197. exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
  198. exonware/xwsystem/io/source_reader.py +223 -0
  199. exonware/xwsystem/io/stream/__init__.py +1 -1
  200. exonware/xwsystem/io/stream/async_operations.py +61 -14
  201. exonware/xwsystem/io/stream/base.py +1 -2
  202. exonware/xwsystem/io/stream/codec_io.py +6 -7
  203. exonware/xwsystem/ipc/__init__.py +1 -0
  204. exonware/xwsystem/ipc/async_fabric.py +4 -4
  205. exonware/xwsystem/ipc/base.py +6 -5
  206. exonware/xwsystem/ipc/contracts.py +41 -66
  207. exonware/xwsystem/ipc/defs.py +2 -1
  208. exonware/xwsystem/ipc/errors.py +2 -1
  209. exonware/xwsystem/ipc/message_queue.py +5 -2
  210. exonware/xwsystem/ipc/pipes.py +70 -34
  211. exonware/xwsystem/ipc/process_manager.py +7 -5
  212. exonware/xwsystem/ipc/process_pool.py +6 -5
  213. exonware/xwsystem/ipc/shared_memory.py +64 -11
  214. exonware/xwsystem/monitoring/__init__.py +7 -0
  215. exonware/xwsystem/monitoring/base.py +11 -8
  216. exonware/xwsystem/monitoring/contracts.py +86 -144
  217. exonware/xwsystem/monitoring/defs.py +2 -1
  218. exonware/xwsystem/monitoring/error_recovery.py +16 -3
  219. exonware/xwsystem/monitoring/errors.py +2 -1
  220. exonware/xwsystem/monitoring/facade.py +183 -0
  221. exonware/xwsystem/monitoring/memory_monitor.py +1 -0
  222. exonware/xwsystem/monitoring/metrics.py +1 -0
  223. exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
  224. exonware/xwsystem/monitoring/performance_monitor.py +1 -0
  225. exonware/xwsystem/monitoring/performance_validator.py +1 -0
  226. exonware/xwsystem/monitoring/system_monitor.py +6 -5
  227. exonware/xwsystem/monitoring/tracing.py +18 -16
  228. exonware/xwsystem/monitoring/tracker.py +2 -1
  229. exonware/xwsystem/operations/__init__.py +5 -50
  230. exonware/xwsystem/operations/base.py +3 -44
  231. exonware/xwsystem/operations/contracts.py +25 -15
  232. exonware/xwsystem/operations/defs.py +1 -1
  233. exonware/xwsystem/operations/diff.py +5 -4
  234. exonware/xwsystem/operations/errors.py +1 -1
  235. exonware/xwsystem/operations/merge.py +6 -4
  236. exonware/xwsystem/operations/patch.py +5 -4
  237. exonware/xwsystem/patterns/__init__.py +1 -0
  238. exonware/xwsystem/patterns/base.py +2 -1
  239. exonware/xwsystem/patterns/context_manager.py +2 -1
  240. exonware/xwsystem/patterns/contracts.py +215 -256
  241. exonware/xwsystem/patterns/defs.py +2 -1
  242. exonware/xwsystem/patterns/dynamic_facade.py +1 -0
  243. exonware/xwsystem/patterns/errors.py +2 -4
  244. exonware/xwsystem/patterns/handler_factory.py +2 -3
  245. exonware/xwsystem/patterns/import_registry.py +1 -0
  246. exonware/xwsystem/patterns/object_pool.py +1 -0
  247. exonware/xwsystem/patterns/registry.py +4 -43
  248. exonware/xwsystem/plugins/__init__.py +2 -1
  249. exonware/xwsystem/plugins/base.py +6 -5
  250. exonware/xwsystem/plugins/contracts.py +94 -158
  251. exonware/xwsystem/plugins/defs.py +2 -1
  252. exonware/xwsystem/plugins/errors.py +2 -1
  253. exonware/xwsystem/py.typed +3 -0
  254. exonware/xwsystem/query/__init__.py +36 -0
  255. exonware/xwsystem/query/contracts.py +56 -0
  256. exonware/xwsystem/query/errors.py +22 -0
  257. exonware/xwsystem/query/registry.py +128 -0
  258. exonware/xwsystem/runtime/__init__.py +2 -1
  259. exonware/xwsystem/runtime/base.py +4 -3
  260. exonware/xwsystem/runtime/contracts.py +39 -60
  261. exonware/xwsystem/runtime/defs.py +2 -1
  262. exonware/xwsystem/runtime/env.py +11 -9
  263. exonware/xwsystem/runtime/errors.py +2 -1
  264. exonware/xwsystem/runtime/reflection.py +3 -2
  265. exonware/xwsystem/security/__init__.py +68 -11
  266. exonware/xwsystem/security/audit.py +167 -0
  267. exonware/xwsystem/security/base.py +121 -24
  268. exonware/xwsystem/security/contracts.py +91 -146
  269. exonware/xwsystem/security/crypto.py +17 -16
  270. exonware/xwsystem/security/defs.py +2 -1
  271. exonware/xwsystem/security/errors.py +2 -1
  272. exonware/xwsystem/security/facade.py +321 -0
  273. exonware/xwsystem/security/file_security.py +330 -0
  274. exonware/xwsystem/security/hazmat.py +11 -8
  275. exonware/xwsystem/security/monitor.py +372 -0
  276. exonware/xwsystem/security/path_validator.py +140 -18
  277. exonware/xwsystem/security/policy.py +357 -0
  278. exonware/xwsystem/security/resource_limits.py +1 -0
  279. exonware/xwsystem/security/validator.py +455 -0
  280. exonware/xwsystem/shared/__init__.py +14 -1
  281. exonware/xwsystem/shared/base.py +285 -2
  282. exonware/xwsystem/shared/contracts.py +415 -126
  283. exonware/xwsystem/shared/defs.py +2 -1
  284. exonware/xwsystem/shared/errors.py +2 -2
  285. exonware/xwsystem/shared/xwobject.py +316 -0
  286. exonware/xwsystem/structures/__init__.py +1 -0
  287. exonware/xwsystem/structures/base.py +3 -2
  288. exonware/xwsystem/structures/circular_detector.py +15 -14
  289. exonware/xwsystem/structures/contracts.py +53 -76
  290. exonware/xwsystem/structures/defs.py +2 -1
  291. exonware/xwsystem/structures/errors.py +2 -1
  292. exonware/xwsystem/structures/tree_walker.py +2 -1
  293. exonware/xwsystem/threading/__init__.py +21 -4
  294. exonware/xwsystem/threading/async_primitives.py +6 -5
  295. exonware/xwsystem/threading/base.py +3 -2
  296. exonware/xwsystem/threading/contracts.py +87 -143
  297. exonware/xwsystem/threading/defs.py +2 -1
  298. exonware/xwsystem/threading/errors.py +2 -1
  299. exonware/xwsystem/threading/facade.py +175 -0
  300. exonware/xwsystem/threading/locks.py +1 -0
  301. exonware/xwsystem/threading/safe_factory.py +1 -0
  302. exonware/xwsystem/utils/__init__.py +40 -0
  303. exonware/xwsystem/utils/base.py +22 -21
  304. exonware/xwsystem/utils/contracts.py +50 -73
  305. exonware/xwsystem/utils/dt/__init__.py +19 -3
  306. exonware/xwsystem/utils/dt/base.py +5 -4
  307. exonware/xwsystem/utils/dt/contracts.py +22 -29
  308. exonware/xwsystem/utils/dt/defs.py +2 -1
  309. exonware/xwsystem/utils/dt/errors.py +2 -5
  310. exonware/xwsystem/utils/dt/formatting.py +88 -2
  311. exonware/xwsystem/utils/dt/humanize.py +10 -9
  312. exonware/xwsystem/utils/dt/parsing.py +56 -5
  313. exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
  314. exonware/xwsystem/utils/errors.py +2 -4
  315. exonware/xwsystem/utils/paths.py +1 -0
  316. exonware/xwsystem/utils/string.py +49 -0
  317. exonware/xwsystem/utils/test_runner.py +185 -0
  318. exonware/xwsystem/utils/utils_contracts.py +2 -1
  319. exonware/xwsystem/utils/web.py +110 -0
  320. exonware/xwsystem/validation/__init__.py +25 -1
  321. exonware/xwsystem/validation/base.py +6 -5
  322. exonware/xwsystem/validation/contracts.py +29 -41
  323. exonware/xwsystem/validation/data_validator.py +1 -0
  324. exonware/xwsystem/validation/declarative.py +11 -8
  325. exonware/xwsystem/validation/defs.py +2 -1
  326. exonware/xwsystem/validation/errors.py +2 -1
  327. exonware/xwsystem/validation/facade.py +198 -0
  328. exonware/xwsystem/validation/fluent_validator.py +22 -19
  329. exonware/xwsystem/validation/schema_discovery.py +210 -0
  330. exonware/xwsystem/validation/type_safety.py +2 -1
  331. exonware/xwsystem/version.py +2 -2
  332. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.4.dist-info/RECORD +337 -0
  334. exonware/xwsystem/cli/__init__.py +0 -43
  335. exonware/xwsystem/cli/console.py +0 -113
  336. exonware/xwsystem/cli/defs.py +0 -134
  337. exonware/xwsystem/conf.py +0 -44
  338. exonware/xwsystem/security/auth.py +0 -484
  339. exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
  340. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/WHEEL +0 -0
  341. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,330 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ #exonware/xwsystem/src/exonware/xwsystem/security/file_security.py
4
+
5
+ Secure File Operations for xwsystem.
6
+
7
+ Provides generic file security operations that can be used by any library:
8
+ - Path validation (REUSES xwsystem.security.PathValidator)
9
+ - Resource limits (REUSES xwsystem.security.resource_limits)
10
+ - File permission checks
11
+ - Secure read/write operations
12
+
13
+ Company: eXonware.com
14
+ Author: Eng. Muhammad AlShehri
15
+ Email: connect@exonware.com
16
+ Version: 0.1.0.4
17
+ Generation Date: 26-Jan-2025
18
+ """
19
+
20
+ import os
21
+ import stat
22
+ from pathlib import Path
23
+ from typing import Optional, List
24
+ from .path_validator import PathValidator, PathSecurityError
25
+ from .resource_limits import get_resource_limits, GenericLimitError
26
+
27
+
28
+ class FileSecurityError(Exception):
29
+ """Base exception for file security errors."""
30
+ def __init__(self, message: str, path: Optional[str] = None, context: Optional[dict] = None):
31
+ super().__init__(message)
32
+ self.path = path
33
+ self.context = context or {}
34
+
35
+
36
+ class FileSizeLimitError(FileSecurityError):
37
+ """Exception raised when file size exceeds limit."""
38
+ def __init__(self, message: str, size: int, limit: int, path: Optional[str] = None):
39
+ super().__init__(message, path=path, context={'size': size, 'limit': limit})
40
+ self.size = size
41
+ self.limit = limit
42
+
43
+
44
+ class FileIOError(FileSecurityError):
45
+ """Exception raised when file I/O operations fail."""
46
+ pass
47
+
48
+
49
+ class FileSecurity:
50
+ """
51
+ Secure file operations with validation and limits.
52
+
53
+ Generic file security class that can be used by any library.
54
+ REUSES xwsystem security features for consistency.
55
+ """
56
+
57
+ def __init__(
58
+ self,
59
+ max_file_size: int = 100 * 1024 * 1024, # 100MB default
60
+ allowed_directories: Optional[List[str]] = None,
61
+ allow_absolute_paths: bool = False
62
+ ):
63
+ """
64
+ Initialize file security.
65
+
66
+ Args:
67
+ max_file_size: Maximum file size in bytes
68
+ allowed_directories: List of allowed base directories
69
+ allow_absolute_paths: If True, allow absolute paths
70
+ """
71
+ self._max_file_size = max_file_size
72
+ self._allowed_directories = allowed_directories
73
+ self._allow_absolute_paths = allow_absolute_paths
74
+ self._path_validator = PathValidator(
75
+ base_path=Path(allowed_directories[0]).resolve() if allowed_directories else None,
76
+ allow_absolute=allow_absolute_paths,
77
+ enable_cache=True
78
+ )
79
+
80
+ def validate_file_path(
81
+ self,
82
+ path: str | Path,
83
+ operation: str = "access",
84
+ check_exists: bool = False
85
+ ) -> Path:
86
+ """
87
+ Validate file path for security.
88
+
89
+ REUSES xwsystem PathValidator for consistency.
90
+
91
+ Args:
92
+ path: File path to validate
93
+ operation: Operation being performed
94
+ check_exists: If True, check if file exists
95
+
96
+ Returns:
97
+ Validated Path object
98
+
99
+ Raises:
100
+ PathSecurityError: If path is invalid
101
+ FileIOError: If file doesn't exist (when check_exists=True)
102
+ """
103
+ path_obj = Path(path)
104
+
105
+ # Check for absolute paths
106
+ if path_obj.is_absolute() and not self._allow_absolute_paths:
107
+ raise PathSecurityError(
108
+ "Absolute paths are not allowed",
109
+ path=str(path),
110
+ context={'operation': operation}
111
+ )
112
+
113
+ # REUSE xwsystem PathValidator
114
+ try:
115
+ validated_path = self._path_validator.validate_path(str(path), for_writing=(operation == "write"))
116
+ except PathSecurityError as e:
117
+ raise PathSecurityError(
118
+ f"Path validation failed: {e}",
119
+ path=str(path),
120
+ context={'operation': operation}
121
+ )
122
+
123
+ validated_path = Path(validated_path)
124
+
125
+ # Check if file exists (if required)
126
+ if check_exists and not validated_path.exists():
127
+ raise FileIOError(
128
+ f"File does not exist: {validated_path}",
129
+ path=str(validated_path)
130
+ )
131
+
132
+ return validated_path
133
+
134
+ def check_file_size(self, path: str | Path) -> int:
135
+ """
136
+ Check file size and validate against limits.
137
+
138
+ REUSES xwsystem resource limits for consistency.
139
+
140
+ Args:
141
+ path: File path
142
+
143
+ Returns:
144
+ File size in bytes
145
+
146
+ Raises:
147
+ FileSizeLimitError: If file exceeds size limit
148
+ FileIOError: If file cannot be accessed
149
+ """
150
+ path_obj = self.validate_file_path(path, operation="size_check", check_exists=True)
151
+
152
+ try:
153
+ size = path_obj.stat().st_size
154
+ except OSError as e:
155
+ raise FileIOError(
156
+ f"Cannot access file: {e}",
157
+ path=str(path_obj)
158
+ )
159
+
160
+ # REUSE xwsystem resource limits for consistency
161
+ resource_limits = get_resource_limits()
162
+ max_file_size = min(self._max_file_size, resource_limits.max_file_size)
163
+
164
+ if size > max_file_size:
165
+ raise FileSizeLimitError(
166
+ f"File size {size} exceeds limit {max_file_size}",
167
+ size=size,
168
+ limit=max_file_size,
169
+ path=str(path_obj)
170
+ )
171
+
172
+ return size
173
+
174
+ def validate_file_permissions(
175
+ self,
176
+ path: str | Path,
177
+ required_permission: str = "read"
178
+ ) -> None:
179
+ """
180
+ Validate file permissions.
181
+
182
+ Args:
183
+ path: File path
184
+ required_permission: Required permission ('read', 'write', 'execute')
185
+
186
+ Raises:
187
+ FileIOError: If file doesn't have required permissions
188
+ """
189
+ path_obj = self.validate_file_path(path, operation="permission_check", check_exists=True)
190
+
191
+ try:
192
+ file_stat = path_obj.stat()
193
+ file_mode = file_stat.st_mode
194
+ except OSError as e:
195
+ raise FileIOError(
196
+ f"Cannot access file permissions: {e}",
197
+ path=str(path_obj)
198
+ )
199
+
200
+ # Check permissions
201
+ if required_permission == "read":
202
+ if not os.access(path_obj, os.R_OK):
203
+ raise FileIOError(
204
+ "File does not have read permission",
205
+ path=str(path_obj)
206
+ )
207
+ elif required_permission == "write":
208
+ if not os.access(path_obj, os.W_OK):
209
+ raise FileIOError(
210
+ "File does not have write permission",
211
+ path=str(path_obj)
212
+ )
213
+ elif required_permission == "execute":
214
+ if not os.access(path_obj, os.X_OK):
215
+ raise FileIOError(
216
+ "File does not have execute permission",
217
+ path=str(path_obj)
218
+ )
219
+
220
+ def secure_read_file(self, path: str | Path) -> bytes:
221
+ """
222
+ Securely read a file with validation.
223
+
224
+ Args:
225
+ path: File path
226
+
227
+ Returns:
228
+ File contents as bytes
229
+
230
+ Raises:
231
+ PathSecurityError: If path is invalid
232
+ FileSizeLimitError: If file exceeds size limit
233
+ FileIOError: If file cannot be read
234
+ """
235
+ # Validate path
236
+ validated_path = self.validate_file_path(path, operation="read", check_exists=True)
237
+
238
+ # Check file size
239
+ self.check_file_size(validated_path)
240
+
241
+ # Check permissions
242
+ self.validate_file_permissions(validated_path, required_permission="read")
243
+
244
+ # Read file
245
+ try:
246
+ with open(validated_path, 'rb') as f:
247
+ return f.read()
248
+ except OSError as e:
249
+ raise FileIOError(
250
+ f"Cannot read file: {e}",
251
+ path=str(validated_path)
252
+ )
253
+
254
+ def secure_write_file(
255
+ self,
256
+ path: str | Path,
257
+ data: bytes,
258
+ check_size: bool = True
259
+ ) -> None:
260
+ """
261
+ Securely write a file with validation.
262
+
263
+ Args:
264
+ path: File path
265
+ data: Data to write
266
+ check_size: If True, check data size against limit
267
+
268
+ Raises:
269
+ PathSecurityError: If path is invalid
270
+ FileSizeLimitError: If data exceeds size limit
271
+ FileIOError: If file cannot be written
272
+ """
273
+ # Validate path
274
+ validated_path = self.validate_file_path(path, operation="write")
275
+
276
+ # Check data size
277
+ if check_size and len(data) > self._max_file_size:
278
+ raise FileSizeLimitError(
279
+ f"Data size {len(data)} exceeds limit {self._max_file_size}",
280
+ size=len(data),
281
+ limit=self._max_file_size,
282
+ path=str(validated_path)
283
+ )
284
+
285
+ # Create parent directory if needed
286
+ validated_path.parent.mkdir(parents=True, exist_ok=True)
287
+
288
+ # Write file
289
+ try:
290
+ with open(validated_path, 'wb') as f:
291
+ f.write(data)
292
+ except OSError as e:
293
+ raise FileIOError(
294
+ f"Cannot write file: {e}",
295
+ path=str(validated_path)
296
+ )
297
+
298
+ def is_safe_path(self, path: str | Path) -> bool:
299
+ """
300
+ Check if path is safe (doesn't raise exception).
301
+
302
+ Args:
303
+ path: Path to check
304
+
305
+ Returns:
306
+ True if path is safe
307
+ """
308
+ try:
309
+ self.validate_file_path(path, operation="check")
310
+ return True
311
+ except (PathSecurityError, FileIOError):
312
+ return False
313
+
314
+
315
+ # Global file security instance
316
+ _file_security: Optional[FileSecurity] = None
317
+
318
+
319
+ def get_file_security() -> FileSecurity:
320
+ """Get global file security instance."""
321
+ global _file_security
322
+ if _file_security is None:
323
+ _file_security = FileSecurity()
324
+ return _file_security
325
+
326
+
327
+ def set_file_security(security: FileSecurity) -> None:
328
+ """Set global file security instance."""
329
+ global _file_security
330
+ _file_security = security
@@ -1,8 +1,9 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/security/hazmat.py
1
2
  """
2
3
  Company: eXonware.com
3
4
  Author: Eng. Muhammad AlShehri
4
5
  Email: connect@exonware.com
5
- Version: 0.1.0.1
6
+ Version: 0.1.0.4
6
7
  Generation Date: September 04, 2025
7
8
 
8
9
  Hazardous Materials (Hazmat) Layer - Low-level cryptographic primitives.
@@ -20,8 +21,10 @@ Features:
20
21
  - Low-level cryptographic operations
21
22
  """
22
23
 
24
+ from __future__ import annotations
25
+
23
26
  import os
24
- from typing import Any, Optional, Union
27
+ from typing import Any, Optional
25
28
 
26
29
  from cryptography.hazmat.primitives import hashes, serialization
27
30
  from cryptography.hazmat.primitives.asymmetric import rsa, ec, ed25519, x25519, padding
@@ -510,7 +513,7 @@ class X509Certificate:
510
513
  Provides parsing, validation, and creation of X.509 certificates.
511
514
  """
512
515
 
513
- def __init__(self, cert_data: Union[bytes, str]):
516
+ def __init__(self, cert_data: bytes | str):
514
517
  """
515
518
  Initialize with certificate data.
516
519
 
@@ -576,7 +579,7 @@ class X509Certificate:
576
579
  """Get signature algorithm name."""
577
580
  return self._cert.signature_algorithm_oid._name
578
581
 
579
- def verify_signature(self, ca_cert: 'X509Certificate') -> bool:
582
+ def verify_signature(self, ca_cert: X509Certificate) -> bool:
580
583
  """
581
584
  Verify certificate signature against CA certificate.
582
585
 
@@ -618,17 +621,17 @@ class X509Certificate:
618
621
  return self._cert.public_bytes(serialization.Encoding.DER)
619
622
 
620
623
  @staticmethod
621
- def load_pem(pem_data: Union[bytes, str]) -> 'X509Certificate':
624
+ def load_pem(pem_data: bytes | str) -> X509Certificate:
622
625
  """Load certificate from PEM data."""
623
626
  return X509Certificate(pem_data)
624
627
 
625
628
  @staticmethod
626
- def load_der(der_data: bytes) -> 'X509Certificate':
629
+ def load_der(der_data: bytes) -> X509Certificate:
627
630
  """Load certificate from DER data."""
628
631
  return X509Certificate(der_data)
629
632
 
630
633
  @staticmethod
631
- def load_from_file(file_path: str) -> 'X509Certificate':
634
+ def load_from_file(file_path: str) -> X509Certificate:
632
635
  """Load certificate from file."""
633
636
  with open(file_path, 'rb') as f:
634
637
  return X509Certificate(f.read())
@@ -712,5 +715,5 @@ def secure_random(length: int) -> bytes:
712
715
 
713
716
  def is_cryptography_available() -> bool:
714
717
  """Check if cryptography library is available."""
715
- # Lazy installation system ensures cryptography is always available
718
+ # Lazy installation system provides cryptography when available
716
719
  return True