exonware-xwsystem 0.1.0.1__py3-none-any.whl → 0.1.0.3__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.3.dist-info}/METADATA +71 -4
  333. exonware_xwsystem-0.1.0.3.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.3.dist-info}/WHEEL +0 -0
  341. {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,357 @@
1
+ #!/usr/bin/env python3
2
+ #exonware/xwsystem/src/exonware/xwsystem/security/policy.py
3
+ """
4
+ Company: eXonware.com
5
+ Author: Eng. Muhammad AlShehri
6
+ Email: connect@exonware.com
7
+ Version: 0.1.0.3
8
+ Generation Date: 07-Jan-2025
9
+
10
+ Security policy implementation for XWSystem.
11
+ Implements ISecurityPolicy protocol for security policy management and enforcement.
12
+ """
13
+
14
+ import json
15
+ import time
16
+ from typing import Any, Optional
17
+ from datetime import datetime
18
+
19
+ from .base import ASecurityPolicyBase
20
+ from .contracts import ISecurityPolicy
21
+ from .defs import SecurityLevel
22
+ from ..config.logging_setup import get_logger
23
+
24
+ logger = get_logger("xwsystem.security.policy")
25
+
26
+
27
+ class SecurityPolicy(ASecurityPolicyBase, ISecurityPolicy):
28
+ """
29
+ Security policy implementation.
30
+
31
+ Provides comprehensive security policy management including:
32
+ - Policy definition and storage
33
+ - Policy validation
34
+ - Policy application
35
+ - Policy violation tracking
36
+ """
37
+
38
+ def __init__(self, security_level: SecurityLevel = SecurityLevel.MEDIUM):
39
+ """
40
+ Initialize security policy manager.
41
+
42
+ Args:
43
+ security_level: Security level for policies
44
+ """
45
+ super().__init__()
46
+ self.security_level = security_level
47
+ self._policies: dict[str, dict[str, Any]] = {}
48
+ self._policy_violations: list[dict[str, Any]] = []
49
+
50
+ # Initialize default policies
51
+ self._initialize_default_policies()
52
+
53
+ def _initialize_default_policies(self) -> None:
54
+ """Initialize default security policies."""
55
+ # Password policy
56
+ self._policies["password"] = {
57
+ "min_length": 8,
58
+ "max_length": 128,
59
+ "require_uppercase": True,
60
+ "require_lowercase": True,
61
+ "require_digits": True,
62
+ "require_special": True,
63
+ "max_age_days": 90,
64
+ "history_count": 5,
65
+ }
66
+
67
+ # Access control policy
68
+ self._policies["access_control"] = {
69
+ "max_failed_attempts": 5,
70
+ "lockout_duration_minutes": 30,
71
+ "session_timeout_minutes": 30,
72
+ "require_mfa": False,
73
+ "allowed_ip_ranges": [],
74
+ "blocked_ip_ranges": [],
75
+ }
76
+
77
+ # Data protection policy
78
+ self._policies["data_protection"] = {
79
+ "encryption_required": True,
80
+ "encryption_algorithm": "AES_256",
81
+ "backup_required": True,
82
+ "retention_days": 365,
83
+ "anonymization_required": False,
84
+ }
85
+
86
+ # Audit policy
87
+ self._policies["audit"] = {
88
+ "log_all_access": True,
89
+ "log_failed_attempts": True,
90
+ "retention_days": 90,
91
+ "alert_on_violations": True,
92
+ }
93
+
94
+ def get_policy(self, policy_name: str) -> dict[str, Any]:
95
+ """
96
+ Get security policy.
97
+
98
+ Args:
99
+ policy_name: Policy name
100
+
101
+ Returns:
102
+ Policy dictionary
103
+ """
104
+ return self._policies.get(policy_name, {}).copy()
105
+
106
+ def set_policy(self, policy_name: str, policy: dict[str, Any]) -> None:
107
+ """
108
+ Set security policy.
109
+
110
+ Args:
111
+ policy_name: Policy name
112
+ policy: Policy dictionary
113
+ """
114
+ # Validate policy before setting
115
+ is_valid, errors = self.validate_policy(policy)
116
+ if not is_valid:
117
+ raise ValueError(f"Invalid policy: {', '.join(errors)}")
118
+
119
+ self._policies[policy_name] = policy.copy()
120
+ logger.info(f"Policy '{policy_name}' updated")
121
+
122
+ def validate_policy(self, policy: dict[str, Any]) -> tuple[bool, list[str]]:
123
+ """
124
+ Validate security policy.
125
+
126
+ Args:
127
+ policy: Policy to validate
128
+
129
+ Returns:
130
+ Tuple of (is_valid, error_messages)
131
+ """
132
+ errors: list[str] = []
133
+
134
+ if not isinstance(policy, dict):
135
+ errors.append("Policy must be a dictionary")
136
+ return False, errors
137
+
138
+ # Check for required fields based on policy type
139
+ if "password" in str(policy).lower():
140
+ required_fields = ["min_length", "max_length"]
141
+ for field in required_fields:
142
+ if field not in policy:
143
+ errors.append(f"Missing required field: {field}")
144
+
145
+ # Validate numeric fields
146
+ numeric_fields = ["min_length", "max_length", "max_age_days", "retention_days"]
147
+ for field in numeric_fields:
148
+ if field in policy:
149
+ if not isinstance(policy[field], (int, float)) or policy[field] < 0:
150
+ errors.append(f"Field '{field}' must be a non-negative number")
151
+
152
+ # Validate boolean fields
153
+ boolean_fields = ["require_uppercase", "require_lowercase", "require_digits",
154
+ "require_special", "encryption_required", "backup_required"]
155
+ for field in boolean_fields:
156
+ if field in policy:
157
+ if not isinstance(policy[field], bool):
158
+ errors.append(f"Field '{field}' must be a boolean")
159
+
160
+ is_valid = len(errors) == 0
161
+ return is_valid, errors
162
+
163
+ def apply_policy(self, policy_name: str, context: dict[str, Any]) -> bool:
164
+ """
165
+ Apply security policy.
166
+
167
+ Args:
168
+ policy_name: Policy name
169
+ context: Context data
170
+
171
+ Returns:
172
+ True if policy applied successfully
173
+ """
174
+ if policy_name not in self._policies:
175
+ logger.warning(f"Policy '{policy_name}' not found")
176
+ return False
177
+
178
+ policy = self._policies[policy_name]
179
+ context_type = context.get("type", "")
180
+
181
+ try:
182
+ if policy_name == "password":
183
+ return self._apply_password_policy(policy, context)
184
+ elif policy_name == "access_control":
185
+ return self._apply_access_control_policy(policy, context)
186
+ elif policy_name == "data_protection":
187
+ return self._apply_data_protection_policy(policy, context)
188
+ elif policy_name == "audit":
189
+ return self._apply_audit_policy(policy, context)
190
+ else:
191
+ # Generic policy application
192
+ return self._apply_generic_policy(policy, context)
193
+
194
+ except Exception as e:
195
+ logger.error(f"Error applying policy '{policy_name}': {str(e)}")
196
+ self._record_violation(policy_name, context, f"Policy application error: {str(e)}")
197
+ return False
198
+
199
+ def list_policies(self) -> list[str]:
200
+ """
201
+ List all security policies.
202
+
203
+ Returns:
204
+ List of policy names
205
+ """
206
+ return list(self._policies.keys())
207
+
208
+ def remove_policy(self, policy_name: str) -> bool:
209
+ """
210
+ Remove security policy.
211
+
212
+ Args:
213
+ policy_name: Policy name to remove
214
+
215
+ Returns:
216
+ True if removed
217
+ """
218
+ if policy_name in self._policies:
219
+ del self._policies[policy_name]
220
+ logger.info(f"Policy '{policy_name}' removed")
221
+ return True
222
+ return False
223
+
224
+ def get_policy_violations(self) -> list[dict[str, Any]]:
225
+ """
226
+ Get policy violations.
227
+
228
+ Returns:
229
+ List of policy violations
230
+ """
231
+ return self._policy_violations.copy()
232
+
233
+ def clear_policy_violations(self) -> None:
234
+ """Clear policy violations."""
235
+ self._policy_violations.clear()
236
+
237
+ def _apply_password_policy(self, policy: dict[str, Any], context: dict[str, Any]) -> bool:
238
+ """Apply password policy."""
239
+ password = context.get("password", "")
240
+
241
+ if len(password) < policy.get("min_length", 8):
242
+ self._record_violation("password", context, "Password too short")
243
+ return False
244
+
245
+ if len(password) > policy.get("max_length", 128):
246
+ self._record_violation("password", context, "Password too long")
247
+ return False
248
+
249
+ if policy.get("require_uppercase", True):
250
+ if not any(c.isupper() for c in password):
251
+ self._record_violation("password", context, "Password must contain uppercase")
252
+ return False
253
+
254
+ if policy.get("require_lowercase", True):
255
+ if not any(c.islower() for c in password):
256
+ self._record_violation("password", context, "Password must contain lowercase")
257
+ return False
258
+
259
+ if policy.get("require_digits", True):
260
+ if not any(c.isdigit() for c in password):
261
+ self._record_violation("password", context, "Password must contain digits")
262
+ return False
263
+
264
+ if policy.get("require_special", True):
265
+ special_chars = "!@#$%^&*(),.?\":{}|<>"
266
+ if not any(c in special_chars for c in password):
267
+ self._record_violation("password", context, "Password must contain special characters")
268
+ return False
269
+
270
+ return True
271
+
272
+ def _apply_access_control_policy(self, policy: dict[str, Any], context: dict[str, Any]) -> bool:
273
+ """Apply access control policy."""
274
+ user = context.get("user", "")
275
+ ip_address = context.get("ip_address", "")
276
+ failed_attempts = context.get("failed_attempts", 0)
277
+
278
+ # Check failed attempts
279
+ max_attempts = policy.get("max_failed_attempts", 5)
280
+ if failed_attempts >= max_attempts:
281
+ self._record_violation("access_control", context,
282
+ f"Exceeded max failed attempts: {failed_attempts}")
283
+ return False
284
+
285
+ # Check IP ranges
286
+ blocked_ranges = policy.get("blocked_ip_ranges", [])
287
+ if ip_address and any(ip_address.startswith(blocked) for blocked in blocked_ranges):
288
+ self._record_violation("access_control", context, f"IP address blocked: {ip_address}")
289
+ return False
290
+
291
+ return True
292
+
293
+ def _apply_data_protection_policy(self, policy: dict[str, Any], context: dict[str, Any]) -> bool:
294
+ """Apply data protection policy."""
295
+ data = context.get("data", "")
296
+ is_encrypted = context.get("is_encrypted", False)
297
+
298
+ if policy.get("encryption_required", True) and not is_encrypted:
299
+ self._record_violation("data_protection", context, "Data encryption required")
300
+ return False
301
+
302
+ return True
303
+
304
+ def _apply_audit_policy(self, policy: dict[str, Any], context: dict[str, Any]) -> bool:
305
+ """Apply audit policy."""
306
+ # Audit policy is typically about logging, so it usually passes
307
+ # but we can check if logging is enabled
308
+ log_all_access = policy.get("log_all_access", True)
309
+
310
+ if log_all_access:
311
+ event_type = context.get("type", "")
312
+ logger.info(f"Audit log: {event_type} - {context.get('user', 'unknown')}")
313
+
314
+ return True
315
+
316
+ def _apply_generic_policy(self, policy: dict[str, Any], context: dict[str, Any]) -> bool:
317
+ """Apply generic policy."""
318
+ # Generic policy application - check if context matches policy rules
319
+ for key, expected_value in policy.items():
320
+ if key in context:
321
+ actual_value = context[key]
322
+ if actual_value != expected_value:
323
+ self._record_violation("generic", context,
324
+ f"Policy violation: {key} = {actual_value}, expected {expected_value}")
325
+ return False
326
+
327
+ return True
328
+
329
+ def _record_violation(self, policy_name: str, context: dict[str, Any], reason: str) -> None:
330
+ """
331
+ Record policy violation.
332
+
333
+ Args:
334
+ policy_name: Policy name
335
+ context: Context data
336
+ reason: Violation reason
337
+ """
338
+ violation = {
339
+ "policy_name": policy_name,
340
+ "reason": reason,
341
+ "context": context.copy(),
342
+ "timestamp": time.time(),
343
+ "datetime": datetime.now().isoformat(),
344
+ }
345
+
346
+ self._policy_violations.append(violation)
347
+
348
+ # Keep only last 1000 violations
349
+ if len(self._policy_violations) > 1000:
350
+ self._policy_violations = self._policy_violations[-1000:]
351
+
352
+ logger.warning(f"Policy violation [{policy_name}]: {reason}")
353
+
354
+ # Alert if configured
355
+ policy = self._policies.get(policy_name, {})
356
+ if policy.get("alert_on_violations", False):
357
+ logger.error(f"SECURITY ALERT: Policy violation detected - {reason}")
@@ -1,3 +1,4 @@
1
+ #exonware/xwsystem/src/exonware/xwsystem/security/resource_limits.py
1
2
  """
2
3
  Generic resource limits and DoS protection.
3
4