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.
- exonware/__init__.py +2 -1
- exonware/conf.py +2 -2
- exonware/xwsystem/__init__.py +115 -43
- exonware/xwsystem/base.py +30 -0
- exonware/xwsystem/caching/__init__.py +39 -13
- exonware/xwsystem/caching/base.py +24 -6
- exonware/xwsystem/caching/bloom_cache.py +2 -2
- exonware/xwsystem/caching/cache_manager.py +2 -1
- exonware/xwsystem/caching/conditional.py +2 -2
- exonware/xwsystem/caching/contracts.py +85 -139
- exonware/xwsystem/caching/decorators.py +6 -19
- exonware/xwsystem/caching/defs.py +2 -1
- exonware/xwsystem/caching/disk_cache.py +2 -1
- exonware/xwsystem/caching/distributed.py +2 -1
- exonware/xwsystem/caching/errors.py +2 -1
- exonware/xwsystem/caching/events.py +110 -27
- exonware/xwsystem/caching/eviction_strategies.py +2 -2
- exonware/xwsystem/caching/external_caching_python.py +701 -0
- exonware/xwsystem/caching/facade.py +253 -0
- exonware/xwsystem/caching/factory.py +300 -0
- exonware/xwsystem/caching/fluent.py +14 -12
- exonware/xwsystem/caching/integrity.py +21 -6
- exonware/xwsystem/caching/lfu_cache.py +2 -1
- exonware/xwsystem/caching/lfu_optimized.py +18 -6
- exonware/xwsystem/caching/lru_cache.py +7 -4
- exonware/xwsystem/caching/memory_bounded.py +2 -2
- exonware/xwsystem/caching/metrics_exporter.py +2 -2
- exonware/xwsystem/caching/observable_cache.py +2 -2
- exonware/xwsystem/caching/pluggable_cache.py +2 -2
- exonware/xwsystem/caching/rate_limiter.py +2 -2
- exonware/xwsystem/caching/read_through.py +2 -2
- exonware/xwsystem/caching/secure_cache.py +81 -28
- exonware/xwsystem/caching/serializable.py +9 -7
- exonware/xwsystem/caching/stats.py +2 -2
- exonware/xwsystem/caching/tagging.py +2 -2
- exonware/xwsystem/caching/ttl_cache.py +4 -3
- exonware/xwsystem/caching/two_tier_cache.py +6 -3
- exonware/xwsystem/caching/utils.py +30 -12
- exonware/xwsystem/caching/validation.py +2 -2
- exonware/xwsystem/caching/warming.py +6 -3
- exonware/xwsystem/caching/write_behind.py +15 -6
- exonware/xwsystem/config/__init__.py +11 -17
- exonware/xwsystem/config/base.py +5 -5
- exonware/xwsystem/config/contracts.py +93 -153
- exonware/xwsystem/config/defaults.py +3 -2
- exonware/xwsystem/config/defs.py +3 -2
- exonware/xwsystem/config/errors.py +2 -5
- exonware/xwsystem/config/logging.py +12 -8
- exonware/xwsystem/config/logging_setup.py +3 -2
- exonware/xwsystem/config/performance.py +1 -46
- exonware/xwsystem/config/performance_modes.py +9 -8
- exonware/xwsystem/config/version_manager.py +1 -0
- exonware/xwsystem/config.py +27 -0
- exonware/xwsystem/console/__init__.py +53 -0
- exonware/xwsystem/console/base.py +133 -0
- exonware/xwsystem/console/cli/__init__.py +61 -0
- exonware/xwsystem/{cli → console/cli}/args.py +27 -24
- exonware/xwsystem/{cli → console/cli}/base.py +18 -87
- exonware/xwsystem/{cli → console/cli}/colors.py +15 -13
- exonware/xwsystem/console/cli/console.py +98 -0
- exonware/xwsystem/{cli → console/cli}/contracts.py +51 -69
- exonware/xwsystem/console/cli/defs.py +87 -0
- exonware/xwsystem/console/cli/encoding.py +69 -0
- exonware/xwsystem/{cli → console/cli}/errors.py +8 -3
- exonware/xwsystem/console/cli/event_logger.py +166 -0
- exonware/xwsystem/{cli → console/cli}/progress.py +25 -21
- exonware/xwsystem/{cli → console/cli}/prompts.py +3 -2
- exonware/xwsystem/{cli → console/cli}/tables.py +27 -24
- exonware/xwsystem/console/contracts.py +113 -0
- exonware/xwsystem/console/defs.py +154 -0
- exonware/xwsystem/console/errors.py +34 -0
- exonware/xwsystem/console/event_logger.py +385 -0
- exonware/xwsystem/console/writer.py +132 -0
- exonware/xwsystem/contracts.py +28 -0
- exonware/xwsystem/data_structures/__init__.py +23 -0
- exonware/xwsystem/data_structures/trie.py +34 -0
- exonware/xwsystem/data_structures/union_find.py +144 -0
- exonware/xwsystem/defs.py +17 -0
- exonware/xwsystem/errors.py +23 -0
- exonware/xwsystem/facade.py +62 -0
- exonware/xwsystem/http_client/__init__.py +22 -1
- exonware/xwsystem/http_client/advanced_client.py +8 -5
- exonware/xwsystem/http_client/base.py +3 -2
- exonware/xwsystem/http_client/client.py +7 -4
- exonware/xwsystem/http_client/contracts.py +42 -56
- exonware/xwsystem/http_client/defs.py +2 -1
- exonware/xwsystem/http_client/errors.py +2 -1
- exonware/xwsystem/http_client/facade.py +156 -0
- exonware/xwsystem/io/__init__.py +22 -3
- exonware/xwsystem/io/archive/__init__.py +8 -2
- exonware/xwsystem/io/archive/archive.py +1 -1
- exonware/xwsystem/io/archive/archive_files.py +4 -7
- exonware/xwsystem/io/archive/archivers.py +120 -10
- exonware/xwsystem/io/archive/base.py +4 -5
- exonware/xwsystem/io/archive/codec_integration.py +1 -2
- exonware/xwsystem/io/archive/compression.py +1 -2
- exonware/xwsystem/io/archive/facade.py +263 -0
- exonware/xwsystem/io/archive/formats/__init__.py +2 -3
- exonware/xwsystem/io/archive/formats/brotli_format.py +20 -7
- exonware/xwsystem/io/archive/formats/lz4_format.py +20 -7
- exonware/xwsystem/io/archive/formats/rar.py +11 -5
- exonware/xwsystem/io/archive/formats/sevenzip.py +12 -6
- exonware/xwsystem/io/archive/formats/squashfs_format.py +1 -2
- exonware/xwsystem/io/archive/formats/tar.py +52 -7
- exonware/xwsystem/io/archive/formats/wim_format.py +11 -5
- exonware/xwsystem/io/archive/formats/zip.py +1 -2
- exonware/xwsystem/io/archive/formats/zpaq_format.py +1 -2
- exonware/xwsystem/io/archive/formats/zstandard.py +20 -7
- exonware/xwsystem/io/base.py +119 -115
- exonware/xwsystem/io/codec/__init__.py +4 -2
- exonware/xwsystem/io/codec/base.py +19 -13
- exonware/xwsystem/io/codec/contracts.py +59 -2
- exonware/xwsystem/io/codec/registry.py +67 -21
- exonware/xwsystem/io/common/__init__.py +1 -1
- exonware/xwsystem/io/common/atomic.py +29 -16
- exonware/xwsystem/io/common/base.py +11 -10
- exonware/xwsystem/io/common/lock.py +6 -5
- exonware/xwsystem/io/common/path_manager.py +2 -1
- exonware/xwsystem/io/common/watcher.py +1 -2
- exonware/xwsystem/io/contracts.py +301 -433
- exonware/xwsystem/io/contracts_1.py +1180 -0
- exonware/xwsystem/io/data_operations.py +19 -20
- exonware/xwsystem/io/defs.py +4 -3
- exonware/xwsystem/io/errors.py +3 -2
- exonware/xwsystem/io/facade.py +87 -61
- exonware/xwsystem/io/file/__init__.py +1 -1
- exonware/xwsystem/io/file/base.py +8 -9
- exonware/xwsystem/io/file/conversion.py +2 -3
- exonware/xwsystem/io/file/file.py +61 -18
- exonware/xwsystem/io/file/paged_source.py +8 -8
- exonware/xwsystem/io/file/paging/__init__.py +1 -2
- exonware/xwsystem/io/file/paging/byte_paging.py +4 -5
- exonware/xwsystem/io/file/paging/line_paging.py +2 -3
- exonware/xwsystem/io/file/paging/record_paging.py +2 -3
- exonware/xwsystem/io/file/paging/registry.py +1 -2
- exonware/xwsystem/io/file/source.py +13 -17
- exonware/xwsystem/io/filesystem/__init__.py +1 -1
- exonware/xwsystem/io/filesystem/base.py +1 -2
- exonware/xwsystem/io/filesystem/local.py +3 -4
- exonware/xwsystem/io/folder/__init__.py +1 -1
- exonware/xwsystem/io/folder/base.py +1 -2
- exonware/xwsystem/io/folder/folder.py +16 -7
- exonware/xwsystem/io/indexing/__init__.py +14 -0
- exonware/xwsystem/io/indexing/facade.py +443 -0
- exonware/xwsystem/io/path_parser.py +98 -0
- exonware/xwsystem/io/serialization/__init__.py +21 -3
- exonware/xwsystem/io/serialization/auto_serializer.py +146 -20
- exonware/xwsystem/io/serialization/base.py +84 -34
- exonware/xwsystem/io/serialization/contracts.py +50 -73
- exonware/xwsystem/io/serialization/defs.py +2 -1
- exonware/xwsystem/io/serialization/errors.py +2 -1
- exonware/xwsystem/io/serialization/flyweight.py +154 -7
- exonware/xwsystem/io/serialization/format_detector.py +15 -14
- exonware/xwsystem/io/serialization/formats/__init__.py +8 -5
- exonware/xwsystem/io/serialization/formats/binary/bson.py +15 -6
- exonware/xwsystem/io/serialization/formats/binary/cbor.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/marshal.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/msgpack.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/pickle.py +5 -5
- exonware/xwsystem/io/serialization/formats/binary/plistlib.py +5 -5
- exonware/xwsystem/io/serialization/formats/database/dbm.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/shelve.py +7 -7
- exonware/xwsystem/io/serialization/formats/database/sqlite3.py +7 -7
- exonware/xwsystem/io/serialization/formats/tabular/__init__.py +27 -0
- exonware/xwsystem/io/serialization/formats/tabular/base.py +89 -0
- exonware/xwsystem/io/serialization/formats/tabular/csv.py +319 -0
- exonware/xwsystem/io/serialization/formats/tabular/df.py +249 -0
- exonware/xwsystem/io/serialization/formats/tabular/excel.py +291 -0
- exonware/xwsystem/io/serialization/formats/tabular/googlesheets.py +374 -0
- exonware/xwsystem/io/serialization/formats/text/__init__.py +1 -1
- exonware/xwsystem/io/serialization/formats/text/append_only_log.py +5 -7
- exonware/xwsystem/io/serialization/formats/text/configparser.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/csv.py +7 -5
- exonware/xwsystem/io/serialization/formats/text/formdata.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/json.py +27 -18
- exonware/xwsystem/io/serialization/formats/text/json5.py +8 -4
- exonware/xwsystem/io/serialization/formats/text/jsonlines.py +18 -14
- exonware/xwsystem/io/serialization/formats/text/multipart.py +5 -5
- exonware/xwsystem/io/serialization/formats/text/toml.py +8 -6
- exonware/xwsystem/io/serialization/formats/text/xml.py +25 -20
- exonware/xwsystem/io/serialization/formats/text/yaml.py +8 -6
- exonware/xwsystem/io/serialization/parsers/__init__.py +3 -2
- exonware/xwsystem/io/serialization/parsers/base.py +6 -5
- exonware/xwsystem/io/serialization/parsers/hybrid_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/msgspec_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/orjson_direct_parser.py +7 -6
- exonware/xwsystem/io/serialization/parsers/orjson_parser.py +11 -8
- exonware/xwsystem/io/serialization/parsers/pysimdjson_parser.py +13 -9
- exonware/xwsystem/io/serialization/parsers/rapidjson_parser.py +10 -7
- exonware/xwsystem/io/serialization/parsers/registry.py +11 -10
- exonware/xwsystem/io/serialization/parsers/standard.py +7 -6
- exonware/xwsystem/io/serialization/parsers/ujson_parser.py +10 -7
- exonware/xwsystem/io/serialization/registry.py +4 -4
- exonware/xwsystem/io/serialization/serializer.py +168 -79
- exonware/xwsystem/io/serialization/universal_options.py +367 -0
- exonware/xwsystem/io/serialization/utils/__init__.py +1 -2
- exonware/xwsystem/io/serialization/utils/path_ops.py +5 -6
- exonware/xwsystem/io/source_reader.py +223 -0
- exonware/xwsystem/io/stream/__init__.py +1 -1
- exonware/xwsystem/io/stream/async_operations.py +61 -14
- exonware/xwsystem/io/stream/base.py +1 -2
- exonware/xwsystem/io/stream/codec_io.py +6 -7
- exonware/xwsystem/ipc/__init__.py +1 -0
- exonware/xwsystem/ipc/async_fabric.py +4 -4
- exonware/xwsystem/ipc/base.py +6 -5
- exonware/xwsystem/ipc/contracts.py +41 -66
- exonware/xwsystem/ipc/defs.py +2 -1
- exonware/xwsystem/ipc/errors.py +2 -1
- exonware/xwsystem/ipc/message_queue.py +5 -2
- exonware/xwsystem/ipc/pipes.py +70 -34
- exonware/xwsystem/ipc/process_manager.py +7 -5
- exonware/xwsystem/ipc/process_pool.py +6 -5
- exonware/xwsystem/ipc/shared_memory.py +64 -11
- exonware/xwsystem/monitoring/__init__.py +7 -0
- exonware/xwsystem/monitoring/base.py +11 -8
- exonware/xwsystem/monitoring/contracts.py +86 -144
- exonware/xwsystem/monitoring/defs.py +2 -1
- exonware/xwsystem/monitoring/error_recovery.py +16 -3
- exonware/xwsystem/monitoring/errors.py +2 -1
- exonware/xwsystem/monitoring/facade.py +183 -0
- exonware/xwsystem/monitoring/memory_monitor.py +1 -0
- exonware/xwsystem/monitoring/metrics.py +1 -0
- exonware/xwsystem/monitoring/performance_manager_generic.py +7 -7
- exonware/xwsystem/monitoring/performance_monitor.py +1 -0
- exonware/xwsystem/monitoring/performance_validator.py +1 -0
- exonware/xwsystem/monitoring/system_monitor.py +6 -5
- exonware/xwsystem/monitoring/tracing.py +18 -16
- exonware/xwsystem/monitoring/tracker.py +2 -1
- exonware/xwsystem/operations/__init__.py +5 -50
- exonware/xwsystem/operations/base.py +3 -44
- exonware/xwsystem/operations/contracts.py +25 -15
- exonware/xwsystem/operations/defs.py +1 -1
- exonware/xwsystem/operations/diff.py +5 -4
- exonware/xwsystem/operations/errors.py +1 -1
- exonware/xwsystem/operations/merge.py +6 -4
- exonware/xwsystem/operations/patch.py +5 -4
- exonware/xwsystem/patterns/__init__.py +1 -0
- exonware/xwsystem/patterns/base.py +2 -1
- exonware/xwsystem/patterns/context_manager.py +2 -1
- exonware/xwsystem/patterns/contracts.py +215 -256
- exonware/xwsystem/patterns/defs.py +2 -1
- exonware/xwsystem/patterns/dynamic_facade.py +1 -0
- exonware/xwsystem/patterns/errors.py +2 -4
- exonware/xwsystem/patterns/handler_factory.py +2 -3
- exonware/xwsystem/patterns/import_registry.py +1 -0
- exonware/xwsystem/patterns/object_pool.py +1 -0
- exonware/xwsystem/patterns/registry.py +4 -43
- exonware/xwsystem/plugins/__init__.py +2 -1
- exonware/xwsystem/plugins/base.py +6 -5
- exonware/xwsystem/plugins/contracts.py +94 -158
- exonware/xwsystem/plugins/defs.py +2 -1
- exonware/xwsystem/plugins/errors.py +2 -1
- exonware/xwsystem/py.typed +3 -0
- exonware/xwsystem/query/__init__.py +36 -0
- exonware/xwsystem/query/contracts.py +56 -0
- exonware/xwsystem/query/errors.py +22 -0
- exonware/xwsystem/query/registry.py +128 -0
- exonware/xwsystem/runtime/__init__.py +2 -1
- exonware/xwsystem/runtime/base.py +4 -3
- exonware/xwsystem/runtime/contracts.py +39 -60
- exonware/xwsystem/runtime/defs.py +2 -1
- exonware/xwsystem/runtime/env.py +11 -9
- exonware/xwsystem/runtime/errors.py +2 -1
- exonware/xwsystem/runtime/reflection.py +3 -2
- exonware/xwsystem/security/__init__.py +68 -11
- exonware/xwsystem/security/audit.py +167 -0
- exonware/xwsystem/security/base.py +121 -24
- exonware/xwsystem/security/contracts.py +91 -146
- exonware/xwsystem/security/crypto.py +17 -16
- exonware/xwsystem/security/defs.py +2 -1
- exonware/xwsystem/security/errors.py +2 -1
- exonware/xwsystem/security/facade.py +321 -0
- exonware/xwsystem/security/file_security.py +330 -0
- exonware/xwsystem/security/hazmat.py +11 -8
- exonware/xwsystem/security/monitor.py +372 -0
- exonware/xwsystem/security/path_validator.py +140 -18
- exonware/xwsystem/security/policy.py +357 -0
- exonware/xwsystem/security/resource_limits.py +1 -0
- exonware/xwsystem/security/validator.py +455 -0
- exonware/xwsystem/shared/__init__.py +14 -1
- exonware/xwsystem/shared/base.py +285 -2
- exonware/xwsystem/shared/contracts.py +415 -126
- exonware/xwsystem/shared/defs.py +2 -1
- exonware/xwsystem/shared/errors.py +2 -2
- exonware/xwsystem/shared/xwobject.py +316 -0
- exonware/xwsystem/structures/__init__.py +1 -0
- exonware/xwsystem/structures/base.py +3 -2
- exonware/xwsystem/structures/circular_detector.py +15 -14
- exonware/xwsystem/structures/contracts.py +53 -76
- exonware/xwsystem/structures/defs.py +2 -1
- exonware/xwsystem/structures/errors.py +2 -1
- exonware/xwsystem/structures/tree_walker.py +2 -1
- exonware/xwsystem/threading/__init__.py +21 -4
- exonware/xwsystem/threading/async_primitives.py +6 -5
- exonware/xwsystem/threading/base.py +3 -2
- exonware/xwsystem/threading/contracts.py +87 -143
- exonware/xwsystem/threading/defs.py +2 -1
- exonware/xwsystem/threading/errors.py +2 -1
- exonware/xwsystem/threading/facade.py +175 -0
- exonware/xwsystem/threading/locks.py +1 -0
- exonware/xwsystem/threading/safe_factory.py +1 -0
- exonware/xwsystem/utils/__init__.py +40 -0
- exonware/xwsystem/utils/base.py +22 -21
- exonware/xwsystem/utils/contracts.py +50 -73
- exonware/xwsystem/utils/dt/__init__.py +19 -3
- exonware/xwsystem/utils/dt/base.py +5 -4
- exonware/xwsystem/utils/dt/contracts.py +22 -29
- exonware/xwsystem/utils/dt/defs.py +2 -1
- exonware/xwsystem/utils/dt/errors.py +2 -5
- exonware/xwsystem/utils/dt/formatting.py +88 -2
- exonware/xwsystem/utils/dt/humanize.py +10 -9
- exonware/xwsystem/utils/dt/parsing.py +56 -5
- exonware/xwsystem/utils/dt/timezone_utils.py +2 -24
- exonware/xwsystem/utils/errors.py +2 -4
- exonware/xwsystem/utils/paths.py +1 -0
- exonware/xwsystem/utils/string.py +49 -0
- exonware/xwsystem/utils/test_runner.py +185 -0
- exonware/xwsystem/utils/utils_contracts.py +2 -1
- exonware/xwsystem/utils/web.py +110 -0
- exonware/xwsystem/validation/__init__.py +25 -1
- exonware/xwsystem/validation/base.py +6 -5
- exonware/xwsystem/validation/contracts.py +29 -41
- exonware/xwsystem/validation/data_validator.py +1 -0
- exonware/xwsystem/validation/declarative.py +11 -8
- exonware/xwsystem/validation/defs.py +2 -1
- exonware/xwsystem/validation/errors.py +2 -1
- exonware/xwsystem/validation/facade.py +198 -0
- exonware/xwsystem/validation/fluent_validator.py +22 -19
- exonware/xwsystem/validation/schema_discovery.py +210 -0
- exonware/xwsystem/validation/type_safety.py +2 -1
- exonware/xwsystem/version.py +2 -2
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/METADATA +71 -4
- exonware_xwsystem-0.1.0.3.dist-info/RECORD +337 -0
- exonware/xwsystem/cli/__init__.py +0 -43
- exonware/xwsystem/cli/console.py +0 -113
- exonware/xwsystem/cli/defs.py +0 -134
- exonware/xwsystem/conf.py +0 -44
- exonware/xwsystem/security/auth.py +0 -484
- exonware_xwsystem-0.1.0.1.dist-info/RECORD +0 -284
- {exonware_xwsystem-0.1.0.1.dist-info → exonware_xwsystem-0.1.0.3.dist-info}/WHEEL +0 -0
- {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}")
|