oxutils 0.4.3__tar.gz → 0.4.4__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.
- {oxutils-0.4.3 → oxutils-0.4.4}/PKG-INFO +1 -1
- {oxutils-0.4.3 → oxutils-0.4.4}/pyproject.toml +1 -1
- oxutils-0.4.4/src/oxutils/__init__.py +53 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/celery/base.py +6 -1
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/logger/settings.py +3 -1
- oxutils-0.4.4/src/oxutils/permissions/apps.py +23 -0
- oxutils-0.4.4/src/oxutils/permissions/presets.py +131 -0
- oxutils-0.4.3/src/oxutils/__init__.py +0 -28
- oxutils-0.4.3/src/oxutils/permissions/apps.py +0 -10
- {oxutils-0.4.3 → oxutils-0.4.4}/README.md +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/export.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/locale/fr/LC_MESSAGES/django.po +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/masks.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/migrations/0001_initial.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/audit/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/adapter.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/admin.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/app_settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/constants.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/emails/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/emails/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/emails/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/emails/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/exceptions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/backend.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/invitations/tokens.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/adapter.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/base/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/base/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/base/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/recovery_codes/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/recovery_codes/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/recovery_codes/flows.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/recovery_codes/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/recovery_codes/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/__ini__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/flows.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/permissions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/totp/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mfa/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/migrations/0001_initial.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/mixins.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/password_reset/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/password_reset/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/password_reset/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/password_reset/permissions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/password_reset/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/registration/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/registration/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/registration/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/sessions/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/sessions/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/sessions/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/signals.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/templatetags/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/templatetags/spa_urls.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/app_settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/tokens.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/tokens/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/auth/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/celery/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/celery/settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/conf.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/constants.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/context/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/context/site_name_processor.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/admin.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/caches.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/enums.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/management/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/management/commands/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/management/commands/sync_currency.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/migrations/0001_initial.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/signals.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/tests.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/currency/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/enums/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/enums/audit.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/enums/invoices.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/exceptions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/functions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/auth.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/middleware.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/tokens.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/jwt/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/logger/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/logger/receivers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/mixins/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/mixins/base.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/mixins/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/mixins/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/base.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/billing.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/change_tracker.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/fields.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/models/invoice.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/admin.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/authorization.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/cacheops.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/caches.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/checks.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/constants.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/context.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/enums.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/exceptions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/locale/fr/LC_MESSAGES/django.po +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/commands/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/commands/grant_tenant_owners.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/commands/init_oxiliere_system.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/middleware.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/permissions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/signals.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/tests.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pagination/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pagination/cursor.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pdf/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pdf/printer.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pdf/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/pdf/views.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/actions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/admin.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/caches.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/checks.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/constants.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/controllers.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/exceptions.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/locale/fr/LC_MESSAGES/django.po +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/management/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/management/commands/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/management/commands/load_permission_preset.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0001_initial.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0002_alter_grant_role.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0003_alter_grant_options_alter_group_options_and_more.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0004_group_app_group_permissions_app_9a9924_idx.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0005_role_app.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0006_alter_rolegrant_options_and_more.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0007_grant_locked_alter_grant_role_and_more.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0008_remove_grant_unique_user_scope_role_and_more.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/0009_grant_is_active.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/perms.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/queryset.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/schemas.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/services.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/tests.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/permissions/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/py.typed +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/s3.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/settings.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/account/email/base_message.txt +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_message.html +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_message.txt +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_subject.txt +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/signup/email_message.html +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/signup/email_subject.txt +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/verified.html +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/types.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/admin.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/apps.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/locale/fr/LC_MESSAGES/django.po +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/migrations/0001_initial.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/migrations/0002_alter_user_first_name_alter_user_last_name.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/migrations/0003_user_photo.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/migrations/0004_alter_user_options.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/migrations/__init__.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/models.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/tests.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/users/utils.py +0 -0
- {oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/utils.py +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""OxUtils — Production-ready Django utilities for multi-tenant SaaS.
|
|
2
|
+
|
|
3
|
+
Authentication & authorization:
|
|
4
|
+
- JWT authentication: Bearer, Cookie, and passive backends with JWKS support
|
|
5
|
+
- RBAC permissions: roles, groups, user grants with scope-based access
|
|
6
|
+
control (``ScopePermission``, ``ScopeAnyPermission``, etc.)
|
|
7
|
+
- Auto-discovery of permission presets from installed apps
|
|
8
|
+
- Complete auth system: registration, login/logout, password reset,
|
|
9
|
+
MFA, invitations, sessions — integrates with django-allauth
|
|
10
|
+
- Api exceptions with error codes and structured responses
|
|
11
|
+
|
|
12
|
+
Multi-tenancy:
|
|
13
|
+
- django-tenants integration with ``X-Organization-ID`` header routing
|
|
14
|
+
- Tenant / tenant-user models, schema-aware middleware and caching
|
|
15
|
+
- Tenant lifecycle signals, authorization, and system-tenant fallback
|
|
16
|
+
|
|
17
|
+
Infrastructure & tooling:
|
|
18
|
+
- Structured logging with correlation IDs, request metadata binding,
|
|
19
|
+
and pre-built ``LOGGING`` configuration (structlog)
|
|
20
|
+
- Audit log export to S3 with export-state tracking and status history
|
|
21
|
+
- Cursor-based pagination for Django Ninja APIs
|
|
22
|
+
- PDF generation via WeasyPrint (``Printer`` class and ``WeasyTemplateView``)
|
|
23
|
+
- Multi-currency support with rate syncing (BCC, Open Exchange Rates)
|
|
24
|
+
- Celery app with task auto-discovery and structlog integration
|
|
25
|
+
- S3 storage backend factory with env-var configuration
|
|
26
|
+
|
|
27
|
+
Model utilities:
|
|
28
|
+
- Reusable mixins: UUID PK, timestamps, user tracking, slug, ordering,
|
|
29
|
+
soft-delete with field masking (``SafeDeleteModelMixin``),
|
|
30
|
+
change tracking, invoicing, and billing
|
|
31
|
+
- Custom user model with email-based auth, ``oxi_id`` linking, and audit
|
|
32
|
+
- Custom Pydantic types (``EmailApiType``, etc.)
|
|
33
|
+
|
|
34
|
+
Other:
|
|
35
|
+
- HTTP header/cookie constants (oxi tokens, JWT tokens)
|
|
36
|
+
- Template context processor (site name & domain)
|
|
37
|
+
- Central pydantic-settings configuration (``oxi_settings``)
|
|
38
|
+
- Shared enums (invoice status, export status)
|
|
39
|
+
- Utility helpers: client IP detection, absolute URL building,
|
|
40
|
+
image validation, bound-request detection
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
__version__ = "0.4.4"
|
|
44
|
+
|
|
45
|
+
from oxutils.conf import AUDIT_MIDDLEWARE, UTILS_APPS
|
|
46
|
+
from oxutils.settings import oxi_settings
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
"oxi_settings",
|
|
50
|
+
"UTILS_APPS",
|
|
51
|
+
"AUDIT_MIDDLEWARE",
|
|
52
|
+
"__version__",
|
|
53
|
+
]
|
|
@@ -30,6 +30,9 @@ def receiver_setup_logging(loglevel, logfile, format, colorize, **kwargs): # pr
|
|
|
30
30
|
"json_formatter": {
|
|
31
31
|
"()": structlog.stdlib.ProcessorFormatter,
|
|
32
32
|
"processor": structlog.processors.JSONRenderer(),
|
|
33
|
+
"foreign_pre_chain": [
|
|
34
|
+
structlog.processors.format_exc_info,
|
|
35
|
+
],
|
|
33
36
|
},
|
|
34
37
|
"plain_console": {
|
|
35
38
|
"()": structlog.stdlib.ProcessorFormatter,
|
|
@@ -40,6 +43,9 @@ def receiver_setup_logging(loglevel, logfile, format, colorize, **kwargs): # pr
|
|
|
40
43
|
"processor": structlog.processors.KeyValueRenderer(
|
|
41
44
|
key_order=['timestamp', 'level', 'event', 'logger']
|
|
42
45
|
),
|
|
46
|
+
"foreign_pre_chain": [
|
|
47
|
+
structlog.processors.format_exc_info,
|
|
48
|
+
],
|
|
43
49
|
},
|
|
44
50
|
},
|
|
45
51
|
"handlers": {
|
|
@@ -88,7 +94,6 @@ def receiver_setup_logging(loglevel, logfile, format, colorize, **kwargs): # pr
|
|
|
88
94
|
structlog.stdlib.add_log_level,
|
|
89
95
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
90
96
|
structlog.processors.StackInfoRenderer(),
|
|
91
|
-
structlog.processors.format_exc_info,
|
|
92
97
|
structlog.processors.UnicodeDecoder(),
|
|
93
98
|
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
|
|
94
99
|
],
|
|
@@ -16,6 +16,9 @@ LOGGING = {
|
|
|
16
16
|
"json_formatter": {
|
|
17
17
|
"()": structlog.stdlib.ProcessorFormatter,
|
|
18
18
|
"processor": structlog.processors.JSONRenderer(),
|
|
19
|
+
"foreign_pre_chain": [
|
|
20
|
+
structlog.processors.format_exc_info,
|
|
21
|
+
],
|
|
19
22
|
},
|
|
20
23
|
"plain_console": {
|
|
21
24
|
"()": structlog.stdlib.ProcessorFormatter,
|
|
@@ -54,7 +57,6 @@ structlog.configure(
|
|
|
54
57
|
structlog.stdlib.add_log_level,
|
|
55
58
|
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
56
59
|
structlog.processors.StackInfoRenderer(),
|
|
57
|
-
structlog.processors.format_exc_info,
|
|
58
60
|
structlog.processors.UnicodeDecoder(),
|
|
59
61
|
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
|
|
60
62
|
],
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
from django.conf import settings
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PermissionsConfig(AppConfig):
|
|
6
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
7
|
+
name = "oxutils.permissions"
|
|
8
|
+
|
|
9
|
+
def ready(self):
|
|
10
|
+
"""Import checks when app is ready."""
|
|
11
|
+
from . import checks # noqa
|
|
12
|
+
|
|
13
|
+
from .presets import (
|
|
14
|
+
register_preset,
|
|
15
|
+
register_access_scopes,
|
|
16
|
+
register_access_applications,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if hasattr(settings, "PERMISSION_PRESET"):
|
|
20
|
+
register_preset(settings.PERMISSION_PRESET)
|
|
21
|
+
|
|
22
|
+
register_access_applications()
|
|
23
|
+
register_access_scopes()
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Permission preset auto-discovery.
|
|
3
|
+
|
|
4
|
+
Walk installed apps, collect their ``PERMISSION_PRESET`` dicts,
|
|
5
|
+
``ACCESS_APPLICATION_NAME`` and ``ACCESS_SCOPES``, and merge them
|
|
6
|
+
into the global configuration.
|
|
7
|
+
|
|
8
|
+
Called from ``PermissionsConfig.ready()`` when the app registry is ready.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import importlib
|
|
12
|
+
|
|
13
|
+
import structlog
|
|
14
|
+
from django.apps import apps
|
|
15
|
+
from django.conf import settings
|
|
16
|
+
|
|
17
|
+
logger = structlog.get_logger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def discover_app_presets() -> list[dict]:
|
|
21
|
+
"""Walk installed apps and collect their ``PERMISSION_PRESET``."""
|
|
22
|
+
presets: list[dict] = []
|
|
23
|
+
for app_config in apps.get_app_configs():
|
|
24
|
+
try:
|
|
25
|
+
mod = importlib.import_module(f"{app_config.name}.permissions")
|
|
26
|
+
except (ModuleNotFoundError, ImportError):
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
preset = getattr(mod, "PERMISSION_PRESET", None)
|
|
30
|
+
if not isinstance(preset, dict):
|
|
31
|
+
continue
|
|
32
|
+
|
|
33
|
+
for role in preset.get("roles", []):
|
|
34
|
+
role.setdefault("app", app_config.label)
|
|
35
|
+
for group in preset.get("groups", []):
|
|
36
|
+
group.setdefault("app", app_config.label)
|
|
37
|
+
for grant in preset.get("role_grants", []):
|
|
38
|
+
grant.setdefault("app", app_config.label)
|
|
39
|
+
|
|
40
|
+
presets.append(preset)
|
|
41
|
+
logger.info(
|
|
42
|
+
"permission_preset_discovered",
|
|
43
|
+
app=app_config.label,
|
|
44
|
+
roles=len(preset.get("roles", [])),
|
|
45
|
+
groups=len(preset.get("groups", [])),
|
|
46
|
+
grants=len(preset.get("role_grants", [])),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return presets
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def discover_access_scopes() -> list[str]:
|
|
53
|
+
"""Walk installed apps and collect their ``ACCESS_SCOPES``."""
|
|
54
|
+
scopes: list[str] = []
|
|
55
|
+
for app_config in apps.get_app_configs():
|
|
56
|
+
try:
|
|
57
|
+
mod = importlib.import_module(f"{app_config.name}.permissions")
|
|
58
|
+
except (ModuleNotFoundError, ImportError):
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
app_scopes = getattr(mod, "ACCESS_SCOPES", None)
|
|
62
|
+
if isinstance(app_scopes, list):
|
|
63
|
+
for scope in app_scopes:
|
|
64
|
+
if scope not in scopes:
|
|
65
|
+
scopes.append(scope)
|
|
66
|
+
logger.info(
|
|
67
|
+
"access_scope_discovered",
|
|
68
|
+
app=app_config.label,
|
|
69
|
+
scope=scope,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
return scopes
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def discover_access_applications() -> list[str]:
|
|
76
|
+
"""Walk installed apps and collect their ``ACCESS_APPLICATION_NAME``."""
|
|
77
|
+
applications: list[str] = []
|
|
78
|
+
for app_config in apps.get_app_configs():
|
|
79
|
+
try:
|
|
80
|
+
mod = importlib.import_module(f"{app_config.name}.permissions")
|
|
81
|
+
except (ModuleNotFoundError, ImportError):
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
app_name = getattr(mod, "ACCESS_APPLICATION_NAME", None)
|
|
85
|
+
if isinstance(app_name, str) and app_name not in applications:
|
|
86
|
+
applications.append(app_name)
|
|
87
|
+
logger.info(
|
|
88
|
+
"access_application_discovered",
|
|
89
|
+
app=app_config.label,
|
|
90
|
+
application=app_name,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return applications
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def register_preset(base_preset: dict) -> dict:
|
|
97
|
+
"""Extend *base_preset* with presets discovered from installed apps."""
|
|
98
|
+
base_roles = base_preset.setdefault("roles", [])
|
|
99
|
+
base_groups = base_preset.setdefault("groups", [])
|
|
100
|
+
base_grants = base_preset.setdefault("role_grants", [])
|
|
101
|
+
|
|
102
|
+
for preset in discover_app_presets():
|
|
103
|
+
base_roles.extend(preset.get("roles", []))
|
|
104
|
+
base_groups.extend(preset.get("groups", []))
|
|
105
|
+
base_grants.extend(preset.get("role_grants", []))
|
|
106
|
+
|
|
107
|
+
return base_preset
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def register_access_scopes() -> None:
|
|
111
|
+
"""Extend ``settings.ACCESS_SCOPES`` with scopes discovered from installed apps."""
|
|
112
|
+
existing = list(getattr(settings, "ACCESS_SCOPES", []))
|
|
113
|
+
|
|
114
|
+
for scope in discover_access_scopes():
|
|
115
|
+
if scope not in existing:
|
|
116
|
+
existing.append(scope)
|
|
117
|
+
|
|
118
|
+
settings.ACCESS_SCOPES = existing
|
|
119
|
+
logger.info("access_scopes_registered", count=len(existing))
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def register_access_applications() -> None:
|
|
123
|
+
"""Extend ``settings.ACCESS_APPLICATIONS`` with apps discovered from installed apps."""
|
|
124
|
+
existing = list(getattr(settings, "ACCESS_APPLICATIONS", []))
|
|
125
|
+
|
|
126
|
+
for app_name in discover_access_applications():
|
|
127
|
+
if app_name not in existing:
|
|
128
|
+
existing.append(app_name)
|
|
129
|
+
|
|
130
|
+
settings.ACCESS_APPLICATIONS = existing
|
|
131
|
+
logger.info("access_applications_registered", count=len(existing))
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"""OxUtils - Production-ready utilities for Django applications.
|
|
2
|
-
|
|
3
|
-
This package provides:
|
|
4
|
-
- JWT authentication with JWKS support
|
|
5
|
-
- Multi-tenant architecture (django-tenants integration, middleware, signals)
|
|
6
|
-
- Auth system: invitations, MFA, password reset, registration, sessions
|
|
7
|
-
- Structured logging with correlation IDs
|
|
8
|
-
- Audit system with S3 export
|
|
9
|
-
- Celery integration
|
|
10
|
-
- Django model mixins (ChangeTracker, CookieToken, SafeDelete)
|
|
11
|
-
- Permission management & authorization
|
|
12
|
-
- PDF generation
|
|
13
|
-
- Pagination utilities
|
|
14
|
-
- Currency utilities
|
|
15
|
-
- Custom exceptions, enums, and type definitions
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
__version__ = "0.4.3"
|
|
19
|
-
|
|
20
|
-
from oxutils.conf import AUDIT_MIDDLEWARE, UTILS_APPS
|
|
21
|
-
from oxutils.settings import oxi_settings
|
|
22
|
-
|
|
23
|
-
__all__ = [
|
|
24
|
-
"oxi_settings",
|
|
25
|
-
"UTILS_APPS",
|
|
26
|
-
"AUDIT_MIDDLEWARE",
|
|
27
|
-
"__version__",
|
|
28
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/commands/grant_tenant_owners.py
RENAMED
|
File without changes
|
{oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/oxiliere/management/commands/init_oxiliere_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_message.html
RENAMED
|
File without changes
|
{oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_message.txt
RENAMED
|
File without changes
|
{oxutils-0.4.3 → oxutils-0.4.4}/src/oxutils/templates/email/password/reset_email_subject.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|