ethyca-fides 2.69.1rc0__py2.py3-none-any.whl → 2.76.0rc2__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.
Files changed (607) hide show
  1. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/METADATA +9 -6
  2. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/RECORD +488 -361
  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/0eef0016cf06_adding_oauth2_config_for_.py +69 -0
  7. fides/api/alembic/migrations/versions/303287c70600_migrate_resource_type_from_enum_to_.py +99 -0
  8. fides/api/alembic/migrations/versions/30369bb8ae01_add_webmonitorgroupjob_model.py +67 -0
  9. fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -0
  10. fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +68 -0
  11. fides/api/alembic/migrations/versions/4d8c0fcc5771_adding_default_system_groups.py +78 -0
  12. fides/api/alembic/migrations/versions/5fa78b1f324d_add_event_audit_table.py +82 -0
  13. fides/api/alembic/migrations/versions/65a1bc82ae09_adds_experience_config_for_delete_.py +53 -0
  14. fides/api/alembic/migrations/versions/67d0e389b003_update_consentstatus_enum.py +47 -0
  15. fides/api/alembic/migrations/versions/795f46f656c0_migrate_field_type_from_enum_to_string.py +61 -0
  16. fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
  17. fides/api/alembic/migrations/versions/918aefc950c9_create_digest_conditional_dependencies.py +125 -0
  18. fides/api/alembic/migrations/versions/9caf76161e55_make_user_assigned_data_uses_nullable_.py +64 -0
  19. fides/api/alembic/migrations/versions/9e0dcbf67b9f_add_digest_config.py +84 -0
  20. fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
  21. fides/api/alembic/migrations/versions/a8e0c016afd_add_classification_benchmark_table.py +126 -0
  22. fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
  23. fides/api/alembic/migrations/versions/b9bfa12c167b_add_not_applicable_to_asset_consentstatus.py +46 -0
  24. fides/api/alembic/migrations/versions/c09e76282dd1_add_privacy_request_duplication_cols.py +64 -0
  25. fides/api/alembic/migrations/versions/cd8649be3a2b_add_classifications_and_user_assigned_.py +74 -0
  26. fides/api/alembic/migrations/versions/e2cda8d6abc3_add_dismissed_in_activity_view_to_.py +29 -0
  27. fides/api/alembic/migrations/versions/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
  28. fides/api/alembic/migrations/versions/f36ce1bde293_add_system_groups.py +132 -0
  29. fides/api/alembic/migrations/versions/fd7571bef683_adds_new_fields_to_messagingconfig_for_.py +31 -0
  30. fides/api/alembic/migrations/versions/xx_2025_10_17_1603_5093e92e2a5a_add_consent_data_v3_to_the_database.py +72 -0
  31. fides/api/alembic/migrations/versions/xx_2025_10_27_1834_67f0f2f4748e_adding_identity_definition_model.py +45 -0
  32. fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
  33. fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
  34. fides/api/alembic/migrations/versions/xx_2025_11_07_1709_56fe6fad2d89_add_notice_display_order.py +47 -0
  35. fides/api/alembic/migrations/versions/xx_2025_11_10_1200_a1b2c3d4e5f6_add_test_datastore_to_connectiontype.py +53 -0
  36. fides/api/alembic/migrations/versions/xx_2025_11_11_1317_7d82c8fc4c34_store_saas_template_datasets.py +68 -0
  37. fides/api/alembic/migrations/versions/xx_2025_11_12_1430_b2c3d4e5f6a7_add_default_identity_definitions.py +81 -0
  38. fides/api/alembic/migrations/versions/xx_2025_11_25_1854_3ff6449c099e_add_index_on_providedidentity_privacy_.py +50 -0
  39. fides/api/api/v1/api.py +2 -0
  40. fides/api/api/v1/endpoints/admin.py +39 -0
  41. fides/api/api/v1/endpoints/connection_endpoints.py +191 -47
  42. fides/api/api/v1/endpoints/connector_template_endpoints.py +167 -0
  43. fides/api/api/v1/endpoints/generic_overrides.py +90 -15
  44. fides/api/api/v1/endpoints/messaging_endpoints.py +164 -34
  45. fides/api/api/v1/endpoints/pre_approval_webhook_endpoints.py +5 -5
  46. fides/api/api/v1/endpoints/privacy_request_endpoints.py +231 -46
  47. fides/api/api/v1/endpoints/saas_config_endpoints.py +63 -92
  48. fides/api/api/v1/endpoints/storage_endpoints.py +5 -1
  49. fides/api/api/v1/endpoints/system.py +157 -100
  50. fides/api/api/v1/endpoints/user_endpoints.py +17 -4
  51. fides/api/app_setup.py +1 -3
  52. fides/api/common_exceptions.py +8 -0
  53. fides/api/db/base.py +8 -0
  54. fides/api/db/crud.py +30 -2
  55. fides/api/db/database.py +261 -4
  56. fides/api/db/safe_crud.py +377 -0
  57. fides/api/db/seed.py +35 -1
  58. fides/api/email_templates/get_email_template.py +3 -0
  59. fides/api/email_templates/template_names.py +1 -0
  60. fides/api/email_templates/templates/external_user_welcome.html +9 -5
  61. fides/api/email_templates/templates/manual_task_digest.html +316 -0
  62. fides/api/main.py +2 -0
  63. fides/api/migrations/post_upgrade_index_creation.py +20 -0
  64. fides/api/models/asset.py +17 -1
  65. fides/api/models/attachment.py +1 -0
  66. fides/api/models/conditional_dependency/__init__.py +0 -0
  67. fides/api/models/conditional_dependency/conditional_dependency_base.py +311 -0
  68. fides/api/models/connection_oauth_credentials.py +57 -0
  69. fides/api/models/connectionconfig.py +11 -1
  70. fides/api/models/detection_discovery/__init__.py +4 -0
  71. fides/api/models/detection_discovery/classification_benchmark.py +140 -0
  72. fides/api/models/detection_discovery/core.py +78 -3
  73. fides/api/models/detection_discovery/monitor_task.py +3 -1
  74. fides/api/models/detection_discovery/staged_resource_error.py +25 -0
  75. fides/api/models/detection_discovery/web_monitor.py +61 -0
  76. fides/api/models/digest/__init__.py +16 -0
  77. fides/api/models/digest/conditional_dependencies.py +275 -0
  78. fides/api/models/digest/digest_config.py +110 -0
  79. fides/api/models/digest/digest_execution.py +142 -0
  80. fides/api/models/event_audit.py +85 -0
  81. fides/api/models/experience_notices.py +6 -1
  82. fides/api/models/fides_user.py +9 -0
  83. fides/api/models/identity_definition.py +66 -0
  84. fides/api/models/location_regulation_selections.py +22 -0
  85. fides/api/models/manual_task/conditional_dependency.py +29 -87
  86. fides/api/models/manual_webhook.py +17 -6
  87. fides/api/models/messaging.py +30 -10
  88. fides/api/models/messaging_template.py +14 -0
  89. fides/api/models/policy.py +27 -0
  90. fides/api/models/privacy_experience.py +41 -0
  91. fides/api/models/privacy_notice.py +196 -13
  92. fides/api/models/privacy_preference.py +2 -0
  93. fides/api/models/privacy_request/duplicate_group.py +84 -0
  94. fides/api/models/privacy_request/privacy_request.py +154 -8
  95. fides/api/models/privacy_request/provided_identity.py +22 -1
  96. fides/api/models/privacy_request/request_task.py +98 -1
  97. fides/api/models/privacy_request/webhook.py +3 -1
  98. fides/api/models/saas_template_dataset.py +63 -0
  99. fides/api/models/sql_models.py +161 -7
  100. fides/api/models/system_group.py +85 -0
  101. fides/api/models/taxonomy.py +91 -9
  102. fides/api/models/v3/__init__.py +0 -0
  103. fides/api/models/v3/privacy_preferences.py +85 -0
  104. fides/api/models/worker_task.py +8 -0
  105. fides/api/oauth/roles.py +4 -0
  106. fides/api/schemas/application_config.py +32 -1
  107. fides/api/schemas/connection_configuration/connection_config.py +1 -30
  108. fides/api/schemas/connection_configuration/connection_oauth_config.py +42 -0
  109. fides/api/schemas/connection_configuration/connection_secrets_mongodb.py +15 -3
  110. fides/api/schemas/connection_configuration/connection_secrets_mssql.py +5 -0
  111. fides/api/schemas/messaging/messaging.py +49 -66
  112. fides/api/schemas/messaging/messaging_secrets_docs_only.py +1 -1
  113. fides/api/schemas/messaging/shared_schemas.py +102 -0
  114. fides/api/schemas/oauth.py +2 -1
  115. fides/api/schemas/privacy_center_config.py +29 -5
  116. fides/api/schemas/privacy_request.py +44 -7
  117. fides/api/schemas/saas/async_polling_configuration.py +81 -0
  118. fides/api/schemas/saas/connector_template.py +14 -0
  119. fides/api/schemas/saas/saas_config.py +12 -20
  120. fides/api/schemas/system.py +8 -0
  121. fides/api/schemas/taxonomy_extensions.py +8 -0
  122. fides/api/schemas/user.py +2 -2
  123. fides/api/service/async_dsr/handlers/__init__.py +0 -0
  124. fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
  125. fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
  126. fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
  127. fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
  128. fides/api/service/async_dsr/strategies/__init__.py +0 -0
  129. fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
  130. fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
  131. fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
  132. fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +691 -0
  133. fides/api/service/async_dsr/utils.py +130 -0
  134. fides/api/service/connectors/base_erasure_email_connector.py +7 -0
  135. fides/api/service/connectors/bigquery_connector.py +34 -16
  136. fides/api/service/connectors/fides/fides_client.py +63 -1
  137. fides/api/service/connectors/http_connector.py +48 -12
  138. fides/api/service/connectors/microsoft_sql_server_connector.py +6 -1
  139. fides/api/service/connectors/mongodb_connector.py +74 -9
  140. fides/api/service/connectors/query_configs/saas_query_config.py +160 -79
  141. fides/api/service/connectors/saas/connector_registry_service.py +42 -135
  142. fides/api/service/connectors/saas_connector.py +116 -76
  143. fides/api/service/connectors/sql_connector.py +14 -4
  144. fides/api/service/deps.py +25 -2
  145. fides/api/service/messaging/message_dispatch_service.py +98 -20
  146. fides/api/service/messaging/messaging_crud_service.py +5 -9
  147. fides/api/service/privacy_request/attachment_handling.py +9 -2
  148. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +17 -9
  149. fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +41 -30
  150. fides/api/service/privacy_request/dsr_package/templates/clickme.html +68 -0
  151. fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +30 -27
  152. fides/api/service/privacy_request/duplication_detection.py +439 -0
  153. fides/api/service/privacy_request/email_batch_service.py +2 -1
  154. fides/api/service/privacy_request/request_runner_service.py +92 -91
  155. fides/api/service/privacy_request/request_service.py +74 -90
  156. fides/api/service/saas_request/saas_request_override_factory.py +71 -1
  157. fides/api/service/storage/streaming/schemas.py +27 -19
  158. fides/api/service/storage/streaming/smart_open_client.py +2 -2
  159. fides/api/service/storage/streaming/smart_open_streaming_storage.py +238 -147
  160. fides/api/service/storage/util.py +20 -106
  161. fides/api/service/strategy.py +6 -3
  162. fides/api/task/conditional_dependencies/privacy_request/__init__.py +0 -0
  163. fides/api/task/conditional_dependencies/privacy_request/convenience_fields.py +155 -0
  164. fides/api/task/conditional_dependencies/privacy_request/privacy_request_data.py +140 -0
  165. fides/api/task/conditional_dependencies/privacy_request/schemas.py +212 -0
  166. fides/api/task/conditional_dependencies/sql_schemas.py +301 -0
  167. fides/api/task/conditional_dependencies/sql_translator.py +757 -0
  168. fides/api/task/conditional_dependencies/util.py +111 -0
  169. fides/api/task/execute_request_tasks.py +34 -13
  170. fides/api/task/filter_results.py +35 -2
  171. fides/api/task/graph_runners.py +2 -32
  172. fides/api/task/graph_task.py +42 -12
  173. fides/api/task/manual/manual_task_conditional_evaluation.py +33 -28
  174. fides/api/task/manual/manual_task_graph_task.py +4 -1
  175. fides/api/task/manual/manual_task_utils.py +68 -26
  176. fides/api/task/scheduler_utils.py +39 -0
  177. fides/api/tasks/__init__.py +15 -1
  178. fides/api/util/cache.py +5 -1
  179. fides/api/util/connection_util.py +101 -218
  180. fides/api/util/event_audit_util.py +230 -0
  181. fides/api/util/filter_utils.py +0 -3
  182. fides/api/util/fuzzy_search_utils.py +7 -1
  183. fides/api/util/lock.py +13 -3
  184. fides/api/util/logger.py +58 -4
  185. fides/api/util/logger_context_utils.py +3 -1
  186. fides/api/util/masking_util.py +31 -0
  187. fides/api/util/memory_watchdog.py +118 -0
  188. fides/api/util/rate_limit.py +25 -7
  189. fides/api/util/saas_config_updater.py +76 -0
  190. fides/api/util/saas_util.py +28 -1
  191. fides/api/worker/__init__.py +6 -0
  192. fides/common/api/scope_registry.py +6 -7
  193. fides/common/api/v1/urn_registry.py +15 -3
  194. fides/config/__init__.py +11 -2
  195. fides/config/celery_settings.py +42 -0
  196. fides/config/config_proxy.py +10 -0
  197. fides/config/duplicate_detection_settings.py +31 -0
  198. fides/config/execution_settings.py +6 -6
  199. fides/config/security_settings.py +4 -1
  200. fides/config/utils.py +5 -0
  201. fides/data/language/languages.yml +2 -0
  202. fides/service/connection/__init__.py +0 -0
  203. fides/service/connection/connection_service.py +651 -0
  204. fides/service/dataset/dataset_service.py +39 -0
  205. fides/service/event_audit_service.py +109 -0
  206. fides/service/messaging/aws_ses_service.py +2 -4
  207. fides/service/messaging/messaging_service.py +75 -74
  208. fides/service/privacy_request/privacy_request_service.py +345 -100
  209. fides/service/system/__init__.py +0 -0
  210. fides/service/system/system_service.py +153 -0
  211. fides/service/taxonomy/handlers/legacy_handler.py +3 -3
  212. fides/service/taxonomy/taxonomy_service.py +64 -18
  213. fides/ui-build/static/admin/404.html +1 -1
  214. fides/ui-build/static/admin/_next/static/chunks/1099-688fa865621531cc.js +1 -0
  215. fides/ui-build/static/admin/_next/static/chunks/1115-7fd171dac1eb0e51.js +1 -0
  216. fides/ui-build/static/admin/_next/static/chunks/1276.deb10ae2643f8463.js +1 -0
  217. fides/ui-build/static/admin/_next/static/chunks/1438-8a33b3834d6e43f3.js +1 -0
  218. fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
  219. fides/ui-build/static/admin/_next/static/chunks/1821-c1daa160f492aacf.js +1 -0
  220. fides/ui-build/static/admin/_next/static/chunks/1840-359ee056e4cf6629.js +1 -0
  221. fides/ui-build/static/admin/_next/static/chunks/{1975.78e719130cfe3fd6.js → 1975.bef017bc80e2012c.js} +1 -1
  222. fides/ui-build/static/admin/_next/static/chunks/2040-70972e15960d9afe.js +1 -0
  223. fides/ui-build/static/admin/_next/static/chunks/2121.321b0fd3932164d4.js +1 -0
  224. fides/ui-build/static/admin/_next/static/chunks/2397-3434603a97f3f5d6.js +1 -0
  225. fides/ui-build/static/admin/_next/static/chunks/2921-49ed0ed897832958.js +1 -0
  226. fides/ui-build/static/admin/_next/static/chunks/3150-da5406b80d25fe6d.js +1 -0
  227. fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
  228. fides/ui-build/static/admin/_next/static/chunks/3377-02bf9780fd383d94.js +1 -0
  229. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
  230. fides/ui-build/static/admin/_next/static/chunks/3655-5e1ba5dd68b5ec48.js +1 -0
  231. fides/ui-build/static/admin/_next/static/chunks/3729-31ff8ba51491bf21.js +1 -0
  232. fides/ui-build/static/admin/_next/static/chunks/3872-cff30ca0844fe2b1.js +1 -0
  233. fides/ui-build/static/admin/_next/static/chunks/3931-8bedde156fe83564.js +1 -0
  234. fides/ui-build/static/admin/_next/static/chunks/401-582d9970d89deefe.js +1 -0
  235. fides/ui-build/static/admin/_next/static/chunks/4093-7e47408c28de5375.js +1 -0
  236. fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
  237. fides/ui-build/static/admin/_next/static/chunks/431-e01ee730c8ad9ece.js +1 -0
  238. fides/ui-build/static/admin/_next/static/chunks/4322-f6aeff6880726c83.js +1 -0
  239. fides/ui-build/static/admin/_next/static/chunks/4339-04a715ab07122744.js +1 -0
  240. fides/ui-build/static/admin/_next/static/chunks/4496-ccbce2459174e0d6.js +1 -0
  241. fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
  242. fides/ui-build/static/admin/_next/static/chunks/4589-c1d83c6a8dab4d30.js +1 -0
  243. fides/ui-build/static/admin/_next/static/chunks/4809-a8f4a108a42f53ed.js +1 -0
  244. fides/ui-build/static/admin/_next/static/chunks/4903-19c0bc07a956dfa8.js +1 -0
  245. fides/ui-build/static/admin/_next/static/chunks/4910-d990773601f794c1.js +1 -0
  246. fides/ui-build/static/admin/_next/static/chunks/5185-96423702fba70ced.js +1 -0
  247. fides/ui-build/static/admin/_next/static/chunks/5258-4e308cca01d59367.js +1 -0
  248. fides/ui-build/static/admin/_next/static/chunks/5487-5c3501754bf027ba.js +1 -0
  249. fides/ui-build/static/admin/_next/static/chunks/549-1bdc3e6f3264c020.js +1 -0
  250. fides/ui-build/static/admin/_next/static/chunks/5505-43b9c39491b88e08.js +1 -0
  251. fides/ui-build/static/admin/_next/static/chunks/5698.2135391a128cc373.js +164 -0
  252. fides/ui-build/static/admin/_next/static/chunks/5783-016dfcee8e49bf61.js +1 -0
  253. fides/ui-build/static/admin/_next/static/chunks/5826-4db99ea4e5077911.js +1 -0
  254. fides/ui-build/static/admin/_next/static/chunks/590-be447cacf12419dd.js +1 -0
  255. fides/ui-build/static/admin/_next/static/chunks/6084-91badbc6569a0efb.js +1 -0
  256. fides/ui-build/static/admin/_next/static/chunks/6344-026cb323c1d49926.js +1 -0
  257. fides/ui-build/static/admin/_next/static/chunks/6362-ba0e12f2fc4cad94.js +1 -0
  258. fides/ui-build/static/admin/_next/static/chunks/6853-882889659769d7b4.js +1 -0
  259. fides/ui-build/static/admin/_next/static/chunks/6882-bb1b469d7d7f5335.js +1 -0
  260. fides/ui-build/static/admin/_next/static/chunks/6954-0dcf22a9aabe39c5.js +1 -0
  261. fides/ui-build/static/admin/_next/static/chunks/7170-46db82bb5b55e856.js +1 -0
  262. fides/ui-build/static/admin/_next/static/chunks/7218-2ace8c82e3e7eb74.js +1 -0
  263. fides/ui-build/static/admin/_next/static/chunks/7245-1cdafb35f289861b.js +1 -0
  264. fides/ui-build/static/admin/_next/static/chunks/7630-7f75ab7b8df42eb3.js +1 -0
  265. fides/ui-build/static/admin/_next/static/chunks/7654-2e9a8be02e41769a.js +1 -0
  266. fides/ui-build/static/admin/_next/static/chunks/8212-348ddd2b6933db70.js +1 -0
  267. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
  268. fides/ui-build/static/admin/_next/static/chunks/{5596-bb601cbf40e47a0f.js → 9195-da717d324917b049.js} +3 -3
  269. fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
  270. fides/ui-build/static/admin/_next/static/chunks/{9676.9fd9552ef744c717.js → 9676.1f395eeb9cc34968.js} +1 -1
  271. fides/ui-build/static/admin/_next/static/chunks/9826-1078e46f3ac0b688.js +1 -0
  272. fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
  273. fides/ui-build/static/admin/_next/static/chunks/pages/{404-471a6b18e712f050.js → 404-800be6996aaa999c.js} +1 -1
  274. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-fcdad91f6f66292b.js → _app-de4b578c904df772.js} +57 -220
  275. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-f12020b82dd4bd1a.js +1 -0
  276. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-a911b7990371704d.js +1 -0
  277. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-ad585b79953c2753.js +1 -0
  278. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-406170eaae4329c6.js → add-vendors-bb263d394ca1c8fa.js} +1 -1
  279. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-6907c368d8611c44.js +1 -0
  280. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-f80cf2d3966816fd.js → [id]-c32f381af358149b.js} +1 -1
  281. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-6efb3c069d8b47dd.js} +1 -1
  282. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-1975c529905eea9b.js +1 -0
  283. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-b378576cba255609.js → [id]-b05331178928ab52.js} +1 -1
  284. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-2ca1de7b88094ab0.js → new-516834e930bb0d0d.js} +1 -1
  285. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-985717f2565f9d9d.js +1 -0
  286. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-226efa1dcd41437f.js → properties-2be773e08498e40c.js} +1 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-850afb74f4192e87.js +1 -0
  288. fides/ui-build/static/admin/_next/static/chunks/pages/consent-b63d1e395d879b86.js +1 -0
  289. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-5b28f0f674ea87bd.js +1 -0
  290. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-04cfe2cfba7b7cd8.js → [projectUrn]-676177e2f3c9c2a2.js} +1 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-794906929efb8e1d.js +1 -0
  292. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-3ccbf7c0d06507b9.js +1 -0
  293. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-1ea0b24d306b1e67.js +1 -0
  294. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-d4861a4a218bb65a.js +1 -0
  295. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-4498881c26f1458d.js +1 -0
  296. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure/[monitorId]-66bd265044daf97d.js +1 -0
  297. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure-c9c79fa8576a4f77.js +1 -0
  298. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-60cacc3232c2eead.js +1 -0
  299. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-437bd64a3016de36.js +1 -0
  300. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-5b3e0009d442bc3f.js +1 -0
  301. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8349248c2da970a6.js +1 -0
  302. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6919a1d6cadaa46b.js +1 -0
  303. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-8f736b078e9842da.js → [resourceUrn]-1a50d421897d3da1.js} +1 -1
  304. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-eb814e3c22807871.js → detection-49509414a15e8393.js} +1 -1
  305. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-6875b7783fcfda2f.js → [resourceUrn]-1a1bb80b586d0c0f.js} +1 -1
  306. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-172dbd7740e212ca.js → discovery-49de61df1e8e7fba.js} +1 -1
  307. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c2719f5cff20c0f8.js +1 -0
  308. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-dfd71c1e9c458b89.js → [...subfieldNames]-415015aebab60436.js} +1 -1
  309. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-7cdc42ec5493b83d.js → [collectionName]-5accb09715b5122d.js} +1 -1
  310. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-aebecca1d8ec5f98.js +1 -0
  311. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-9551a82ddec9f909.js +1 -0
  312. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-72f8fe47beef0f09.js +1 -0
  313. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-3a8aa3f633528e88.js +1 -0
  314. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-87512616f35ec6da.js +1 -0
  315. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-2f1bf4eac7aa55fd.js +1 -0
  316. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
  317. fides/ui-build/static/admin/_next/static/chunks/pages/index-8d67cd2872cb682a.js +1 -0
  318. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-7a631df29cd0e31a.js +1 -0
  319. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-ea3bc43cdaf273de.js +1 -0
  320. fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-5d8632bba1b81cd4.js +1 -0
  321. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/[id]-92e01822ecde8fb8.js +1 -0
  322. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/new-1256cf6d3f6794e0.js +1 -0
  323. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-0daac00911d27617.js +1 -0
  324. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/[key]-2d976fe5e8ba0a3a.js +1 -0
  325. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/new-7766ba497b863740.js +1 -0
  326. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-f2880d2ed4734270.js +1 -0
  327. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/[id]-669f585c3458faff.js +1 -0
  328. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/add-template-c79e7724e4bc3899.js +1 -0
  329. fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-891654e8dc13965c.js +1 -0
  330. fides/ui-build/static/admin/_next/static/chunks/pages/notifications-40c8148244c5d347.js +1 -0
  331. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-1e86f3e28bd23ed6.js +1 -0
  332. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-9b7bd8c38f02c091.js +1 -0
  333. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-b18a53a940cf9e19.js +1 -0
  334. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6d028d7450e77578.js +1 -0
  335. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-8399083ee2cd8cc2.js +1 -0
  336. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-0a910125cdb2b3b8.js +1 -0
  337. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-acc90b6f7fe915cb.js +1 -0
  338. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bbc42026f2685438.js +1 -0
  339. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-c08ca6ad21c99799.js +1 -0
  340. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-77c2db582f8823bc.js +1 -0
  341. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-e784c05d056b2371.js → [id]-74ccea4868408e3d.js} +1 -1
  342. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-0a7a2db148a7561a.js → add-property-7d9f09bfe9d44dfc.js} +1 -1
  343. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-da734840e4f9d04b.js → properties-cd77bc30672bb1fa.js} +1 -1
  344. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-cc3bd9540132d5ed.js +1 -0
  345. fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-7ce7d720107ab4b5.js +1 -0
  346. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-68eaac2d79133679.js +1 -0
  347. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6c4904c157477285.js +1 -0
  348. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ae789892343c24f5.js +1 -0
  349. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-13ee1b331ced0846.js +1 -0
  350. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-ee4e43692336a330.js +1 -0
  351. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-ca51d794abfcbf25.js +1 -0
  352. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-ecd1dc5db8e81409.js +1 -0
  353. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-df06f7e2f668c540.js +1 -0
  354. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-da0c77bd510c6c51.js +1 -0
  355. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-950b0c115bf673d8.js +1 -0
  356. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-2e635dcd11b78224.js → locations-7e36cb4756973a9d.js} +1 -1
  357. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-a0e5ed486d24ccf3.js +1 -0
  358. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-3cdebafb6870d3ad.js +1 -0
  359. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-7c02e469d8c5bd74.js → regulations-159aad34f1021320.js} +1 -1
  360. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-dbd1a64090ad0946.js +1 -0
  361. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-7d042497a57a3788.js +1 -0
  362. fides/ui-build/static/admin/_next/static/chunks/pages/systems-21f1172e73dfc9f0.js +1 -0
  363. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-e553161e6338ee48.js +1 -0
  364. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-92f52c43f522a350.js → new-efc4af017723e57a.js} +1 -1
  365. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-64452dfae2c5e614.js → [id]-b152319d67372ee4.js} +1 -1
  366. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dba8692491f7935e.js +1 -0
  367. fides/ui-build/static/admin/_next/static/chunks/webpack-09ca52bc7beb0b43.js +1 -0
  368. fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
  369. fides/ui-build/static/admin/_next/static/css/05d05fc31d09638b.css +1 -0
  370. fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
  371. fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
  372. fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
  373. fides/ui-build/static/admin/_next/static/css/3d66bb57ddcb0978.css +1 -0
  374. fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
  375. fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
  376. fides/ui-build/static/admin/_next/static/css/a1e4be9466578ef1.css +1 -0
  377. fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
  378. fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
  379. fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
  380. fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
  381. fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
  382. fides/ui-build/static/admin/_next/static/l2vgGUHB04Fi4oEVlVMrc/_buildManifest.js +1 -0
  383. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  384. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  385. fides/ui-build/static/admin/add-systems.html +1 -1
  386. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  387. fides/ui-build/static/admin/consent/configure.html +1 -1
  388. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  389. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  390. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  391. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  392. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  393. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  394. fides/ui-build/static/admin/consent/properties.html +1 -1
  395. fides/ui-build/static/admin/consent/reporting.html +1 -1
  396. fides/ui-build/static/admin/consent.html +1 -1
  397. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  398. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  399. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  400. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  401. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  402. fides/ui-build/static/admin/data-catalog.html +1 -1
  403. fides/ui-build/static/admin/data-discovery/action-center/datastore/[monitorId].html +1 -0
  404. fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
  405. fides/ui-build/static/admin/data-discovery/action-center/infrastructure/[monitorId].html +1 -0
  406. fides/ui-build/static/admin/data-discovery/action-center/infrastructure.html +1 -0
  407. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
  408. fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
  409. fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
  410. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  411. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  412. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  413. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  414. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  415. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  416. fides/ui-build/static/admin/datamap.html +1 -1
  417. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  418. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  419. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  420. fides/ui-build/static/admin/dataset/new.html +1 -1
  421. fides/ui-build/static/admin/dataset.html +1 -1
  422. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  423. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  424. fides/ui-build/static/admin/datastore-connection.html +1 -1
  425. fides/ui-build/static/admin/index.html +1 -1
  426. fides/ui-build/static/admin/integrations/[id].html +1 -1
  427. fides/ui-build/static/admin/integrations.html +1 -1
  428. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  429. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  430. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  431. fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
  432. fides/ui-build/static/admin/lib/fides.js +3 -3
  433. fides/ui-build/static/admin/login/[provider].html +1 -1
  434. fides/ui-build/static/admin/login.html +1 -1
  435. fides/ui-build/static/admin/new-privacy-requests.html +1 -0
  436. fides/ui-build/static/admin/notifications/digests/[id].html +1 -0
  437. fides/ui-build/static/admin/notifications/digests/new.html +1 -0
  438. fides/ui-build/static/admin/notifications/digests.html +1 -0
  439. fides/ui-build/static/admin/notifications/providers/[key].html +1 -0
  440. fides/ui-build/static/admin/notifications/providers/new.html +1 -0
  441. fides/ui-build/static/admin/notifications/providers.html +1 -0
  442. fides/ui-build/static/admin/notifications/templates/[id].html +1 -0
  443. fides/ui-build/static/admin/notifications/templates/add-template.html +1 -0
  444. fides/ui-build/static/admin/notifications/templates.html +1 -0
  445. fides/ui-build/static/admin/notifications.html +1 -0
  446. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  447. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  448. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  449. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  450. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  451. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  452. fides/ui-build/static/admin/poc/forms.html +1 -1
  453. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  454. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  455. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  456. fides/ui-build/static/admin/privacy-requests.html +1 -1
  457. fides/ui-build/static/admin/properties/[id].html +1 -1
  458. fides/ui-build/static/admin/properties/add-property.html +1 -1
  459. fides/ui-build/static/admin/properties.html +1 -1
  460. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  461. fides/ui-build/static/admin/sandbox/privacy-notices.html +1 -0
  462. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  463. fides/ui-build/static/admin/settings/about.html +1 -1
  464. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  465. fides/ui-build/static/admin/settings/consent.html +1 -1
  466. fides/ui-build/static/admin/settings/custom-fields/[id].html +1 -0
  467. fides/ui-build/static/admin/settings/custom-fields/new.html +1 -0
  468. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  469. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  470. fides/ui-build/static/admin/settings/domains.html +1 -1
  471. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  472. fides/ui-build/static/admin/settings/locations.html +1 -1
  473. fides/ui-build/static/admin/settings/organization.html +1 -1
  474. fides/ui-build/static/admin/settings/privacy-requests.html +1 -1
  475. fides/ui-build/static/admin/settings/regulations.html +1 -1
  476. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  477. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  478. fides/ui-build/static/admin/systems.html +1 -1
  479. fides/ui-build/static/admin/taxonomy.html +1 -1
  480. fides/ui-build/static/admin/user-management/new.html +1 -1
  481. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  482. fides/ui-build/static/admin/user-management.html +1 -1
  483. fides/api/service/async_dsr/async_dsr_service.py +0 -75
  484. fides/api/service/privacy_request/dsr_package/templates/welcome.html +0 -66
  485. fides/ui-build/static/admin/_next/static/OmXHlY9MvjoZH9jDkAytl/_buildManifest.js +0 -1
  486. fides/ui-build/static/admin/_next/static/chunks/1099-79646e64f26d62fa.js +0 -1
  487. fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
  488. fides/ui-build/static/admin/_next/static/chunks/1345-5e1c5b66e25c566e.js +0 -1
  489. fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
  490. fides/ui-build/static/admin/_next/static/chunks/1817-0ca16d288fad916d.js +0 -1
  491. fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
  492. fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
  493. fides/ui-build/static/admin/_next/static/chunks/2921-52328140bc420d0f.js +0 -1
  494. fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
  495. fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +0 -1
  496. fides/ui-build/static/admin/_next/static/chunks/3620-602eb74dc896d556.js +0 -1
  497. fides/ui-build/static/admin/_next/static/chunks/3729-c17ac8031a4c4fd1.js +0 -1
  498. fides/ui-build/static/admin/_next/static/chunks/3847-230bf61b053bc706.js +0 -1
  499. fides/ui-build/static/admin/_next/static/chunks/3855-ef5194cdb228beb6.js +0 -1
  500. fides/ui-build/static/admin/_next/static/chunks/3872-f78dec02f0d959ae.js +0 -1
  501. fides/ui-build/static/admin/_next/static/chunks/3923-bb2417b8dcade7a4.js +0 -1
  502. fides/ui-build/static/admin/_next/static/chunks/401-4af0a912e249d30f.js +0 -1
  503. fides/ui-build/static/admin/_next/static/chunks/4164-355644b916ae0094.js +0 -1
  504. fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +0 -1
  505. fides/ui-build/static/admin/_next/static/chunks/4608-be8cba73f5d7c326.js +0 -1
  506. fides/ui-build/static/admin/_next/static/chunks/4786-61154adf88e448e1.js +0 -1
  507. fides/ui-build/static/admin/_next/static/chunks/4808-dd4157aa72648068.js +0 -1
  508. fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +0 -1
  509. fides/ui-build/static/admin/_next/static/chunks/4844-46324c3d848b8b6a.js +0 -1
  510. fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
  511. fides/ui-build/static/admin/_next/static/chunks/5258-b0de22a8521686ab.js +0 -1
  512. fides/ui-build/static/admin/_next/static/chunks/5487-02d00bad7c6830e0.js +0 -1
  513. fides/ui-build/static/admin/_next/static/chunks/549-38ea1d91ee2addaa.js +0 -1
  514. fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
  515. fides/ui-build/static/admin/_next/static/chunks/6084-c153669d5567e242.js +0 -1
  516. fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +0 -1
  517. fides/ui-build/static/admin/_next/static/chunks/6853-b17673391117c976.js +0 -1
  518. fides/ui-build/static/admin/_next/static/chunks/6954-5296188c19d7d0ac.js +0 -1
  519. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
  520. fides/ui-build/static/admin/_next/static/chunks/7476-45c5088baa8b66af.js +0 -1
  521. fides/ui-build/static/admin/_next/static/chunks/7630-7ed6c6117775dffe.js +0 -1
  522. fides/ui-build/static/admin/_next/static/chunks/787-a8c7eab617e2fceb.js +0 -1
  523. fides/ui-build/static/admin/_next/static/chunks/79-65674011d455af4d.js +0 -1
  524. fides/ui-build/static/admin/_next/static/chunks/796-9e1ca1a4030707c5.js +0 -1
  525. fides/ui-build/static/admin/_next/static/chunks/8002-24af20d679efc04e.js +0 -1
  526. fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
  527. fides/ui-build/static/admin/_next/static/chunks/9046-712156d461165f56.js +0 -1
  528. fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
  529. fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
  530. fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
  531. fides/ui-build/static/admin/_next/static/chunks/9826-dbae8dee941a7fac.js +0 -1
  532. fides/ui-build/static/admin/_next/static/chunks/9951-a88367a129b724ba.js +0 -1
  533. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-ace203dfacacbdc4.js +0 -1
  534. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-920fb469e0dda1d2.js +0 -1
  535. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-bd0d82078e67cac3.js +0 -1
  536. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-7207ab23bdb36ce8.js +0 -1
  537. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-9dda4de5ec580279.js +0 -1
  538. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-0d4844d0b808e6e4.js +0 -1
  539. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-28b192e2c074b0f3.js +0 -1
  540. fides/ui-build/static/admin/_next/static/chunks/pages/consent-3e8bdefe714254ec.js +0 -1
  541. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2c29ff7a01198f30.js +0 -1
  542. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-5f2d7b24804f861f.js +0 -1
  543. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-8eb581024bc0172f.js +0 -1
  544. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-30108b00ac769fc3.js +0 -1
  545. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e1ba213fb666b3f4.js +0 -1
  546. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-6d133580045abdda.js +0 -1
  547. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9a81d42a474e1e48.js +0 -1
  548. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-b6ae7adb8ef0b525.js +0 -1
  549. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c7390e046b2e2b7f.js +0 -1
  550. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e12b11ba15bc3fc1.js +0 -1
  551. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-e32fccc4ca520d2b.js +0 -1
  552. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7c59a6abf6ba6207.js +0 -1
  553. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-927b7e476c4b47d0.js +0 -1
  554. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-cbe100d50df34285.js +0 -1
  555. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cce20440b177050b.js +0 -1
  556. fides/ui-build/static/admin/_next/static/chunks/pages/index-6cd8708106331b8d.js +0 -1
  557. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4c3c413a2668df53.js +0 -1
  558. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-95402b5001c07ef2.js +0 -1
  559. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-3c6dc2f6e6bae960.js +0 -1
  560. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-4a6d4023a7791be8.js +0 -1
  561. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-76b204c9b98d656f.js +0 -1
  562. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-bc0e2adf6e0d3ac7.js +0 -1
  563. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-86ffcc1ad3fa912e.js +0 -1
  564. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-ec04f595465bdf69.js +0 -1
  565. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-41d309754ff0c1de.js +0 -1
  566. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-cab1f78cec7808f9.js +0 -1
  567. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-eb6058221403b156.js +0 -1
  568. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-48500551fd6a7602.js +0 -1
  569. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-0f25a76dd18c5e20.js +0 -1
  570. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-ad6ad3e5bd72765d.js +0 -1
  571. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6032d82f0fc2893d.js +0 -1
  572. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-d83e5bd52a638234.js +0 -1
  573. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-baf31c3e4b081046.js +0 -1
  574. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6903f42a0412bfa6.js +0 -1
  575. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-a82f3df840d5c1b5.js +0 -1
  576. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-d06fb16487705b9d.js +0 -1
  577. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-9495e2eb506606c7.js +0 -1
  578. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-93a978443bf299db.js +0 -1
  579. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-9ecb803099082bf4.js +0 -1
  580. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-16fdd91a81074dd1.js +0 -1
  581. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-4cdd6001e7cb9aee.js +0 -1
  582. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-1914de830ce5cfc4.js +0 -1
  583. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-f547f1f33c12faf3.js +0 -1
  584. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +0 -1
  585. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-20b1193ed76c56b0.js +0 -1
  586. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-6e15332935f6b538.js +0 -1
  587. fides/ui-build/static/admin/_next/static/chunks/pages/systems-fbc8761ef4d55516.js +0 -1
  588. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-4d7827fc9c46b6b8.js +0 -1
  589. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-9cec020f89544426.js +0 -1
  590. fides/ui-build/static/admin/_next/static/chunks/webpack-678e89d68dbcd94f.js +0 -1
  591. fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
  592. fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
  593. fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
  594. fides/ui-build/static/admin/_next/static/css/650df9c348000a26.css +0 -1
  595. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
  596. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
  597. fides/ui-build/static/admin/messaging/[id].html +0 -1
  598. fides/ui-build/static/admin/messaging/add-template.html +0 -1
  599. fides/ui-build/static/admin/messaging.html +0 -1
  600. fides/ui-build/static/admin/poc/table-migration.html +0 -1
  601. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +0 -1
  602. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/WHEEL +0 -0
  603. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/entry_points.txt +0 -0
  604. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/licenses/LICENSE +0 -0
  605. {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/top_level.txt +0 -0
  606. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-de704de849960f01.js → resources-81d1b50585468fb0.js} +0 -0
  607. /fides/ui-build/static/admin/_next/static/{OmXHlY9MvjoZH9jDkAytl → l2vgGUHB04Fi4oEVlVMrc}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@ import csv
4
4
  import io
5
5
  import json
6
6
  from collections import defaultdict
7
- from datetime import datetime, timezone
7
+ from datetime import datetime, timedelta, timezone
8
8
  from typing import (
9
9
  Annotated,
10
10
  Any,
@@ -29,7 +29,7 @@ from loguru import logger
29
29
  from pydantic import Field
30
30
  from pydantic import ValidationError as PydanticValidationError
31
31
  from sqlalchemy import cast, column, null, or_, select
32
- from sqlalchemy.orm import Query, Session
32
+ from sqlalchemy.orm import Query, Session, selectinload
33
33
  from sqlalchemy.sql.expression import nullslast
34
34
  from starlette.responses import StreamingResponse
35
35
  from starlette.status import (
@@ -88,9 +88,11 @@ from fides.api.schemas.dataset import CollectionAddressResponse, DryRunDatasetRe
88
88
  from fides.api.schemas.external_https import PrivacyRequestResumeFormat
89
89
  from fides.api.schemas.policy import ActionType, CurrentStep
90
90
  from fides.api.schemas.privacy_request import (
91
+ BULK_PRIVACY_REQUEST_BATCH_SIZE,
91
92
  BulkPostPrivacyRequests,
92
93
  BulkReviewResponse,
93
94
  BulkSoftDeletePrivacyRequests,
95
+ CancelPrivacyRequests,
94
96
  CheckpointActionRequired,
95
97
  DenyPrivacyRequests,
96
98
  ExecutionLogDetailResponse,
@@ -144,8 +146,10 @@ from fides.common.api.v1.urn_registry import (
144
146
  PRIVACY_REQUEST_APPROVE,
145
147
  PRIVACY_REQUEST_AUTHENTICATED,
146
148
  PRIVACY_REQUEST_BATCH_EMAIL_SEND,
149
+ PRIVACY_REQUEST_BULK_FINALIZE,
147
150
  PRIVACY_REQUEST_BULK_RETRY,
148
151
  PRIVACY_REQUEST_BULK_SOFT_DELETE,
152
+ PRIVACY_REQUEST_CANCEL,
149
153
  PRIVACY_REQUEST_DENY,
150
154
  PRIVACY_REQUEST_FILTERED_RESULTS,
151
155
  PRIVACY_REQUEST_FINALIZE,
@@ -222,7 +226,9 @@ def create_privacy_request(
222
226
  privacy_request_service: PrivacyRequestService = Depends(
223
227
  get_privacy_request_service
224
228
  ),
225
- data: Annotated[List[PrivacyRequestCreate], Field(max_length=50)], # type: ignore
229
+ data: Annotated[
230
+ List[PrivacyRequestCreate], Field(max_length=BULK_PRIVACY_REQUEST_BATCH_SIZE)
231
+ ], # type: ignore
226
232
  ) -> BulkPostPrivacyRequests:
227
233
  """
228
234
  Given a list of privacy request data elements, create corresponding PrivacyRequest objects
@@ -248,7 +254,9 @@ def create_privacy_request_authenticated(
248
254
  verify_oauth_client,
249
255
  scopes=[PRIVACY_REQUEST_CREATE],
250
256
  ),
251
- data: Annotated[List[PrivacyRequestCreate], Field(max_length=50)], # type: ignore
257
+ data: Annotated[
258
+ List[PrivacyRequestCreate], Field(max_length=BULK_PRIVACY_REQUEST_BATCH_SIZE)
259
+ ], # type: ignore
252
260
  ) -> BulkPostPrivacyRequests:
253
261
  """
254
262
  Given a list of privacy request data elements, create corresponding PrivacyRequest objects
@@ -269,48 +277,73 @@ def privacy_request_csv_download(
269
277
  f = io.StringIO()
270
278
  csv_file = csv.writer(f)
271
279
 
280
+ # Execute query once and convert to list to avoid multiple iterations
281
+ privacy_requests: List[PrivacyRequest] = privacy_request_query.all()
282
+ privacy_request_ids: List[str] = [r.id for r in privacy_requests]
283
+
284
+ denial_audit_log_query: Query = db.query(AuditLog).filter(
285
+ AuditLog.action == AuditLogAction.denied,
286
+ AuditLog.privacy_request_id.in_(privacy_request_ids),
287
+ )
288
+ denial_audit_logs: Dict[str, str] = {
289
+ r.privacy_request_id: r.message for r in denial_audit_log_query
290
+ }
291
+
292
+ identity_columns, custom_field_columns = get_variable_columns(privacy_requests)
293
+
272
294
  csv_file.writerow(
273
295
  [
274
296
  "Status",
275
297
  "Request Type",
276
- "Subject Identity",
277
- "Custom Privacy Request Fields",
278
298
  "Time Received",
299
+ "Deadline",
279
300
  "Reviewed By",
280
301
  "Request ID",
281
302
  "Time Approved/Denied",
282
303
  "Denial Reason",
304
+ "Last Updated",
305
+ "Completed On",
283
306
  ]
307
+ + identity_columns
308
+ + with_prefix("Custom Field", list(custom_field_columns.values()))
284
309
  )
285
- privacy_request_ids: List[str] = [r.id for r in privacy_request_query]
286
- denial_audit_log_query: Query = db.query(AuditLog).filter(
287
- AuditLog.action == AuditLogAction.denied,
288
- AuditLog.privacy_request_id.in_(privacy_request_ids),
289
- )
290
- denial_audit_logs: Dict[str, str] = {
291
- r.privacy_request_id: r.message for r in denial_audit_log_query
292
- }
293
310
 
294
- for pr in privacy_request_query:
311
+ pr: PrivacyRequest
312
+ for pr in privacy_requests:
295
313
  denial_reason = (
296
314
  denial_audit_logs[pr.id]
297
315
  if pr.status == PrivacyRequestStatus.denied and pr.id in denial_audit_logs
298
316
  else None
299
317
  )
300
318
 
301
- csv_file.writerow(
302
- [
303
- pr.status.value if pr.status else None,
304
- pr.policy.rules[0].action_type if len(pr.policy.rules) > 0 else None,
305
- pr.get_persisted_identity().model_dump(mode="json"),
306
- pr.get_persisted_custom_privacy_request_fields(),
307
- pr.created_at,
308
- pr.reviewed_by,
309
- pr.id,
310
- pr.reviewed_at,
311
- denial_reason,
312
- ]
313
- )
319
+ action_types: List[str] = []
320
+ if pr and pr.policy:
321
+ for rule in pr.policy.rules or []: # type: ignore
322
+ action_types.append(rule.action_type)
323
+
324
+ deadline: Optional[datetime] = None
325
+ if pr.days_left and pr.created_at:
326
+ deadline = pr.created_at + timedelta(days=pr.days_left)
327
+
328
+ static_cells = [
329
+ pr.status.value if pr.status else None,
330
+ ("+".join(action_types)),
331
+ pr.created_at,
332
+ deadline,
333
+ pr.reviewed_by,
334
+ pr.id,
335
+ pr.reviewed_at,
336
+ denial_reason,
337
+ pr.updated_at,
338
+ pr.finalized_at,
339
+ ]
340
+
341
+ identity_cells = extract_identity_cells(identity_columns, pr)
342
+ custom_field_cells = extract_custom_field_cells(custom_field_columns, pr)
343
+
344
+ row = static_cells + identity_cells + custom_field_cells
345
+
346
+ csv_file.writerow(row)
314
347
 
315
348
  f.seek(0)
316
349
  response = StreamingResponse(f, media_type="text/csv")
@@ -320,6 +353,64 @@ def privacy_request_csv_download(
320
353
  return response
321
354
 
322
355
 
356
+ def get_variable_columns(
357
+ privacy_requests: List[PrivacyRequest],
358
+ ) -> tuple[List[str], Dict[str, str]]:
359
+ identity_columns: Set[str] = set()
360
+ custom_field_columns: Dict[str, str] = {}
361
+
362
+ for pr in privacy_requests:
363
+ identity_columns.update(
364
+ extract_identity_column_names(pr.get_persisted_identity().model_dump())
365
+ )
366
+ custom_field_columns.update(
367
+ extract_custom_field_column_names(
368
+ pr.get_persisted_custom_privacy_request_fields()
369
+ )
370
+ )
371
+
372
+ return list(identity_columns), custom_field_columns
373
+
374
+
375
+ def extract_identity_column_names(identities: dict[str, Any]) -> Set[str]:
376
+ """Extract column names from identity data that have non-empty values."""
377
+ return {key for key, value in identities.items() if value}
378
+
379
+
380
+ def extract_custom_field_column_names(custom_fields: dict[str, Any]) -> Dict[str, str]:
381
+ """Extract column names and labels from custom field data that have non-empty values."""
382
+ return {
383
+ key: value["label"]
384
+ for key, value in custom_fields.items()
385
+ if value.get("value")
386
+ }
387
+
388
+
389
+ def with_prefix(prefix: str, items: List[str]) -> List[str]:
390
+ return [f"{prefix} {item}" for item in items]
391
+
392
+
393
+ def extract_custom_field_cells(
394
+ custom_field_columns: Dict[str, str], pr: PrivacyRequest
395
+ ) -> List[str]:
396
+ custom_fields = pr.get_persisted_custom_privacy_request_fields()
397
+ return [
398
+ custom_fields.get(custom_field_column, {}).get("value")
399
+ for custom_field_column in custom_field_columns
400
+ ]
401
+
402
+
403
+ def extract_identity_cells(
404
+ identity_columns: List[str], pr: PrivacyRequest
405
+ ) -> List[str]:
406
+ identity = pr.get_persisted_identity()
407
+ identity_dict = identity.model_dump()
408
+ return [
409
+ identity_dict.get(identity_column) # type: ignore
410
+ for identity_column in identity_columns
411
+ ]
412
+
413
+
323
414
  def execution_and_audit_logs_by_dataset_name(
324
415
  self: PrivacyRequest,
325
416
  ) -> DefaultDict[str, List[Union["AuditLog", "ExecutionLog"]]]:
@@ -405,7 +496,7 @@ def _filter_privacy_request_queryset(
405
496
  errored_gt: Optional[datetime] = None,
406
497
  external_id: Optional[str] = None,
407
498
  location: Optional[str] = None,
408
- action_type: Optional[ActionType] = None,
499
+ action_type: Optional[Union[ActionType, List[ActionType]]] = None,
409
500
  include_consent_webhook_requests: Optional[bool] = False,
410
501
  include_deleted_requests: Optional[bool] = False,
411
502
  ) -> Query:
@@ -595,9 +686,11 @@ def _filter_privacy_request_queryset(
595
686
  PrivacyRequest.finished_processing_at > errored_gt,
596
687
  )
597
688
  if action_type:
689
+ if isinstance(action_type, ActionType):
690
+ action_type = [action_type]
598
691
  policy_ids_for_action_type = (
599
692
  db.query(Rule)
600
- .filter(Rule.action_type == action_type)
693
+ .filter(Rule.action_type.in_(action_type))
601
694
  .with_entities(Rule.policy_id)
602
695
  .distinct()
603
696
  )
@@ -711,7 +804,7 @@ def _shared_privacy_request_search(
711
804
  errored_gt: Optional[datetime] = None,
712
805
  external_id: Optional[str] = None,
713
806
  location: Optional[str] = None,
714
- action_type: Optional[ActionType] = None,
807
+ action_type: Optional[Union[ActionType, List[ActionType]]] = None,
715
808
  verbose: Optional[bool] = False,
716
809
  include_identities: Optional[bool] = False,
717
810
  include_custom_privacy_request_fields: Optional[bool] = False,
@@ -730,7 +823,8 @@ def _shared_privacy_request_search(
730
823
 
731
824
  logger.debug("Finding all request statuses with pagination params {}", params)
732
825
 
733
- query = db.query(PrivacyRequest)
826
+ # Use query_without_large_columns to prevent OOM errors when loading many privacy requests
827
+ query = PrivacyRequest.query_without_large_columns(db)
734
828
  query = _filter_privacy_request_queryset(
735
829
  db,
736
830
  query,
@@ -762,10 +856,29 @@ def _shared_privacy_request_search(
762
856
 
763
857
  if download_csv:
764
858
  _validate_result_size(query)
859
+ # Eager load relationships needed for CSV export to avoid N+1 queries
860
+ query = query.options(
861
+ selectinload(PrivacyRequest.provided_identities), # type: ignore[attr-defined]
862
+ selectinload(PrivacyRequest.custom_fields), # type: ignore[attr-defined]
863
+ selectinload(PrivacyRequest.policy).selectinload(Policy.rules), # type: ignore[attr-defined]
864
+ )
765
865
  # Returning here if download_csv param was specified
766
866
  logger.info("Downloading privacy requests as csv")
767
867
  return privacy_request_csv_download(db, query)
768
868
 
869
+ # Eager load relationships for regular list view to avoid N+1 queries
870
+ if include_identities or include_custom_privacy_request_fields:
871
+ eager_load_options = []
872
+ if include_identities:
873
+ eager_load_options.append(
874
+ selectinload(PrivacyRequest.provided_identities) # type: ignore[attr-defined]
875
+ )
876
+ if include_custom_privacy_request_fields:
877
+ eager_load_options.append(
878
+ selectinload(PrivacyRequest.custom_fields) # type: ignore[attr-defined]
879
+ )
880
+ query = query.options(*eager_load_options)
881
+
769
882
  # Conditionally embed execution log details in the response.
770
883
  if verbose:
771
884
  logger.info("Finding execution and audit log details")
@@ -1202,15 +1315,26 @@ def validate_manual_input(
1202
1315
  ],
1203
1316
  )
1204
1317
  def bulk_restart_privacy_request_from_failure(
1205
- privacy_request_ids: List[str],
1318
+ privacy_request_ids: Annotated[
1319
+ List[str], Field(max_length=BULK_PRIVACY_REQUEST_BATCH_SIZE)
1320
+ ],
1206
1321
  *,
1207
1322
  db: Session = Depends(deps.get_db),
1208
1323
  ) -> BulkPostPrivacyRequests:
1209
- """Bulk restart a of privacy request from failure."""
1324
+ """Bulk restart privacy requests from failure."""
1210
1325
  succeeded: List[PrivacyRequestResponse] = []
1211
1326
  failed: List[Dict[str, Any]] = []
1327
+
1328
+ # Fetch all privacy requests in one query to avoid N+1
1329
+ privacy_requests_dict = {
1330
+ pr.id: pr
1331
+ for pr in PrivacyRequest.query_without_large_columns(db)
1332
+ .filter(PrivacyRequest.id.in_(privacy_request_ids))
1333
+ .all()
1334
+ }
1335
+
1212
1336
  for privacy_request_id in privacy_request_ids:
1213
- privacy_request = PrivacyRequest.get(db, object_id=privacy_request_id)
1337
+ privacy_request = privacy_requests_dict.get(privacy_request_id)
1214
1338
 
1215
1339
  if not privacy_request:
1216
1340
  failed.append(
@@ -1276,10 +1400,10 @@ def restart_privacy_request_from_failure(
1276
1400
  )
1277
1401
 
1278
1402
  # Automatically resubmit the request if the cache has expired
1403
+
1279
1404
  if (
1280
- not privacy_request.get_cached_identity_data()
1281
- and privacy_request.status
1282
- not in [PrivacyRequestStatus.complete, PrivacyRequestStatus.pending]
1405
+ not privacy_request.verify_cache_for_identity_data()
1406
+ and privacy_request.status != PrivacyRequestStatus.complete
1283
1407
  ):
1284
1408
  logger.info(
1285
1409
  f"Cached data for privacy request {privacy_request.id} has expired, automatically resubmitting request"
@@ -1396,10 +1520,37 @@ def deny_privacy_request(
1396
1520
  )
1397
1521
 
1398
1522
 
1523
+ @router.patch(
1524
+ PRIVACY_REQUEST_CANCEL,
1525
+ status_code=HTTP_200_OK,
1526
+ response_model=BulkReviewResponse,
1527
+ )
1528
+ def cancel_privacy_request(
1529
+ *,
1530
+ client: ClientDetail = Security(
1531
+ verify_oauth_client,
1532
+ scopes=[PRIVACY_REQUEST_REVIEW],
1533
+ ),
1534
+ privacy_request_service: PrivacyRequestService = Depends(
1535
+ get_privacy_request_service
1536
+ ),
1537
+ privacy_requests: CancelPrivacyRequests,
1538
+ ) -> BulkReviewResponse:
1539
+ """Cancel a list of privacy requests and/or report failure"""
1540
+
1541
+ return privacy_request_service.cancel_privacy_requests(
1542
+ privacy_requests.request_ids, privacy_requests.reason, user_id=client.user_id
1543
+ )
1544
+
1545
+
1399
1546
  def _validate_privacy_request_pending_or_error(
1400
1547
  db: Session, privacy_request_id: str
1401
1548
  ) -> None:
1402
- privacy_request = PrivacyRequest.get(db, object_id=privacy_request_id)
1549
+ privacy_request = (
1550
+ PrivacyRequest.query_without_large_columns(db)
1551
+ .filter(PrivacyRequest.id == privacy_request_id)
1552
+ .first()
1553
+ )
1403
1554
  if not privacy_request:
1404
1555
  raise HTTPException(
1405
1556
  status_code=HTTP_404_NOT_FOUND,
@@ -1667,17 +1818,15 @@ def privacy_request_data_transfer(
1667
1818
  detail=f"Rule key {rule_key} not found",
1668
1819
  )
1669
1820
 
1670
- value_dict: Dict[str, Optional[List[Row]]] = cache.get_encoded_objects_by_prefix(
1671
- f"{privacy_request_id}__access_request"
1821
+ access_result: Dict[str, Optional[List[Row]]] = (
1822
+ privacy_request.get_raw_access_results()
1672
1823
  )
1673
1824
 
1674
- if not value_dict:
1825
+ if not access_result:
1675
1826
  raise HTTPException(
1676
1827
  status_code=HTTP_404_NOT_FOUND,
1677
1828
  detail=f"No access request information found for privacy request id {privacy_request_id}",
1678
1829
  )
1679
-
1680
- access_result = {k.split("__")[-1]: v for k, v in value_dict.items()}
1681
1830
  datasets = DatasetConfig.all(db=db)
1682
1831
  if not datasets:
1683
1832
  raise HTTPException(
@@ -1893,6 +2042,32 @@ def resume_privacy_request_from_requires_input(
1893
2042
  return privacy_request # type: ignore[return-value]
1894
2043
 
1895
2044
 
2045
+ @router.post(
2046
+ PRIVACY_REQUEST_BULK_FINALIZE,
2047
+ status_code=HTTP_200_OK,
2048
+ response_model=BulkReviewResponse,
2049
+ )
2050
+ def bulk_finalize_privacy_requests(
2051
+ *,
2052
+ client: ClientDetail = Security(
2053
+ verify_oauth_client,
2054
+ scopes=[PRIVACY_REQUEST_REVIEW],
2055
+ ),
2056
+ privacy_request_service: PrivacyRequestService = Depends(
2057
+ get_privacy_request_service
2058
+ ),
2059
+ privacy_requests: ReviewPrivacyRequestIds,
2060
+ ) -> BulkReviewResponse:
2061
+ """
2062
+ Bulk finalize privacy requests that are in requires_manual_finalization status.
2063
+ Each request will be moved from the 'requires_finalization' state to 'complete'.
2064
+ Returns an object with the list of successfully finalized privacy requests and the list of failed finalizations.
2065
+ """
2066
+ return privacy_request_service.finalize_privacy_requests(
2067
+ privacy_requests.request_ids, user_id=client.user_id
2068
+ )
2069
+
2070
+
1896
2071
  @router.post(
1897
2072
  PRIVACY_REQUEST_FINALIZE,
1898
2073
  status_code=HTTP_200_OK,
@@ -2079,8 +2254,18 @@ def bulk_soft_delete_privacy_requests(
2079
2254
  if client.id == CONFIG.security.oauth_root_client_id:
2080
2255
  user_id = "root"
2081
2256
 
2082
- for privacy_request_id in privacy_requests.request_ids:
2083
- privacy_request = PrivacyRequest.get(db, object_id=privacy_request_id)
2257
+ request_ids = privacy_requests.request_ids
2258
+
2259
+ # Fetch all privacy requests in one query to avoid N+1
2260
+ privacy_requests_dict = {
2261
+ pr.id: pr
2262
+ for pr in PrivacyRequest.query_without_large_columns(db)
2263
+ .filter(PrivacyRequest.id.in_(request_ids))
2264
+ .all()
2265
+ }
2266
+
2267
+ for privacy_request_id in request_ids:
2268
+ privacy_request = privacy_requests_dict.get(privacy_request_id)
2084
2269
 
2085
2270
  if not privacy_request:
2086
2271
  failed.append(
@@ -1,12 +1,11 @@
1
- from io import BytesIO
2
1
  from typing import Optional
3
- from zipfile import BadZipFile, ZipFile
4
2
 
5
- from fastapi import Body, Depends, HTTPException, Request
3
+ from fastapi import Depends, HTTPException, Request
4
+ from fastapi.encoders import jsonable_encoder
6
5
  from fastapi.params import Security
7
- from fastapi.responses import JSONResponse
8
6
  from fideslang.validation import FidesKey
9
7
  from loguru import logger
8
+ from pydantic import ValidationError
10
9
  from sqlalchemy.orm import Session
11
10
  from starlette.status import (
12
11
  HTTP_200_OK,
@@ -18,9 +17,15 @@ from starlette.status import (
18
17
  )
19
18
 
20
19
  from fides.api.api import deps
21
- from fides.api.common_exceptions import FidesopsException, KeyOrNameAlreadyExists
20
+ from fides.api.common_exceptions import (
21
+ FidesopsException,
22
+ KeyOrNameAlreadyExists,
23
+ SaaSConfigNotFoundException,
24
+ )
25
+ from fides.api.common_exceptions import ValidationError as FidesValidationError
22
26
  from fides.api.models.connectionconfig import ConnectionConfig, ConnectionType
23
27
  from fides.api.models.datasetconfig import DatasetConfig
28
+ from fides.api.models.event_audit import EventAuditStatus, EventAuditType
24
29
  from fides.api.models.sql_models import System # type: ignore
25
30
  from fides.api.oauth.utils import verify_oauth_client
26
31
  from fides.api.schemas.connection_configuration.connection_config import (
@@ -29,7 +34,6 @@ from fides.api.schemas.connection_configuration.connection_config import (
29
34
  from fides.api.schemas.connection_configuration.saas_config_template_values import (
30
35
  SaasConnectionTemplateValues,
31
36
  )
32
- from fides.api.schemas.saas.connector_template import ConnectorTemplate
33
37
  from fides.api.schemas.saas.saas_config import (
34
38
  SaaSConfig,
35
39
  SaaSConfigValidationDetails,
@@ -41,17 +45,11 @@ from fides.api.service.authentication.authentication_strategy import (
41
45
  from fides.api.service.authentication.authentication_strategy_oauth2_authorization_code import (
42
46
  OAuth2AuthorizationCodeAuthenticationStrategy,
43
47
  )
44
- from fides.api.service.connectors.saas.connector_registry_service import (
45
- ConnectorRegistry,
46
- CustomConnectorTemplateLoader,
47
- create_connection_config_from_template_no_save,
48
- upsert_dataset_config_from_template,
49
- )
50
48
  from fides.api.util.api_router import APIRouter
51
- from fides.api.util.connection_util import validate_secrets
49
+ from fides.api.util.connection_util import validate_secrets_error_message
50
+ from fides.api.util.event_audit_util import generate_connection_audit_event_details
52
51
  from fides.common.api.scope_registry import (
53
52
  CONNECTION_AUTHORIZE,
54
- CONNECTOR_TEMPLATE_REGISTER,
55
53
  SAAS_CONFIG_CREATE_OR_UPDATE,
56
54
  SAAS_CONFIG_DELETE,
57
55
  SAAS_CONFIG_READ,
@@ -59,13 +57,16 @@ from fides.common.api.scope_registry import (
59
57
  )
60
58
  from fides.common.api.v1.urn_registry import (
61
59
  AUTHORIZE,
62
- CONNECTION_TYPES,
63
- REGISTER_CONNECTOR_TEMPLATE,
64
60
  SAAS_CONFIG,
65
61
  SAAS_CONFIG_VALIDATE,
66
62
  SAAS_CONNECTOR_FROM_TEMPLATE,
67
63
  V1_URL_PREFIX,
68
64
  )
65
+ from fides.service.connection.connection_service import (
66
+ ConnectionService,
67
+ ConnectorTemplateNotFound,
68
+ )
69
+ from fides.service.event_audit_service import EventAuditService
69
70
 
70
71
  router = APIRouter(tags=["SaaS Configs"], prefix=V1_URL_PREFIX)
71
72
 
@@ -168,12 +169,29 @@ def patch_saas_config(
168
169
  Given a SaaS config element, update the corresponding ConnectionConfig object
169
170
  or report failure
170
171
  """
172
+
171
173
  logger.info(
172
174
  "Updating SaaS config '{}' on connection config '{}'",
173
175
  saas_config.fides_key,
174
176
  connection_config.key,
175
177
  )
176
178
  connection_config.update_saas_config(db, saas_config=saas_config)
179
+
180
+ # Create audit event for SaaS config update
181
+ event_audit_service = EventAuditService(db)
182
+ event_details, description = generate_connection_audit_event_details(
183
+ EventAuditType.connection_updated,
184
+ connection_config=connection_config,
185
+ )
186
+ event_audit_service.create_event_audit(
187
+ event_type=EventAuditType.connection_updated,
188
+ status=EventAuditStatus.succeeded,
189
+ resource_type="connection_config",
190
+ resource_identifier=connection_config.key,
191
+ description=description,
192
+ event_details=event_details,
193
+ )
194
+
177
195
  return connection_config.saas_config # type: ignore
178
196
 
179
197
 
@@ -286,11 +304,11 @@ def authorize_connection(
286
304
  response_model=SaasConnectionTemplateResponse,
287
305
  )
288
306
  def instantiate_connection_from_template(
289
- saas_connector_type: str,
307
+ connector_template_type: str,
290
308
  template_values: SaasConnectionTemplateValues,
291
309
  db: Session = Depends(deps.get_db),
292
310
  ) -> SaasConnectionTemplateResponse:
293
- return instantiate_connection(db, saas_connector_type, template_values)
311
+ return instantiate_connection(db, connector_template_type, template_values)
294
312
 
295
313
 
296
314
  def instantiate_connection(
@@ -305,92 +323,45 @@ def instantiate_connection(
305
323
  Looks up the connector type in the SaaS connector registry and, if all required
306
324
  fields are provided, persists the associated connection config and dataset to the database.
307
325
  """
308
- connector_template: Optional[ConnectorTemplate] = (
309
- ConnectorRegistry.get_connector_template(saas_connector_type)
310
- )
311
- if not connector_template:
312
- raise HTTPException(
313
- status_code=HTTP_404_NOT_FOUND,
314
- detail=f"SaaS connector type '{saas_connector_type}' is not yet available in Fidesops. For a list of available SaaS connectors, refer to {CONNECTION_TYPES}.",
326
+ event_audit_service = EventAuditService(db)
327
+ connection_service = ConnectionService(db, event_audit_service)
328
+ try:
329
+ connection_config, dataset_config = connection_service.instantiate_connection(
330
+ saas_connector_type, template_values, system
315
331
  )
316
-
317
- if DatasetConfig.filter(
318
- db=db,
319
- conditions=(DatasetConfig.fides_key == template_values.instance_key), # type: ignore[arg-type]
320
- ).count():
332
+ except ConnectorTemplateNotFound as exc:
321
333
  raise HTTPException(
322
- status_code=HTTP_400_BAD_REQUEST,
323
- detail=f"SaaS connector instance key '{template_values.instance_key}' already exists.",
324
- )
325
-
326
- try:
327
- connection_config: ConnectionConfig = (
328
- create_connection_config_from_template_no_save(
329
- db, connector_template, template_values
330
- )
334
+ status_code=HTTP_404_NOT_FOUND,
335
+ detail=f"{exc.args[0]}",
331
336
  )
332
337
  except KeyOrNameAlreadyExists as exc:
333
338
  raise HTTPException(
334
339
  status_code=HTTP_400_BAD_REQUEST,
335
340
  detail=exc.args[0],
336
341
  )
337
-
338
- connection_config.secrets = validate_secrets(
339
- db, template_values.secrets, connection_config
340
- ).model_dump(mode="json")
341
- if system:
342
- connection_config.system_id = system.id
343
- connection_config.save(db=db) # Not persisted to db until secrets are validated
344
-
345
- try:
346
- dataset_config: DatasetConfig = upsert_dataset_config_from_template(
347
- db, connection_config, connector_template, template_values
342
+ except SaaSConfigNotFoundException:
343
+ raise HTTPException(
344
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
345
+ detail=validate_secrets_error_message(),
346
+ )
347
+ except FidesValidationError as e:
348
+ # Check if the exception has the original pydantic errors attached
349
+ raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail=e.message)
350
+ except ValidationError as e:
351
+ errors = e.errors(include_url=False, include_input=False)
352
+ for err in errors:
353
+ # Additionally, manually remove the context from the error message -
354
+ # this may contain sensitive information
355
+ err.pop("ctx", None)
356
+ raise HTTPException(
357
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
358
+ detail=jsonable_encoder(errors),
348
359
  )
349
- except Exception:
350
- connection_config.delete(db)
360
+ except Exception as exc:
351
361
  raise HTTPException(
352
362
  status_code=HTTP_500_INTERNAL_SERVER_ERROR,
353
- detail=f"SaaS Connector could not be created from the '{saas_connector_type}' template at this time.",
363
+ detail=f"{exc.args[0]}",
354
364
  )
355
- logger.info(
356
- "SaaS Connector and Dataset {} successfully created from '{}' template.",
357
- template_values.instance_key,
358
- saas_connector_type,
359
- )
360
-
361
365
  return SaasConnectionTemplateResponse(
362
366
  connection=connection_config, dataset=dataset_config.ctl_dataset
363
367
  )
364
-
365
-
366
- @router.post(
367
- REGISTER_CONNECTOR_TEMPLATE,
368
- dependencies=[Security(verify_oauth_client, scopes=[CONNECTOR_TEMPLATE_REGISTER])],
369
- )
370
- def register_custom_connector_template(
371
- file: bytes = Body(..., media_type="application/zip"),
372
- db: Session = Depends(deps.get_db),
373
- ) -> JSONResponse:
374
- """
375
- Registers a custom connector template from a zip file uploaded by the user.
376
- The endpoint performs the following steps:
377
-
378
- 1. Validates the uploaded file is a proper zip file.
379
- 2. Uses the CustomConnectorTemplateLoader to validate, register, and save the template to the database.
380
-
381
- If the uploaded file is not a valid zip file or there are any validation errors
382
- when creating the ConnectorTemplates an HTTP 400 status code with error details is returned.
383
- """
384
-
385
- try:
386
- with ZipFile(BytesIO(file), "r") as zip_file:
387
- CustomConnectorTemplateLoader.save_template(db=db, zip_file=zip_file)
388
- except BadZipFile:
389
- raise HTTPException(status_code=400, detail="Invalid zip file")
390
- except Exception as exc:
391
- logger.exception("Error loading connector template from zip file.")
392
- raise HTTPException(status_code=400, detail=str(exc))
393
-
394
- return JSONResponse(
395
- content={"message": "Connector template successfully registered."}
396
- )