ethyca-fides 2.62.1b2__py2.py3-none-any.whl → 2.62.1rc0__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 (272) hide show
  1. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/METADATA +1 -2
  2. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/RECORD +221 -223
  3. fides/_version.py +3 -3
  4. fides/api/api/v1/endpoints/privacy_request_endpoints.py +2 -2
  5. fides/api/main.py +1 -0
  6. fides/api/models/attachment.py +10 -117
  7. fides/api/models/detection_discovery.py +1 -66
  8. fides/api/models/privacy_request/privacy_request.py +1 -40
  9. fides/api/service/connectors/query_configs/saas_query_config.py +8 -3
  10. fides/api/service/connectors/saas_connector.py +4 -7
  11. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +2 -4
  12. fides/api/service/storage/s3.py +15 -40
  13. fides/api/tasks/storage.py +2 -2
  14. fides/api/util/storage_util.py +8 -14
  15. fides/config/config_proxy.py +1 -0
  16. fides/config/execution_settings.py +4 -0
  17. fides/service/error_handling/__init__.py +0 -0
  18. fides/service/error_handling/error_handler.py +202 -0
  19. fides/ui-build/static/admin/404.html +1 -1
  20. fides/ui-build/static/admin/_next/static/K1_4-1GhwfL7h4fYYQBvB/_buildManifest.js +1 -0
  21. fides/ui-build/static/admin/_next/static/chunks/1327-92a38135ee8d55ec.js +1 -0
  22. fides/ui-build/static/admin/_next/static/chunks/1817-721fdeb29c07c6be.js +1 -0
  23. fides/ui-build/static/admin/_next/static/chunks/1904-7e5354990377a849.js +1 -0
  24. fides/ui-build/static/admin/_next/static/chunks/{2310-6a5fb2f76f7b6491.js → 2310-0d63c66c2685e83c.js} +1 -1
  25. fides/ui-build/static/admin/_next/static/chunks/3119-e441b14cdab4320e.js +1 -0
  26. fides/ui-build/static/admin/_next/static/chunks/3426-e49cb4766324b2dd.js +1 -0
  27. fides/ui-build/static/admin/_next/static/chunks/{3513-293b1e54699cf3e7.js → 3513-87b54d931698986f.js} +1 -1
  28. fides/ui-build/static/admin/_next/static/chunks/355-e4340980d72b4faa.js +1 -0
  29. fides/ui-build/static/admin/_next/static/chunks/{3872-99da5bb6140ff810.js → 3872-6b828cb00fb2ce93.js} +1 -1
  30. fides/ui-build/static/admin/_next/static/chunks/4060-9593a3f98e600487.js +1 -0
  31. fides/ui-build/static/admin/_next/static/chunks/4121-5c3af879cdd8b3be.js +1 -0
  32. fides/ui-build/static/admin/_next/static/chunks/4481-8398edf74aabb8ea.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/4723-4c3c7a375e998c15.js +1 -0
  34. fides/ui-build/static/admin/_next/static/chunks/5258-e000d07844eccf7e.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/{5487-218e4847b8250fbb.js → 5487-62955c11bab63734.js} +1 -1
  36. fides/ui-build/static/admin/_next/static/chunks/5626-1b636798faad78e1.js +1 -0
  37. fides/ui-build/static/admin/_next/static/chunks/5683-44966a05fa5ad566.js +1 -0
  38. fides/ui-build/static/admin/_next/static/chunks/5826-ce34f25ac2eeb807.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/5973-56d90405c3616068.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/6277-c35c8cc806f7571f.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/6853-0cee00c9da26a40e.js +1 -0
  42. fides/ui-build/static/admin/_next/static/chunks/{6954-04030a21a0c8cf5a.js → 6954-d02d474ba30756b2.js} +1 -1
  43. fides/ui-build/static/admin/_next/static/chunks/79-e5884e6878fc1bbb.js +1 -0
  44. fides/ui-build/static/admin/_next/static/chunks/7980-e17dda2f50ec76b8.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/{9494-d1fd4fb83c3d4836.js → 9494-0df032fe6ee531a5.js} +1 -1
  46. fides/ui-build/static/admin/_next/static/chunks/9767-74320abc2e9a4550.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-94950df9c97cd079.js → _app-371b155655c83a1e.js} +69 -69
  48. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-1292fd216f2839c7.js → manual-7d789458fb296270.js} +1 -1
  49. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-2ffc37614e9d1fa9.js → multiple-90320455052466cd.js} +1 -1
  50. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-a69f8946466471aa.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-c8033d6560635046.js → add-vendors-bcc515a765c0119d.js} +1 -1
  52. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-49b9f1b56262dfdc.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-fd71fb440dbe60e4.js → privacy-experience-5ef03041a530b0e2.js} +1 -1
  54. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-12f3ba4609bc2ba5.js +1 -0
  55. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-5960170d492acb03.js → properties-ffa15d7ff64a9f05.js} +1 -1
  56. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-b959d61c2a3682b3.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-18e3faf7963962e4.js → [resourceUrn]-7ddf45ffd49533b0.js} +1 -1
  58. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-a10a0f3e6592f350.js → [projectUrn]-ecf23116a845188a.js} +1 -1
  59. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-6971531bb09dff3a.js → projects-79f8e613827c55c1.js} +1 -1
  60. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-7320524a47104798.js → [resourceUrn]-ed213bc1b7041aa2.js} +1 -1
  61. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-51d99174c8006eb5.js → resources-1f033ca5a0702018.js} +1 -1
  62. fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-4dbc71d8be9765f3.js → data-catalog-e950d41b75f86c85.js} +1 -1
  63. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-84ead584a88ab662.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-90f1975f559fff3e.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-4b820a3173f35504.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-db3853a09933097a.js → activity-beedbc38ee2b0094.js} +1 -1
  67. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-4c526db0c30c488a.js → [resourceUrn]-f38b3ef885a29ea6.js} +1 -1
  68. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-6f27dbb7c8edc69d.js → detection-29fd0d5a73f13a00.js} +1 -1
  69. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-562d2b8ae90dd1f0.js → [resourceUrn]-9a80241f1028c470.js} +1 -1
  70. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-fe7f51502eda57c9.js → discovery-c58333981b1522c9.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-3aaa99709d83a1f6.js → datamap-2d6f95b2769a0936.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c08363922838022a.js → [...subfieldNames]-3536ae978741b659.js} +1 -1
  73. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-f12df2140e309dfb.js → [collectionName]-8b5afe14cf42a4ac.js} +1 -1
  74. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-3f564c8d6cfb03d4.js → [datasetId]-b8dca4298b5bb085.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-1e26702b1a7e0e12.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-1f0c4e2e5d0b5bf6.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b078218865a8fd28.js → [id]-ebf54ea9874c59ae.js} +1 -1
  78. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-c39e8e2269883796.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-9db81467fa254996.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/pages/{index-2e6ba5382358fcf8.js → index-868b60407eae35da.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-ebc41649161f7fb9.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-b89b9f68ccc69c1b.js +1 -0
  83. fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-71166bf207804754.js → messaging-5f41afae411cd8a4.js} +1 -1
  84. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-928430cd40c35ef2.js +1 -0
  85. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-07ef58b04404479d.js +1 -0
  86. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-595ed9f6ca438020.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-b3384299166bcd1e.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/{properties-4a5e8ec41574c6b5.js → properties-f00530710b699afd.js} +1 -1
  89. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6a6016708efb5f4f.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ba15c12c89ee10f8.js +1 -0
  91. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-0f2daeec241bd1a2.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-0401208a3128fa4d.js +1 -0
  93. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-92e8246170b492b5.js → domain-records-0daa256958675a23.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-4fbab6716326060d.js +1 -0
  95. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-b235f961f9ca39a6.js → organization-9404a6b0b2951992.js} +1 -1
  96. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-99cd1a12ae0373b0.js → test-datasets-48be14ad09ed4133.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-01006a55ac873135.js → [id]-b03403fed4dd8805.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/{systems-45990d85a4c5739b.js → systems-ae591953b24e2fc9.js} +1 -1
  99. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-913efe5371344de6.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-dc11ba29dbd4708b.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-c0b2113b44f46112.js +1 -0
  102. fides/ui-build/static/admin/_next/static/css/b89fc4b36b501cf6.css +1 -0
  103. fides/ui-build/static/admin/_next/static/css/{1b227ba7eabbfe2f.css → c0c2eb63ad3e7390.css} +1 -1
  104. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  105. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  106. fides/ui-build/static/admin/add-systems.html +1 -1
  107. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  108. fides/ui-build/static/admin/consent/configure.html +1 -1
  109. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  110. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  111. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  112. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  113. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  114. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  115. fides/ui-build/static/admin/consent/properties.html +1 -1
  116. fides/ui-build/static/admin/consent/reporting.html +1 -1
  117. fides/ui-build/static/admin/consent.html +1 -1
  118. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  119. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  120. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  121. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  122. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  123. fides/ui-build/static/admin/data-catalog.html +1 -1
  124. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  125. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  126. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  127. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  128. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  129. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  130. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  131. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  132. fides/ui-build/static/admin/datamap.html +1 -1
  133. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  134. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  135. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  136. fides/ui-build/static/admin/dataset/new.html +1 -1
  137. fides/ui-build/static/admin/dataset.html +1 -1
  138. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  139. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  140. fides/ui-build/static/admin/datastore-connection.html +1 -1
  141. fides/ui-build/static/admin/index.html +1 -1
  142. fides/ui-build/static/admin/integrations/[id].html +1 -1
  143. fides/ui-build/static/admin/integrations.html +1 -1
  144. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  145. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  146. fides/ui-build/static/admin/lib/fides-preview.js +1 -1
  147. fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
  148. fides/ui-build/static/admin/lib/fides.js +2 -2
  149. fides/ui-build/static/admin/login/[provider].html +1 -1
  150. fides/ui-build/static/admin/login.html +1 -1
  151. fides/ui-build/static/admin/messaging/[id].html +1 -1
  152. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  153. fides/ui-build/static/admin/messaging.html +1 -1
  154. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  155. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  156. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  157. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  158. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  159. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  160. fides/ui-build/static/admin/poc/forms.html +1 -1
  161. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  162. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  163. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  164. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  165. fides/ui-build/static/admin/privacy-requests.html +1 -1
  166. fides/ui-build/static/admin/properties/[id].html +1 -1
  167. fides/ui-build/static/admin/properties/add-property.html +1 -1
  168. fides/ui-build/static/admin/properties.html +1 -1
  169. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  170. fides/ui-build/static/admin/settings/about.html +1 -1
  171. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  172. fides/ui-build/static/admin/settings/consent.html +1 -1
  173. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  174. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  175. fides/ui-build/static/admin/settings/domains.html +1 -1
  176. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  177. fides/ui-build/static/admin/settings/locations.html +1 -1
  178. fides/ui-build/static/admin/settings/organization.html +1 -1
  179. fides/ui-build/static/admin/settings/regulations.html +1 -1
  180. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  181. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  182. fides/ui-build/static/admin/systems.html +1 -1
  183. fides/ui-build/static/admin/taxonomy.html +1 -1
  184. fides/ui-build/static/admin/user-management/new.html +1 -1
  185. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  186. fides/ui-build/static/admin/user-management.html +1 -1
  187. fides/api/alembic/migrations/versions/2263583b0e44_add_shared_monitor_config.py +0 -82
  188. fides/ui-build/static/admin/_next/static/chunks/1327-da0303f70d12fb20.js +0 -1
  189. fides/ui-build/static/admin/_next/static/chunks/1817-d2543e460cec0dcb.js +0 -1
  190. fides/ui-build/static/admin/_next/static/chunks/1904-25e5d4f1b8146fb3.js +0 -1
  191. fides/ui-build/static/admin/_next/static/chunks/3119-b5e40d8d24af1e79.js +0 -1
  192. fides/ui-build/static/admin/_next/static/chunks/3426-77fccf2c9a5e10cd.js +0 -1
  193. fides/ui-build/static/admin/_next/static/chunks/3923-c6dcaeaa3267f254.js +0 -1
  194. fides/ui-build/static/admin/_next/static/chunks/401-a882199f6c94a4dc.js +0 -1
  195. fides/ui-build/static/admin/_next/static/chunks/4060-c657e58514e91e91.js +0 -1
  196. fides/ui-build/static/admin/_next/static/chunks/4121-ec1d8faa3cf5783c.js +0 -1
  197. fides/ui-build/static/admin/_next/static/chunks/4481-9357e3930d35073b.js +0 -1
  198. fides/ui-build/static/admin/_next/static/chunks/5258-49e73e5998c01254.js +0 -1
  199. fides/ui-build/static/admin/_next/static/chunks/5683-3d5c4194b1b1493e.js +0 -1
  200. fides/ui-build/static/admin/_next/static/chunks/5973-d776c0029db45971.js +0 -1
  201. fides/ui-build/static/admin/_next/static/chunks/6277-db781b6c1dde3c84.js +0 -1
  202. fides/ui-build/static/admin/_next/static/chunks/6853-348fe2ba132b400c.js +0 -1
  203. fides/ui-build/static/admin/_next/static/chunks/7553-0f3e9e7eaf1a8b62.js +0 -1
  204. fides/ui-build/static/admin/_next/static/chunks/79-d877d3bde220da44.js +0 -1
  205. fides/ui-build/static/admin/_next/static/chunks/796-7424eb6391142ccd.js +0 -1
  206. fides/ui-build/static/admin/_next/static/chunks/7980-041df432c4d3a68b.js +0 -1
  207. fides/ui-build/static/admin/_next/static/chunks/9767-f8ea7d0127f81294.js +0 -1
  208. fides/ui-build/static/admin/_next/static/chunks/9965-92f4a28823a5e623.js +0 -1
  209. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-0234733a90ed5127.js +0 -1
  210. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-2ba21b95aa3bb15e.js +0 -1
  211. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-5a63fc903408412e.js +0 -1
  212. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-80bd51f8217edae4.js +0 -1
  213. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-67ddc090cf949af4.js +0 -1
  214. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-07ff657ee49e5742.js +0 -1
  215. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-dbc8c95c22b9f2aa.js +0 -1
  216. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-157b00d23b651d12.js +0 -1
  217. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-9d29dd6cf109891d.js +0 -1
  218. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-b01f89d250ff52af.js +0 -1
  219. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-9fc15228581786e6.js +0 -1
  220. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-43abc599f0768331.js +0 -1
  221. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-d69c9f1007e76046.js +0 -1
  222. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-fec150afcfeb3fb5.js +0 -1
  223. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-2862630f0e9e484b.js +0 -1
  224. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-35e58b5ed6b12b2b.js +0 -1
  225. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bb02092af39446da.js +0 -1
  226. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6baa485385ce0678.js +0 -1
  227. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-707551df97d5eebd.js +0 -1
  228. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-e4df123bef1ff2b1.js +0 -1
  229. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-2fd6b0ff9b6741fc.js +0 -1
  230. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-3a829c53d5d723d2.js +0 -1
  231. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-4194ce716b81480d.js +0 -1
  232. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-ec739e169cd5eafe.js +0 -1
  233. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-603c2bdbd8dc00ca.js +0 -1
  234. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-592e497369673e1a.js +0 -1
  235. fides/ui-build/static/admin/_next/static/css/5ded47c57dae5baf.css +0 -1
  236. fides/ui-build/static/admin/_next/static/ulYEH5vwbFjKDz3nI321R/_buildManifest.js +0 -1
  237. fides/ui-build/static/admin/poc/table-migration.html +0 -1
  238. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/WHEEL +0 -0
  239. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/entry_points.txt +0 -0
  240. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/licenses/LICENSE +0 -0
  241. {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/top_level.txt +0 -0
  242. /fides/ui-build/static/admin/_next/static/{ulYEH5vwbFjKDz3nI321R → K1_4-1GhwfL7h4fYYQBvB}/_ssgManifest.js +0 -0
  243. /fides/ui-build/static/admin/_next/static/chunks/{1099-b652e6f9a0cd778b.js → 1099-98458e8e9ff67508.js} +0 -0
  244. /fides/ui-build/static/admin/_next/static/chunks/{1100-e19e94b0a6486255.js → 1100-4106d99f5e1ebd75.js} +0 -0
  245. /fides/ui-build/static/admin/_next/static/chunks/{2921-771dc5d9e95dc6b4.js → 2921-ca04a0476e2e56c5.js} +0 -0
  246. /fides/ui-build/static/admin/_next/static/chunks/{3505-313087fc1744a0ca.js → 3505-e58b93f9c1cbdcad.js} +0 -0
  247. /fides/ui-build/static/admin/_next/static/chunks/{69-ef4c11c574b4e6dd.js → 69-dc52e39d26a4ad14.js} +0 -0
  248. /fides/ui-build/static/admin/_next/static/chunks/{8433-755359b501d32eaa.js → 8433-a77c2cd1c1a6887e.js} +0 -0
  249. /fides/ui-build/static/admin/_next/static/chunks/{8499-06ab15acbfec037c.js → 8499-34a34015c91fc38b.js} +0 -0
  250. /fides/ui-build/static/admin/_next/static/chunks/{9327-b691be8352e31b58.js → 9327-a25347d72bfbe680.js} +0 -0
  251. /fides/ui-build/static/admin/_next/static/chunks/pages/{404-e868487119cd14fc.js → 404-c00773c4c6e930af.js} +0 -0
  252. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-94391554a7607c5b.js → [id]-d4137bb7fdc1ac6e.js} +0 -0
  253. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-596dd2a35b455f21.js → [id]-a5a95ac63b1ce206.js} +0 -0
  254. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-fa7f0d2639e12a5a.js → new-946ce1a2aa1500d4.js} +0 -0
  255. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-dd2a0e3b536b8b42.js → consent-7797e367dd946a18.js} +0 -0
  256. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-111b07344f1ee9e4.js → [id]-22812f08e81bd4f3.js} +0 -0
  257. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-c41f368fb6b35de4.js → add-template-ca22869201847ccc.js} +0 -0
  258. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-3dabaf6828acb2cb.js → ant-components-173bd3ad45ea61c6.js} +0 -0
  259. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-784081c774042249.js → AntForm-4dfe984ad80927cd.js} +0 -0
  260. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-63905f2382f158cd.js → FormikAntFormItem-f790e1ea5cbc26c0.js} +0 -0
  261. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-43f6eab28eae7b56.js → FormikControlled-af9e682ec620e990.js} +0 -0
  262. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-e4a07abc908fc9b5.js → FormikField-6ce407101daa6000.js} +0 -0
  263. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-71a3bfb94280fc49.js → forms-9ee8cf14a93eaa4a.js} +0 -0
  264. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-42213855a0a8c209.js → configure-25a3add8e7982e43.js} +0 -0
  265. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d547a1da0b74f00f.js → [id]-081f13526443e0a6.js} +0 -0
  266. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-a7de6f8409a76358.js → add-property-17fb474e458b63e7.js} +0 -0
  267. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-704fc28e61b17247.js → about-177919b4ccf8f660.js} +0 -0
  268. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-f0e9ee8756a65540.js → domains-26810d1ffedcd156.js} +0 -0
  269. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-a4771098466af1ed.js → email-templates-eb78b645d0c1d4ea.js} +0 -0
  270. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-8cff97fe57f42ed3.js → regulations-0a3aa951ef4a44ba.js} +0 -0
  271. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-b124cc24b930c9e1.js → new-69176abe09cf9b52.js} +0 -0
  272. /fides/ui-build/static/admin/_next/static/chunks/{webpack-3a61b934ba2fb620.js → webpack-abd3efcb23c0bb03.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-03T15:45:25-0300",
11
+ "date": "2025-06-06T15:00:50-0400",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "2c58fc8696c47cf695b2beb925ac37c9ff867299",
15
- "version": "2.62.1b2"
14
+ "full-revisionid": "4fca3c3a4592528e57449b8ee9cafed8010d6052",
15
+ "version": "2.62.1rc0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -120,7 +120,7 @@ from fides.api.util.collection_util import Row
120
120
  from fides.api.util.endpoint_utils import validate_start_and_end_filters
121
121
  from fides.api.util.enums import ColumnSort
122
122
  from fides.api.util.fuzzy_search_utils import get_decrypted_identities_automaton
123
- from fides.api.util.storage_util import StorageJSONEncoder
123
+ from fides.api.util.storage_util import storage_json_encoder
124
124
  from fides.common.api.scope_registry import (
125
125
  PRIVACY_REQUEST_CALLBACK_RESUME,
126
126
  PRIVACY_REQUEST_CREATE,
@@ -2129,7 +2129,7 @@ def get_test_privacy_request_results(
2129
2129
 
2130
2130
  # Escape datetime and ObjectId values
2131
2131
  raw_data = privacy_request.get_raw_access_results()
2132
- escaped_json = json.dumps(raw_data, indent=2, cls=StorageJSONEncoder)
2132
+ escaped_json = json.dumps(raw_data, indent=2, default=storage_json_encoder)
2133
2133
  results = json.loads(escaped_json)
2134
2134
 
2135
2135
  filtered_results: Dict[str, Any] = filter_access_results(
fides/api/main.py CHANGED
@@ -240,6 +240,7 @@ async def log_request(request: Request, call_next: Callable) -> Response:
240
240
  status_code=response.status_code,
241
241
  handler_time=f"{total_time}ms",
242
242
  path=request.url.path,
243
+ fides_client=request.headers.get("Fides-Client", "unknown"),
243
244
  ).info("Request received")
244
245
  return response
245
246
 
@@ -12,14 +12,12 @@ from sqlalchemy.orm import Session, relationship
12
12
 
13
13
  from fides.api.db.base_class import Base
14
14
  from fides.api.schemas.storage.storage import StorageDetails, StorageType
15
- from fides.api.service.storage.gcs import get_gcs_client
16
15
  from fides.api.service.storage.s3 import (
17
16
  generic_delete_from_s3,
18
17
  generic_retrieve_from_s3,
19
18
  generic_upload_to_s3,
20
19
  )
21
- from fides.api.service.storage.util import AllowedFileType, get_local_filename
22
- from fides.config import CONFIG
20
+ from fides.api.service.storage.util import get_local_filename
23
21
 
24
22
  if TYPE_CHECKING:
25
23
  from fides.api.models.comment import Comment
@@ -117,13 +115,8 @@ class Attachment(Base):
117
115
  uselist=False,
118
116
  )
119
117
 
120
- @property
121
- def content_type(self) -> str:
122
- """Returns the content type of the attachment."""
123
- return AllowedFileType[self.file_name.split(".")[-1]].value
124
-
125
118
  def upload(self, attachment: IO[bytes]) -> None:
126
- """Uploads an attachment to S3, GCS, or local storage."""
119
+ """Uploads an attachment to S3 or local storage."""
127
120
  if self.config.type == StorageType.s3:
128
121
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
129
122
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
@@ -137,23 +130,6 @@ class Attachment(Base):
137
130
  log.info(f"Uploaded {self.file_name} to S3 bucket {bucket_name}/{self.id}")
138
131
  return
139
132
 
140
- if self.config.type == StorageType.gcs:
141
- bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
142
- auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
143
- storage_client = get_gcs_client(auth_method, self.config.secrets)
144
- bucket = storage_client.bucket(bucket_name)
145
- blob = bucket.blob(f"{self.id}/{self.file_name}")
146
-
147
- # Reset the file pointer to the beginning
148
- try:
149
- attachment.seek(0)
150
- except Exception as e:
151
- raise ValueError(f"Failed to reset file pointer for attachment: {e}")
152
-
153
- blob.upload_from_file(attachment)
154
- log.info(f"Uploaded {self.file_name} to GCS bucket {bucket_name}/{self.id}")
155
- return
156
-
157
133
  if self.config.type == StorageType.local:
158
134
  filename = get_local_filename(f"{self.id}/{self.file_name}")
159
135
 
@@ -188,16 +164,13 @@ class Attachment(Base):
188
164
  self,
189
165
  ) -> Tuple[int, AnyHttpUrlString]:
190
166
  """
191
- Retrieves the size of the attachment and a presigned/signed URL.
167
+ Retrieves a the size of the attachment and the presigned URL to retrieve it.
192
168
  - For s3:
193
169
  - the size is retrieved from the s3 object metadata
194
- - returns presigned URL
195
- - For gcs:
196
- - the size is retrieved from the blob metadata
197
- - returns signed URL
170
+ - the presigned URL is retrieved from the s3 client
198
171
  - For local:
199
172
  - the size is retrieved from the file size
200
- - returns the local file path
173
+ - the URL is the local file path
201
174
  """
202
175
  if self.config.type == StorageType.s3:
203
176
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
@@ -207,81 +180,19 @@ class Attachment(Base):
207
180
  bucket_name=bucket_name,
208
181
  file_key=f"{self.id}/{self.file_name}",
209
182
  auth_method=auth_method,
210
- get_content=False,
211
183
  )
212
184
  return size, url
213
185
 
214
- if self.config.type == StorageType.gcs:
215
- bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
216
- auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
217
- storage_client = get_gcs_client(auth_method, self.config.secrets)
218
- bucket = storage_client.bucket(bucket_name)
219
- blob = bucket.blob(f"{self.id}/{self.file_name}")
220
-
221
- # Ensure we have the blob metadata
222
- blob.reload()
223
- url = blob.generate_signed_url(
224
- version="v4",
225
- expiration=CONFIG.security.subject_request_download_link_ttl_seconds,
226
- method="GET",
227
- )
228
- return blob.size, url
229
-
230
- if self.config.type == StorageType.local:
231
- filename = get_local_filename(f"{self.id}/{self.file_name}")
232
- size = os.path.getsize(filename)
233
- return size, filename
234
-
235
- raise ValueError(f"Unsupported storage type: {self.config.type}")
236
-
237
- def retrieve_attachment_content(
238
- self,
239
- ) -> Tuple[int, bytes]:
240
- """
241
- Retrieves the size of the attachment and its actual content.
242
- - For s3:
243
- - the size is retrieved from the s3 object metadata
244
- - returns the actual content
245
- - For gcs:
246
- - the size is retrieved from the blob metadata
247
- - returns the actual content
248
- - For local:
249
- - the size is retrieved from the file size
250
- - returns the actual content
251
- """
252
- if self.config.type == StorageType.s3:
253
- bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
254
- auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
255
- size, content = generic_retrieve_from_s3(
256
- storage_secrets=self.config.secrets,
257
- bucket_name=bucket_name,
258
- file_key=f"{self.id}/{self.file_name}",
259
- auth_method=auth_method,
260
- get_content=True,
261
- )
262
- return size, content
263
-
264
- if self.config.type == StorageType.gcs:
265
- bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
266
- auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
267
- storage_client = get_gcs_client(auth_method, self.config.secrets)
268
- bucket = storage_client.bucket(bucket_name)
269
- blob = bucket.blob(f"{self.id}/{self.file_name}")
270
-
271
- content = blob.download_as_bytes()
272
- return len(content), content
273
-
274
186
  if self.config.type == StorageType.local:
275
187
  filename = get_local_filename(f"{self.id}/{self.file_name}")
276
188
  with open(filename, "rb") as file:
277
- content = file.read()
278
- size = len(content)
279
- return size, content
189
+ size = len(file.read())
190
+ return size, filename
280
191
 
281
192
  raise ValueError(f"Unsupported storage type: {self.config.type}")
282
193
 
283
194
  def delete_attachment_from_storage(self) -> None:
284
- """Deletes an attachment from S3, GCS, or local storage."""
195
+ """Deletes an attachment from S3 or local storage."""
285
196
  if self.config.type == StorageType.s3:
286
197
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
287
198
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
@@ -293,27 +204,9 @@ class Attachment(Base):
293
204
  )
294
205
  return
295
206
 
296
- if self.config.type == StorageType.gcs:
297
- bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
298
- auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
299
- storage_client = get_gcs_client(auth_method, self.config.secrets)
300
- bucket = storage_client.bucket(bucket_name)
301
-
302
- # List and delete all blobs in the folder
303
- prefix = f"{self.id}/"
304
- blobs = bucket.list_blobs(prefix=prefix)
305
- for blob in blobs:
306
- blob.delete()
307
- return
308
-
309
207
  if self.config.type == StorageType.local:
310
- folder_path = os.path.dirname(
311
- get_local_filename(f"{self.id}/{self.file_name}")
312
- )
313
- if os.path.exists(folder_path):
314
- import shutil
315
-
316
- shutil.rmtree(folder_path)
208
+ filename = get_local_filename(f"{self.id}/{self.file_name}")
209
+ os.remove(filename)
317
210
  return
318
211
 
319
212
  raise ValueError(f"Unsupported storage type: {self.config.type}")
@@ -9,7 +9,6 @@ from loguru import logger
9
9
  from sqlalchemy import ARRAY, Boolean, Column, DateTime, ForeignKey, String, func
10
10
  from sqlalchemy.dialects.postgresql import JSONB
11
11
  from sqlalchemy.ext.asyncio import AsyncSession
12
- from sqlalchemy.ext.declarative import declared_attr
13
12
  from sqlalchemy.ext.mutable import MutableDict
14
13
  from sqlalchemy.future import select
15
14
  from sqlalchemy.orm import Session, relationship
@@ -48,29 +47,6 @@ class MonitorFrequency(Enum):
48
47
  QUARTERLY_MONTH_PATTERN = r"^\d+,\d+,\d+,\d+$"
49
48
 
50
49
 
51
- class SharedMonitorConfig(Base, FidesBase):
52
- """SQL model for shareable monitor configurations"""
53
-
54
- @declared_attr
55
- def __tablename__(self) -> str:
56
- return "shared_monitor_config"
57
-
58
- # Basic info
59
- name = Column(String, nullable=False)
60
- key = Column(String, unique=True, nullable=False)
61
- description = Column(String, nullable=True)
62
-
63
- # Classification parameters (including regex patterns)
64
- classify_params = Column(
65
- MutableDict.as_mutable(JSONB),
66
- index=False,
67
- unique=False,
68
- nullable=False,
69
- server_default="{}",
70
- default=dict,
71
- )
72
-
73
-
74
50
  class MonitorConfig(Base):
75
51
  """
76
52
  Monitor configuration used for data detection and discovery.
@@ -111,9 +87,7 @@ class MonitorConfig(Base):
111
87
  ) # stores the cron-based kwargs for scheduling the monitor execution.
112
88
  # see https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html
113
89
 
114
- # We use _classify_params for the actual column to prevent direct access
115
- _classify_params = Column(
116
- "classify_params",
90
+ classify_params = Column(
117
91
  MutableDict.as_mutable(JSONB),
118
92
  index=False,
119
93
  unique=False,
@@ -150,45 +124,6 @@ class MonitorConfig(Base):
150
124
  backref="monitor_config",
151
125
  )
152
126
 
153
- shared_config_id = Column(
154
- String,
155
- ForeignKey(SharedMonitorConfig.id_field_path, ondelete="RESTRICT"),
156
- nullable=True,
157
- index=True,
158
- )
159
-
160
- shared_config = relationship(SharedMonitorConfig)
161
-
162
- @property
163
- def classify_params(self) -> dict:
164
- """
165
- Returns the merged classify parameters from both the monitor config and
166
- the shared config (if it exists).
167
-
168
- The shared config parameters take precedence over the monitor's own parameters,
169
- but only for values that are not falsy (None, empty, etc.).
170
- """
171
- # Start with an empty dict
172
- merged_params = {}
173
-
174
- # Add this monitor's params if available
175
- if self._classify_params:
176
- merged_params.update(self._classify_params)
177
-
178
- # Add/override with shared config params if available
179
- if self.shared_config and self.shared_config.classify_params:
180
- # Only update with non-falsy values from shared config
181
- for key, value in self.shared_config.classify_params.items():
182
- if value: # Only override if the value is not falsy
183
- merged_params[key] = value
184
-
185
- return merged_params
186
-
187
- @classify_params.setter
188
- def classify_params(self, value: Dict[str, Any]) -> None:
189
- """Setter for the classify_params to maintain compatibility with existing code"""
190
- self._classify_params = value
191
-
192
127
  @property
193
128
  def connection_config_key(self) -> str:
194
129
  """Derives the `connection_config_key`"""
@@ -1089,46 +1089,6 @@ class PrivacyRequest(
1089
1089
  if attachment:
1090
1090
  attachment.delete(db)
1091
1091
 
1092
- def _get_manual_webhook_attachments(
1093
- self, db: Session, manual_webhook_id: str, reference_type: str
1094
- ) -> List[Attachment]:
1095
- """Helper method to get attachments that have references to both this privacy request and the specified manual webhook"""
1096
- query = """
1097
- SELECT DISTINCT a.*
1098
- FROM attachment a
1099
- INNER JOIN attachment_reference ar1 ON a.id = ar1.attachment_id
1100
- INNER JOIN attachment_reference ar2 ON a.id = ar2.attachment_id
1101
- WHERE ar1.reference_id = :privacy_request_id
1102
- AND ar1.reference_type = 'privacy_request'
1103
- AND ar2.reference_id = :manual_webhook_id
1104
- AND ar2.reference_type = :reference_type
1105
- """
1106
- result = db.execute(
1107
- query,
1108
- {
1109
- "privacy_request_id": self.id,
1110
- "manual_webhook_id": manual_webhook_id,
1111
- "reference_type": reference_type,
1112
- },
1113
- )
1114
- return [Attachment(**row) for row in result]
1115
-
1116
- def get_access_manual_webhook_attachments(
1117
- self, db: Session, manual_webhook_id: str
1118
- ) -> List[Attachment]:
1119
- """Get all attachments that have references to both this privacy request and the specified access manual webhook"""
1120
- return self._get_manual_webhook_attachments(
1121
- db, manual_webhook_id, "access_manual_webhook"
1122
- )
1123
-
1124
- def get_erasure_manual_webhook_attachments(
1125
- self, db: Session, manual_webhook_id: str
1126
- ) -> List[Attachment]:
1127
- """Get all attachments that have references to both this privacy request and the specified erasure manual webhook"""
1128
- return self._get_manual_webhook_attachments(
1129
- db, manual_webhook_id, "erasure_manual_webhook"
1130
- )
1131
-
1132
1092
  def get_existing_request_task(
1133
1093
  self,
1134
1094
  db: Session,
@@ -1268,6 +1228,7 @@ class PrivacyRequest(
1268
1228
  """
1269
1229
  if not self.policy.get_rules_for_action(action_type=ActionType.access):
1270
1230
  return None
1231
+
1271
1232
  self.filtered_final_upload = results
1272
1233
  self.save(db)
1273
1234
 
@@ -52,6 +52,7 @@ from fides.api.util.saas_util import (
52
52
  get_identities,
53
53
  )
54
54
  from fides.common.api.v1.urn_registry import REQUEST_TASK_CALLBACK, V1_URL_PREFIX
55
+ from fides.config.config_proxy import ConfigProxy
55
56
 
56
57
  T = TypeVar("T")
57
58
 
@@ -143,12 +144,16 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
143
144
  """
144
145
  Returns a tuple of the preferred action and SaaSRequest to use for masking.
145
146
  An update request is preferred, but we can use a gdpr delete endpoint or
146
- delete endpoint.
147
+ delete endpoint if not MASKING_STRICT.
147
148
  """
148
149
 
149
150
  update: Optional[SaaSRequest] = self.get_erasure_request_by_action("update")
150
- gdpr_delete: Optional[SaaSRequest] = self.data_protection_request
151
- delete: Optional[SaaSRequest] = self.get_erasure_request_by_action("delete")
151
+ gdpr_delete: Optional[SaaSRequest] = None
152
+ delete: Optional[SaaSRequest] = None
153
+
154
+ if not ConfigProxy(db).execution.masking_strict:
155
+ gdpr_delete = self.data_protection_request
156
+ delete = self.get_erasure_request_by_action("delete")
152
157
 
153
158
  try:
154
159
  # Return first viable option
@@ -530,15 +530,11 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
530
530
 
531
531
  session = Session.object_session(privacy_request)
532
532
  masking_request = query_config.get_masking_request(session)
533
- rows_updated = 0
534
-
535
533
  if not masking_request:
536
- logger.info(
537
- "No masking request found for the '{}' collection in {}",
538
- self.current_collection_name,
539
- self.saas_config.fides_key, # type: ignore
534
+ raise Exception(
535
+ f"Either no masking request configured or no valid masking request for {node.address.collection}. "
536
+ f"Check that MASKING_STRICT env var is appropriately set"
540
537
  )
541
- return rows_updated
542
538
 
543
539
  self.set_saas_request_state(masking_request)
544
540
 
@@ -569,6 +565,7 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
569
565
  cast(Optional[List[PostProcessorStrategy]], masking_request.postprocessors),
570
566
  )
571
567
 
568
+ rows_updated = 0
572
569
  client = self.create_client()
573
570
  for row in rows:
574
571
  try:
@@ -11,7 +11,7 @@ from jinja2 import Environment, FileSystemLoader
11
11
 
12
12
  from fides.api.models.privacy_request import PrivacyRequest
13
13
  from fides.api.schemas.policy import ActionType
14
- from fides.api.util.storage_util import StorageJSONEncoder
14
+ from fides.api.util.storage_util import storage_json_encoder
15
15
 
16
16
  DSR_DIRECTORY = Path(__file__).parent.resolve()
17
17
 
@@ -41,9 +41,7 @@ class DsrReportBuilder:
41
41
 
42
42
  # Jinja template environment initialization
43
43
  def pretty_print(value: str, indent: int = 4) -> str:
44
- return json.dumps(
45
- value, indent=indent, default=StorageJSONEncoder().default
46
- )
44
+ return json.dumps(value, indent=indent, default=storage_json_encoder)
47
45
 
48
46
  jinja2.filters.FILTERS["pretty_print"] = pretty_print
49
47
  self.template_loader = Environment(
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import IO, Any, Dict, Tuple, Union
3
+ from typing import IO, Any, Dict, Tuple
4
4
 
5
5
  from boto3.s3.transfer import TransferConfig
6
6
  from botocore.exceptions import ClientError, ParamValidationError
@@ -129,38 +129,25 @@ def generic_retrieve_from_s3(
129
129
  bucket_name: str,
130
130
  file_key: str,
131
131
  auth_method: str,
132
- get_content: bool = False,
133
- ) -> Tuple[int, Union[str, bytes]]:
132
+ ) -> Tuple[int, AnyHttpUrlString]:
134
133
  """
135
- Retrieves a file from S3 and returns its size and either a presigned URL or the actual content.
136
-
137
- Args:
138
- storage_secrets: Dictionary containing S3 credentials
139
- bucket_name: Name of the S3 bucket
140
- file_key: Key of the file in the bucket
141
- auth_method: Authentication method to use
142
- get_content: If True, returns the actual content instead of a presigned URL
134
+ Retrieves file metadata and generates a presigned URL for downloading an S3 object.
143
135
 
144
- Returns:
145
- Tuple containing (file_size, presigned_url_or_content)
136
+ :param storage_secrets: S3 storage secrets
137
+ :param bucket_name: Name of the S3 bucket
138
+ :param file_key: Key of the file in the bucket
139
+ :param auth_method: Authentication method for S3
140
+ :return: Tuple containing (file_size, presigned_url)
146
141
  """
147
142
  logger.info("Retrieving S3 object: {}", file_key)
148
- s3_client = get_s3_client(auth_method, storage_secrets)
149
143
 
144
+ s3_client = maybe_get_s3_client(auth_method, storage_secrets)
150
145
  try:
151
- if get_content:
152
- # Get the actual content
153
- response = s3_client.get_object(Bucket=bucket_name, Key=file_key)
154
- content = response["Body"].read()
155
- return response["ContentLength"], content
156
-
157
- # Get presigned URL
158
- presigned_url = create_presigned_url_for_s3(s3_client, bucket_name, file_key)
159
- # Get file size
160
- response = s3_client.head_object(Bucket=bucket_name, Key=file_key)
161
- return int(response["ContentLength"]), str(presigned_url)
162
- except ClientError as e:
163
- logger.error(f"Error retrieving file from S3: {e}")
146
+ get_allowed_file_type_or_raise(file_key)
147
+ file_size = get_file_size(s3_client, bucket_name, file_key)
148
+ return file_size, create_presigned_url_for_s3(s3_client, bucket_name, file_key)
149
+ except Exception as e:
150
+ logger.error("Encountered error while retrieving S3 object: {}", e)
164
151
  raise e
165
152
 
166
153
 
@@ -171,8 +158,7 @@ def generic_delete_from_s3(
171
158
  auth_method: str,
172
159
  ) -> None:
173
160
  """
174
- Deletes arbitrary data from s3. If file_key ends with a filename, deletes just that file.
175
- If file_key ends with a '/', deletes all objects with that prefix.
161
+ Deletes arbitrary data from s3
176
162
 
177
163
  :param storage_secrets: S3 storage secrets
178
164
  :param bucket_name: Name of the S3 bucket
@@ -183,17 +169,6 @@ def generic_delete_from_s3(
183
169
 
184
170
  s3_client = maybe_get_s3_client(auth_method, storage_secrets)
185
171
  try:
186
- # If the file_key ends with a '/', it's a folder prefix
187
- if file_key.endswith("/"):
188
- # List all objects with the prefix, handling pagination
189
- paginator = s3_client.get_paginator("list_objects_v2")
190
- for page in paginator.paginate(Bucket=bucket_name, Prefix=file_key):
191
- if "Contents" in page:
192
- for obj in page["Contents"]:
193
- s3_client.delete_object(Bucket=bucket_name, Key=obj["Key"])
194
- return
195
-
196
- # Delete single object
197
172
  s3_client.delete_object(Bucket=bucket_name, Key=file_key)
198
173
  except Exception as e:
199
174
  logger.error("Encountered error while deleting s3 object: {}", e)
@@ -30,7 +30,7 @@ from fides.api.util.cache import get_cache, get_encryption_cache_key
30
30
  from fides.api.util.encryption.aes_gcm_encryption_scheme import (
31
31
  encrypt_to_bytes_verify_secrets_length,
32
32
  )
33
- from fides.api.util.storage_util import StorageJSONEncoder
33
+ from fides.api.util.storage_util import storage_json_encoder
34
34
  from fides.config import CONFIG
35
35
 
36
36
  if TYPE_CHECKING:
@@ -75,7 +75,7 @@ def write_to_in_memory_buffer(
75
75
  logger.debug("Writing data to in-memory buffer")
76
76
 
77
77
  if resp_format == ResponseFormat.json.value:
78
- json_str = json.dumps(data, indent=2, default=StorageJSONEncoder().default)
78
+ json_str = json.dumps(data, indent=2, default=storage_json_encoder)
79
79
  return BytesIO(
80
80
  encrypt_access_request_results(json_str, privacy_request.id).encode(
81
81
  CONFIG.security.encoding
@@ -1,5 +1,5 @@
1
1
  from datetime import datetime
2
- from typing import Any, Union
2
+ from typing import Any, Dict, Union
3
3
 
4
4
  from bson import ObjectId
5
5
  from pydantic import ValidationError
@@ -11,7 +11,6 @@ from fides.api.schemas.storage.storage import (
11
11
  StorageType,
12
12
  )
13
13
  from fides.api.schemas.storage.storage_secrets_docs_only import possible_storage_secrets
14
- from fides.api.util.custom_json_encoder import CustomJSONEncoder
15
14
 
16
15
 
17
16
  def get_schema_for_secrets(
@@ -49,15 +48,10 @@ def get_schema_for_secrets(
49
48
  raise ValueError(errors)
50
49
 
51
50
 
52
- class StorageJSONEncoder(CustomJSONEncoder):
53
- """
54
- A JSON encoder specifically for storage operations that maintains the original
55
- format for datetime and ObjectId while inheriting other functionality from CustomJSONEncoder.
56
- """
57
-
58
- def default(self, o: Any) -> Any:
59
- if isinstance(o, datetime):
60
- return o.strftime("%Y-%m-%dT%H:%M:%S")
61
- if isinstance(o, ObjectId):
62
- return {"$oid": str(o)}
63
- return super().default(o)
51
+ def storage_json_encoder(field: Any) -> Union[str, Dict[str, str]]:
52
+ """Specify str format for datetime objects"""
53
+ if isinstance(field, datetime):
54
+ return field.strftime("%Y-%m-%dT%H:%M:%S")
55
+ if isinstance(field, ObjectId):
56
+ return {"$oid": str(field)}
57
+ return field
@@ -106,6 +106,7 @@ class ExecutionSettingsProxy(ConfigProxyBase):
106
106
  subject_identity_verification_required: bool
107
107
  disable_consent_identity_verification: bool
108
108
  require_manual_request_approval: bool
109
+ masking_strict: bool
109
110
 
110
111
  def __getattribute__(self, name: str) -> Any:
111
112
  """
@@ -11,6 +11,10 @@ ENV_PREFIX = "FIDES__EXECUTION__"
11
11
  class ExecutionSettings(FidesSettings):
12
12
  """Configuration settings for DSR execution."""
13
13
 
14
+ masking_strict: bool = Field(
15
+ default=True,
16
+ description="If set to True, only use UPDATE requests to mask data. If False, Fides will use any defined DELETE or GDPR DELETE endpoints to remove PII, which may extend beyond the specific data categories that configured in your execution policy.",
17
+ )
14
18
  privacy_request_delay_timeout: int = Field(
15
19
  default=3600,
16
20
  description="The amount of time to wait for actions which delay privacy requests (e.g., pre- and post-processing webhooks).",
File without changes