ethyca-fides 2.71.1b1__py2.py3-none-any.whl → 2.74.0rc1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ethyca-fides might be problematic. Click here for more details.

Files changed (495) hide show
  1. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/METADATA +3 -2
  2. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/RECORD +377 -327
  3. fides/_version.py +3 -3
  4. fides/api/alembic/alembic.ini +5 -1
  5. fides/api/alembic/migrations/env.py +7 -1
  6. fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +68 -0
  7. fides/api/alembic/migrations/versions/65a1bc82ae09_adds_experience_config_for_delete_.py +53 -0
  8. fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
  9. fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
  10. fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
  11. fides/api/alembic/migrations/versions/c09e76282dd1_add_privacy_request_duplication_cols.py +64 -0
  12. fides/api/alembic/migrations/versions/xx_2025_10_17_1603_5093e92e2a5a_add_consent_data_v3_to_the_database.py +72 -0
  13. fides/api/alembic/migrations/versions/xx_2025_10_27_1834_67f0f2f4748e_adding_identity_definition_model.py +45 -0
  14. fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
  15. fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
  16. fides/api/api/v1/endpoints/connection_endpoints.py +38 -45
  17. fides/api/api/v1/endpoints/generic_overrides.py +75 -6
  18. fides/api/api/v1/endpoints/privacy_request_endpoints.py +60 -6
  19. fides/api/api/v1/endpoints/saas_config_endpoints.py +60 -48
  20. fides/api/api/v1/endpoints/system.py +11 -43
  21. fides/api/api/v1/endpoints/user_endpoints.py +8 -1
  22. fides/api/app_setup.py +1 -3
  23. fides/api/common_exceptions.py +8 -0
  24. fides/api/db/base.py +2 -0
  25. fides/api/db/database.py +257 -2
  26. fides/api/email_templates/get_email_template.py +3 -0
  27. fides/api/email_templates/template_names.py +1 -0
  28. fides/api/email_templates/templates/manual_task_digest.html +316 -0
  29. fides/api/main.py +2 -2
  30. fides/api/models/attachment.py +1 -0
  31. fides/api/models/detection_discovery/__init__.py +2 -0
  32. fides/api/models/detection_discovery/core.py +10 -0
  33. fides/api/models/detection_discovery/monitor_task.py +1 -0
  34. fides/api/models/detection_discovery/staged_resource_error.py +25 -0
  35. fides/api/models/digest/__init__.py +2 -0
  36. fides/api/models/digest/digest_config.py +10 -1
  37. fides/api/models/digest/digest_execution.py +142 -0
  38. fides/api/models/event_audit.py +17 -0
  39. fides/api/models/identity_definition.py +65 -0
  40. fides/api/models/messaging_template.py +7 -0
  41. fides/api/models/privacy_experience.py +11 -0
  42. fides/api/models/privacy_preference.py +2 -0
  43. fides/api/models/privacy_request/duplicate_group.py +84 -0
  44. fides/api/models/privacy_request/privacy_request.py +56 -8
  45. fides/api/models/privacy_request/request_task.py +98 -1
  46. fides/api/models/sql_models.py +3 -0
  47. fides/api/models/taxonomy.py +14 -4
  48. fides/api/models/v3/__init__.py +0 -0
  49. fides/api/models/v3/privacy_preferences.py +85 -0
  50. fides/api/models/worker_task.py +8 -0
  51. fides/api/schemas/application_config.py +28 -0
  52. fides/api/schemas/connection_configuration/connection_config.py +1 -30
  53. fides/api/schemas/messaging/messaging.py +15 -0
  54. fides/api/schemas/privacy_request.py +17 -3
  55. fides/api/schemas/saas/async_polling_configuration.py +81 -0
  56. fides/api/schemas/saas/saas_config.py +10 -3
  57. fides/api/schemas/saas/strategy_configuration.py +0 -12
  58. fides/api/schemas/taxonomy_extensions.py +8 -0
  59. fides/api/service/async_dsr/handlers/__init__.py +0 -0
  60. fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
  61. fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
  62. fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
  63. fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
  64. fides/api/service/async_dsr/strategies/__init__.py +0 -0
  65. fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
  66. fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
  67. fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
  68. fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +686 -0
  69. fides/api/service/async_dsr/utils.py +130 -0
  70. fides/api/service/connectors/bigquery_connector.py +34 -16
  71. fides/api/service/connectors/fides/fides_client.py +63 -1
  72. fides/api/service/connectors/query_configs/saas_query_config.py +160 -79
  73. fides/api/service/connectors/saas/connector_registry_service.py +1 -138
  74. fides/api/service/connectors/saas_connector.py +116 -94
  75. fides/api/service/connectors/sql_connector.py +14 -4
  76. fides/api/service/deps.py +8 -0
  77. fides/api/service/messaging/message_dispatch_service.py +38 -1
  78. fides/api/service/privacy_request/attachment_handling.py +9 -2
  79. fides/api/service/privacy_request/duplication_detection.py +424 -0
  80. fides/api/service/privacy_request/request_runner_service.py +46 -84
  81. fides/api/service/privacy_request/request_service.py +47 -74
  82. fides/api/service/saas_request/saas_request_override_factory.py +71 -1
  83. fides/api/task/execute_request_tasks.py +17 -9
  84. fides/api/task/filter_results.py +35 -2
  85. fides/api/task/graph_task.py +37 -8
  86. fides/api/tasks/__init__.py +0 -1
  87. fides/api/util/connection_util.py +99 -215
  88. fides/api/util/event_audit_util.py +230 -0
  89. fides/api/util/logger_context_utils.py +3 -1
  90. fides/api/util/masking_util.py +31 -0
  91. fides/api/util/memory_watchdog.py +118 -0
  92. fides/api/util/saas_config_updater.py +66 -0
  93. fides/api/util/saas_util.py +28 -1
  94. fides/common/api/scope_registry.py +0 -7
  95. fides/common/api/v1/urn_registry.py +2 -0
  96. fides/config/__init__.py +10 -1
  97. fides/config/celery_settings.py +42 -0
  98. fides/config/config_proxy.py +10 -0
  99. fides/config/duplicate_detection_settings.py +31 -0
  100. fides/config/execution_settings.py +7 -3
  101. fides/config/utils.py +5 -0
  102. fides/data/language/languages.yml +2 -0
  103. fides/service/connection/__init__.py +0 -0
  104. fides/service/connection/connection_service.py +651 -0
  105. fides/service/event_audit_service.py +16 -22
  106. fides/service/privacy_request/privacy_request_service.py +162 -43
  107. fides/service/taxonomy/handlers/legacy_handler.py +3 -3
  108. fides/service/taxonomy/taxonomy_service.py +15 -15
  109. fides/ui-build/static/admin/404.html +1 -1
  110. fides/ui-build/static/admin/_next/static/FZTEUgamBvOhgPWce135w/_buildManifest.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/{1115-90baef2a89f361ad.js → 1115-0da062111df309bf.js} +1 -1
  112. fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
  113. fides/ui-build/static/admin/_next/static/chunks/1817-508b16628e8eb225.js +1 -0
  114. fides/ui-build/static/admin/_next/static/chunks/1840-5bbe6d878ed73fb4.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/{1975.78e719130cfe3fd6.js → 1975.afe8cad52f904fcf.js} +1 -1
  116. fides/ui-build/static/admin/_next/static/chunks/{2040-fdecc41a18e40bdc.js → 2040-fe1a06d82c0413f1.js} +1 -1
  117. fides/ui-build/static/admin/_next/static/chunks/2397-40b8db1cb2f23e2a.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/2921-b10bbc3a9104933b.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/3377-eb5cd82b3ee6ab0c.js +1 -0
  121. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/3655-93ecd09f1cb9dbef.js +1 -0
  123. fides/ui-build/static/admin/_next/static/chunks/{3696-90c8b336bbc46782.js → 3696-6db05a35ae806825.js} +1 -1
  124. fides/ui-build/static/admin/_next/static/chunks/{3923-98bea73b618292aa.js → 3923-44255a63d6d80ff5.js} +1 -1
  125. fides/ui-build/static/admin/_next/static/chunks/401-fe8db8b5d8f600de.js +1 -0
  126. fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
  127. fides/ui-build/static/admin/_next/static/chunks/4277-13bcf4516326d474.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/431-e01ee730c8ad9ece.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/4496-bed72bd5639075be.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
  131. fides/ui-build/static/admin/_next/static/chunks/4817-d29f40d4ce729f37.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/5185-b2ac9fecc00b67e7.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/5258-4672eae0656430f9.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/5487-8dedd1ca94fbba54.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/549-6e2442db533a711e.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/5643-55d758444a8d7162.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/5724-1e40975cefa405f0.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/{5783-d119cb132abd8a91.js → 5783-6055edba275155ca.js} +1 -1
  139. fides/ui-build/static/admin/_next/static/chunks/6084-82e2df433fe5ba85.js +1 -0
  140. fides/ui-build/static/admin/_next/static/chunks/6344-3e21444374f8059f.js +1 -0
  141. fides/ui-build/static/admin/_next/static/chunks/6362-12e3fd23130ccf15.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/6372-a8d0f08dac1ebd0e.js +1 -0
  143. fides/ui-build/static/admin/_next/static/chunks/6780-3db5133c1f4c6f1e.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/6853-1adbdf6418ec3d62.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/6954-aa0c60ee1092be8e.js +1 -0
  146. fides/ui-build/static/admin/_next/static/chunks/7059-12be23a345a94c1e.js +1 -0
  147. fides/ui-build/static/admin/_next/static/chunks/7079-6e6efc3396ff1ebb.js +1 -0
  148. fides/ui-build/static/admin/_next/static/chunks/7218-d297a4a06f924b09.js +1 -0
  149. fides/ui-build/static/admin/_next/static/chunks/7245-686665c197b58e68.js +1 -0
  150. fides/ui-build/static/admin/_next/static/chunks/{7476-d055aa931da47ac0.js → 7476-a43c046c24de37cc.js} +1 -1
  151. fides/ui-build/static/admin/_next/static/chunks/7630-c654c61ba98d8c74.js +1 -0
  152. fides/ui-build/static/admin/_next/static/chunks/7654-716cf37a020b3d11.js +1 -0
  153. fides/ui-build/static/admin/_next/static/chunks/{796-02086581996a0548.js → 796-e83ace3c6ab99ac7.js} +1 -1
  154. fides/ui-build/static/admin/_next/static/chunks/8212-b9e8295ca883c9f8.js +1 -0
  155. fides/ui-build/static/admin/_next/static/chunks/8939-4925751c57c51f87.js +1 -0
  156. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
  157. fides/ui-build/static/admin/_next/static/chunks/9046-e4daf28840a69fd6.js +1 -0
  158. fides/ui-build/static/admin/_next/static/chunks/{5596-29a7c8322530b7cf.js → 9195-550bd50d538c5f79.js} +3 -3
  159. fides/ui-build/static/admin/_next/static/chunks/9330-e519adec48222d45.js +1 -0
  160. fides/ui-build/static/admin/_next/static/chunks/9341-bfc0e59bcc56c604.js +1 -0
  161. fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
  162. fides/ui-build/static/admin/_next/static/chunks/{9676.b86ecbcfe5afd25d.js → 9676.7d029a5383595b69.js} +1 -1
  163. fides/ui-build/static/admin/_next/static/chunks/9682-da69ac5d06f281da.js +1 -0
  164. fides/ui-build/static/admin/_next/static/chunks/{9826-ccedc28e978ca9e1.js → 9826-657652d55936a8c6.js} +1 -1
  165. fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
  166. fides/ui-build/static/admin/_next/static/chunks/9965-56c5e4fc9cd3b3a5.js +1 -0
  167. fides/ui-build/static/admin/_next/static/chunks/pages/{404-2eb8aed4939f1142.js → 404-d079b8bf35250874.js} +1 -1
  168. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-c1c2f757b1f3da12.js → _app-e64fd8510033a27c.js} +63 -63
  169. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-ddd9d7d40847fc28.js +1 -0
  170. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-b4d18c1f4d414f5f.js +1 -0
  171. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-d451bc8932330141.js +1 -0
  172. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-7a258b7ecd6da4b8.js → add-vendors-c24663cd5dec57db.js} +1 -1
  173. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-fb5017ff5fa54fcc.js → configure-d93418688bd258eb.js} +1 -1
  174. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-e1e2fd704ac2d71d.js → [id]-9b1f2b1c06968166.js} +1 -1
  175. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-a5e738a234dadc7e.js → new-115a085e5d42de45.js} +1 -1
  176. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-d9b7b311195df29e.js +1 -0
  177. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-5fc78b78a51c239c.js → [id]-3de34624829cbce8.js} +1 -1
  178. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-b79bcb93b5f4c734.js → new-dc95e7ed278d1a29.js} +1 -1
  179. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-cdfc9bb19f47c709.js +1 -0
  180. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-069f4e3ee96ebf77.js → properties-0b995b01dc4dbd1f.js} +1 -1
  181. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e3ad3a55624e302a.js +1 -0
  182. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-d2bf72508c3cad55.js → consent-b37ed76849330edd.js} +1 -1
  183. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-2fa4b3a58f75f81d.js → [resourceUrn]-dd82729296dee5c5.js} +1 -1
  184. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-49e5477eb1a11b92.js +1 -0
  185. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-dfc1ead4a12c9ffa.js +1 -0
  186. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-5b31e3d7727b917a.js → [resourceUrn]-8442eb219958ac7e.js} +1 -1
  187. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-feda358d1801c18d.js +1 -0
  188. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-d16acb6fc07aad46.js +1 -0
  189. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-c51a1e98c45d231a.js +1 -0
  190. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-4498881c26f1458d.js +1 -0
  191. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-bcfe38eebca30f8c.js +1 -0
  192. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-f66d0655897c4400.js +1 -0
  193. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-5b3e0009d442bc3f.js +1 -0
  194. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-6f1e012cd641da19.js +1 -0
  195. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-581d6248fcf98d17.js +1 -0
  196. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-844a8de0d1b506e2.js → [resourceUrn]-ddc1c1641e1e9430.js} +1 -1
  197. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-11b07cf2d91b17ef.js → detection-2b48f7e524743b2b.js} +1 -1
  198. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-5525cf287d4ab493.js → [resourceUrn]-862b67418600251e.js} +1 -1
  199. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-ed4723e1b67d890e.js → discovery-0ffec855f5df262c.js} +1 -1
  200. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-6a030ab8c2e2b0db.js +1 -0
  201. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-6cb66f649b8ca4bf.js +1 -0
  202. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-0b008dad90b00aaa.js +1 -0
  203. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-5566edf9a9d1be2d.js +1 -0
  204. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4ca1f485b6e9e02.js +1 -0
  205. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-85dee7e81dc4bafb.js +1 -0
  206. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-e905e018a2cab35d.js +1 -0
  207. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-912723bc86299b1a.js +1 -0
  208. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-f1f0affc18327033.js +1 -0
  209. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
  210. fides/ui-build/static/admin/_next/static/chunks/pages/{index-b74d1e8608ae5b5d.js → index-692d27dbe9392c9f.js} +1 -1
  211. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-1b94e2d769a182b2.js +1 -0
  212. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-adfe6c5ac5b703d0.js +1 -0
  213. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-f9be7080ebbb7445.js +1 -0
  214. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/[id]-caaa8602a1d449b1.js +1 -0
  215. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/new-9b106b1d2d93985b.js +1 -0
  216. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-6a1ded8cdde836c4.js +1 -0
  217. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/[key]-f94e3accf9507ebf.js +1 -0
  218. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/new-5e83220ff1f2a250.js +1 -0
  219. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-a03cbd698a23e5b3.js +1 -0
  220. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/[id]-3cde574b3c8447c0.js +1 -0
  221. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/add-template-0448bb4ae8536c58.js +1 -0
  222. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-1621a4b87c432117.js +1 -0
  223. fides/ui-build/static/admin/_next/static/chunks/pages/notifications-4ea28f6b1dd63642.js +1 -0
  224. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-e02516d9fd314528.js +1 -0
  225. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-fec08bea801b4918.js +1 -0
  226. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-d911e5fbf5a4a888.js +1 -0
  227. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-91b1adcac6a57b2d.js +1 -0
  228. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-de309d8813b1ebfb.js +1 -0
  229. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-f2943c1309062284.js +1 -0
  230. fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-29fb7b39f8962650.js → table-migration-03eda417711ae909.js} +1 -1
  231. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-1fe486f3af832c80.js +1 -0
  232. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-ea6f78fa8b2d3f6c.js +1 -0
  233. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-8f577df28ebca869.js → configure-bda7b474493e7128.js} +1 -1
  234. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-2c0ec8fed16c20ae.js +1 -0
  235. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-57a75c7e9659271a.js → [id]-30d298a47e85709f.js} +1 -1
  236. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-8964c2300206bc89.js → add-property-438084cca0d0f10d.js} +1 -1
  237. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-08472b2a6bf1d392.js → properties-17fd44d98f5bd5b6.js} +1 -1
  238. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-baf77d34a3b3bece.js +1 -0
  239. fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-8c80391025ca7339.js +1 -0
  240. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-7c19810858b708cc.js +1 -0
  241. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-ee8820fe0fa14c77.js +1 -0
  242. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{[id]-bd1042a0e9be6aff.js → [id]-8eb862182f19a6c2.js} +1 -1
  243. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/{new-469ad83c8cfa1290.js → new-37c29ef618e9fe3c.js} +1 -1
  244. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-1db425150dcb1b6b.js +1 -0
  245. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-744f669431b84f71.js → domain-records-e334b43fa5c5b1e6.js} +1 -1
  246. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-9d18eb5c38d85522.js +1 -0
  247. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-604790638c656fbd.js → email-templates-cb937ed7c4b1e5a8.js} +1 -1
  248. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-be2a885150adc133.js → locations-835281251f0785cd.js} +1 -1
  249. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-3c86162afe9759df.js → organization-7fd050c92866938c.js} +1 -1
  250. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-59ea66130fca0d05.js +1 -0
  251. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-4fe3b90747d885e5.js → regulations-b0fe1051d908f366.js} +1 -1
  252. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-f108bf5015144d2f.js +1 -0
  253. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-4d470bbf199a2f9c.js → [id]-0e7c7228d01290ea.js} +1 -1
  254. fides/ui-build/static/admin/_next/static/chunks/pages/systems-adc13b542e10a37d.js +1 -0
  255. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-23dd250da26511c5.js +1 -0
  256. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-98f737e735eaa0f0.js → [id]-aed30fb22ae7c9ec.js} +1 -1
  257. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-562624e5461083ec.js → user-management-6b88ca3e02ee67c9.js} +1 -1
  258. fides/ui-build/static/admin/_next/static/chunks/webpack-6f97ebe373e7ef6b.js +1 -0
  259. fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
  260. fides/ui-build/static/admin/_next/static/css/05d05fc31d09638b.css +1 -0
  261. fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
  262. fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
  263. fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
  264. fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
  265. fides/ui-build/static/admin/_next/static/css/65ae906f224cd8ae.css +1 -0
  266. fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
  267. fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
  268. fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
  269. fides/ui-build/static/admin/_next/static/css/d5701118537cbdd2.css +1 -0
  270. fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
  271. fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
  272. fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
  273. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  274. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  275. fides/ui-build/static/admin/add-systems.html +1 -1
  276. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  277. fides/ui-build/static/admin/consent/configure.html +1 -1
  278. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  279. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  280. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  281. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  282. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  283. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  284. fides/ui-build/static/admin/consent/properties.html +1 -1
  285. fides/ui-build/static/admin/consent/reporting.html +1 -1
  286. fides/ui-build/static/admin/consent.html +1 -1
  287. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  288. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  289. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  290. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  291. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  292. fides/ui-build/static/admin/data-catalog.html +1 -1
  293. fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -0
  294. fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
  295. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
  296. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
  297. fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
  298. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  299. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  300. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  301. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  302. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  303. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  304. fides/ui-build/static/admin/datamap.html +1 -1
  305. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  306. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  307. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  308. fides/ui-build/static/admin/dataset/new.html +1 -1
  309. fides/ui-build/static/admin/dataset.html +1 -1
  310. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  311. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  312. fides/ui-build/static/admin/datastore-connection.html +1 -1
  313. fides/ui-build/static/admin/index.html +1 -1
  314. fides/ui-build/static/admin/integrations/[id].html +1 -1
  315. fides/ui-build/static/admin/integrations.html +1 -1
  316. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  317. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  318. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  319. fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
  320. fides/ui-build/static/admin/lib/fides.js +3 -3
  321. fides/ui-build/static/admin/login/[provider].html +1 -1
  322. fides/ui-build/static/admin/login.html +1 -1
  323. fides/ui-build/static/admin/new-privacy-requests.html +1 -0
  324. fides/ui-build/static/admin/notifications/digests/[id].html +1 -0
  325. fides/ui-build/static/admin/notifications/digests/new.html +1 -0
  326. fides/ui-build/static/admin/notifications/digests.html +1 -0
  327. fides/ui-build/static/admin/notifications/providers/[key].html +1 -0
  328. fides/ui-build/static/admin/notifications/providers/new.html +1 -0
  329. fides/ui-build/static/admin/notifications/providers.html +1 -0
  330. fides/ui-build/static/admin/notifications/templates/[id].html +1 -0
  331. fides/ui-build/static/admin/notifications/templates/add-template.html +1 -0
  332. fides/ui-build/static/admin/notifications/templates.html +1 -0
  333. fides/ui-build/static/admin/notifications.html +1 -0
  334. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  335. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  336. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  337. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  338. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  339. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  340. fides/ui-build/static/admin/poc/forms.html +1 -1
  341. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  342. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  343. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  344. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  345. fides/ui-build/static/admin/privacy-requests.html +1 -1
  346. fides/ui-build/static/admin/properties/[id].html +1 -1
  347. fides/ui-build/static/admin/properties/add-property.html +1 -1
  348. fides/ui-build/static/admin/properties.html +1 -1
  349. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  350. fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -0
  351. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  352. fides/ui-build/static/admin/settings/about.html +1 -1
  353. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  354. fides/ui-build/static/admin/settings/consent.html +1 -1
  355. fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -1
  356. fides/ui-build/static/admin/settings/custom-fields/new.html +1 -1
  357. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  358. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  359. fides/ui-build/static/admin/settings/domains.html +1 -1
  360. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  361. fides/ui-build/static/admin/settings/locations.html +1 -1
  362. fides/ui-build/static/admin/settings/organization.html +1 -1
  363. fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
  364. fides/ui-build/static/admin/settings/regulations.html +1 -1
  365. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  366. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  367. fides/ui-build/static/admin/systems.html +1 -1
  368. fides/ui-build/static/admin/taxonomy.html +1 -1
  369. fides/ui-build/static/admin/user-management/new.html +1 -1
  370. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  371. fides/ui-build/static/admin/user-management.html +1 -1
  372. fides/api/service/async_dsr/async_dsr_service.py +0 -195
  373. fides/api/service/async_dsr/async_dsr_strategy.py +0 -5
  374. fides/api/service/async_dsr/async_dsr_strategy_callback.py +0 -16
  375. fides/api/service/async_dsr/async_dsr_strategy_factory.py +0 -63
  376. fides/api/service/async_dsr/async_dsr_strategy_polling.py +0 -94
  377. fides/ui-build/static/admin/_next/static/_IxwgneyQjdSaZFEF3Tqu/_buildManifest.js +0 -1
  378. fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
  379. fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
  380. fides/ui-build/static/admin/_next/static/chunks/155-b4337d0826d5addc.js +0 -1
  381. fides/ui-build/static/admin/_next/static/chunks/1817-1ad037b7d6d2f6d2.js +0 -1
  382. fides/ui-build/static/admin/_next/static/chunks/1896-49010da5c2705fc5.js +0 -1
  383. fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
  384. fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
  385. fides/ui-build/static/admin/_next/static/chunks/2921-66f65496c3a09316.js +0 -1
  386. fides/ui-build/static/admin/_next/static/chunks/2962-e92d525bf570a9a3.js +0 -1
  387. fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
  388. fides/ui-build/static/admin/_next/static/chunks/3550-83cb70e80cbe41ba.js +0 -1
  389. fides/ui-build/static/admin/_next/static/chunks/3585-f728d32fda6f1ac1.js +0 -1
  390. fides/ui-build/static/admin/_next/static/chunks/3855-ed226b8a8050bd40.js +0 -1
  391. fides/ui-build/static/admin/_next/static/chunks/3872-04d3afbfa41a7782.js +0 -1
  392. fides/ui-build/static/admin/_next/static/chunks/401-ffe4e8436e1eceb9.js +0 -1
  393. fides/ui-build/static/admin/_next/static/chunks/409-5c3d31163028339f.js +0 -1
  394. fides/ui-build/static/admin/_next/static/chunks/431-78bf05f35d7eec4f.js +0 -1
  395. fides/ui-build/static/admin/_next/static/chunks/4558-8305aee48def1dcd.js +0 -1
  396. fides/ui-build/static/admin/_next/static/chunks/4608-0c6ef78e30a51f84.js +0 -1
  397. fides/ui-build/static/admin/_next/static/chunks/4718-3a412bdb90add82f.js +0 -1
  398. fides/ui-build/static/admin/_next/static/chunks/502-0d9f4ac29ef34a1c.js +0 -1
  399. fides/ui-build/static/admin/_next/static/chunks/504-88caa30c03374e9b.js +0 -1
  400. fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
  401. fides/ui-build/static/admin/_next/static/chunks/5185-51eaa78e3ed6bfb7.js +0 -1
  402. fides/ui-build/static/admin/_next/static/chunks/5279-12c9cbdc67ad7b14.js +0 -1
  403. fides/ui-build/static/admin/_next/static/chunks/5309-3b6cf0cc9d0c6a83.js +0 -1
  404. fides/ui-build/static/admin/_next/static/chunks/5574-c31ea831371610d5.js +0 -1
  405. fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
  406. fides/ui-build/static/admin/_next/static/chunks/5643-10a36584c399526c.js +0 -1
  407. fides/ui-build/static/admin/_next/static/chunks/6277-182efc294d413f64.js +0 -1
  408. fides/ui-build/static/admin/_next/static/chunks/6419-9b3a86af57c86791.js +0 -1
  409. fides/ui-build/static/admin/_next/static/chunks/6853-7004a8c420b1ca02.js +0 -1
  410. fides/ui-build/static/admin/_next/static/chunks/6882-dbe0a25dcf1a8ee0.js +0 -1
  411. fides/ui-build/static/admin/_next/static/chunks/6954-4b24e1731c1cc3b3.js +0 -1
  412. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
  413. fides/ui-build/static/admin/_next/static/chunks/7045-14e955890f1147e4.js +0 -1
  414. fides/ui-build/static/admin/_next/static/chunks/7079-50571e9f3269d74d.js +0 -1
  415. fides/ui-build/static/admin/_next/static/chunks/7158-04745cc8d684b2e7.js +0 -1
  416. fides/ui-build/static/admin/_next/static/chunks/7218-e2983b96b95e33b4.js +0 -1
  417. fides/ui-build/static/admin/_next/static/chunks/7630-d0d3a0fe3f95e971.js +0 -1
  418. fides/ui-build/static/admin/_next/static/chunks/7725-f2a7be705b75dcc3.js +0 -1
  419. fides/ui-build/static/admin/_next/static/chunks/7929-0fd0d4948bc8d70e.js +0 -1
  420. fides/ui-build/static/admin/_next/static/chunks/8002-ed832921ad190832.js +0 -1
  421. fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
  422. fides/ui-build/static/admin/_next/static/chunks/9037-453224ba3ee65b13.js +0 -1
  423. fides/ui-build/static/admin/_next/static/chunks/9046-b6616ba7b59d947e.js +0 -1
  424. fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
  425. fides/ui-build/static/admin/_next/static/chunks/9226-4a7027057f55ca2a.js +0 -1
  426. fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
  427. fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
  428. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-4ec03eed67572861.js +0 -1
  429. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-2ca59996860a33c5.js +0 -1
  430. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-19214babd1f219e3.js +0 -1
  431. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-92182be6603c2842.js +0 -1
  432. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-ab54b19609bff325.js +0 -1
  433. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-c1a3caf3c286bf5d.js +0 -1
  434. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-4a1af12d2d7cd660.js +0 -1
  435. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-99573a1ee3ef8f4c.js +0 -1
  436. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources-6e429b7511028d60.js +0 -1
  437. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-b7326c51d88cc2cc.js +0 -1
  438. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-5b57f9132426fe52.js +0 -1
  439. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-0d512528b498d75c.js +0 -1
  440. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-040813022f0890c9.js +0 -1
  441. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-a28cc0e23bbe4fc8.js +0 -1
  442. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-7d22222608ec3aac.js +0 -1
  443. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-0abd30eada811b5b.js +0 -1
  444. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-007965429368d9a3.js +0 -1
  445. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-60a4a9eb4aab4c11.js +0 -1
  446. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d514cd4ec62e3b03.js +0 -1
  447. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-0e3a6ac4797ffbbb.js +0 -1
  448. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-816e02b6cbe4a684.js +0 -1
  449. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-b6838162200141b3.js +0 -1
  450. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-223c2d1ded51bfb1.js +0 -1
  451. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-153eb88ab4e7dc6d.js +0 -1
  452. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-331544e9b85c4ac2.js +0 -1
  453. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-e8d2140787045acd.js +0 -1
  454. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-e3f93462a08251bf.js +0 -1
  455. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-b5f7d6afdecd013d.js +0 -1
  456. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-248ad9f65a872442.js +0 -1
  457. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-aedb66a62042b10a.js +0 -1
  458. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-018df38b7cd77fdb.js +0 -1
  459. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6ca9099d03aab817.js +0 -1
  460. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-0f2c90786ea005a4.js +0 -1
  461. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-200b51a725f8b2d1.js +0 -1
  462. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-7dac2302f573f5ee.js +0 -1
  463. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-479890582973deaf.js +0 -1
  464. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-7af00f72cf694077.js +0 -1
  465. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-f7753e9effae3816.js +0 -1
  466. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-f3e6e74e0efb005c.js +0 -1
  467. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-4d658222ec800511.js +0 -1
  468. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-2fcd95c41e578d57.js +0 -1
  469. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-a3275554ffe8e640.js +0 -1
  470. fides/ui-build/static/admin/_next/static/chunks/pages/settings/messaging-providers/[key]-77239269acc2d31a.js +0 -1
  471. fides/ui-build/static/admin/_next/static/chunks/pages/settings/messaging-providers/new-8bf1821722b082e9.js +0 -1
  472. fides/ui-build/static/admin/_next/static/chunks/pages/settings/messaging-providers-8d92be437793c96f.js +0 -1
  473. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-97221067330c0c27.js +0 -1
  474. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-2deb6becece69d46.js +0 -1
  475. fides/ui-build/static/admin/_next/static/chunks/pages/systems-6c91bdea40875227.js +0 -1
  476. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-3059aba38adefa56.js +0 -1
  477. fides/ui-build/static/admin/_next/static/chunks/webpack-2766492c5dbceb0a.js +0 -1
  478. fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
  479. fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
  480. fides/ui-build/static/admin/_next/static/css/295d729ea1b11885.css +0 -1
  481. fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
  482. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
  483. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
  484. fides/ui-build/static/admin/messaging/[id].html +0 -1
  485. fides/ui-build/static/admin/messaging/add-template.html +0 -1
  486. fides/ui-build/static/admin/messaging.html +0 -1
  487. fides/ui-build/static/admin/settings/messaging-providers/[key].html +0 -1
  488. fides/ui-build/static/admin/settings/messaging-providers/new.html +0 -1
  489. fides/ui-build/static/admin/settings/messaging-providers.html +0 -1
  490. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/WHEEL +0 -0
  491. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/entry_points.txt +0 -0
  492. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/licenses/LICENSE +0 -0
  493. {ethyca_fides-2.71.1b1.dist-info → ethyca_fides-2.74.0rc1.dist-info}/top_level.txt +0 -0
  494. /fides/ui-build/static/admin/_next/static/{_IxwgneyQjdSaZFEF3Tqu → FZTEUgamBvOhgPWce135w}/_ssgManifest.js +0 -0
  495. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-629c88e90699369b.js → new-7dce2916cc589c54.js} +0 -0
@@ -0,0 +1,424 @@
1
+ from datetime import datetime, timedelta, timezone
2
+ from typing import Optional
3
+ from uuid import UUID
4
+
5
+ from loguru import logger
6
+ from sqlalchemy.orm import Session
7
+
8
+ from fides.api.models.privacy_request.duplicate_group import (
9
+ DuplicateGroup,
10
+ generate_rule_version,
11
+ )
12
+ from fides.api.models.privacy_request.privacy_request import PrivacyRequest
13
+ from fides.api.schemas.policy import ActionType
14
+ from fides.api.schemas.privacy_request import PrivacyRequestStatus
15
+ from fides.api.task.conditional_dependencies.schemas import (
16
+ Condition,
17
+ ConditionGroup,
18
+ ConditionLeaf,
19
+ GroupOperator,
20
+ Operator,
21
+ )
22
+ from fides.api.task.conditional_dependencies.sql_translator import (
23
+ SQLConditionTranslator,
24
+ )
25
+ from fides.config.config_proxy import ConfigProxy
26
+ from fides.config.duplicate_detection_settings import DuplicateDetectionSettings
27
+
28
+ ACTIONED_REQUEST_STATUSES = [
29
+ PrivacyRequestStatus.approved,
30
+ PrivacyRequestStatus.in_processing,
31
+ PrivacyRequestStatus.requires_manual_finalization,
32
+ PrivacyRequestStatus.requires_input,
33
+ PrivacyRequestStatus.paused,
34
+ PrivacyRequestStatus.awaiting_email_send,
35
+ PrivacyRequestStatus.error,
36
+ ]
37
+
38
+
39
+ class DuplicateDetectionService:
40
+ def __init__(self, db: Session):
41
+ self.db = db
42
+ self._config = ConfigProxy(db).privacy_request_duplicate_detection
43
+
44
+ def is_enabled(self) -> bool:
45
+ return self._config.enabled
46
+
47
+ def _create_identity_conditions(
48
+ self, current_request: PrivacyRequest
49
+ ) -> list[Condition]:
50
+ """Creates conditions for matching identity fields.
51
+
52
+ For identity field matching using the EAV pattern in ProvidedIdentity, we need to match both field_name
53
+ and hashed_value. This function creates the required nested conditions for each identity field.
54
+ Also adds a condition for the policy_id to ensure that we are only matching requests for the same policy.
55
+ """
56
+ conditions: list[Condition] = []
57
+ current_identities: dict[str, str] = {
58
+ pi.field_name: pi.hashed_value
59
+ for pi in current_request.provided_identities # type: ignore [attr-defined]
60
+ if pi.field_name in self._config.match_identity_fields
61
+ }
62
+ if len(current_identities) != len(self._config.match_identity_fields):
63
+ missing_fields = [
64
+ field
65
+ for field in self._config.match_identity_fields
66
+ if field not in current_identities.keys()
67
+ ]
68
+ logger.debug(
69
+ f"Some identity fields were not found in the current request: {missing_fields}"
70
+ )
71
+ return []
72
+
73
+ for field_name, hashed_value in current_identities.items():
74
+ identity_condition = ConditionGroup(
75
+ logical_operator=GroupOperator.and_,
76
+ conditions=[
77
+ ConditionLeaf(
78
+ field_address="privacyrequest.provided_identities.field_name",
79
+ operator=Operator.eq,
80
+ value=field_name,
81
+ ),
82
+ ConditionLeaf(
83
+ field_address="privacyrequest.provided_identities.hashed_value",
84
+ operator=Operator.eq,
85
+ value=hashed_value,
86
+ ),
87
+ ],
88
+ )
89
+ conditions.append(identity_condition)
90
+ policy_condition = ConditionLeaf(
91
+ field_address="privacyrequest.policy_id",
92
+ operator=Operator.eq,
93
+ value=current_request.policy_id,
94
+ )
95
+ conditions.append(policy_condition)
96
+ return conditions
97
+
98
+ def _create_time_window_condition(self, time_window_days: int) -> Condition:
99
+ """Creates a condition for matching requests within a time window."""
100
+ cutoff_date = datetime.now(timezone.utc) - timedelta(days=time_window_days)
101
+ condition = ConditionLeaf(
102
+ field_address="privacyrequest.created_at",
103
+ operator=Operator.gte,
104
+ value=cutoff_date.isoformat(),
105
+ )
106
+ return condition
107
+
108
+ def create_duplicate_detection_conditions(
109
+ self,
110
+ current_request: PrivacyRequest,
111
+ ) -> Optional[ConditionGroup]:
112
+ """
113
+ Create conditions for duplicate detection based on configuration.
114
+
115
+ Args:
116
+ current_request: The current privacy request to find duplicates for
117
+ config: Duplicate detection configuration settings
118
+
119
+ Returns:
120
+ A ConditionGroup with AND operator, or None if no conditions can be created
121
+ """
122
+ if len(self._config.match_identity_fields) == 0:
123
+ return None
124
+
125
+ identity_conditions = self._create_identity_conditions(current_request)
126
+ if not identity_conditions:
127
+ return None # Only proceed if we have identity conditions
128
+
129
+ time_window_condition = self._create_time_window_condition(
130
+ self._config.time_window_days
131
+ )
132
+
133
+ # Combine all conditions with AND operator
134
+ all_conditions: list[Condition] = [*identity_conditions, time_window_condition]
135
+ return ConditionGroup(
136
+ logical_operator=GroupOperator.and_, conditions=all_conditions
137
+ )
138
+
139
+ def find_duplicate_privacy_requests(
140
+ self,
141
+ current_request: PrivacyRequest,
142
+ ) -> list[PrivacyRequest]:
143
+ """
144
+ Find potential duplicate privacy requests based on duplicate detection configuration.
145
+
146
+ Uses the SQLConditionTranslator to build queries from conditions, which handles
147
+ the ProvidedIdentity relationship using SQLAlchemy's .any() method.
148
+
149
+ Args:
150
+ current_request: The privacy request to check for duplicates
151
+ config: Duplicate detection configuration settings
152
+
153
+ Returns:
154
+ List of PrivacyRequest objects that match the duplicate criteria,
155
+ does not include the current request
156
+ """
157
+ condition = self.create_duplicate_detection_conditions(current_request)
158
+
159
+ if condition is None:
160
+ return []
161
+
162
+ translator = SQLConditionTranslator(self.db)
163
+ query = translator.generate_query_from_condition(condition)
164
+
165
+ query = query.filter(PrivacyRequest.id != current_request.id).filter(
166
+ PrivacyRequest.deleted_at.is_(None)
167
+ )
168
+ return query.all()
169
+
170
+ def generate_dedup_key(self, request: PrivacyRequest) -> str:
171
+ """
172
+ Generate a dedup key for a request based on the duplicate detection settings.
173
+ """
174
+ current_identities: dict[str, str] = {
175
+ pi.field_name: pi.hashed_value
176
+ for pi in request.provided_identities # type: ignore [attr-defined]
177
+ if pi.field_name in self._config.match_identity_fields
178
+ }
179
+ if len(current_identities) != len(self._config.match_identity_fields):
180
+ raise ValueError(
181
+ "This request does not contain the required identity fields for duplicate detection."
182
+ )
183
+ return "|".join(
184
+ [
185
+ current_identities[field]
186
+ for field in sorted(self._config.match_identity_fields)
187
+ ]
188
+ )
189
+
190
+ def update_duplicate_group_ids(
191
+ self,
192
+ request: PrivacyRequest,
193
+ duplicates: list[PrivacyRequest],
194
+ duplicate_group_id: UUID,
195
+ ) -> None:
196
+ """
197
+ Update the duplicate request group ids for a request and its duplicates.
198
+ Args:
199
+ request: The privacy request to update
200
+ duplicates: The list of duplicate requests to update
201
+ duplicate_group_id: The duplicate request group id to update
202
+ """
203
+ update_all = [request] + duplicates
204
+ try:
205
+ for privacy_request in update_all:
206
+ privacy_request.duplicate_request_group_id = duplicate_group_id # type: ignore [assignment]
207
+ except Exception as e:
208
+ logger.error(f"Failed to update duplicate request group ids: {e}")
209
+ raise e
210
+
211
+ def mark_as_duplicate(self, request: PrivacyRequest, message: str) -> None:
212
+ """
213
+ Mark a request as a duplicate.
214
+ """
215
+ request.update(self.db, data={"status": PrivacyRequestStatus.duplicate})
216
+ logger.debug(message)
217
+ self.add_error_execution_log(request, message)
218
+
219
+ def add_error_execution_log(self, request: PrivacyRequest, message: str) -> None:
220
+ request.add_error_execution_log(
221
+ db=self.db,
222
+ connection_key=None,
223
+ dataset_name="Duplicate Request Detection",
224
+ collection_name=None,
225
+ message=message,
226
+ action_type=(
227
+ request.policy.get_action_type() # type: ignore [arg-type]
228
+ if request.policy
229
+ else ActionType.access
230
+ ),
231
+ )
232
+
233
+ def add_success_execution_log(self, request: PrivacyRequest, message: str) -> None:
234
+ request.add_success_execution_log(
235
+ db=self.db,
236
+ connection_key=None,
237
+ dataset_name="Duplicate Request Detection",
238
+ collection_name=None,
239
+ message=message,
240
+ action_type=(
241
+ request.policy.get_action_type() # type: ignore [arg-type]
242
+ if request.policy
243
+ else ActionType.access
244
+ ),
245
+ )
246
+
247
+ def verified_identity_cases(
248
+ self, request: PrivacyRequest, duplicates: list[PrivacyRequest]
249
+ ) -> bool:
250
+ """
251
+ Apply verified identity rules to determine if a request is a duplicate request.
252
+ - If this request does not have a verified identity, it may be a duplicate if another request in the group is verified.
253
+ - If this is the first request to be verified, it is not a duplicate request
254
+ - If other requests identities were verified before this request, it is a duplicate request
255
+ Args:
256
+ request: The privacy request to check
257
+ duplicates: The list of duplicate requests
258
+
259
+ Returns:
260
+ True if the request is a duplicate request, False otherwise
261
+ """
262
+ verified_in_group = [
263
+ duplicate for duplicate in duplicates if duplicate.identity_verified_at
264
+ ]
265
+
266
+ # The request identity is not verified.
267
+ if not request.identity_verified_at:
268
+ if len(verified_in_group) > 0:
269
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) {[duplicate.id for duplicate in verified_in_group]}."
270
+ self.mark_as_duplicate(request, message)
271
+ return True
272
+
273
+ canonical_request = min(duplicates, key=lambda x: x.created_at) # type: ignore [arg-type, return-value]
274
+ canonical_request_created_at = canonical_request.created_at or datetime.now(
275
+ timezone.utc
276
+ )
277
+ request_created_at = request.created_at or datetime.now(timezone.utc)
278
+ if request_created_at < canonical_request_created_at:
279
+ message = f"Request {request.id} is not a duplicate: it is the first request to be created in the group."
280
+ logger.debug(message)
281
+ self.add_success_execution_log(request, message)
282
+ return False
283
+
284
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
285
+ self.mark_as_duplicate(request, message)
286
+ return True
287
+
288
+ # The request identity is verified.
289
+ if not verified_in_group:
290
+ message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
291
+ logger.debug(message)
292
+ for duplicate in duplicates:
293
+ dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
294
+ self.mark_as_duplicate(duplicate, dup_message)
295
+ self.add_success_execution_log(request, message)
296
+ return False
297
+
298
+ # If this request is the first with a verified identity, it is not a duplicate.
299
+ canonical_request = min(verified_in_group, key=lambda x: x.identity_verified_at) # type: ignore [arg-type, return-value]
300
+ canonical_request_verified_at = (
301
+ canonical_request.identity_verified_at or datetime.now(timezone.utc)
302
+ )
303
+ request_verified_at = request.identity_verified_at or datetime.now(timezone.utc)
304
+ if request_verified_at < canonical_request_verified_at:
305
+ message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
306
+ logger.debug(message)
307
+ self.add_success_execution_log(request, message)
308
+ for duplicate in duplicates:
309
+ dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
310
+ self.mark_as_duplicate(duplicate, dup_message)
311
+ return False
312
+ message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
313
+ self.mark_as_duplicate(request, message)
314
+ return True
315
+
316
+ # pylint: disable=too-many-return-statements
317
+ def is_duplicate_request(self, request: PrivacyRequest) -> bool:
318
+ """
319
+ Determine if a request is a duplicate request and assigns a duplicate request group id.
320
+
321
+ The hierarchy is:
322
+ 1. Actioned requests: if this request duplicates an actioned request, it is a duplicate.
323
+ 2. Verified identity requests:
324
+ a. if this request has a verified identity:
325
+ - If none of the duplicates have a verified identity, it is not a duplicate.
326
+ - If duplicates have verified identities, but this request is the first with a verified identity, it is not a duplicate.
327
+ b. if this request does not have a verified identity:
328
+ - If no duplicates have a verified identity, and this was the first created request, it is not a duplicate.
329
+ 3. First created request: if this is the first created request in the group, it is not a duplicate.
330
+ 4. If no canonical requests are found (meaning all requests are marked as duplicates), this request is not a duplicate.
331
+ - Could occur if configuration changes and previous requests were already marked as duplicates.
332
+
333
+ Args:
334
+ request: The privacy request to check
335
+ config: Duplicate detection configuration settings
336
+ Returns:
337
+ True if the request is a duplicate request, False otherwise
338
+ """
339
+ if request.policy.get_action_type() == ActionType.consent:
340
+ message = f"Consent request {request.id} is not a duplicate."
341
+ logger.info(message)
342
+ self.add_success_execution_log(request, message)
343
+ return False
344
+ duplicates = self.find_duplicate_privacy_requests(request)
345
+ rule_version = generate_rule_version(
346
+ DuplicateDetectionSettings(
347
+ enabled=self._config.enabled,
348
+ time_window_days=self._config.time_window_days,
349
+ match_identity_fields=self._config.match_identity_fields,
350
+ )
351
+ )
352
+ try:
353
+ dedup_key = self.generate_dedup_key(request)
354
+ except ValueError as e:
355
+ message = f"Request {request.id} is not a duplicate: {e}"
356
+ logger.warning(message)
357
+ self.add_success_execution_log(request, message)
358
+ return False
359
+
360
+ _, duplicate_group = DuplicateGroup.get_or_create(
361
+ db=self.db, data={"rule_version": rule_version, "dedup_key": dedup_key}
362
+ )
363
+ if duplicate_group is None:
364
+ message = f"Failed to create duplicate group for request {request.id} with dedup key {dedup_key}"
365
+ logger.error(message)
366
+ self.add_error_execution_log(request, message)
367
+ return False
368
+
369
+ self.update_duplicate_group_ids(request, duplicates, duplicate_group.id) # type: ignore [arg-type]
370
+
371
+ if request.status in ACTIONED_REQUEST_STATUSES:
372
+ message = (
373
+ f"Request {request.id} is not a duplicate: it is an actioned request."
374
+ )
375
+ logger.debug(message)
376
+ self.add_success_execution_log(request, message)
377
+ return False
378
+
379
+ # if this is the only request in the group, it is not a duplicate
380
+ if len(duplicates) == 0:
381
+ message = f"Request {request.id} is not a duplicate."
382
+ logger.debug(message)
383
+ self.add_success_execution_log(request, message)
384
+ return False
385
+
386
+ if request.status == PrivacyRequestStatus.duplicate:
387
+ return True
388
+
389
+ # only compare to non-duplicate/complete requests for the following cases
390
+ canonical_requests = [
391
+ duplicate
392
+ for duplicate in duplicates
393
+ if duplicate.status
394
+ not in [PrivacyRequestStatus.duplicate, PrivacyRequestStatus.complete]
395
+ ]
396
+ # If no non-duplicate requests are found, this request is not a duplicate.
397
+ if len(canonical_requests) == 0:
398
+ message = f"Request {request.id} is not a duplicate."
399
+ logger.debug(message)
400
+ self.add_success_execution_log(request, message)
401
+ return False
402
+
403
+ # If any requests in group are actioned, this request is a duplicate.
404
+ actioned_in_group = [
405
+ duplicate
406
+ for duplicate in canonical_requests
407
+ if duplicate.status in ACTIONED_REQUEST_STATUSES
408
+ ]
409
+ if len(actioned_in_group) > 0:
410
+ message = f"Request {request.id} is a duplicate: it is duplicating actioned request(s) {[duplicate.id for duplicate in actioned_in_group]}."
411
+ self.mark_as_duplicate(request, message)
412
+ return True
413
+ # Check against verified identity rules.
414
+ return self.verified_identity_cases(request, canonical_requests)
415
+
416
+
417
+ def check_for_duplicates(db: Session, privacy_request: PrivacyRequest) -> None:
418
+ duplicate_detection_service = DuplicateDetectionService(db)
419
+ if duplicate_detection_service.is_enabled():
420
+ logger.info(
421
+ "Duplicate detection is enabled. Checking if privacy request is a duplicate."
422
+ )
423
+ if duplicate_detection_service.is_duplicate_request(privacy_request):
424
+ logger.info("Terminating privacy request: request is a duplicate.")
@@ -2,10 +2,13 @@
2
2
  import time
3
3
  from copy import deepcopy
4
4
  from datetime import datetime, timedelta
5
- from typing import Any, Optional, Tuple
5
+ from typing import Any, Optional
6
6
 
7
- import requests
7
+ import sqlalchemy.exc
8
8
  from loguru import logger
9
+
10
+ # pylint: disable=no-name-in-module
11
+ from psycopg2.errors import InternalError_ # type: ignore[import-untyped]
9
12
  from pydantic import ValidationError as PydanticValidationError
10
13
  from sqlalchemy.orm import Query, Session
11
14
 
@@ -22,7 +25,6 @@ from fides.api.common_exceptions import (
22
25
  ValidationError,
23
26
  )
24
27
  from fides.api.db.session import get_db_session
25
- from fides.api.graph.config import CollectionAddress
26
28
  from fides.api.graph.graph import DatasetGraph
27
29
  from fides.api.models.attachment import Attachment, AttachmentReferenceType
28
30
  from fides.api.models.audit_log import AuditLog, AuditLogAction
@@ -53,7 +55,7 @@ from fides.api.schemas.policy import ActionType, CurrentStep
53
55
  from fides.api.schemas.privacy_request import PrivacyRequestStatus
54
56
  from fides.api.schemas.redis_cache import Identity
55
57
  from fides.api.schemas.storage.storage import StorageType
56
- from fides.api.service.connectors import FidesConnector, get_connector
58
+ from fides.api.service.connectors import get_connector
57
59
  from fides.api.service.connectors.consent_email_connector import (
58
60
  CONSENT_EMAIL_CONNECTOR_TYPES,
59
61
  )
@@ -69,6 +71,7 @@ from fides.api.service.privacy_request.attachment_handling import (
69
71
  get_attachments_content,
70
72
  process_attachments_for_upload,
71
73
  )
74
+ from fides.api.service.privacy_request.duplication_detection import check_for_duplicates
72
75
  from fides.api.service.storage.storage_uploader_service import upload
73
76
  from fides.api.task.filter_results import filter_data_categories
74
77
  from fides.api.task.graph_runners import access_runner, consent_runner, erasure_runner
@@ -85,11 +88,7 @@ from fides.api.util.collection_util import Row
85
88
  from fides.api.util.logger import Pii, _log_exception, _log_warning
86
89
  from fides.api.util.logger_context_utils import LoggerContextKeys, log_context
87
90
  from fides.api.util.memory_watchdog import memory_limiter
88
- from fides.common.api.v1.urn_registry import (
89
- PRIVACY_CENTER_DSR_PACKAGE,
90
- PRIVACY_REQUEST_TRANSFER_TO_PARENT,
91
- V1_URL_PREFIX,
92
- )
91
+ from fides.common.api.v1.urn_registry import PRIVACY_CENTER_DSR_PACKAGE
93
92
  from fides.config import CONFIG
94
93
  from fides.config.config_proxy import ConfigProxy
95
94
 
@@ -276,6 +275,11 @@ def upload_access_results(
276
275
  return download_urls
277
276
 
278
277
 
278
+ @log_context(
279
+ capture_args={
280
+ "privacy_request_id": LoggerContextKeys.privacy_request_id,
281
+ }
282
+ )
279
283
  def save_access_results(
280
284
  session: Session,
281
285
  privacy_request: PrivacyRequest,
@@ -284,12 +288,34 @@ def save_access_results(
284
288
  ) -> None:
285
289
  """Save the results we uploaded to the user for later retrieval"""
286
290
  # Save the results we uploaded to the user for later retrieval
287
- privacy_request.save_filtered_access_results(session, rule_filtered_results)
288
291
  # Saving access request URL's on the privacy request in case DSR 3.0
289
292
  # exits processing before the email is sent
290
293
  privacy_request.access_result_urls = {"access_result_urls": download_urls}
291
294
  privacy_request.save(session)
292
295
 
296
+ # Try to save the backup results, but don't fail the DSR if this fails
297
+ try:
298
+ privacy_request.save_filtered_access_results(session, rule_filtered_results)
299
+ logger.info("Successfully saved backup filtered access results to database")
300
+ except (
301
+ InternalError_, # invalid memory alloc request size 1073741824
302
+ sqlalchemy.exc.StatementError, # SQL statement errors
303
+ # Python memory errors
304
+ MemoryError, # system out of memory
305
+ OverflowError, # numeric overflow during serialization
306
+ ) as exc:
307
+ logger.warning(
308
+ "Failed to save backup of DSR results to database after successful S3 upload. "
309
+ "DSR will continue processing. Error: {}",
310
+ str(exc),
311
+ )
312
+ except Exception as exc:
313
+ logger.error(
314
+ "Failed to save backup of DSR results to database after successful S3 upload. "
315
+ "DSR will continue processing. Unexpected Error: {}",
316
+ str(exc),
317
+ )
318
+
293
319
 
294
320
  @log_context(
295
321
  capture_args={
@@ -307,8 +333,11 @@ def upload_and_save_access_results( # pylint: disable=R0912
307
333
  ) -> list[str]:
308
334
  """Process the data uploads after the access portion of the privacy request has completed"""
309
335
  download_urls: list[str] = []
310
- # Remove manual webhook attachments from the list of attachments
311
- # This is done because the manual webhook attachments are already included in the manual_data
336
+ # Remove manual webhook attachments and request task attachments from the list of attachments
337
+ # This is done because:
338
+ # - manual webhook attachments are already included in the manual_data
339
+ # - manual task submission attachments are already included in the manual_data
340
+ # - request task attachments (from async polling) are already embedded in the dataset results
312
341
  loaded_attachments = [
313
342
  attachment
314
343
  for attachment in privacy_request.attachments
@@ -317,6 +346,7 @@ def upload_and_save_access_results( # pylint: disable=R0912
317
346
  in [
318
347
  AttachmentReferenceType.access_manual_webhook,
319
348
  AttachmentReferenceType.manual_task_submission,
349
+ AttachmentReferenceType.request_task,
320
350
  ]
321
351
  for ref in attachment.references
322
352
  )
@@ -417,6 +447,10 @@ def run_privacy_request(
417
447
  logger.info("Terminating privacy request: request deleted.")
418
448
  return
419
449
 
450
+ check_for_duplicates(db=session, privacy_request=privacy_request)
451
+ if privacy_request.status == PrivacyRequestStatus.duplicate:
452
+ return
453
+
420
454
  logger.info("Dispatching privacy request")
421
455
  privacy_request.start_processing(session)
422
456
 
@@ -922,78 +956,6 @@ def mark_paused_privacy_request_as_expired(privacy_request_id: str) -> None:
922
956
  db.close()
923
957
 
924
958
 
925
- def _retrieve_child_results( # pylint: disable=R0911
926
- fides_connector: Tuple[str, ConnectionConfig],
927
- rule_key: str,
928
- access_result: dict[str, list[Row]],
929
- ) -> Optional[list[dict[str, Optional[list[Row]]]]]:
930
- """Get child access request results to add to upload."""
931
- try:
932
- connector = FidesConnector(fides_connector[1])
933
- except Exception as e:
934
- logger.error(
935
- "Error create client for child server {}: {}", fides_connector[0], e
936
- )
937
- return None
938
-
939
- results = []
940
-
941
- for key, rows in access_result.items():
942
- address = CollectionAddress.from_string(key)
943
- privacy_request_id = None
944
- if address.dataset == fides_connector[0]:
945
- if not rows:
946
- logger.info("No rows found for result entry {}", key)
947
- continue
948
- privacy_request_id = rows[0]["id"]
949
-
950
- if not privacy_request_id:
951
- logger.error(
952
- "No privacy request found for connector key {}", fides_connector[0]
953
- )
954
- continue
955
-
956
- try:
957
- client = connector.create_client()
958
- except requests.exceptions.HTTPError as e:
959
- logger.error(
960
- "Error logger into to child server for privacy request {}: {}",
961
- privacy_request_id,
962
- e,
963
- )
964
- continue
965
-
966
- try:
967
- request = client.authenticated_request(
968
- method="get",
969
- path=f"{V1_URL_PREFIX}{PRIVACY_REQUEST_TRANSFER_TO_PARENT.format(privacy_request_id=privacy_request_id, rule_key=rule_key)}",
970
- headers={"Authorization": f"Bearer {client.token}"},
971
- )
972
- response = client.session.send(request)
973
- except requests.exceptions.HTTPError as e:
974
- logger.error(
975
- "Error retrieving data from child server for privacy request {}: {}",
976
- privacy_request_id,
977
- e,
978
- )
979
- continue
980
-
981
- if response.status_code != 200:
982
- logger.error(
983
- "Error retrieving data from child server for privacy request {}: {}",
984
- privacy_request_id,
985
- response.json(),
986
- )
987
- continue
988
-
989
- results.append(response.json())
990
-
991
- if not results:
992
- return None
993
-
994
- return results
995
-
996
-
997
959
  def get_consent_email_connection_configs(db: Session) -> Query:
998
960
  """Return enabled consent email connection configs."""
999
961
  return db.query(ConnectionConfig).filter(