ethyca-fides 2.63.3rc0__py2.py3-none-any.whl → 2.64.1b0__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 (362) hide show
  1. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/METADATA +2 -2
  2. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/RECORD +249 -242
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/ba414a58ba90_create_manual_task_config_tables.py +121 -0
  5. fides/api/api/v1/endpoints/connection_endpoints.py +16 -3
  6. fides/api/api/v1/endpoints/oauth_endpoints.py +8 -2
  7. fides/api/db/base.py +4 -0
  8. fides/api/models/attachment.py +37 -23
  9. fides/api/models/manual_tasks/__init__.py +6 -0
  10. fides/api/models/manual_tasks/manual_task.py +11 -1
  11. fides/api/models/manual_tasks/manual_task_config.py +136 -0
  12. fides/api/models/manual_tasks/manual_task_log.py +13 -9
  13. fides/api/schemas/connection_configuration/connection_config.py +19 -4
  14. fides/api/schemas/manual_tasks/manual_task_config.py +311 -0
  15. fides/api/schemas/manual_tasks/manual_task_schemas.py +1 -1
  16. fides/api/schemas/manual_tasks/manual_task_status.py +1 -1
  17. fides/api/schemas/privacy_request.py +2 -0
  18. fides/api/service/connectors/query_configs/saas_query_config.py +15 -0
  19. fides/api/service/privacy_request/attachment_handling.py +132 -0
  20. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +264 -46
  21. fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +33 -0
  22. fides/api/service/privacy_request/dsr_package/templates/collection_index.html +34 -9
  23. fides/api/service/privacy_request/dsr_package/templates/main.css +45 -2
  24. fides/api/service/privacy_request/dsr_package/templates/welcome.html +12 -8
  25. fides/api/service/privacy_request/request_runner_service.py +258 -139
  26. fides/api/service/storage/gcs.py +15 -3
  27. fides/api/service/storage/s3.py +28 -14
  28. fides/api/service/storage/util.py +45 -7
  29. fides/api/tasks/csv_utils.py +170 -0
  30. fides/api/tasks/encryption_utils.py +42 -0
  31. fides/api/tasks/storage.py +85 -91
  32. fides/api/util/cache.py +6 -3
  33. fides/api/util/saas_util.py +1 -0
  34. fides/config/redis_settings.py +105 -44
  35. fides/service/manual_tasks/manual_task_config_service.py +370 -0
  36. fides/service/manual_tasks/manual_task_service.py +231 -87
  37. fides/service/manual_tasks/utils.py +185 -0
  38. fides/ui-build/static/admin/404.html +1 -1
  39. fides/ui-build/static/admin/_next/static/chunks/1040-630c7f4284dc6f70.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/1100-d43cb04522a6505c.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/1316-6cc72a45ebf7ff81.js +1 -0
  42. fides/ui-build/static/admin/_next/static/chunks/1817-b4688ba5042ec687.js +1 -0
  43. fides/ui-build/static/admin/_next/static/chunks/2430-b480401d44c55416.js +1 -0
  44. fides/ui-build/static/admin/_next/static/chunks/2599-6c4d22e75028d8b6.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/2921-aabf41bf3d7573f9.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/3450-bdaeb35442d810b4.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/3505-a79256cd851dfab4.js +1 -0
  48. fides/ui-build/static/admin/_next/static/chunks/3513-8677ee280eaef0da.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/3855-0dec3e7d9e886550.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/3872-ffa16c2df7ef0ab6.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/3923-5d580fbb1dd6ae01.js +1 -0
  52. fides/ui-build/static/admin/_next/static/chunks/401-fceaae662cfca5a5.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/4060-71cd041e5a57ca5a.js +1 -0
  54. fides/ui-build/static/admin/_next/static/chunks/409-037cfc3f096150f0.js +1 -0
  55. fides/ui-build/static/admin/_next/static/chunks/4121-78a76e980acbd539.js +1 -0
  56. fides/ui-build/static/admin/_next/static/chunks/4230-1cdb7ea1be370ed3.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/431-f72599f01b98f07d.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/4481-f597a7cf03f8c9e1.js +1 -0
  59. fides/ui-build/static/admin/_next/static/chunks/5309-4511df9708d5a63c.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/5574-3cd33b3a6c937899.js +1 -0
  61. fides/ui-build/static/admin/_next/static/chunks/6277-3fb4c7fc790a6d20.js +1 -0
  62. fides/ui-build/static/admin/_next/static/chunks/6662-cb11881dcaabe5e2.js +1 -0
  63. fides/ui-build/static/admin/_next/static/chunks/6853-a4097260e402980e.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/6882-3cc73d407a088d7d.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/69-6889d6674c95e7b5.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/6954-13a25cef3a8fdd76.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/7553-a95939c32d54b5b7.js +1 -0
  69. fides/ui-build/static/admin/_next/static/chunks/79-5670e31eb65d0a53.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/796-9a6b13c838e25538.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/8433-adb1fcb29d82f1b7.js +1 -0
  72. fides/ui-build/static/admin/_next/static/chunks/9046-fdf53cc7e926a8c1.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/{905-8ab919e7b274ed50.js → 905-742074a074be1055.js} +2 -2
  74. fides/ui-build/static/admin/_next/static/chunks/9226-ba6587e46ec7659a.js +1 -0
  75. fides/ui-build/static/admin/_next/static/chunks/{9392.81edc11e3a175275.js → 9392.25024e070026343d.js} +1 -1
  76. fides/ui-build/static/admin/_next/static/chunks/9676.e60a53f1f5890847.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/9767-e49b065d03ce4e80.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/9951-f9ab5cac7e2c05ab.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/404-ac2f0844e5c4b4cd.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-f70bffa5a7903c46.js → _app-8ec6e466f3373ac0.js} +10 -10
  81. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-0a5f2310ce6b1059.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-00cb904825aad7e3.js +1 -0
  83. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-587e21d14e0a5196.js +1 -0
  84. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/add-vendors-fa7305b88c1afd20.js +1 -0
  85. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-f140ec9d8e8a0f7a.js +1 -0
  86. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-0edb7c92518e7d21.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-d8d926f0735a2546.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/[id]-5c949f2e3cef2398.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/new-130155cfb4a0bcc7.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-1135ad8924d32c36.js +1 -0
  91. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-776855e370414beb.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-21c23f75ff1135d9.js +1 -0
  93. fides/ui-build/static/admin/_next/static/chunks/pages/consent-4d5ea70a77df1bb8.js +1 -0
  94. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-18e3faf7963962e4.js → [resourceUrn]-c623d6f1a61c8ea9.js} +1 -1
  95. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-030ee304cbe5e530.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-cfac259a30641e68.js +1 -0
  97. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-7320524a47104798.js → [resourceUrn]-57bd5cdf784f059f.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-7b5aec33da578745.js +1 -0
  99. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-c948f93c833d4358.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-333f53caab751428.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-27205f8457a1ecb0.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-20a1043f6a06198f.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-4c526db0c30c488a.js → [resourceUrn]-06edce289876dea1.js} +1 -1
  104. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-6f27dbb7c8edc69d.js → detection-faf326a6200637d0.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-562d2b8ae90dd1f0.js → [resourceUrn]-64acf269256ee74f.js} +1 -1
  106. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-fe7f51502eda57c9.js → discovery-8c3e4be6d36da66d.js} +1 -1
  107. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-fb50de22f83edd4a.js +1 -0
  108. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-41ab27c4195cfa93.js +1 -0
  109. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-6e2caba24b3e78c2.js +1 -0
  110. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-904d43e31157aa55.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d4e31a1c4a58800e.js +1 -0
  112. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-8f7d16bc5e9229c8.js +1 -0
  113. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-4a33dd0371dbaebc.js +1 -0
  114. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-e88509346b2d2851.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-8f9b8890018e1ea5.js +1 -0
  116. fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-80b241bf6cddb72e.js → fides-js-docs-5d8fd1af75f19e2f.js} +1 -1
  117. fides/ui-build/static/admin/_next/static/chunks/pages/index-1adb6bcb71701ac2.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-fdc2964fa7d1d8fd.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-adc286ff254e7f41.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-9b4d1d61c7c97509.js +1 -0
  121. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-f8fd4795e260887c.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-aa744ae8b61e5ff2.js +1 -0
  123. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-3407158757fb3627.js +1 -0
  124. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-47e947c02ae90fd0.js +1 -0
  125. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-24f9a44512ce8827.js +1 -0
  126. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-e567a69f8c37fb9a.js +1 -0
  127. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-35a33f9c7def2220.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-780e18dde8e38099.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-7a17dffa515e5560.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-91dd0039cc2b70bc.js +1 -0
  131. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-b01cbbaac34dadbc.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-a15410de7f1d0f84.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-1a1aa83a3f88844c.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-c4e1b69fb5bab61a.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/pages/properties/[id]-19737d4f21aadbee.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-9ccb295110feee20.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/pages/properties-3a1037a2e036212a.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-4cdbbb8cd1d8698e.js +1 -0
  139. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-965cc21889b25e44.js +1 -0
  140. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-0e1c381d488a7ada.js +1 -0
  141. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-d0e350d2a2667883.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-7796fbf458f8f159.js +1 -0
  143. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-6f866bc799a5f67f.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-0b44b2b224077dcd.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-5d00e1155bd11178.js +1 -0
  146. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-d2cdbe770683e9df.js +1 -0
  147. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-811dadb489f23d7d.js +1 -0
  148. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-24108f615ff5e1e7.js +1 -0
  149. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-54f142bc3e4c95ba.js +1 -0
  150. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-fef247a87baeb080.js +1 -0
  151. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-6eb886e7b7e6785b.js +1 -0
  152. fides/ui-build/static/admin/_next/static/chunks/pages/systems-7b71274334c559a4.js +1 -0
  153. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-18534d2a79a3850b.js +1 -0
  154. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-75d41fde668b9025.js +1 -0
  155. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dd43755b687c09a7.js +1 -0
  156. fides/ui-build/static/admin/_next/static/chunks/webpack-0a61b5bd21a41fe6.js +1 -0
  157. fides/ui-build/static/admin/_next/static/css/c693338e3bc8dcc6.css +1 -0
  158. fides/ui-build/static/admin/_next/static/nRQ3pmK_d3F5PJE39rP2h/_buildManifest.js +1 -0
  159. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  160. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  161. fides/ui-build/static/admin/add-systems.html +1 -1
  162. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  163. fides/ui-build/static/admin/consent/configure.html +1 -1
  164. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  165. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  166. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  167. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  168. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  169. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  170. fides/ui-build/static/admin/consent/properties.html +1 -1
  171. fides/ui-build/static/admin/consent/reporting.html +1 -1
  172. fides/ui-build/static/admin/consent.html +1 -1
  173. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  174. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  175. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  176. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  177. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  178. fides/ui-build/static/admin/data-catalog.html +1 -1
  179. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  180. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  181. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  182. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  183. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  184. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  185. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  186. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  187. fides/ui-build/static/admin/datamap.html +1 -1
  188. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  189. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  190. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  191. fides/ui-build/static/admin/dataset/new.html +1 -1
  192. fides/ui-build/static/admin/dataset.html +1 -1
  193. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  194. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  195. fides/ui-build/static/admin/datastore-connection.html +1 -1
  196. fides/ui-build/static/admin/images/connector-logos/salesforce.svg +41 -0
  197. fides/ui-build/static/admin/index.html +1 -1
  198. fides/ui-build/static/admin/integrations/[id].html +1 -1
  199. fides/ui-build/static/admin/integrations.html +1 -1
  200. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  201. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  202. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  203. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  204. fides/ui-build/static/admin/lib/fides.js +2 -2
  205. fides/ui-build/static/admin/login/[provider].html +1 -1
  206. fides/ui-build/static/admin/login.html +1 -1
  207. fides/ui-build/static/admin/messaging/[id].html +1 -1
  208. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  209. fides/ui-build/static/admin/messaging.html +1 -1
  210. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  211. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  212. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  213. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  214. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  215. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  216. fides/ui-build/static/admin/poc/forms.html +1 -1
  217. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  218. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  219. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  220. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  221. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  222. fides/ui-build/static/admin/privacy-requests.html +1 -1
  223. fides/ui-build/static/admin/properties/[id].html +1 -1
  224. fides/ui-build/static/admin/properties/add-property.html +1 -1
  225. fides/ui-build/static/admin/properties.html +1 -1
  226. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  227. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  228. fides/ui-build/static/admin/settings/about.html +1 -1
  229. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  230. fides/ui-build/static/admin/settings/consent.html +1 -1
  231. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  232. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  233. fides/ui-build/static/admin/settings/domains.html +1 -1
  234. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  235. fides/ui-build/static/admin/settings/locations.html +1 -1
  236. fides/ui-build/static/admin/settings/organization.html +1 -1
  237. fides/ui-build/static/admin/settings/regulations.html +1 -1
  238. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  239. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  240. fides/ui-build/static/admin/systems.html +1 -1
  241. fides/ui-build/static/admin/taxonomy.html +1 -1
  242. fides/ui-build/static/admin/user-management/new.html +1 -1
  243. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  244. fides/ui-build/static/admin/user-management.html +1 -1
  245. fides/api/service/privacy_request/dsr_package/templates/item.html +0 -37
  246. fides/ui-build/static/admin/_next/static/chunks/1099-667e84655846e78c.js +0 -1
  247. fides/ui-build/static/admin/_next/static/chunks/1100-0b01f500b1eaf60d.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/1817-951f58ddd5d46081.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/1904-964f8eb328dc2715.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/2310-744354001d01f366.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/2921-49af55ad7c631c93.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/3119-e36ae5071c8f27a5.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/3505-113f9c95d34b7aae.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/3513-5c2d412a84a78971.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/3872-45cc725e241211f0.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/3923-b4f701ada3ef0ee0.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/401-7e800aed05537126.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/4060-90a52a9afc655bfc.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/4121-66b0e00d5e7ae817.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/4132-9b1731bfec6ee537.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/4481-7f6710c928bb0cb0.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/5258-2079138c8cc34f6c.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/5404-2694509cf5fa96da.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/5487-2cbd8d2169eb2a65.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/5683-37137111b3e769fb.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/6202-081545c7822d09af.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/6277-459e054b2702c60e.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/641-7e4eef3222cbda70.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/6853-688df0b88fe65fd5.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/69-00cba94689b9e740.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/6954-4e313b4599b8763d.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/7553-08bc3d9f66695111.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/79-fc548561beed136f.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/796-d6586308ed44334b.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/7980-736f9fd1e749ddd2.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/8032-74d94f7bd5b81c89.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/8433-51870336908fb253.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/8499-1fd392d0be9e8ee4.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/8702-d1c8296f9f6afc10.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/9033-fdd87182c15b91e2.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/9187-851756440f79cd75.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/9327-6a53461c9764b16f.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/9494-1ffb888b95289891.js +0 -1
  284. fides/ui-build/static/admin/_next/static/chunks/9676.61cf5f6d6a083175.js +0 -1
  285. fides/ui-build/static/admin/_next/static/chunks/9767-afd674014a1d1152.js +0 -1
  286. fides/ui-build/static/admin/_next/static/chunks/pages/404-ec04f826f3dd79ea.js +0 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-1bec086d567aacff.js +0 -1
  288. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-f68bf100e4e60e88.js +0 -1
  289. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-effde5cfe49de55f.js +0 -1
  290. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/add-vendors-ec95ed8cb0712828.js +0 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-4cc195e15e0c3cc8.js +0 -1
  292. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-be8972c79fb39705.js +0 -1
  293. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-ccf96207de3b74ea.js +0 -1
  294. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/[id]-b9823cc008372cee.js +0 -1
  295. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/new-373f5772ab41bc93.js +0 -1
  296. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-b9beeee1bde5ca79.js +0 -1
  297. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-6ab3a5baafebd199.js +0 -1
  298. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-8562790ae07f17c9.js +0 -1
  299. fides/ui-build/static/admin/_next/static/chunks/pages/consent-42d4d2d6e0253671.js +0 -1
  300. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-9d1df6d890671b0c.js +0 -1
  301. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-7eb08af333baaa8e.js +0 -1
  302. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-bb57eed84f59a932.js +0 -1
  303. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-47eb34aef3e31ac6.js +0 -1
  304. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-76cefefc53e84c7f.js +0 -1
  305. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9d8e84a8b4bf568d.js +0 -1
  306. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-f208fef5e72dafd6.js +0 -1
  307. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-db45aa864e9dda8a.js +0 -1
  308. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-d5cfdebc74654337.js +0 -1
  309. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-618b89228f83435e.js +0 -1
  310. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-12fc86f15a4c764e.js +0 -1
  311. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-c23d18a9b56c2e3c.js +0 -1
  312. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-e3b2d8e3980ab093.js +0 -1
  313. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-6e27257eccf65f01.js +0 -1
  314. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-bbac1f624424282d.js +0 -1
  315. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-84eb56f5a07bdf4f.js +0 -1
  316. fides/ui-build/static/admin/_next/static/chunks/pages/index-773182b5e35d0045.js +0 -1
  317. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-eb28c927da5bd653.js +0 -1
  318. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-781808bca01f8048.js +0 -1
  319. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-b51bee8680d66b20.js +0 -1
  320. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-1de479533f733fbd.js +0 -1
  321. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-7dc295b3ed3d2224.js +0 -1
  322. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-f64dac3392f5ded7.js +0 -1
  323. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-eb020bfac4bee532.js +0 -1
  324. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-0bd62e28b539e114.js +0 -1
  325. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-936877004113c2a6.js +0 -1
  326. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-6416f01524482af9.js +0 -1
  327. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-3f4e1313d1f2969b.js +0 -1
  328. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-1db7a54437db7db0.js +0 -1
  329. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-64236fd0141414fd.js +0 -1
  330. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-8cab04871908cfeb.js +0 -1
  331. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-150d40428245ee0c.js +0 -1
  332. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-b6c876dceb16ad1b.js +0 -1
  333. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-20cdb2c8a03deae1.js +0 -1
  334. fides/ui-build/static/admin/_next/static/chunks/pages/properties/[id]-54bcc875592d1fb9.js +0 -1
  335. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-644dc669b508a79a.js +0 -1
  336. fides/ui-build/static/admin/_next/static/chunks/pages/properties-9a88220d03e7e02f.js +0 -1
  337. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-70dc1081df37ea69.js +0 -1
  338. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-3c71b4dbcb6fd6c9.js +0 -1
  339. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-7cb16e0000dd16c9.js +0 -1
  340. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-a18d8f12ee8dcf5d.js +0 -1
  341. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-dc220e116ad5c09e.js +0 -1
  342. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-55ddc5f25b86f28e.js +0 -1
  343. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-5ca7decded228bc8.js +0 -1
  344. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-a6fafa1be2834c40.js +0 -1
  345. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-e633750d2b45ddd6.js +0 -1
  346. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-3948686cbd372969.js +0 -1
  347. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-04ece499c22d23f4.js +0 -1
  348. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-7752305084280cca.js +0 -1
  349. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-9e5f9066be6f218d.js +0 -1
  350. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-86de9e6d72098e45.js +0 -1
  351. fides/ui-build/static/admin/_next/static/chunks/pages/systems-cac52e6c3abf6a15.js +0 -1
  352. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-60d5930b6855679b.js +0 -1
  353. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-b0f4c34752d32c73.js +0 -1
  354. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-7dee83dd6d9292aa.js +0 -1
  355. fides/ui-build/static/admin/_next/static/chunks/webpack-8457bad7859c44f0.js +0 -1
  356. fides/ui-build/static/admin/_next/static/css/1fdf5c593349dbc6.css +0 -1
  357. fides/ui-build/static/admin/_next/static/f_8LkSZkhtDM14f8gbC0b/_buildManifest.js +0 -1
  358. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/WHEEL +0 -0
  359. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/entry_points.txt +0 -0
  360. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/licenses/LICENSE +0 -0
  361. {ethyca_fides-2.63.3rc0.dist-info → ethyca_fides-2.64.1b0.dist-info}/top_level.txt +0 -0
  362. /fides/ui-build/static/admin/_next/static/{f_8LkSZkhtDM14f8gbC0b → nRQ3pmK_d3F5PJE39rP2h}/_ssgManifest.js +0 -0
fides/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-06-18T10:17:23-0400",
11
+ "date": "2025-06-19T09:18:36-0400",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "21a5a1a7cbc29691214ef6286321eec2cc2a002b",
15
- "version": "2.63.3rc0"
14
+ "full-revisionid": "c3bc4b8de4e47f68bc323c928a4a0b1aadf2570f",
15
+ "version": "2.64.1b0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,121 @@
1
+ """create manual task config tables
2
+
3
+ Revision ID: ba414a58ba90
4
+ Revises: 29e56fa1fdb3
5
+ Create Date: 2025-06-09 19:56:18.254209
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+ from sqlalchemy.dialects.postgresql import JSONB
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = "ba414a58ba90"
15
+ down_revision = "29e56fa1fdb3"
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade():
21
+ # Create manual_task_config table
22
+ op.create_table(
23
+ "manual_task_config",
24
+ sa.Column("id", sa.String(), nullable=False),
25
+ sa.Column(
26
+ "created_at",
27
+ sa.DateTime(timezone=True),
28
+ nullable=False,
29
+ server_default=sa.text("now()"),
30
+ ),
31
+ sa.Column(
32
+ "updated_at",
33
+ sa.DateTime(timezone=True),
34
+ nullable=False,
35
+ server_default=sa.text("now()"),
36
+ ),
37
+ sa.Column("task_id", sa.String(), nullable=False),
38
+ sa.Column("config_type", sa.String(), nullable=False),
39
+ sa.Column("version", sa.Integer(), nullable=False, server_default="1"),
40
+ sa.Column("is_current", sa.Boolean(), nullable=False, server_default="true"),
41
+ sa.ForeignKeyConstraint(["task_id"], ["manual_task.id"], ondelete="CASCADE"),
42
+ sa.PrimaryKeyConstraint("id"),
43
+ )
44
+
45
+ # Create manual_task_config_field table
46
+ op.create_table(
47
+ "manual_task_config_field",
48
+ sa.Column("id", sa.String(), nullable=False),
49
+ sa.Column(
50
+ "created_at",
51
+ sa.DateTime(timezone=True),
52
+ nullable=False,
53
+ server_default=sa.text("now()"),
54
+ ),
55
+ sa.Column(
56
+ "updated_at",
57
+ sa.DateTime(timezone=True),
58
+ nullable=False,
59
+ server_default=sa.text("now()"),
60
+ ),
61
+ sa.Column("task_id", sa.String(), nullable=False),
62
+ sa.Column("config_id", sa.String(), nullable=False),
63
+ sa.Column("field_key", sa.String(), nullable=False),
64
+ sa.Column("field_type", sa.String(), nullable=False),
65
+ sa.Column("field_metadata", JSONB, nullable=False, server_default="{}"),
66
+ sa.ForeignKeyConstraint(["task_id"], ["manual_task.id"], ondelete="CASCADE"),
67
+ sa.ForeignKeyConstraint(
68
+ ["config_id"], ["manual_task_config.id"], ondelete="CASCADE"
69
+ ),
70
+ sa.PrimaryKeyConstraint("id"),
71
+ sa.UniqueConstraint(
72
+ "config_id", "field_key", name="unique_field_key_per_config"
73
+ ),
74
+ )
75
+
76
+ # Add foreign key constraint to manual_task_log table
77
+ op.create_foreign_key(
78
+ "fk_manual_task_log_config_id",
79
+ "manual_task_log",
80
+ "manual_task_config",
81
+ ["config_id"],
82
+ ["id"],
83
+ ondelete="SET NULL",
84
+ )
85
+
86
+ # Create indexes
87
+ op.create_index("ix_manual_task_config_task_id", "manual_task_config", ["task_id"])
88
+ op.create_index(
89
+ "ix_manual_task_config_config_type", "manual_task_config", ["config_type"]
90
+ )
91
+ op.create_index(
92
+ "ix_manual_task_config_field_task_id", "manual_task_config_field", ["task_id"]
93
+ )
94
+ op.create_index(
95
+ "ix_manual_task_config_field_config_id",
96
+ "manual_task_config_field",
97
+ ["config_id"],
98
+ )
99
+ op.create_index(
100
+ "ix_manual_task_config_field_field_key",
101
+ "manual_task_config_field",
102
+ ["field_key"],
103
+ )
104
+
105
+
106
+ def downgrade():
107
+ # Drop indexes
108
+ op.drop_index("ix_manual_task_config_field_field_key")
109
+ op.drop_index("ix_manual_task_config_field_config_id")
110
+ op.drop_index("ix_manual_task_config_field_task_id")
111
+ op.drop_index("ix_manual_task_config_config_type")
112
+ op.drop_index("ix_manual_task_config_task_id")
113
+
114
+ # Drop foreign key constraint from manual_task_log
115
+ op.drop_constraint(
116
+ "fk_manual_task_log_config_id", "manual_task_log", type_="foreignkey"
117
+ )
118
+
119
+ # Drop tables
120
+ op.drop_table("manual_task_config_field")
121
+ op.drop_table("manual_task_config")
@@ -22,6 +22,7 @@ from fides.api.schemas.connection_configuration import connection_secrets_schema
22
22
  from fides.api.schemas.connection_configuration.connection_config import (
23
23
  BulkPutConnectionConfiguration,
24
24
  ConnectionConfigurationResponse,
25
+ ConnectionConfigurationResponseWithSystemKey,
25
26
  CreateConnectionConfigurationWithSecrets,
26
27
  )
27
28
  from fides.api.schemas.connection_configuration.connection_secrets import (
@@ -154,13 +155,25 @@ def get_connections(
154
155
  @router.get(
155
156
  CONNECTION_BY_KEY,
156
157
  dependencies=[Security(verify_oauth_client, scopes=[CONNECTION_READ])],
157
- response_model=ConnectionConfigurationResponse,
158
+ response_model=ConnectionConfigurationResponseWithSystemKey,
158
159
  )
159
160
  def get_connection_detail(
160
161
  connection_key: FidesKey, db: Session = Depends(deps.get_db)
161
- ) -> ConnectionConfig:
162
+ ) -> ConnectionConfigurationResponseWithSystemKey:
162
163
  """Returns connection configuration with matching key."""
163
- return get_connection_config_or_error(db, connection_key)
164
+ connection_config = get_connection_config_or_error(db, connection_key)
165
+
166
+ # Convert to Pydantic model with all fields
167
+ response = ConnectionConfigurationResponseWithSystemKey.model_validate(
168
+ connection_config
169
+ )
170
+
171
+ # Override just the system_key field to use only the system's fides_key without fallback
172
+ response.system_key = (
173
+ connection_config.system.fides_key if connection_config.system else None
174
+ )
175
+
176
+ return response
164
177
 
165
178
 
166
179
  @router.patch(
@@ -274,9 +274,15 @@ def oauth_callback(code: str, state: str, db: Session = Depends(get_db)) -> Resp
274
274
 
275
275
  parsed_url = urlparse(authentication_request.referer)
276
276
  base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
277
- system_key = connection_config.system.fides_key
277
+
278
+ if connection_config.system is not None:
279
+ system_key = connection_config.system.fides_key
280
+ redirect_path = f"/systems/configure/{system_key}"
281
+ else:
282
+ redirect_path = f"/integrations/{connection_config.key}"
283
+
278
284
  return RedirectResponse(
279
- url=f"{base_url}/systems/configure/{system_key}?status={test_status_value}"
285
+ url=f"{base_url}{redirect_path}?status={test_status_value}"
280
286
  )
281
287
  return PlainTextResponse(
282
288
  content=f"Connection test status: {test_status_value}. No referer URL available. Please navigate back to the Fides Admin UI.",
fides/api/db/base.py CHANGED
@@ -32,6 +32,10 @@ from fides.api.models.fides_user_respondent_email_verification import (
32
32
  from fides.api.models.identity_salt import IdentitySalt
33
33
  from fides.api.models.location_regulation_selections import LocationRegulationSelections
34
34
  from fides.api.models.manual_tasks.manual_task import ManualTask, ManualTaskReference
35
+ from fides.api.models.manual_tasks.manual_task_config import (
36
+ ManualTaskConfig,
37
+ ManualTaskConfigField,
38
+ )
35
39
  from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
36
40
  from fides.api.models.manual_webhook import AccessManualWebhook
37
41
  from fides.api.models.messaging import MessagingConfig
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  from enum import Enum as EnumType
3
+ from io import BytesIO
3
4
  from typing import IO, TYPE_CHECKING, Any, Tuple
4
5
 
5
6
  from fideslang.validation import AnyHttpUrlString
@@ -19,7 +20,6 @@ from fides.api.service.storage.s3 import (
19
20
  generic_upload_to_s3,
20
21
  )
21
22
  from fides.api.service.storage.util import AllowedFileType, get_local_filename
22
- from fides.config import CONFIG
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  from fides.api.models.comment import Comment
@@ -28,6 +28,11 @@ if TYPE_CHECKING:
28
28
  from fides.api.models.storage import StorageConfig
29
29
 
30
30
 
31
+ # This is 7 days in seconds and is currently the max allowed
32
+ # configurable expiration time for presigned URLs for both s3 and gcs.
33
+ MAX_TTL_SECONDS = 604800
34
+
35
+
31
36
  class AttachmentType(str, EnumType):
32
37
  """
33
38
  Enum for attachment types. Indicates attachment usage.
@@ -46,6 +51,7 @@ class AttachmentReferenceType(str, EnumType):
46
51
  erasure_manual_webhook = "erasure_manual_webhook"
47
52
  privacy_request = "privacy_request"
48
53
  comment = "comment"
54
+ manual_task_submission = "manual_task_submission"
49
55
 
50
56
 
51
57
  class AttachmentReference(Base):
@@ -122,6 +128,11 @@ class Attachment(Base):
122
128
  """Returns the content type of the attachment."""
123
129
  return AllowedFileType[self.file_name.split(".")[-1]].value
124
130
 
131
+ @property
132
+ def file_key(self) -> str:
133
+ """Returns the file key of the attachment."""
134
+ return f"{self.id}/{self.file_name}"
135
+
125
136
  def upload(self, attachment: IO[bytes]) -> None:
126
137
  """Uploads an attachment to S3, GCS, or local storage."""
127
138
  if self.config.type == StorageType.s3:
@@ -130,7 +141,7 @@ class Attachment(Base):
130
141
  generic_upload_to_s3(
131
142
  storage_secrets=self.config.secrets,
132
143
  bucket_name=bucket_name,
133
- file_key=f"{self.id}/{self.file_name}",
144
+ file_key=self.file_key,
134
145
  document=attachment,
135
146
  auth_method=auth_method,
136
147
  )
@@ -142,7 +153,7 @@ class Attachment(Base):
142
153
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
143
154
  storage_client = get_gcs_client(auth_method, self.config.secrets)
144
155
  bucket = storage_client.bucket(bucket_name)
145
- blob = bucket.blob(f"{self.id}/{self.file_name}")
156
+ blob = bucket.blob(self.file_key)
146
157
 
147
158
  # Reset the file pointer to the beginning
148
159
  try:
@@ -155,7 +166,7 @@ class Attachment(Base):
155
166
  return
156
167
 
157
168
  if self.config.type == StorageType.local:
158
- filename = get_local_filename(f"{self.id}/{self.file_name}")
169
+ filename = get_local_filename(self.file_key)
159
170
 
160
171
  # Validate that attachment is a file-like object
161
172
  if not hasattr(attachment, "read"):
@@ -205,9 +216,10 @@ class Attachment(Base):
205
216
  size, url = generic_retrieve_from_s3(
206
217
  storage_secrets=self.config.secrets,
207
218
  bucket_name=bucket_name,
208
- file_key=f"{self.id}/{self.file_name}",
219
+ file_key=self.file_key,
209
220
  auth_method=auth_method,
210
221
  get_content=False,
222
+ ttl_seconds=MAX_TTL_SECONDS,
211
223
  )
212
224
  return size, url
213
225
 
@@ -216,19 +228,20 @@ class Attachment(Base):
216
228
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
217
229
  storage_client = get_gcs_client(auth_method, self.config.secrets)
218
230
  bucket = storage_client.bucket(bucket_name)
219
- blob = bucket.blob(f"{self.id}/{self.file_name}")
231
+ blob = bucket.blob(self.file_key)
220
232
 
221
233
  # Ensure we have the blob metadata
222
234
  blob.reload()
235
+ # Expiration is set to 7 days
223
236
  url = blob.generate_signed_url(
224
237
  version="v4",
225
- expiration=CONFIG.security.subject_request_download_link_ttl_seconds,
238
+ expiration=MAX_TTL_SECONDS,
226
239
  method="GET",
227
240
  )
228
241
  return blob.size, url
229
242
 
230
243
  if self.config.type == StorageType.local:
231
- filename = get_local_filename(f"{self.id}/{self.file_name}")
244
+ filename = get_local_filename(self.file_key)
232
245
  size = os.path.getsize(filename)
233
246
  return size, filename
234
247
 
@@ -236,7 +249,7 @@ class Attachment(Base):
236
249
 
237
250
  def retrieve_attachment_content(
238
251
  self,
239
- ) -> Tuple[int, bytes]:
252
+ ) -> Tuple[int, IO[bytes]]:
240
253
  """
241
254
  Retrieves the size of the attachment and its actual content.
242
255
  - For s3:
@@ -252,30 +265,33 @@ class Attachment(Base):
252
265
  if self.config.type == StorageType.s3:
253
266
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
254
267
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
255
- size, content = generic_retrieve_from_s3(
268
+ size, fileobj = generic_retrieve_from_s3(
256
269
  storage_secrets=self.config.secrets,
257
270
  bucket_name=bucket_name,
258
- file_key=f"{self.id}/{self.file_name}",
271
+ file_key=self.file_key,
259
272
  auth_method=auth_method,
260
273
  get_content=True,
261
274
  )
262
- return size, content
275
+ return size, fileobj
263
276
 
264
277
  if self.config.type == StorageType.gcs:
265
278
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
266
279
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
267
280
  storage_client = get_gcs_client(auth_method, self.config.secrets)
268
281
  bucket = storage_client.bucket(bucket_name)
269
- blob = bucket.blob(f"{self.id}/{self.file_name}")
282
+ blob = bucket.blob(self.file_key)
270
283
 
271
- content = blob.download_as_bytes()
272
- return len(content), content
284
+ fileobj = BytesIO()
285
+ blob.download_to_file(fileobj)
286
+ fileobj.seek(0) # Reset pointer to beginning after download
287
+ return blob.size, fileobj
273
288
 
274
289
  if self.config.type == StorageType.local:
275
- filename = get_local_filename(f"{self.id}/{self.file_name}")
276
- with open(filename, "rb") as file:
277
- content = file.read()
278
- size = len(content)
290
+ filename = get_local_filename(self.file_key)
291
+ size = os.path.getsize(filename)
292
+ with open(filename, "rb") as fileobj:
293
+ content = BytesIO(fileobj.read())
294
+ content.seek(0) # Reset pointer to beginning
279
295
  return size, content
280
296
 
281
297
  raise ValueError(f"Unsupported storage type: {self.config.type}")
@@ -288,7 +304,7 @@ class Attachment(Base):
288
304
  generic_delete_from_s3(
289
305
  storage_secrets=self.config.secrets,
290
306
  bucket_name=bucket_name,
291
- file_key=f"{self.id}/{self.file_name}",
307
+ file_key=self.file_key,
292
308
  auth_method=auth_method,
293
309
  )
294
310
  return
@@ -307,9 +323,7 @@ class Attachment(Base):
307
323
  return
308
324
 
309
325
  if self.config.type == StorageType.local:
310
- folder_path = os.path.dirname(
311
- get_local_filename(f"{self.id}/{self.file_name}")
312
- )
326
+ folder_path = os.path.dirname(get_local_filename(self.file_key))
313
327
  if os.path.exists(folder_path):
314
328
  import shutil
315
329
 
@@ -1,8 +1,14 @@
1
1
  from fides.api.models.manual_tasks.manual_task import ManualTask, ManualTaskReference
2
+ from fides.api.models.manual_tasks.manual_task_config import (
3
+ ManualTaskConfig,
4
+ ManualTaskConfigField,
5
+ )
2
6
  from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
3
7
 
4
8
  __all__ = [
5
9
  "ManualTask",
10
+ "ManualTaskConfig",
11
+ "ManualTaskConfigField",
6
12
  "ManualTaskReference",
7
13
  "ManualTaskLog",
8
14
  ]
@@ -1,4 +1,4 @@
1
- from typing import Any
1
+ from typing import TYPE_CHECKING, Any
2
2
 
3
3
  from sqlalchemy import Column, DateTime, ForeignKey, String
4
4
  from sqlalchemy.ext.declarative import declared_attr
@@ -14,6 +14,11 @@ from fides.api.schemas.manual_tasks.manual_task_schemas import (
14
14
  ManualTaskType,
15
15
  )
16
16
 
17
+ if TYPE_CHECKING: # pragma: no cover
18
+ from fides.api.models.manual_tasks.manual_task_config import ( # pragma: no cover
19
+ ManualTaskConfig,
20
+ )
21
+
17
22
 
18
23
  class ManualTask(Base):
19
24
  """Model for storing manual tasks.
@@ -59,6 +64,11 @@ class ManualTask(Base):
59
64
  viewonly=True,
60
65
  order_by="ManualTaskLog.created_at",
61
66
  )
67
+ configs = relationship(
68
+ "ManualTaskConfig",
69
+ back_populates="task",
70
+ cascade="all, delete-orphan",
71
+ )
62
72
 
63
73
  # Properties
64
74
  @property
@@ -0,0 +1,136 @@
1
+ from typing import TYPE_CHECKING, Any, Optional
2
+
3
+ from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
4
+ from sqlalchemy.dialects.postgresql import JSONB
5
+ from sqlalchemy.ext.declarative import declared_attr
6
+ from sqlalchemy.orm import Session, relationship
7
+
8
+ from fides.api.db.base_class import Base
9
+ from fides.api.db.util import EnumColumn
10
+ from fides.api.models.manual_tasks.manual_task_log import ManualTaskLog
11
+ from fides.api.schemas.manual_tasks.manual_task_config import (
12
+ ManualTaskConfigurationType,
13
+ ManualTaskFieldMetadata,
14
+ ManualTaskFieldType,
15
+ )
16
+ from fides.api.schemas.manual_tasks.manual_task_schemas import ManualTaskLogStatus
17
+
18
+ if TYPE_CHECKING: # pragma: no cover
19
+ from fides.api.models.manual_tasks.manual_task import ManualTask # pragma: no cover
20
+
21
+
22
+ class ManualTaskConfig(Base):
23
+ """Model for storing manual task configurations.
24
+ A single configuration may have many fields of different types.
25
+ """
26
+
27
+ @declared_attr
28
+ def __tablename__(cls) -> str:
29
+ return "manual_task_config"
30
+
31
+ task_id = Column(String, ForeignKey("manual_task.id"), nullable=False)
32
+ config_type = Column(EnumColumn(ManualTaskConfigurationType), nullable=False)
33
+ version = Column(Integer, nullable=False, default=1)
34
+ is_current = Column(Boolean, nullable=False, default=True)
35
+
36
+ # Relationships
37
+ task = relationship("ManualTask", back_populates="configs")
38
+ field_definitions = relationship(
39
+ "ManualTaskConfigField",
40
+ back_populates="config",
41
+ cascade="all, delete-orphan",
42
+ uselist=True,
43
+ )
44
+ logs = relationship(
45
+ "ManualTaskLog",
46
+ back_populates="config",
47
+ primaryjoin="ManualTaskConfig.id == ManualTaskLog.config_id",
48
+ viewonly=True,
49
+ )
50
+
51
+ @classmethod
52
+ def create(
53
+ cls, db: Session, *, data: dict[str, Any], check_name: bool = True
54
+ ) -> "ManualTaskConfig":
55
+ """Create a new manual task configuration."""
56
+ # Validate config_type
57
+ try:
58
+ ManualTaskConfigurationType(data["config_type"])
59
+ except ValueError:
60
+ raise ValueError(f"Invalid config type: {data['config_type']}")
61
+
62
+ config = super().create(db=db, data=data, check_name=check_name)
63
+
64
+ # Log the config creation as a task-level log
65
+ ManualTaskLog.create_log(
66
+ db=db,
67
+ task_id=data["task_id"],
68
+ config_id=config.id,
69
+ status=ManualTaskLogStatus.created,
70
+ message=f"Created manual task configuration for {data['config_type']}",
71
+ details={
72
+ "config_type": data["config_type"],
73
+ },
74
+ )
75
+ return config
76
+
77
+ def get_field(self, field_key: str) -> Optional["ManualTaskConfigField"]:
78
+ """Get a field by its key."""
79
+ for field in self.field_definitions:
80
+ if field.field_key == field_key:
81
+ return field
82
+ return None
83
+
84
+
85
+ class ManualTaskConfigField(Base):
86
+ """Model for storing fields associated with each config."""
87
+
88
+ @declared_attr
89
+ def __tablename__(cls) -> str:
90
+ return "manual_task_config_field"
91
+
92
+ task_id = Column(String, ForeignKey("manual_task.id"), nullable=False)
93
+ config_id = Column(String, ForeignKey("manual_task_config.id"), nullable=False)
94
+ field_key = Column(String, nullable=False)
95
+ field_type = Column(
96
+ EnumColumn(ManualTaskFieldType), nullable=False
97
+ ) # Using ManualTaskFieldType
98
+ field_metadata = Column(JSONB, nullable=False, default={})
99
+
100
+ # Relationships
101
+ config = relationship("ManualTaskConfig", back_populates="field_definitions")
102
+
103
+ @property
104
+ def field_metadata_model(self) -> ManualTaskFieldMetadata:
105
+ """Get the field metadata as a Pydantic model."""
106
+ return ManualTaskFieldMetadata.model_validate(self.field_metadata)
107
+
108
+ @classmethod
109
+ def create(
110
+ cls, db: Session, *, data: dict[str, Any], check_name: bool = True
111
+ ) -> "ManualTaskConfigField":
112
+ """Create a new manual task config field."""
113
+ # Get the config to access its task_id and check if it exists
114
+ try:
115
+ config = (
116
+ db.query(ManualTaskConfig)
117
+ .filter(ManualTaskConfig.id == data["config_id"])
118
+ .first()
119
+ )
120
+ if not config:
121
+ raise ValueError(f"Config with id {data['config_id']} not found")
122
+ except Exception as e:
123
+ raise ValueError(f"Config with id {data['config_id']} not found: {e}")
124
+
125
+ # Create the field and let SQLAlchemy complex type validation handled in service.
126
+ field = super().create(db=db, data=data, check_name=check_name)
127
+
128
+ # Create a log entry
129
+ ManualTaskLog.create_log(
130
+ db=db,
131
+ task_id=config.task_id,
132
+ config_id=data["config_id"],
133
+ status=ManualTaskLogStatus.created,
134
+ message=f"Created manual task config field for {data['field_key']}",
135
+ )
136
+ return field
@@ -8,8 +8,11 @@ from sqlalchemy.orm import Session, relationship
8
8
  from fides.api.db.base_class import Base
9
9
  from fides.api.schemas.manual_tasks.manual_task_schemas import ManualTaskLogStatus
10
10
 
11
- if TYPE_CHECKING:
12
- from fides.api.models.manual_tasks.manual_task import ManualTask
11
+ if TYPE_CHECKING: # pragma: no cover
12
+ from fides.api.models.manual_tasks.manual_task import ManualTask # pragma: no cover
13
+ from fides.api.models.manual_tasks.manual_task_config import (
14
+ ManualTaskConfig, # pragma: no cover
15
+ )
13
16
 
14
17
 
15
18
  class ManualTaskLog(Base):
@@ -23,28 +26,29 @@ class ManualTaskLog(Base):
23
26
  task_id = Column(
24
27
  String, ForeignKey("manual_task.id", ondelete="CASCADE"), nullable=False
25
28
  )
26
- # TODO: Add foreign key constraints when config and instance are implemented
27
- config_id = Column(String, nullable=True)
29
+ config_id = Column(String, ForeignKey("manual_task_config.id"), nullable=True)
28
30
  instance_id = Column(String, nullable=True)
29
31
  status = Column(String, nullable=False)
30
- message = Column(String, nullable=True)
32
+ message = Column(String, nullable=False)
31
33
  details = Column(JSONB, nullable=True)
32
34
 
33
35
  # Relationships - using string references to avoid circular imports
34
36
  task = relationship("ManualTask", back_populates="logs", foreign_keys=[task_id])
35
- # TODO: Add config and instance relationships when they are implemented
36
- # config = relationship("ManualTaskConfig", back_populates="logs")
37
+ config = relationship(
38
+ "ManualTaskConfig", back_populates="logs", foreign_keys=[config_id]
39
+ )
40
+ # TODO: Add instance relationship when it is implemented
37
41
  # instance = relationship("ManualTaskInstance", back_populates="logs")
38
42
 
39
43
  @classmethod
40
44
  def create_log(
41
45
  cls,
42
46
  db: Session,
43
- status: ManualTaskLogStatus,
44
47
  task_id: str,
48
+ status: ManualTaskLogStatus,
49
+ message: str,
45
50
  config_id: Optional[str] = None,
46
51
  instance_id: Optional[str] = None,
47
- message: Optional[str] = None,
48
52
  details: Optional[dict[str, Any]] = None,
49
53
  ) -> "ManualTaskLog":
50
54
  """Create a new task log entry.
@@ -111,10 +111,10 @@ class ConnectionConfigSecretsMixin(BaseModel):
111
111
  return self
112
112
 
113
113
 
114
- class ConnectionConfigurationResponse(ConnectionConfigSecretsMixin):
114
+ class ConnectionConfigurationResponseBase(ConnectionConfigSecretsMixin):
115
115
  """
116
- Describes the returned schema for a ConnectionConfiguration.
117
-
116
+ Base schema for ConnectionConfiguration responses,
117
+ excluding fields that might be conditionally omitted.
118
118
  The mixin base class ensures that `secrets` sensitive values are masked.
119
119
  """
120
120
 
@@ -129,10 +129,25 @@ class ConnectionConfigurationResponse(ConnectionConfigSecretsMixin):
129
129
  last_test_succeeded: Optional[bool] = None
130
130
  authorized: Optional[bool] = False
131
131
  enabled_actions: Optional[List[ActionType]] = None
132
-
133
132
  model_config = ConfigDict(from_attributes=True)
134
133
 
135
134
 
135
+ class ConnectionConfigurationResponseWithSystemKey(ConnectionConfigurationResponseBase):
136
+ """
137
+ Describes the full returned schema for a ConnectionConfiguration.
138
+ """
139
+
140
+ # Using this response with models returned from an async DB session will error
141
+ # because the system_key is lazy loaded. Just a quirk of SQLAlchemy 1.4.
142
+ system_key: Optional[str] = None
143
+
144
+
145
+ class ConnectionConfigurationResponse(ConnectionConfigurationResponseBase):
146
+ """
147
+ Describes the returned schema for a ConnectionConfiguration.
148
+ """
149
+
150
+
136
151
  class BulkPutConnectionConfiguration(BulkResponse):
137
152
  """Schema with mixed success/failure responses for Bulk Create/Update of ConnectionConfiguration responses."""
138
153