hexcore 10.2.0__tar.gz → 11.0.2__tar.gz
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.
- {hexcore-10.2.0/hexcore.egg-info → hexcore-11.0.2}/PKG-INFO +28 -5
- {hexcore-10.2.0 → hexcore-11.0.2}/README.md +23 -4
- hexcore-11.0.2/hexcore/__init__.py +35 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/_deprecation.py +14 -10
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/__init__.py +4 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/__init__.pyi +3 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/services.py +4 -34
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/context.py +43 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/ports.py +49 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/lifespan.py +40 -2
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/__init__.py +325 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/cache.py +68 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/conditions.py +850 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/domain.py +307 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/__init__.py +7 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/beanie/__init__.py +5 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/beanie/repository.py +351 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/__init__.py +6 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/models.py +81 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/models_mixins.py +175 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/orms/sqlalchemy/repository.py +399 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/pdp.py +398 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/pip.py +147 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/predicates.py +136 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/provider.py +34 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/router.py +515 -0
- hexcore-11.0.2/hexcore/darwin/plugins/drbac/service.py +276 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/__init__.py +1 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/__init__.py +1 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/__init__.py +1 -1
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/__init__.py +386 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/cache.py +145 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/cli.py +153 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/domain.py +371 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/matcher.py +95 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/__init__.py +13 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/beanie/__init__.py +6 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/beanie/repository.py +413 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/__init__.py +7 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/models.py +114 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/models_mixins.py +261 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/orms/sqlalchemy/repository.py +528 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/provider.py +166 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/resolver.py +99 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/router.py +305 -0
- hexcore-11.0.2/hexcore/darwin/plugins/rbac/service.py +468 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/__init__.py +1 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/helpers.py +1 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/events.py +0 -40
- hexcore-11.0.2/hexcore/infrastructure/repositories/orms/sqlalchemy/id_types.py +56 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/utils.py +4 -1
- {hexcore-10.2.0 → hexcore-11.0.2/hexcore.egg-info}/PKG-INFO +28 -5
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/SOURCES.txt +41 -6
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/requires.txt +6 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/pyproject.toml +12 -1
- hexcore-11.0.2/tests/test_darwin_10_4_hardening.py +418 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_backend_neutrality.py +18 -4
- hexcore-11.0.2/tests/test_darwin_drbac_conditions.py +412 -0
- hexcore-11.0.2/tests/test_darwin_drbac_pdp.py +449 -0
- hexcore-11.0.2/tests/test_darwin_drbac_router.py +381 -0
- hexcore-11.0.2/tests/test_darwin_drbac_service.py +470 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_impersonate.py +2 -2
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_oauth.py +2 -2
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_passkey.py +2 -2
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_plugin_decoupling.py +2 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_plugins.py +126 -0
- hexcore-11.0.2/tests/test_darwin_rbac.py +438 -0
- hexcore-11.0.2/tests/test_darwin_rbac_service.py +518 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_schema_registration.py +13 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_username.py +18 -11
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_deprecations.py +104 -222
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_documentation_examples.py +5 -1
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_optional_dependencies.py +69 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_testing_kit.py +7 -7
- hexcore-10.2.0/hexcore/__init__.py +0 -86
- hexcore-10.2.0/hexcore/domain/auth/__init__.py +0 -66
- hexcore-10.2.0/hexcore/domain/auth/permissions.py +0 -71
- hexcore-10.2.0/hexcore/domain/auth/value_objects.py +0 -17
- hexcore-10.2.0/hexcore/infrastructure/events/events_backends/memory.py +0 -40
- hexcore-10.2.0/hexcore/infrastructure/repositories/__init__.py +0 -0
- hexcore-10.2.0/hexcore/infrastructure/repositories/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/LICENSE +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/MANIFEST.in +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/__main__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/adapters.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/config.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/factory.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/in_memory_buses.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/pipeline.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/registry.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/cqrs/scheduler.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/base.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/cursor.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/errors.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/dtos/query.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/config.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/factory.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/projector.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/relay.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/eventsourcing/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/base.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/application/use_cases/query.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/capabilities.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/config.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/cqrs.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/cqrs.pyi +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/authorization.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/authz_middleware.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/commands.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/config.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/container.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/hooks.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/application/plugins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/authorization.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/entities.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/events.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/exceptions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/permissions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/plugins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/domain/value_objects.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/authorization.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/dependencies.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/middlewares.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/api/routers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/cli.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/clock.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/envelope.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/hashing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/keys.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/documents.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/repositories.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/beanie/schema.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/selection.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/registry.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/repositories.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/orms/sqlalchemy/schema.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/revocation.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/secretbox.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/tokens.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/infrastructure/transports.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/commands.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/domain.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/impersonate/service.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/commands.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/magic_link/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/domain.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/http.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/beanie/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/orms/sqlalchemy/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/providers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/oauth/service.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/domain.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/beanie/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/orms/sqlalchemy/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/organization/service.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/domain.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/beanie/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/orms/sqlalchemy/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/service.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/passkey/webauthn_adapter.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/storage.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/commands.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/crypto.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/domain.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/beanie/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/orms/sqlalchemy/repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/router.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/service.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/plugins/two_factor/totp.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/fakes.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/darwin/testing/fixtures.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/base.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/buses.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/commands.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/context.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/cron.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/decorators.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/dispatch.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/envelope.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/exceptions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/handlers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/middleware.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/queries.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/resolution.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/serializer.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/cqrs/task_queues.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/aggregate.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/exceptions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/projections.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/snapshots.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/store.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/eventsourcing/stored.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/exceptions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/repositories.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/services.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/domain/uow.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/eventsourcing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/eventsourcing.pyi +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/fastapi.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/fastapi.pyi +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/app.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/cqrs.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/eventsourcing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/exception_handlers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/health.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/lifespan.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/middlewares.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/rate_limit.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/routing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/streaming.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/api/utils.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/memory.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cache/cache_backends/redis.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cli.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/cron_sql.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/middlewares.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/postgres_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/postgres_lock.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/procrastinate.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/pydantic_serializer.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/rabbitmq.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/redis_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/cqrs/redis_lock.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/beanie_documents.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/beanie_store.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/memory.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/redis_store.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_models_mixins.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/eventsourcing/sqlalchemy_store.py +0 -0
- {hexcore-10.2.0/hexcore/infrastructure/events → hexcore-11.0.2/hexcore/infrastructure/repositories}/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/_beanie_impl.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/_sqlalchemy_impl.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/base.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/decorators.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/implementations.py +0 -0
- {hexcore-10.2.0/hexcore/infrastructure/events/events_backends → hexcore-11.0.2/hexcore/infrastructure/repositories/orms}/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/beanie/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/beanie/utils.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/orms/sqlalchemy/session.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/repositories/utils.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/celery_adapter.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/task_queues/procrastinate_adapter.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/decorators.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/helpers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/uow/scopes.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/consumer.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/rabbitmq_worker.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/infrastructure/workers/runner.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/py.typed +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/sql.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/sql.pyi +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/__init__.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/fakes.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/fixtures.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/helpers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/testing/repositories.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore/types.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/dependency_links.txt +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/entry_points.txt +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/hexcore.egg-info/top_level.txt +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/setup.cfg +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_alembic_metadata_completeness.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_anclas_del_repo.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_app_and_lifespan.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_cqrs_providers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_exception_handlers.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_health.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_middlewares_and_routing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_rate_limit.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_api_streaming.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_basic.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_beanie_query_utils.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_celery_event_loop.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_config_cors_security.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_config_loading.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_consumer_optional_event_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_envelope.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_factory.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cqrs_middlewares.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_cron_sql.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_authorization_engine.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_authorization_http.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_beanie.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_cli.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_container.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_context.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_custom_plugin.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_envelope.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_facade_and_events.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_flows.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_hashing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_http.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_magic_link.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_models.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_openapi.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_organization.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_permissions.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_principals.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_production_defaults.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_repositories.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_revocation.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_storage_selection.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_tokens.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_two_factor.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_darwin_value_objects.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_domain_base_contract.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_domain_service_query.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_dotted_resolution.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_event_dispatch_mro.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_aggregate.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_beanie.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_config.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_ports.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_projections.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_redis.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_relay.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_repository.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_snapshot_checkpoint.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_sql_schema.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_store_contract.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_eventsourcing_uow_integration.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_facades.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_handler_registry.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_infrastructure_query_path.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_lock_error_policy.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_packaging.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_postgres_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_postgres_lock.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_query_cursor_and_endpoint.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_query_field_validation.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_rabbitmq_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_redis_bus.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_redis_lock.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_repositories_utils.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_scheduler.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_scheduler_catchup.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_smart_routing.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_sql_naming_convention.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_sql_session_layer.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_task_queues_adapters.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_testing_utilities.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_typing_gate.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_uow_session_regression.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_use_cases_query.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_worker_bus_integration.py +0 -0
- {hexcore-10.2.0 → hexcore-11.0.2}/tests/test_worker_runner.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hexcore
|
|
3
|
-
Version:
|
|
3
|
+
Version: 11.0.2
|
|
4
4
|
Summary: Reusable core for Python projects with hexagonal architecture, DDD, CQRS and background tasks. Ships the abstractions and the infrastructure: SQL session layer, FastAPI factories, worker runner, dynamic cron and identity.
|
|
5
5
|
Author-email: "David Latosefki (Indroic)" <indroic@outlook.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -71,6 +71,10 @@ Requires-Dist: hexcore[darwin]; extra == "darwin-passkey"
|
|
|
71
71
|
Requires-Dist: webauthn>=2.0.0; extra == "darwin-passkey"
|
|
72
72
|
Provides-Extra: darwin-organization
|
|
73
73
|
Requires-Dist: hexcore[darwin]; extra == "darwin-organization"
|
|
74
|
+
Provides-Extra: darwin-rbac
|
|
75
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-rbac"
|
|
76
|
+
Provides-Extra: darwin-drbac
|
|
77
|
+
Requires-Dist: hexcore[darwin]; extra == "darwin-drbac"
|
|
74
78
|
Provides-Extra: all
|
|
75
79
|
Requires-Dist: fastapi>=0.116.1; extra == "all"
|
|
76
80
|
Requires-Dist: redis>=6.4.0; extra == "all"
|
|
@@ -278,8 +282,9 @@ Both generate a root `config.py` and leave Alembic configured. See
|
|
|
278
282
|
|
|
279
283
|
| Series | Status | What it means |
|
|
280
284
|
| :-- | :-- | :-- |
|
|
281
|
-
| **
|
|
282
|
-
| **
|
|
285
|
+
| **11.x** | ✅ **Active** | The only supported one. Receives features and fixes. Removes everything 11.0 had promised to remove — see the table below — and fixes the plugin startup steps that broke boot. |
|
|
286
|
+
| **10.x** | ⛔ **Deprecated** | Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. Migrating to 11.x means dropping the names removed there; the deprecation warnings named each replacement. |
|
|
287
|
+
| **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. The schema change is not mechanical: see the storage guide. |
|
|
283
288
|
| **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
|
|
284
289
|
| **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
|
|
285
290
|
| **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
|
|
@@ -305,8 +310,8 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
|
|
|
305
310
|
| `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
|
|
306
311
|
| `IMiddleware` | `AbstractMiddleware` |
|
|
307
312
|
| `ISerializer` | `AbstractSerializer` |
|
|
308
|
-
| `IEventDispatcher` | `
|
|
309
|
-
| `EventBus.register()` / `.dispatch()` | `
|
|
313
|
+
| `IEventDispatcher` | `AbstractEventBus` |
|
|
314
|
+
| `EventBus.register()` / `.dispatch()` | `AbstractEventBus.subscribe()` / `.publish()` |
|
|
310
315
|
| `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
|
|
311
316
|
| `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
|
|
312
317
|
| `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
|
|
@@ -314,6 +319,24 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
|
|
|
314
319
|
| `reset_sqlalchemy_engine()` | `dispose_engine()` |
|
|
315
320
|
| `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
|
|
316
321
|
|
|
322
|
+
The 9.0 and 10.0 deprecations were removed in 11.0, on the schedule each warning announced.
|
|
323
|
+
The replacement is mechanical in every case: the old name kept working, and warned, for a full
|
|
324
|
+
major.
|
|
325
|
+
|
|
326
|
+
| Removed in 11.0 | Use instead | Deprecated since |
|
|
327
|
+
| :-- | :-- | :-- |
|
|
328
|
+
| `hexcore.domain.events.EventBus` | `hexcore.domain.cqrs.buses.AbstractEventBus` | 9.0 |
|
|
329
|
+
| `hexcore.infrastructure.events.events_backends.memory.InMemoryEventBus` | `hexcore.cqrs.InMemoryEventBus` | 9.0 |
|
|
330
|
+
| `hexcore.domain.auth` (the whole package) | `hexcore.darwin` | 10.0 |
|
|
331
|
+
| `hexcore.domain.auth.PermissionsRegistry`, `hexcore.PermissionsRegistry` | `hexcore.darwin.RoleRegistry` | 10.0 |
|
|
332
|
+
| `hexcore.domain.auth.TokenClaims`, `hexcore.TokenClaims` | `hexcore.darwin.AccessTokenClaims` | 10.0 |
|
|
333
|
+
| `IdentityService.sign_in(email=...)` | `IdentityService.sign_in(identifier=...)` | 10.0 |
|
|
334
|
+
|
|
335
|
+
`TokenClaims` and `AccessTokenClaims` were never interchangeable — different fields, different
|
|
336
|
+
invariants, and `TokenClaims` had no `sid`, so a session issued with it could not be revoked.
|
|
337
|
+
That is why the old name returned the old object and warned instead of aliasing to the new one,
|
|
338
|
+
and it is why porting is a rewrite of the claims you build, not a rename.
|
|
339
|
+
|
|
317
340
|
Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
|
|
318
341
|
rather than being silently ignored: pydantic discards keyword arguments it does not know, and
|
|
319
342
|
keeping the default bus without noticing would surface much later as "my events never arrive".
|
|
@@ -187,8 +187,9 @@ Both generate a root `config.py` and leave Alembic configured. See
|
|
|
187
187
|
|
|
188
188
|
| Series | Status | What it means |
|
|
189
189
|
| :-- | :-- | :-- |
|
|
190
|
-
| **
|
|
191
|
-
| **
|
|
190
|
+
| **11.x** | ✅ **Active** | The only supported one. Receives features and fixes. Removes everything 11.0 had promised to remove — see the table below — and fixes the plugin startup steps that broke boot. |
|
|
191
|
+
| **10.x** | ⛔ **Deprecated** | Darwin gains username sign-in, an optional email, a resolver for roles and scopes, a persisted key store, and startup checks that refuse the development defaults in production. Migrating to 11.x means dropping the names removed there; the deprecation warnings named each replacement. |
|
|
192
|
+
| **9.x** | ⛔ **Deprecated** | Adds the event store and Event Sourcing, and leaves a single event bus port. The schema change is not mechanical: see the storage guide. |
|
|
192
193
|
| **8.x** | ⛔ **Deprecated** | Ships Darwin. Migrating to 9.x is mechanical: the two deprecated names still resolve and warn. |
|
|
193
194
|
| **7.x** | ⛔ **Deprecated** | Removes the pre-5.0 surface and fixes the CORS and rate-limiting defects. No Darwin: it shipped before the module landed on `master`. |
|
|
194
195
|
| **6.x** | ⛔ **Deprecated** | No longer receives fixes. Contains the CORS and rate-limiting security defects fixed in 7.0, and the pre-5.0 aliases still present. |
|
|
@@ -214,8 +215,8 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
|
|
|
214
215
|
| `ICommandHandler`, `IQueryHandler` | `AbstractCommandHandler`, `AbstractQueryHandler` |
|
|
215
216
|
| `IMiddleware` | `AbstractMiddleware` |
|
|
216
217
|
| `ISerializer` | `AbstractSerializer` |
|
|
217
|
-
| `IEventDispatcher` | `
|
|
218
|
-
| `EventBus.register()` / `.dispatch()` | `
|
|
218
|
+
| `IEventDispatcher` | `AbstractEventBus` |
|
|
219
|
+
| `EventBus.register()` / `.dispatch()` | `AbstractEventBus.subscribe()` / `.publish()` |
|
|
219
220
|
| `ServerConfig.event_dispatcher` | `ServerConfig.event_bus` |
|
|
220
221
|
| `SQLAlchemyCommonImplementationsRepo` | `SqlAlchemyRepository` |
|
|
221
222
|
| `BeanieODMCommonImplementationsRepo` | `BeanieRepository` |
|
|
@@ -223,6 +224,24 @@ The v1/v2 aliases were deprecated since 5.0 — two full majors of notice — an
|
|
|
223
224
|
| `reset_sqlalchemy_engine()` | `dispose_engine()` |
|
|
224
225
|
| `MiddlewareConfig` | **Removed in 3.0.** It was dead code: never read. |
|
|
225
226
|
|
|
227
|
+
The 9.0 and 10.0 deprecations were removed in 11.0, on the schedule each warning announced.
|
|
228
|
+
The replacement is mechanical in every case: the old name kept working, and warned, for a full
|
|
229
|
+
major.
|
|
230
|
+
|
|
231
|
+
| Removed in 11.0 | Use instead | Deprecated since |
|
|
232
|
+
| :-- | :-- | :-- |
|
|
233
|
+
| `hexcore.domain.events.EventBus` | `hexcore.domain.cqrs.buses.AbstractEventBus` | 9.0 |
|
|
234
|
+
| `hexcore.infrastructure.events.events_backends.memory.InMemoryEventBus` | `hexcore.cqrs.InMemoryEventBus` | 9.0 |
|
|
235
|
+
| `hexcore.domain.auth` (the whole package) | `hexcore.darwin` | 10.0 |
|
|
236
|
+
| `hexcore.domain.auth.PermissionsRegistry`, `hexcore.PermissionsRegistry` | `hexcore.darwin.RoleRegistry` | 10.0 |
|
|
237
|
+
| `hexcore.domain.auth.TokenClaims`, `hexcore.TokenClaims` | `hexcore.darwin.AccessTokenClaims` | 10.0 |
|
|
238
|
+
| `IdentityService.sign_in(email=...)` | `IdentityService.sign_in(identifier=...)` | 10.0 |
|
|
239
|
+
|
|
240
|
+
`TokenClaims` and `AccessTokenClaims` were never interchangeable — different fields, different
|
|
241
|
+
invariants, and `TokenClaims` had no `sid`, so a session issued with it could not be revoked.
|
|
242
|
+
That is why the old name returned the old object and warned instead of aliasing to the new one,
|
|
243
|
+
and it is why porting is a rewrite of the claims you build, not a rename.
|
|
244
|
+
|
|
226
245
|
Passing `event_dispatcher=` to `ServerConfig` **fails with an error that says what to use**,
|
|
227
246
|
rather than being silently ignored: pydantic discards keyword arguments it does not know, and
|
|
228
247
|
keeping the default bus without noticing would surface much later as "my events never arrive".
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Euphoria Kernel Core
|
|
3
|
+
Submódulo principal con entidades, eventos y repositorios.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from .domain.base import BaseEntity
|
|
8
|
+
from .domain.events import (
|
|
9
|
+
DomainEvent,
|
|
10
|
+
EntityCreatedEvent,
|
|
11
|
+
EntityDeletedEvent,
|
|
12
|
+
EntityUpdatedEvent,
|
|
13
|
+
)
|
|
14
|
+
from .domain.repositories import IBaseRepository
|
|
15
|
+
from .infrastructure.repositories.base import (
|
|
16
|
+
BaseSQLAlchemyRepository,
|
|
17
|
+
)
|
|
18
|
+
from .infrastructure import cli
|
|
19
|
+
from .infrastructure import cache
|
|
20
|
+
from .application.dtos.base import DTO
|
|
21
|
+
from . import config
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"BaseEntity",
|
|
25
|
+
"DTO",
|
|
26
|
+
"DomainEvent",
|
|
27
|
+
"EntityCreatedEvent",
|
|
28
|
+
"EntityDeletedEvent",
|
|
29
|
+
"EntityUpdatedEvent",
|
|
30
|
+
"IBaseRepository",
|
|
31
|
+
"BaseSQLAlchemyRepository",
|
|
32
|
+
"cli",
|
|
33
|
+
"cache",
|
|
34
|
+
"config",
|
|
35
|
+
]
|
|
@@ -3,8 +3,10 @@ Mecanismo de deprecación de HexCore.
|
|
|
3
3
|
|
|
4
4
|
Los alias anteriores a 5.0 (`ICommandBus`, `ISerializer`, `NoSqlUnitOfWork`, …) **se
|
|
5
5
|
eliminaron en 7.0**: estaban deprecados desde 5.0, o sea dos majors de aviso. Este módulo
|
|
6
|
-
queda como el mecanismo, no como su inventario — lo usa lo que se deprece de acá en adelante
|
|
7
|
-
|
|
6
|
+
queda como el mecanismo, no como su inventario — lo usa lo que se deprece de acá en adelante.
|
|
7
|
+
En 11.0 se eliminó la tanda que vencía ahí (`hexcore.domain.auth`, los dos buses de eventos
|
|
8
|
+
viejos y `sign_in(email=...)`), así que hoy el inventario está vacío: el módulo es el mecanismo
|
|
9
|
+
listo para la próxima deprecación.
|
|
8
10
|
|
|
9
11
|
Un alias declarado como `ICommandBus = AbstractCommandBus` **no puede avisar**: es una
|
|
10
12
|
asignación, y leerlo no ejecuta nada. Por eso el aviso se implementa con `__getattr__` de
|
|
@@ -45,14 +47,16 @@ __all__ = [
|
|
|
45
47
|
#: En 7.0 los alias pre-5.0 **se eliminaron de verdad**. La constante apunta siempre al
|
|
46
48
|
#: próximo major por publicar, y por eso se corre con cada major en vez de quedarse fija.
|
|
47
49
|
#:
|
|
48
|
-
#:
|
|
49
|
-
#: `hexcore.domain.events.EventBus` y el `InMemoryEventBus` de
|
|
50
|
-
#:
|
|
50
|
+
#: En 11.0 se eliminó lo que prometía irse en 11.0, que es lo que mantiene honesta a la
|
|
51
|
+
#: constante: `hexcore.domain.events.EventBus` y el `InMemoryEventBus` de
|
|
52
|
+
#: `infrastructure.events` (deprecados en 9.0), `hexcore.domain.auth` entero con
|
|
53
|
+
#: `PermissionsRegistry` y `TokenClaims`, y el alias `sign_in(email=...)` (deprecado en 10.0).
|
|
54
|
+
#: El bump a 11.0.0 los dejó pasar, y los dos tests de abajo fueron los que lo cazaron.
|
|
51
55
|
#:
|
|
52
56
|
#: Lo vigila `test_removed_in_is_ahead_of_the_published_version`: si un bump vuelve a alcanzar
|
|
53
57
|
#: este valor, el fallo salta en CI y no en el aviso que lee el usuario. Ese test es el que
|
|
54
58
|
#: convierte "se nos pasó" en "no se puede releasear".
|
|
55
|
-
REMOVED_IN = "
|
|
59
|
+
REMOVED_IN = "12.0"
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
def warn_deprecated(
|
|
@@ -135,10 +139,10 @@ def deprecated_lazy_names(
|
|
|
135
139
|
|
|
136
140
|
La diferencia con `deprecated_aliases`, que es la razón de que existan las dos: `deprecated_aliases`
|
|
137
141
|
resuelve el alias al **reemplazo** —sirve cuando los dos nombres apuntan a lo mismo— y esto
|
|
138
|
-
devuelve lo viejo, que sigue existiendo con su propia forma.
|
|
139
|
-
`hexcore.domain.auth
|
|
140
|
-
campos, distintos invariantes), así que aliasarlos
|
|
141
|
-
|
|
142
|
+
devuelve lo viejo, que sigue existiendo con su propia forma. Fue el caso de
|
|
143
|
+
`hexcore.domain.auth` hasta que se eliminó en 11.0: `TokenClaims` y `AccessTokenClaims` **no**
|
|
144
|
+
eran intercambiables (distintos campos, distintos invariantes), así que aliasarlos habría roto
|
|
145
|
+
a quien todavía usaba el viejo. Lo que hacía falta era que siguiera funcionando **y avisara**.
|
|
142
146
|
|
|
143
147
|
Y perezoso porque el objeto viejo puede vivir en un módulo que no se quiere importar en el
|
|
144
148
|
arranque: el `from` eager es justamente lo que se está sacando.
|
|
@@ -90,6 +90,10 @@ _EXPORTS: dict[str, tuple[str, str]] = {
|
|
|
90
90
|
"hexcore.darwin.domain.ports",
|
|
91
91
|
"NullPrincipalResolver",
|
|
92
92
|
),
|
|
93
|
+
"CompositePrincipalResolver": (
|
|
94
|
+
"hexcore.darwin.domain.ports",
|
|
95
|
+
"CompositePrincipalResolver",
|
|
96
|
+
),
|
|
93
97
|
"ResolvedPrincipal": ("hexcore.darwin.domain.ports", "ResolvedPrincipal"),
|
|
94
98
|
"AbstractSessionRepository": (
|
|
95
99
|
"hexcore.darwin.domain.ports",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
#
|
|
10
10
|
# Existe porque la fachada resuelve sus exports con `__getattr__` y declara
|
|
11
11
|
# `__all__ = sorted(_EXPORTS)`: las dos son expresiones de runtime, así que sin este stub
|
|
12
|
-
# los
|
|
12
|
+
# los 215 símbolos de `hexcore.darwin` tipan `Any`. El runtime no cambia — Python usa
|
|
13
13
|
# el `.py` y el checker usa el `.pyi`, así que la carga perezosa se mantiene.
|
|
14
14
|
|
|
15
15
|
|
|
@@ -128,6 +128,7 @@ from hexcore.darwin.domain.ports import AbstractRevocationList as AbstractRevoca
|
|
|
128
128
|
from hexcore.darwin.domain.ports import AbstractSessionRepository as AbstractSessionRepository
|
|
129
129
|
from hexcore.darwin.domain.ports import AbstractUserRepository as AbstractUserRepository
|
|
130
130
|
from hexcore.darwin.domain.ports import AbstractVerificationRepository as AbstractVerificationRepository
|
|
131
|
+
from hexcore.darwin.domain.ports import CompositePrincipalResolver as CompositePrincipalResolver
|
|
131
132
|
from hexcore.darwin.domain.ports import NullPrincipalResolver as NullPrincipalResolver
|
|
132
133
|
from hexcore.darwin.domain.ports import ResolvedPrincipal as ResolvedPrincipal
|
|
133
134
|
from hexcore.darwin.domain.value_objects import AccessTokenClaims as AccessTokenClaims
|
|
@@ -270,6 +271,7 @@ __all__ = [
|
|
|
270
271
|
"CacheErrorPolicy",
|
|
271
272
|
"CacheRevocationList",
|
|
272
273
|
"ChangePassword",
|
|
274
|
+
"CompositePrincipalResolver",
|
|
273
275
|
"CookieConfig",
|
|
274
276
|
"CookieTransport",
|
|
275
277
|
"CoreVerificationPurpose",
|
|
@@ -798,34 +798,6 @@ class IdentityService:
|
|
|
798
798
|
)
|
|
799
799
|
return usuario, codigo
|
|
800
800
|
|
|
801
|
-
def _resolver_alias_de_identificador(
|
|
802
|
-
self, identifier: str | None, email: str | None
|
|
803
|
-
) -> str:
|
|
804
|
-
"""
|
|
805
|
-
Acepta `email=` como alias deprecado de `identifier=`.
|
|
806
|
-
|
|
807
|
-
El parámetro se llamaba `email` hasta 10.0, y renombrarlo sin más rompería en silencio
|
|
808
|
-
a todo el que llame al servicio por keyword — que es la forma en que el servicio se
|
|
809
|
-
llama, porque la firma es keyword-only.
|
|
810
|
-
"""
|
|
811
|
-
if identifier is not None and email is not None:
|
|
812
|
-
raise ValueError(
|
|
813
|
-
"Se pasaron `identifier` y `email` a la vez. `email` es el nombre viejo del "
|
|
814
|
-
"mismo parámetro: usá sólo `identifier`."
|
|
815
|
-
)
|
|
816
|
-
if identifier is not None:
|
|
817
|
-
return identifier
|
|
818
|
-
if email is not None:
|
|
819
|
-
from hexcore._deprecation import warn_deprecated
|
|
820
|
-
|
|
821
|
-
warn_deprecated(
|
|
822
|
-
"IdentityService.sign_in(email=...)",
|
|
823
|
-
"IdentityService.sign_in(identifier=...)",
|
|
824
|
-
since="10.0",
|
|
825
|
-
)
|
|
826
|
-
return email
|
|
827
|
-
raise ValueError("Falta el identificador: `sign_in(identifier=..., password=...)`.")
|
|
828
|
-
|
|
829
801
|
async def _buscar_por_identificador(self, identificador: str) -> User | None:
|
|
830
802
|
"""
|
|
831
803
|
Busca al usuario por lo que la configuración habilite.
|
|
@@ -930,20 +902,19 @@ class IdentityService:
|
|
|
930
902
|
async def sign_in(
|
|
931
903
|
self,
|
|
932
904
|
*,
|
|
933
|
-
identifier: str
|
|
905
|
+
identifier: str,
|
|
934
906
|
password: str,
|
|
935
907
|
transport: Transport = "cookie",
|
|
936
908
|
ip_address: str | None = None,
|
|
937
909
|
user_agent: str | None = None,
|
|
938
910
|
scopes: t.Iterable[str] | None = None,
|
|
939
|
-
email: str | None = None,
|
|
940
911
|
) -> tuple[User, IdentitySession, TokenPair]:
|
|
941
912
|
"""
|
|
942
913
|
Autentica con credencial local y crea la sesión.
|
|
943
914
|
|
|
944
915
|
`identifier` es el mail o el nombre de usuario, según lo que habilite
|
|
945
|
-
`IdentityConfig.sign_in_identifiers`. `email
|
|
946
|
-
|
|
916
|
+
`IdentityConfig.sign_in_identifiers`. El alias `email=`, deprecado en 10.0, se
|
|
917
|
+
**eliminó en 11.0**.
|
|
947
918
|
|
|
948
919
|
**El orden de los chequeos es deliberado y es la parte que importa.** Primero se resuelve
|
|
949
920
|
la credencial y se verifica la contraseña —hasheando un señuelo si no hay fila— y sólo
|
|
@@ -962,8 +933,7 @@ class IdentityService:
|
|
|
962
933
|
mismo error para los dos**, y con el mismo tiempo de respuesta.
|
|
963
934
|
AccountLockedError, EmailNotVerifiedError: sólo tras validar la contraseña.
|
|
964
935
|
"""
|
|
965
|
-
|
|
966
|
-
usuario = await self._buscar_por_identificador(identificador)
|
|
936
|
+
usuario = await self._buscar_por_identificador(identifier)
|
|
967
937
|
|
|
968
938
|
credencial = (
|
|
969
939
|
await self._accounts.get_credential(usuario.id) if usuario else None
|
|
@@ -226,6 +226,49 @@ class AuthContext(BaseModel, t.Generic[TUser]):
|
|
|
226
226
|
|
|
227
227
|
return self
|
|
228
228
|
|
|
229
|
+
# ── Callers externos a Darwin ─────────────────────────────────────────────
|
|
230
|
+
@classmethod
|
|
231
|
+
def external(
|
|
232
|
+
cls,
|
|
233
|
+
user_id: UUID,
|
|
234
|
+
*,
|
|
235
|
+
roles: t.Iterable[str] = (),
|
|
236
|
+
scopes: t.Iterable[str] = (),
|
|
237
|
+
status: str | None = None,
|
|
238
|
+
transport: Transport = "bearer",
|
|
239
|
+
) -> "AuthContext[t.Any]":
|
|
240
|
+
"""
|
|
241
|
+
Un `AuthContext` para un caller externo a Darwin (HC-21).
|
|
242
|
+
|
|
243
|
+
`AccessRequest.context` exige un `AuthContext`, y hasta acá la única forma de tener uno
|
|
244
|
+
era un `Principal` de Darwin real —con su `session_id`, resuelto por
|
|
245
|
+
`AbstractPrincipalResolver`—. Un token de **otro** sistema de identidad —el caso que
|
|
246
|
+
motiva esto es la APK de redv2, que se queda en Better Auth mientras la web migra a
|
|
247
|
+
Darwin— no tiene nada de eso, y no había forma de que ese caller pasara por
|
|
248
|
+
`AuthorizationEngine.decide()` sin fabricar una sesión Darwin que no existe.
|
|
249
|
+
|
|
250
|
+
`actor` y `subject` son el mismo `Principal`, sin `session_id` (no hay sesión Darwin
|
|
251
|
+
que revocar) y sin `impersonation` (un caller externo no tiene cómo impersonar *dentro*
|
|
252
|
+
de Darwin — esa noción no existe para él). `transport` queda auditado como lo que
|
|
253
|
+
realmente es: por defecto `"bearer"`, pasable si el caller usa otro transporte.
|
|
254
|
+
|
|
255
|
+
Uso::
|
|
256
|
+
|
|
257
|
+
contexto = AuthContext.external(
|
|
258
|
+
UUID(claims["sub"]), roles=claims["roles"], scopes=claims["permissions"]
|
|
259
|
+
)
|
|
260
|
+
decision = await engine.decide(
|
|
261
|
+
AccessRequest(context=contexto, action="invoice.approve", resource=recurso)
|
|
262
|
+
)
|
|
263
|
+
"""
|
|
264
|
+
principal = Principal(
|
|
265
|
+
user_id=user_id,
|
|
266
|
+
roles=frozenset(roles),
|
|
267
|
+
scopes=frozenset(scopes),
|
|
268
|
+
status=status,
|
|
269
|
+
)
|
|
270
|
+
return cls(actor=principal, subject=principal, transport=transport)
|
|
271
|
+
|
|
229
272
|
# ── Identidades ───────────────────────────────────────────────────────────
|
|
230
273
|
@property
|
|
231
274
|
def actor_id(self) -> UUID | str:
|
|
@@ -49,6 +49,7 @@ __all__ = [
|
|
|
49
49
|
"AbstractAuditSink",
|
|
50
50
|
"AbstractPrincipalResolver",
|
|
51
51
|
"NullPrincipalResolver",
|
|
52
|
+
"CompositePrincipalResolver",
|
|
52
53
|
"ResolvedPrincipal",
|
|
53
54
|
]
|
|
54
55
|
|
|
@@ -466,3 +467,51 @@ class NullPrincipalResolver(AbstractPrincipalResolver):
|
|
|
466
467
|
async def resolve(self, user: "User") -> "ResolvedPrincipal":
|
|
467
468
|
del user
|
|
468
469
|
return ResolvedPrincipal()
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
class CompositePrincipalResolver(AbstractPrincipalResolver):
|
|
473
|
+
"""
|
|
474
|
+
Combina varios `AbstractPrincipalResolver` en uno solo.
|
|
475
|
+
|
|
476
|
+
`configure_identity(principals=...)` sólo tiene **un** slot (HC-16): no hay forma de
|
|
477
|
+
cablear a la vez, por ejemplo, `RbacPrincipalResolver` —que resuelve roles/scopes y nunca
|
|
478
|
+
toca `status`— con un resolver propio de la app que sólo sabe de `status` ("pending",
|
|
479
|
+
"banned", lo que sea). Sin este puente, quien necesitara ambos tenía que reimplementar a
|
|
480
|
+
mano lo que `RbacPrincipalResolver` ya hace, sólo para poder agregarle un `status`.
|
|
481
|
+
|
|
482
|
+
Corre los resolvers en orden y los combina:
|
|
483
|
+
|
|
484
|
+
- `roles` y `scopes`: unión de todos.
|
|
485
|
+
- `status`: el primer resolver de la lista que devuelva algo distinto de `None` — no una
|
|
486
|
+
unión, porque el estado de una cuenta no es un conjunto, es un valor. El orden importa:
|
|
487
|
+
poné primero el resolver cuyo `status` tiene que ganar.
|
|
488
|
+
|
|
489
|
+
Uso::
|
|
490
|
+
|
|
491
|
+
configure_identity(
|
|
492
|
+
IdentityConfig(),
|
|
493
|
+
principals=CompositePrincipalResolver([
|
|
494
|
+
rbac.principal_resolver(), # roles y scopes
|
|
495
|
+
EstadoDeCuentaResolver(uow), # status
|
|
496
|
+
]),
|
|
497
|
+
)
|
|
498
|
+
"""
|
|
499
|
+
|
|
500
|
+
def __init__(self, resolvers: t.Sequence[AbstractPrincipalResolver]) -> None:
|
|
501
|
+
self._resolvers = list(resolvers)
|
|
502
|
+
|
|
503
|
+
async def resolve(self, user: "User") -> "ResolvedPrincipal":
|
|
504
|
+
roles: set[str] = set()
|
|
505
|
+
scopes: set[str] = set()
|
|
506
|
+
status: str | None = None
|
|
507
|
+
|
|
508
|
+
for resolver in self._resolvers:
|
|
509
|
+
resuelto = await resolver.resolve(user)
|
|
510
|
+
roles.update(resuelto.roles)
|
|
511
|
+
scopes.update(resuelto.scopes)
|
|
512
|
+
if status is None and resuelto.status is not None:
|
|
513
|
+
status = resuelto.status
|
|
514
|
+
|
|
515
|
+
return ResolvedPrincipal(
|
|
516
|
+
roles=frozenset(roles), scopes=frozenset(scopes), status=status
|
|
517
|
+
)
|
|
@@ -22,6 +22,26 @@ logger = logging.getLogger("hexcore.darwin.lifespan")
|
|
|
22
22
|
__all__ = ["IdentityStep", "SessionReaperStep", "identity_startup_steps"]
|
|
23
23
|
|
|
24
24
|
|
|
25
|
+
def _verificar_paso(paso: t.Any) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Verifica que el paso de un plugin cumpla `StartupStep` **antes** de arrancar ninguno.
|
|
28
|
+
|
|
29
|
+
Se valida la lista entera primero, y recién después se arranca: un paso mal formado en el
|
|
30
|
+
segundo plugin no puede descubrirse después de que el primero ya corrió su seeding.
|
|
31
|
+
|
|
32
|
+
El mensaje nombra al paso y la forma que le falta porque el síntoma sin esto es
|
|
33
|
+
`AttributeError: 'X' object has no attribute 'start'` saliendo de un módulo del framework,
|
|
34
|
+
que no le dice a nadie que el culpable es el plugin que acaba de agregar.
|
|
35
|
+
"""
|
|
36
|
+
if callable(getattr(paso, "start", None)):
|
|
37
|
+
return
|
|
38
|
+
raise TypeError(
|
|
39
|
+
f"El paso de arranque {type(paso).__name__!r} que aporta un plugin no cumple "
|
|
40
|
+
"`StartupStep`: le falta `async def start(self) -> None`. Un `__call__` no alcanza — "
|
|
41
|
+
"`build_lifespan` y `IdentityStep` llaman a `start()`."
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
25
45
|
class IdentityStep:
|
|
26
46
|
"""
|
|
27
47
|
Configura Darwin y verifica que su esquema esté visible para Alembic.
|
|
@@ -56,11 +76,12 @@ class IdentityStep:
|
|
|
56
76
|
self._config = config
|
|
57
77
|
self._components = dict(components or {})
|
|
58
78
|
self._verify_schema = verify_schema
|
|
79
|
+
self._plugin_steps: list[t.Any] = []
|
|
59
80
|
|
|
60
81
|
async def start(self) -> None:
|
|
61
82
|
from hexcore.darwin.application.container import configure_identity
|
|
62
83
|
|
|
63
|
-
configure_identity(self._config, **self._components)
|
|
84
|
+
contenedor = configure_identity(self._config, **self._components)
|
|
64
85
|
logger.info("Darwin configurado.")
|
|
65
86
|
|
|
66
87
|
self._verificar_defaults_de_produccion()
|
|
@@ -68,15 +89,32 @@ class IdentityStep:
|
|
|
68
89
|
if self._verify_schema:
|
|
69
90
|
self._verificar_esquema()
|
|
70
91
|
|
|
92
|
+
# `PluginRegistry.startup_steps()` existe hace varias versiones, pero nada lo llamaba
|
|
93
|
+
# acá — `RbacSeedStep` (y cualquier otro paso de plugin, como el reaper de passkeys)
|
|
94
|
+
# sólo corría si el consumidor lo descubría y lo agregaba a mano a su propio
|
|
95
|
+
# `build_lifespan(...)` (HC-17). Se corren en el orden en que los plugins fueron
|
|
96
|
+
# registrados, después de que el contenedor ya existe.
|
|
97
|
+
self._plugin_steps = list(contenedor.plugins.startup_steps())
|
|
98
|
+
for paso in self._plugin_steps:
|
|
99
|
+
_verificar_paso(paso)
|
|
100
|
+
for paso in self._plugin_steps:
|
|
101
|
+
await paso.start()
|
|
102
|
+
|
|
71
103
|
async def stop(self) -> None:
|
|
72
104
|
"""
|
|
73
|
-
|
|
105
|
+
Para los pasos de los plugins y descarta el contenedor.
|
|
74
106
|
|
|
75
107
|
Importa en un worker de vida larga que reconfigura, y en los tests: sin esto el
|
|
76
108
|
registro del sobre queda apuntando a un contenedor que ya no existe.
|
|
77
109
|
"""
|
|
78
110
|
from hexcore.darwin.application.container import reset_identity
|
|
79
111
|
|
|
112
|
+
for paso in reversed(self._plugin_steps):
|
|
113
|
+
detener = getattr(paso, "stop", None)
|
|
114
|
+
if detener is not None:
|
|
115
|
+
await detener()
|
|
116
|
+
self._plugin_steps = []
|
|
117
|
+
|
|
80
118
|
reset_identity()
|
|
81
119
|
|
|
82
120
|
def _verificar_esquema(self) -> None:
|