gramps-webapi 3.22.1__tar.gz → 3.22.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.
Files changed (286) hide show
  1. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/PKG-INFO +1 -1
  2. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/_version.py +1 -1
  3. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/media.py +1 -0
  4. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/trees.py +1 -1
  5. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/util.py +1 -0
  6. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/__init__.py +45 -42
  7. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/const.py +9 -0
  8. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi.egg-info/PKG-INFO +1 -1
  9. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_oidc.py +74 -0
  10. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.devcontainer/Dockerfile +0 -0
  11. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.devcontainer/devcontainer.json +0 -0
  12. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.devcontainer/docker-compose.yml +0 -0
  13. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.dockerignore +0 -0
  14. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.editorconfig +0 -0
  15. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.flake8 +0 -0
  16. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  17. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  18. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  19. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/workflows/base-image.yml +0 -0
  20. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/workflows/image.yml +0 -0
  21. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/workflows/pypi.yml +0 -0
  22. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.github/workflows/test.yml +0 -0
  23. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.gitignore +0 -0
  24. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.pre-commit-config.yaml +0 -0
  25. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.pylintrc +0 -0
  26. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.vscode/extensions.json +0 -0
  27. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.vscode/launch.json +0 -0
  28. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.vscode/settings.json +0 -0
  29. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/.vscode/tasks.json +0 -0
  30. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/CLAUDE.md +0 -0
  31. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/CODE_OF_CONDUCT.md +0 -0
  32. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/CONTRIBUTING.md +0 -0
  33. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/Dockerfile +0 -0
  34. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/Dockerfile.base +0 -0
  35. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/LICENSE +0 -0
  36. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/MANIFEST.in +0 -0
  37. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/README.md +0 -0
  38. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/ROADMAP.md +0 -0
  39. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic.ini +0 -0
  40. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/README +0 -0
  41. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/env.py +0 -0
  42. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/script.py.mako +0 -0
  43. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/2082445b0769_add_oidc_accounts_table_for_secure_.py +0 -0
  44. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/22c8d1fba959_add_trees_enabled.py +0 -0
  45. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/66e56620891a_add_trees_table.py +0 -0
  46. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/6d8f3cb50b71_add_persistent_access_tokens_table.py +0 -0
  47. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/84960b7d968c_use_bigint_for_quota_media.py +0 -0
  48. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/a8e57fe0d82e_add_columns_for_ai_quota.py +0 -0
  49. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/b0582f54029c_use_bigint_for_usage_media.py +0 -0
  50. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/b2c3d4e5f6a7_add_tree_config_column.py +0 -0
  51. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/c1d2e3f4a5b6_merge_task_tree_and_tree_config.py +0 -0
  52. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/c89728e71264_.py +0 -0
  53. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/d4e9a1c7b3f2_drop_unique_constraint_on_user_email.py +0 -0
  54. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/e176543c72a8_add_tree_column_to_user.py +0 -0
  55. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/e5e738d09fa7_added_configuration_table.py +0 -0
  56. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/alembic_users/versions/f3a1c8e92b47_add_task_tree_table.py +0 -0
  57. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/docker-entrypoint.sh +0 -0
  58. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/__init__.py +0 -0
  59. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/__main__.py +0 -0
  60. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/__init__.py +0 -0
  61. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/auth.py +0 -0
  62. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/blueprint.py +0 -0
  63. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/cache.py +0 -0
  64. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/check.py +0 -0
  65. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/deprecations.py +0 -0
  66. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/dna.py +0 -0
  67. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/emails.py +0 -0
  68. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/export.py +0 -0
  69. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/file.py +0 -0
  70. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/html.py +0 -0
  71. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/image.py +0 -0
  72. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/llm/__init__.py +0 -0
  73. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/llm/agent.py +0 -0
  74. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/llm/deps.py +0 -0
  75. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/llm/tools.py +0 -0
  76. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/media_importer.py +0 -0
  77. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/people_families_cache.py +0 -0
  78. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/ratelimiter.py +0 -0
  79. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/report.py +0 -0
  80. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/__init__.py +0 -0
  81. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/access_tokens.py +0 -0
  82. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/anniversaries.py +0 -0
  83. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/base.py +0 -0
  84. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/bookmarks.py +0 -0
  85. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/chat.py +0 -0
  86. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/citations.py +0 -0
  87. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/config.py +0 -0
  88. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/db_backend.py +0 -0
  89. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/delete.py +0 -0
  90. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/dna.py +0 -0
  91. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/emit.py +0 -0
  92. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/events.py +0 -0
  93. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/export_media.py +0 -0
  94. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/exporters.py +0 -0
  95. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/face_detection.py +0 -0
  96. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/facts.py +0 -0
  97. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/families.py +0 -0
  98. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/file.py +0 -0
  99. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/filters.py +0 -0
  100. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/history.py +0 -0
  101. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/holidays.py +0 -0
  102. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/import_media.py +0 -0
  103. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/importers.py +0 -0
  104. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/living.py +0 -0
  105. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/match.py +0 -0
  106. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/media.py +0 -0
  107. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/merge.py +0 -0
  108. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/metadata.py +0 -0
  109. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/name_formats.py +0 -0
  110. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/name_groups.py +0 -0
  111. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/notes.py +0 -0
  112. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/object_query.py +0 -0
  113. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/objects.py +0 -0
  114. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/ocr.py +0 -0
  115. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/oidc.py +0 -0
  116. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/people.py +0 -0
  117. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/places.py +0 -0
  118. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/relations.py +0 -0
  119. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/reports.py +0 -0
  120. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/repositories.py +0 -0
  121. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/restore.py +0 -0
  122. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/schemas.py +0 -0
  123. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/search.py +0 -0
  124. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/sort.py +0 -0
  125. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/sources.py +0 -0
  126. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/tags.py +0 -0
  127. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/tasks.py +0 -0
  128. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/timeline.py +0 -0
  129. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/token.py +0 -0
  130. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/transactions.py +0 -0
  131. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/translations.py +0 -0
  132. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/types.py +0 -0
  133. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/user.py +0 -0
  134. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/util.py +0 -0
  135. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/verify.py +0 -0
  136. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/resources/ydna.py +0 -0
  137. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/s3.py +0 -0
  138. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/__init__.py +0 -0
  139. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/embeddings.py +0 -0
  140. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/indexer.py +0 -0
  141. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/metadata.py +0 -0
  142. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/text.py +0 -0
  143. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/search/text_semantic.py +0 -0
  144. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/tasks.py +0 -0
  145. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/api/telemetry.py +0 -0
  146. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/app.py +0 -0
  147. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/oidc.py +0 -0
  148. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/oidc_helpers.py +0 -0
  149. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/passwords.py +0 -0
  150. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/auth/sql_guid.py +0 -0
  151. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/celery.py +0 -0
  152. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/config.py +0 -0
  153. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/const.py +0 -0
  154. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/data/empty_gramps_auth.cfg +0 -0
  155. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/data/example_gramps_auth.cfg +0 -0
  156. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/data/face_detection_yunet_2023mar.onnx +0 -0
  157. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/data/test_auth.cfg +0 -0
  158. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/dbloader.py +0 -0
  159. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/dbmanager.py +0 -0
  160. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/logging_utils.py +0 -0
  161. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/profiler.py +0 -0
  162. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/sentry.py +0 -0
  163. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/static/index.html +0 -0
  164. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/templates/confirmation.html +0 -0
  165. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/templates/reset_password.html +0 -0
  166. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/templates/reset_password_base.html +0 -0
  167. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/templates/reset_password_error.html +0 -0
  168. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/translogger.py +0 -0
  169. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/types.py +0 -0
  170. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/undodb.py +0 -0
  171. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/util/__init__.py +0 -0
  172. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/util/celery.py +0 -0
  173. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/verify_lib.py +0 -0
  174. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi/wsgi.py +0 -0
  175. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi.egg-info/SOURCES.txt +0 -0
  176. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi.egg-info/dependency_links.txt +0 -0
  177. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi.egg-info/requires.txt +0 -0
  178. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/gramps_webapi.egg-info/top_level.txt +0 -0
  179. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/mypy.ini +0 -0
  180. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/pyproject.toml +0 -0
  181. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/requirements-dev.txt +0 -0
  182. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/scripts/s3_rename.py +0 -0
  183. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/scripts/start_dev_container.sh +0 -0
  184. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/semantic_index.txt +0 -0
  185. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/setup.cfg +0 -0
  186. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/setup.py +0 -0
  187. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/__init__.py +0 -0
  188. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_check.py +0 -0
  189. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_cli.py +0 -0
  190. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_db.py +0 -0
  191. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_delete.py +0 -0
  192. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_deprecations.py +0 -0
  193. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_dna_match_parser.py +0 -0
  194. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_embeddings.py +0 -0
  195. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/__init__.py +0 -0
  196. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/checks.py +0 -0
  197. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_access_tokens.py +0 -0
  198. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_anniversaries_ics.py +0 -0
  199. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_bookmarks.py +0 -0
  200. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_chat.py +0 -0
  201. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_citations.py +0 -0
  202. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_config.py +0 -0
  203. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_db_handle.py +0 -0
  204. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_delete.py +0 -0
  205. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_dna.py +0 -0
  206. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_events.py +0 -0
  207. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_exporters.py +0 -0
  208. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_facts.py +0 -0
  209. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_families.py +0 -0
  210. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_file.py +0 -0
  211. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_filters.py +0 -0
  212. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_history.py +0 -0
  213. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_holidays.py +0 -0
  214. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_import_media.py +0 -0
  215. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_importers.py +0 -0
  216. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_living.py +0 -0
  217. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_media.py +0 -0
  218. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_media_archive.py +0 -0
  219. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_merge.py +0 -0
  220. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_metadata.py +0 -0
  221. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_name_formats.py +0 -0
  222. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_name_groups.py +0 -0
  223. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_notes.py +0 -0
  224. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_object_query.py +0 -0
  225. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_object_query_where_tree.py +0 -0
  226. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_ocr.py +0 -0
  227. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_paging_sort.py +0 -0
  228. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_people.py +0 -0
  229. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_people_query.py +0 -0
  230. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_places.py +0 -0
  231. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_post.py +0 -0
  232. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_profiler.py +0 -0
  233. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_put.py +0 -0
  234. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_ready.py +0 -0
  235. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_relations.py +0 -0
  236. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_repair.py +0 -0
  237. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_reports.py +0 -0
  238. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_repositories.py +0 -0
  239. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_restore.py +0 -0
  240. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_s3.py +0 -0
  241. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_search.py +0 -0
  242. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_sources.py +0 -0
  243. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_tags.py +0 -0
  244. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_tasks.py +0 -0
  245. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_timelines.py +0 -0
  246. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_token.py +0 -0
  247. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_transactions.py +0 -0
  248. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_translations.py +0 -0
  249. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_treeless_admin.py +0 -0
  250. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_trees.py +0 -0
  251. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_types.py +0 -0
  252. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_upload.py +0 -0
  253. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_user.py +0 -0
  254. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_verify.py +0 -0
  255. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/test_ydna.py +0 -0
  256. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_endpoints/util.py +0 -0
  257. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_file.py +0 -0
  258. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_image.py +0 -0
  259. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_import_util.py +0 -0
  260. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_jwt.py +0 -0
  261. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_limiter.py +0 -0
  262. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_llm_errors.py +0 -0
  263. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_llm_tools.py +0 -0
  264. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_logging_utils.py +0 -0
  265. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_map_tile.py +0 -0
  266. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_media_importer.py +0 -0
  267. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_media_prefix_tree.py +0 -0
  268. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_migrate_grampsdb.py +0 -0
  269. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_object_query_parsing.py +0 -0
  270. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_oidc_auth.py +0 -0
  271. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_openapi_operation_ids.py +0 -0
  272. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_password.py +0 -0
  273. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_private_proxy.py +0 -0
  274. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_s3.py +0 -0
  275. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_search_metadata.py +0 -0
  276. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_sentry.py +0 -0
  277. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_sort_raw_data.py +0 -0
  278. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_sqlauth.py +0 -0
  279. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_task_error.py +0 -0
  280. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_tasks.py +0 -0
  281. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_telemetry.py +0 -0
  282. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_text.py +0 -0
  283. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_undodb.py +0 -0
  284. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_util.py +0 -0
  285. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_verify_lib.py +0 -0
  286. {gramps_webapi-3.22.1 → gramps_webapi-3.22.2}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gramps-webapi
3
- Version: 3.22.1
3
+ Version: 3.22.2
4
4
  Summary: A RESTful web API for the Gramps genealogical database.
5
5
  Author: Gramps Development Team
6
6
  Author-email: "David M. Straub" <straub@protonmail.com>
@@ -19,4 +19,4 @@
19
19
 
20
20
  """Version information."""
21
21
 
22
- __version__ = "3.22.1"
22
+ __version__ = "3.22.2"
@@ -390,6 +390,7 @@ def check_quota_media(
390
390
  usage_dict = get_tree_usage(tree)
391
391
  assert usage_dict is not None, "Unexpected error while looking up usage data."
392
392
  usage = usage_dict["usage_media"]
393
+ assert usage is not None, "Unexpected error while looking up usage data."
393
394
  quota = usage_dict.get("quota_media")
394
395
  if quota is None:
395
396
  return
@@ -77,7 +77,7 @@ from .schemas import TreeConfigSchema, TreeSchema
77
77
  TREE_ID_REGEX = re.compile(r"^[a-zA-Z0-9_-]+$")
78
78
 
79
79
 
80
- def get_tree_details(tree_id: str) -> Dict[str, str | bool | int]:
80
+ def get_tree_details(tree_id: str) -> Dict[str, str | bool | int | None]:
81
81
  """Get details about a tree."""
82
82
  try:
83
83
  dbmgr = WebDbManager(
@@ -747,6 +747,7 @@ def check_quota_people(
747
747
  usage_dict = get_tree_usage(tree)
748
748
  assert usage_dict is not None, "Unexpected error while looking up usage data."
749
749
  usage = usage_dict["usage_people"]
750
+ assert usage is not None, "Unexpected error while looking up usage data."
750
751
  quota = usage_dict.get("quota_people")
751
752
  if quota is None:
752
753
  return
@@ -30,7 +30,7 @@ import sqlalchemy as sa
30
30
  from flask import current_app
31
31
  from flask_sqlalchemy import SQLAlchemy
32
32
  from sqlalchemy.exc import IntegrityError, StatementError
33
- from sqlalchemy.orm import mapped_column
33
+ from sqlalchemy.orm import Mapped, mapped_column
34
34
  from sqlalchemy.sql.functions import coalesce
35
35
 
36
36
 
@@ -483,7 +483,7 @@ def config_get(key: str) -> Optional[str]:
483
483
  return config.value
484
484
 
485
485
 
486
- def config_get_all() -> Dict[str, str]:
486
+ def config_get_all() -> Dict[str, str | None]:
487
487
  """Get all config items as dictionary."""
488
488
  query = user_db.session.query(Config) # pylint: disable=no-member
489
489
  configs = query.all()
@@ -513,7 +513,7 @@ def config_delete(key: str) -> None:
513
513
  user_db.session.commit() # pylint: disable=no-member
514
514
 
515
515
 
516
- def get_tree_usage(tree: str) -> Optional[dict[str, int]]:
516
+ def get_tree_usage(tree: str) -> Optional[dict[str, int | None]]:
517
517
  """Get tree usage info."""
518
518
  query = user_db.session.query(Tree) # pylint: disable=no-member
519
519
  tree_obj: Tree = query.filter_by(id=tree).scalar()
@@ -529,7 +529,7 @@ def get_tree_usage(tree: str) -> Optional[dict[str, int]]:
529
529
  }
530
530
 
531
531
 
532
- def get_tree_permissions(tree: str) -> Optional[dict[str, int]]:
532
+ def get_tree_permissions(tree: str) -> Optional[dict[str, int | None]]:
533
533
  """Get tree permissions."""
534
534
  query = user_db.session.query(Tree) # pylint: disable=no-member
535
535
  tree_obj: Tree = query.filter_by(id=tree).scalar()
@@ -667,13 +667,14 @@ class User(user_db.Model): # type: ignore
667
667
 
668
668
  __tablename__ = "users"
669
669
 
670
- id = mapped_column(GUID, primary_key=True)
671
- name = mapped_column(sa.String, unique=True, nullable=False)
672
- email = mapped_column(sa.String, index=True)
673
- fullname = mapped_column(sa.String)
674
- pwhash = mapped_column(sa.String, nullable=False)
675
- role = mapped_column(sa.Integer, default=0)
676
- tree = mapped_column(sa.String, index=True)
670
+ id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True)
671
+ name: Mapped[str] = mapped_column(sa.String, unique=True, nullable=False)
672
+ email: Mapped[str | None] = mapped_column(sa.String, index=True)
673
+ fullname: Mapped[str | None] = mapped_column(sa.String)
674
+ pwhash: Mapped[str] = mapped_column(sa.String, nullable=False)
675
+ # nullable in the schema, but always set via the default
676
+ role: Mapped[int] = mapped_column(sa.Integer, nullable=True, default=0)
677
+ tree: Mapped[str | None] = mapped_column(sa.String, index=True)
677
678
 
678
679
  def __repr__(self):
679
680
  """Return string representation of instance."""
@@ -685,19 +686,19 @@ class AccessToken(user_db.Model): # type: ignore
685
686
 
686
687
  __tablename__ = "access_tokens"
687
688
 
688
- id = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
689
- user_id = mapped_column(
689
+ id: Mapped[int] = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
690
+ user_id: Mapped[uuid.UUID] = mapped_column(
690
691
  GUID, sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
691
692
  )
692
- scope = mapped_column(sa.String(64), nullable=False, index=True)
693
- token_hash = mapped_column(sa.String(64), nullable=True)
694
- created_at = mapped_column(
693
+ scope: Mapped[str] = mapped_column(sa.String(64), nullable=False, index=True)
694
+ token_hash: Mapped[str | None] = mapped_column(sa.String(64), nullable=True)
695
+ created_at: Mapped[datetime] = mapped_column(
695
696
  sa.DateTime, nullable=False, server_default=sa.func.now()
696
697
  )
697
- updated_at = mapped_column(
698
+ updated_at: Mapped[datetime] = mapped_column(
698
699
  sa.DateTime, nullable=False, server_default=sa.func.now()
699
700
  )
700
- revoked_at = mapped_column(sa.DateTime, nullable=True)
701
+ revoked_at: Mapped[datetime | None] = mapped_column(sa.DateTime, nullable=True)
701
702
 
702
703
  __table_args__ = (
703
704
  sa.UniqueConstraint("user_id", "scope", name="uq_access_tokens_user_scope"),
@@ -717,9 +718,9 @@ class Config(user_db.Model): # type: ignore
717
718
 
718
719
  __tablename__ = "configuration"
719
720
 
720
- id = mapped_column(sa.Integer, primary_key=True)
721
- key = mapped_column(sa.String, unique=True, nullable=False)
722
- value = mapped_column(sa.String)
721
+ id: Mapped[int] = mapped_column(sa.Integer, primary_key=True)
722
+ key: Mapped[str] = mapped_column(sa.String, unique=True, nullable=False)
723
+ value: Mapped[str | None] = mapped_column(sa.String)
723
724
 
724
725
  def __repr__(self):
725
726
  """Return string representation of instance."""
@@ -731,16 +732,18 @@ class Tree(user_db.Model): # type: ignore
731
732
 
732
733
  __tablename__ = "trees"
733
734
 
734
- id = mapped_column(sa.String, primary_key=True)
735
- quota_media = mapped_column(sa.BigInteger)
736
- quota_people = mapped_column(sa.Integer)
737
- quota_ai = mapped_column(sa.Integer)
738
- usage_media = mapped_column(sa.BigInteger)
739
- usage_people = mapped_column(sa.Integer)
740
- usage_ai = mapped_column(sa.Integer)
741
- min_role_ai = mapped_column(sa.Integer)
742
- enabled = mapped_column(sa.Integer, default=1, server_default="1")
743
- config = mapped_column(sa.JSON, nullable=True)
735
+ id: Mapped[str] = mapped_column(sa.String, primary_key=True)
736
+ quota_media: Mapped[int | None] = mapped_column(sa.BigInteger)
737
+ quota_people: Mapped[int | None] = mapped_column(sa.Integer)
738
+ quota_ai: Mapped[int | None] = mapped_column(sa.Integer)
739
+ usage_media: Mapped[int | None] = mapped_column(sa.BigInteger)
740
+ usage_people: Mapped[int | None] = mapped_column(sa.Integer)
741
+ usage_ai: Mapped[int | None] = mapped_column(sa.Integer)
742
+ min_role_ai: Mapped[int | None] = mapped_column(sa.Integer)
743
+ enabled: Mapped[int | None] = mapped_column(
744
+ sa.Integer, default=1, server_default="1"
745
+ )
746
+ config: Mapped[dict | None] = mapped_column(sa.JSON, nullable=True)
744
747
 
745
748
  def __repr__(self):
746
749
  """Return string representation of instance."""
@@ -752,14 +755,14 @@ class OIDCAccount(user_db.Model): # type: ignore
752
755
 
753
756
  __tablename__ = "oidc_accounts"
754
757
 
755
- id = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
756
- user_id = mapped_column(
758
+ id: Mapped[int] = mapped_column(sa.Integer, primary_key=True, autoincrement=True)
759
+ user_id: Mapped[uuid.UUID] = mapped_column(
757
760
  GUID, sa.ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
758
761
  )
759
- provider_id = mapped_column(sa.String(64), nullable=False)
760
- subject_id = mapped_column(sa.String(255), nullable=False)
761
- email = mapped_column(sa.String(255), nullable=True, index=True)
762
- created_at = mapped_column(
762
+ provider_id: Mapped[str] = mapped_column(sa.String(64), nullable=False)
763
+ subject_id: Mapped[str] = mapped_column(sa.String(255), nullable=False)
764
+ email: Mapped[str | None] = mapped_column(sa.String(255), nullable=True, index=True)
765
+ created_at: Mapped[datetime] = mapped_column(
763
766
  sa.DateTime, nullable=False, server_default=sa.func.now()
764
767
  )
765
768
 
@@ -779,11 +782,11 @@ class TaskTree(user_db.Model): # type: ignore
779
782
 
780
783
  __tablename__ = "task_tree"
781
784
 
782
- task_id = mapped_column(sa.String(155), primary_key=True)
783
- tree = mapped_column(sa.String, index=True)
784
- user_id = mapped_column(sa.String, index=True)
785
- name = mapped_column(sa.String, nullable=False)
786
- created_at = mapped_column(
785
+ task_id: Mapped[str] = mapped_column(sa.String(155), primary_key=True)
786
+ tree: Mapped[str | None] = mapped_column(sa.String, index=True)
787
+ user_id: Mapped[str | None] = mapped_column(sa.String, index=True)
788
+ name: Mapped[str] = mapped_column(sa.String, nullable=False)
789
+ created_at: Mapped[datetime] = mapped_column(
787
790
  sa.DateTime, nullable=False, server_default=sa.func.now()
788
791
  )
789
792
 
@@ -129,6 +129,15 @@ PERMISSIONS[ROLE_ADMIN] = PERMISSIONS[ROLE_OWNER] | {
129
129
  PERM_DISABLE_TREE,
130
130
  }
131
131
 
132
+ # Users with a negative role (disabled or unconfirmed) hold no permissions,
133
+ # but the role must still be a key here: get_permissions() looks up
134
+ # PERMISSIONS[user.role] directly, and the OIDC callback resolves permissions
135
+ # before it checks for a disabled account, so a missing key raises instead of
136
+ # reaching the "Account Under Review" page. Local login is unaffected (it
137
+ # rejects a negative role before any permission lookup).
138
+ PERMISSIONS[ROLE_DISABLED] = set()
139
+ PERMISSIONS[ROLE_UNCONFIRMED] = set()
140
+
132
141
  # keys/values for user claims
133
142
  CLAIM_LIMITED_SCOPE = "limited_scope"
134
143
  SCOPE_RESET_PW = "reset_password"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gramps-webapi
3
- Version: 3.22.1
3
+ Version: 3.22.2
4
4
  Summary: A RESTful web API for the Gramps genealogical database.
5
5
  Author: Gramps Development Team
6
6
  Author-email: "David M. Straub" <straub@protonmail.com>
@@ -934,6 +934,80 @@ class TestOIDCSingleTree(unittest.TestCase):
934
934
  )
935
935
  self.assertEqual(rv.status_code, 422)
936
936
 
937
+ @patch("gramps_webapi.api.resources.oidc.is_oidc_enabled", return_value=True)
938
+ @patch(
939
+ "gramps_webapi.api.resources.oidc.get_available_oidc_providers",
940
+ return_value=["custom"],
941
+ )
942
+ @patch("gramps_webapi.api.resources.oidc.create_or_update_oidc_user")
943
+ @patch("gramps_webapi.api.resources.oidc.get_name")
944
+ def test_callback_negative_role_renders_review_page(
945
+ self,
946
+ mock_get_name,
947
+ mock_create_user,
948
+ mock_providers,
949
+ mock_oidc_enabled,
950
+ ):
951
+ """A disabled or unconfirmed account sees the review page, not a 500.
952
+
953
+ New OIDC sign-ups default to ROLE_DISABLED when no group->role
954
+ mapping is configured, and an account may also be ROLE_UNCONFIRMED.
955
+ Resolving permissions for either negative role must not raise, so
956
+ that the callback reaches its "Account Under Review" branch and
957
+ renders it instead of returning 500.
958
+ """
959
+ from gramps_webapi.auth import add_user, delete_user, get_guid, get_tree
960
+ from gramps_webapi.auth.const import ROLE_DISABLED, ROLE_UNCONFIRMED
961
+
962
+ for role in (ROLE_DISABLED, ROLE_UNCONFIRMED):
963
+ with self.subTest(role=role):
964
+ username = f"oidc_negative_{role}"
965
+ with self.client.application.app_context():
966
+ # Belong to the same tree as the seeded users, so tree
967
+ # resolution succeeds and the login is not refused for
968
+ # want of a tree; the account is simply not active.
969
+ tree = get_tree(get_guid("owner"))
970
+ add_user(
971
+ name=username,
972
+ password="disabled-pw",
973
+ role=role,
974
+ tree=tree,
975
+ )
976
+ account_guid = get_guid(username)
977
+
978
+ try:
979
+ mock_create_user.return_value = account_guid
980
+ mock_get_name.return_value = username
981
+
982
+ mock_oauth = MagicMock()
983
+ mock_oidc_client = MagicMock()
984
+ mock_oauth.gramps_custom = mock_oidc_client
985
+ mock_oidc_client.authorize_access_token.return_value = {
986
+ "access_token": "t"
987
+ }
988
+ mock_oidc_client.userinfo.return_value = {
989
+ "sub": f"negative-subject-{role}",
990
+ "email": "inactive@example.com",
991
+ }
992
+
993
+ # get_tree_id_and_permissions() -> get_permissions()
994
+ # runs for real here: that lookup is what used to raise
995
+ # KeyError for a negative role.
996
+ with patch.dict(
997
+ self.client.application.extensions,
998
+ {"authlib.integrations.flask_client": mock_oauth},
999
+ clear=False,
1000
+ ):
1001
+ rv = self.client.get(
1002
+ BASE_URL + "/oidc/callback/custom?code=auth_code"
1003
+ )
1004
+
1005
+ self.assertEqual(rv.status_code, 200)
1006
+ self.assertIn(b"Account Under Review", rv.data)
1007
+ finally:
1008
+ with self.client.application.app_context():
1009
+ delete_user(username)
1010
+
937
1011
 
938
1012
  class TestOIDCCodeExchange(unittest.TestCase):
939
1013
  """Test cases for the single-use exchange code and its redemption."""
File without changes
File without changes
File without changes
File without changes
File without changes