oxutils 0.4.1__tar.gz → 0.4.3__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.
Files changed (211) hide show
  1. {oxutils-0.4.1 → oxutils-0.4.3}/PKG-INFO +1 -1
  2. {oxutils-0.4.1 → oxutils-0.4.3}/pyproject.toml +1 -1
  3. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/__init__.py +1 -1
  4. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/middleware.py +19 -2
  5. oxutils-0.4.3/src/oxutils/permissions/__init__.py +1 -0
  6. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/checks.py +36 -0
  7. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/perms.py +58 -0
  8. oxutils-0.4.1/src/oxutils/users/migrations/__init__.py +0 -0
  9. {oxutils-0.4.1 → oxutils-0.4.3}/README.md +0 -0
  10. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/apps.py +0 -0
  11. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/__init__.py +0 -0
  12. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/apps.py +0 -0
  13. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/export.py +0 -0
  14. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/locale/fr/LC_MESSAGES/django.po +0 -0
  15. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/masks.py +0 -0
  16. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/migrations/0001_initial.py +0 -0
  17. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/migrations/__init__.py +0 -0
  18. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/models.py +0 -0
  19. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/settings.py +0 -0
  20. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/audit/utils.py +0 -0
  21. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/__init__.py +0 -0
  22. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/adapter.py +0 -0
  23. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/admin.py +0 -0
  24. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/app_settings.py +0 -0
  25. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/apps.py +0 -0
  26. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/constants.py +0 -0
  27. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/controllers.py +0 -0
  28. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/emails/__init__.py +0 -0
  29. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/emails/controllers.py +0 -0
  30. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/emails/schemas.py +0 -0
  31. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/emails/services.py +0 -0
  32. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/exceptions.py +0 -0
  33. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/__init__.py +0 -0
  34. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/backend.py +0 -0
  35. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/controllers.py +0 -0
  36. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/models.py +0 -0
  37. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/schemas.py +0 -0
  38. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/invitations/tokens.py +0 -0
  39. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/__init__.py +0 -0
  40. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/adapter.py +0 -0
  41. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/base/__init__.py +0 -0
  42. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/base/controllers.py +0 -0
  43. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/base/schemas.py +0 -0
  44. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/recovery_codes/__init__.py +0 -0
  45. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/recovery_codes/controllers.py +0 -0
  46. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/recovery_codes/flows.py +0 -0
  47. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/recovery_codes/schemas.py +0 -0
  48. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/recovery_codes/services.py +0 -0
  49. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/__ini__.py +0 -0
  50. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/controllers.py +0 -0
  51. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/flows.py +0 -0
  52. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/permissions.py +0 -0
  53. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/schemas.py +0 -0
  54. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/totp/services.py +0 -0
  55. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mfa/utils.py +0 -0
  56. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/migrations/0001_initial.py +0 -0
  57. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/migrations/__init__.py +0 -0
  58. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/mixins.py +0 -0
  59. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/models.py +0 -0
  60. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/password_reset/__init__.py +0 -0
  61. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/password_reset/controllers.py +0 -0
  62. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/password_reset/models.py +0 -0
  63. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/password_reset/permissions.py +0 -0
  64. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/password_reset/schemas.py +0 -0
  65. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/registration/__init__.py +0 -0
  66. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/registration/controllers.py +0 -0
  67. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/registration/schemas.py +0 -0
  68. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/schemas.py +0 -0
  69. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/sessions/__init__.py +0 -0
  70. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/sessions/controllers.py +0 -0
  71. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/sessions/schemas.py +0 -0
  72. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/signals.py +0 -0
  73. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/templatetags/__init__.py +0 -0
  74. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/templatetags/spa_urls.py +0 -0
  75. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/__init__.py +0 -0
  76. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/app_settings.py +0 -0
  77. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/models.py +0 -0
  78. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/schemas.py +0 -0
  79. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/tokens.py +0 -0
  80. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/tokens/utils.py +0 -0
  81. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/auth/utils.py +0 -0
  82. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/celery/__init__.py +0 -0
  83. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/celery/base.py +0 -0
  84. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/celery/settings.py +0 -0
  85. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/conf.py +0 -0
  86. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/constants.py +0 -0
  87. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/context/__init__.py +0 -0
  88. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/context/site_name_processor.py +0 -0
  89. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/__init__.py +0 -0
  90. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/admin.py +0 -0
  91. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/apps.py +0 -0
  92. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/caches.py +0 -0
  93. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/controllers.py +0 -0
  94. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/enums.py +0 -0
  95. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/management/__init__.py +0 -0
  96. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/management/commands/__init__.py +0 -0
  97. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/management/commands/sync_currency.py +0 -0
  98. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/migrations/0001_initial.py +0 -0
  99. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/migrations/__init__.py +0 -0
  100. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/models.py +0 -0
  101. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/schemas.py +0 -0
  102. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/signals.py +0 -0
  103. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/tests.py +0 -0
  104. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/currency/utils.py +0 -0
  105. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/enums/__init__.py +0 -0
  106. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/enums/audit.py +0 -0
  107. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/enums/invoices.py +0 -0
  108. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/exceptions.py +0 -0
  109. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/functions.py +0 -0
  110. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/__init__.py +0 -0
  111. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/auth.py +0 -0
  112. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/middleware.py +0 -0
  113. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/models.py +0 -0
  114. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/tokens.py +0 -0
  115. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/jwt/utils.py +0 -0
  116. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/logger/__init__.py +0 -0
  117. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/logger/receivers.py +0 -0
  118. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/logger/settings.py +0 -0
  119. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/mixins/__init__.py +0 -0
  120. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/mixins/base.py +0 -0
  121. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/mixins/schemas.py +0 -0
  122. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/mixins/services.py +0 -0
  123. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/__init__.py +0 -0
  124. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/base.py +0 -0
  125. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/billing.py +0 -0
  126. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/change_tracker.py +0 -0
  127. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/fields.py +0 -0
  128. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/models/invoice.py +0 -0
  129. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/__init__.py +0 -0
  130. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/admin.py +0 -0
  131. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/apps.py +0 -0
  132. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/authorization.py +0 -0
  133. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/cacheops.py +0 -0
  134. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/caches.py +0 -0
  135. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/checks.py +0 -0
  136. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/constants.py +0 -0
  137. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/context.py +0 -0
  138. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/controllers.py +0 -0
  139. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/enums.py +0 -0
  140. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/exceptions.py +0 -0
  141. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/locale/fr/LC_MESSAGES/django.po +0 -0
  142. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/management/__init__.py +0 -0
  143. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/management/commands/__init__.py +0 -0
  144. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/management/commands/grant_tenant_owners.py +0 -0
  145. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/management/commands/init_oxiliere_system.py +0 -0
  146. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/migrations/__init__.py +0 -0
  147. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/models.py +0 -0
  148. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/permissions.py +0 -0
  149. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/schemas.py +0 -0
  150. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/services.py +0 -0
  151. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/settings.py +0 -0
  152. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/signals.py +0 -0
  153. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/tests.py +0 -0
  154. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/oxiliere/utils.py +0 -0
  155. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pagination/__init__.py +0 -0
  156. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pagination/cursor.py +0 -0
  157. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pdf/__init__.py +0 -0
  158. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pdf/printer.py +0 -0
  159. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pdf/utils.py +0 -0
  160. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/pdf/views.py +0 -0
  161. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/actions.py +0 -0
  162. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/admin.py +0 -0
  163. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/apps.py +0 -0
  164. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/caches.py +0 -0
  165. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/constants.py +0 -0
  166. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/controllers.py +0 -0
  167. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/exceptions.py +0 -0
  168. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/locale/fr/LC_MESSAGES/django.po +0 -0
  169. {oxutils-0.4.1/src/oxutils/permissions → oxutils-0.4.3/src/oxutils/permissions/management}/__init__.py +0 -0
  170. {oxutils-0.4.1/src/oxutils/permissions/management → oxutils-0.4.3/src/oxutils/permissions/management/commands}/__init__.py +0 -0
  171. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/management/commands/load_permission_preset.py +0 -0
  172. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0001_initial.py +0 -0
  173. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0002_alter_grant_role.py +0 -0
  174. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0003_alter_grant_options_alter_group_options_and_more.py +0 -0
  175. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0004_group_app_group_permissions_app_9a9924_idx.py +0 -0
  176. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0005_role_app.py +0 -0
  177. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0006_alter_rolegrant_options_and_more.py +0 -0
  178. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0007_grant_locked_alter_grant_role_and_more.py +0 -0
  179. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0008_remove_grant_unique_user_scope_role_and_more.py +0 -0
  180. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/migrations/0009_grant_is_active.py +0 -0
  181. {oxutils-0.4.1/src/oxutils/permissions/management/commands → oxutils-0.4.3/src/oxutils/permissions/migrations}/__init__.py +0 -0
  182. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/models.py +0 -0
  183. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/queryset.py +0 -0
  184. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/schemas.py +0 -0
  185. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/services.py +0 -0
  186. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/tests.py +0 -0
  187. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/permissions/utils.py +0 -0
  188. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/py.typed +0 -0
  189. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/s3.py +0 -0
  190. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/settings.py +0 -0
  191. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/account/email/base_message.txt +0 -0
  192. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/email/password/reset_email_message.html +0 -0
  193. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/email/password/reset_email_message.txt +0 -0
  194. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/email/password/reset_email_subject.txt +0 -0
  195. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/email/signup/email_message.html +0 -0
  196. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/email/signup/email_subject.txt +0 -0
  197. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/templates/verified.html +0 -0
  198. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/types.py +0 -0
  199. {oxutils-0.4.1/src/oxutils/permissions/migrations → oxutils-0.4.3/src/oxutils/users}/__init__.py +0 -0
  200. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/admin.py +0 -0
  201. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/apps.py +0 -0
  202. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/locale/fr/LC_MESSAGES/django.po +0 -0
  203. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/migrations/0001_initial.py +0 -0
  204. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/migrations/0002_alter_user_first_name_alter_user_last_name.py +0 -0
  205. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/migrations/0003_user_photo.py +0 -0
  206. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/migrations/0004_alter_user_options.py +0 -0
  207. {oxutils-0.4.1/src/oxutils/users → oxutils-0.4.3/src/oxutils/users/migrations}/__init__.py +0 -0
  208. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/models.py +0 -0
  209. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/tests.py +0 -0
  210. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/users/utils.py +0 -0
  211. {oxutils-0.4.1 → oxutils-0.4.3}/src/oxutils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oxutils
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: Production-ready utilities for Django applications in the Oxiliere ecosystem
5
5
  Keywords: django,utilities,jwt,audit,logging,celery,structlog
6
6
  Author: Edimedia Mutoke
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "oxutils"
3
- version = "0.4.1"
3
+ version = "0.4.3"
4
4
  description = "Production-ready utilities for Django applications in the Oxiliere ecosystem"
5
5
  readme = "README.md"
6
6
  license = "LGPL-3.0-only"
@@ -15,7 +15,7 @@ This package provides:
15
15
  - Custom exceptions, enums, and type definitions
16
16
  """
17
17
 
18
- __version__ = "0.4.1"
18
+ __version__ = "0.4.3"
19
19
 
20
20
  from oxutils.conf import AUDIT_MIDDLEWARE, UTILS_APPS
21
21
  from oxutils.settings import oxi_settings
@@ -99,8 +99,25 @@ class TenantMainMiddleware(MiddlewareMixin):
99
99
 
100
100
  return HttpResponseBadRequest("Missing X-Organization-ID header")
101
101
  else:
102
- # oxi_id present but no authenticated user
103
- return self.no_tenant_found(request, oxi_id)
102
+ # oxi_id present but no authenticated user → fall back to system tenant
103
+ # (same behaviour as "no org header") — previously this raised Http404,
104
+ # which broke every route (including public ones) when the JWT token
105
+ # expired but the front-end still sent X-Organization-ID.
106
+ try:
107
+ from oxutils.oxiliere.caches import get_system_tenant
108
+
109
+ tenant = get_system_tenant()
110
+ # don't try to attach a tenant-user — the user is anonymous anyway
111
+ tenant.user = None
112
+ except Exception as e:
113
+ logger.error(
114
+ "system_tenant_not_found",
115
+ oxi_id=oxi_id,
116
+ error=str(e),
117
+ )
118
+ from django.http import HttpResponseBadRequest
119
+
120
+ return HttpResponseBadRequest("Missing X-Organization-ID header")
104
121
 
105
122
  # ── Status guards ─────────────────────────────────────────────
106
123
  if tenant.is_deleted or not tenant.is_active:
@@ -291,4 +291,40 @@ def check_permission_settings(app_configs, **kwargs):
291
291
  )
292
292
  )
293
293
 
294
+ # Validate EXTRA_PERMISSIONS
295
+ if hasattr(settings, 'EXTRA_PERMISSIONS'):
296
+ extra = settings.EXTRA_PERMISSIONS
297
+ if not isinstance(extra, (list, tuple)):
298
+ errors.append(
299
+ Error(
300
+ 'EXTRA_PERMISSIONS must be a list or tuple',
301
+ hint='Set EXTRA_PERMISSIONS = ["dotted.path.ToPermission", ...]',
302
+ id='permissions.E019',
303
+ )
304
+ )
305
+ else:
306
+ from django.utils.module_loading import import_string
307
+
308
+ for path in extra:
309
+ if not isinstance(path, str):
310
+ errors.append(
311
+ Error(
312
+ f'Each entry in EXTRA_PERMISSIONS must be a string, got {type(path).__name__}',
313
+ hint='Use dotted paths like "myapp.permissions.MyPermission"',
314
+ id='permissions.E020',
315
+ )
316
+ )
317
+ continue
318
+ try:
319
+ cls = import_string(path)
320
+ except ImportError:
321
+ errors.append(
322
+ Error(
323
+ f'Cannot import "{path}" from EXTRA_PERMISSIONS',
324
+ hint='Check that the module and class exist',
325
+ id='permissions.E021',
326
+ )
327
+ )
328
+ continue
329
+
294
330
  return errors
@@ -1,8 +1,10 @@
1
+ from functools import lru_cache
1
2
  from typing import Optional
2
3
 
3
4
  from django.conf import settings
4
5
  from django.core.exceptions import ImproperlyConfigured
5
6
  from django.http import HttpRequest
7
+ from django.utils.module_loading import import_string
6
8
  from ninja_extra.controllers import ControllerBase
7
9
  from ninja_extra.permissions import BasePermission
8
10
 
@@ -199,3 +201,59 @@ def access_manager(actions: str):
199
201
  )
200
202
 
201
203
  return ScopePermission(perm, context)
204
+
205
+
206
+ @lru_cache(maxsize=1)
207
+ def extra_permissions():
208
+ """
209
+ Return the list of permission instances defined in
210
+ ``EXTRA_PERMISSIONS`` (settings.py).
211
+
212
+ Each entry is a dotted path to an **already instantiated** permission
213
+ object (e.g. a module-level singleton). The object is imported via
214
+ :func:`django.utils.module_loading.import_string` and returned as-is.
215
+
216
+ The result is cached via :func:`functools.lru_cache` so that
217
+ ``import_string`` is only called once per process.
218
+
219
+ Example::
220
+
221
+ # myapp/permissions.py
222
+ from ninja_extra.permissions import BasePermission
223
+
224
+ class IsPremium(BasePermission):
225
+ def has_permission(self, request, controller):
226
+ return request.user.is_premium
227
+
228
+ IsPremium = IsPremium() # <-- singleton instance
229
+
230
+ # settings.py
231
+ EXTRA_PERMISSIONS = [
232
+ "myapp.permissions.IsPremium",
233
+ ]
234
+
235
+ # controller
236
+ from oxutils.permissions import extra_permissions
237
+
238
+ @api_controller(
239
+ "/api",
240
+ permissions=[*extra_permissions(), ScopePermission("articles:r")],
241
+ )
242
+ class MyController:
243
+ ...
244
+ """
245
+ paths = getattr(settings, "EXTRA_PERMISSIONS", [])
246
+ if not isinstance(paths, (list, tuple)):
247
+ raise ImproperlyConfigured(
248
+ "EXTRA_PERMISSIONS must be a list or tuple of dotted paths."
249
+ )
250
+ instances = []
251
+ for path in paths:
252
+ try:
253
+ instance = import_string(path)
254
+ except ImportError as exc:
255
+ raise ImproperlyConfigured(
256
+ f"Cannot import permission from EXTRA_PERMISSIONS: {path}"
257
+ ) from exc
258
+ instances.append(instance)
259
+ return instances
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