ethyca-fides 2.62.1rc0__py2.py3-none-any.whl → 2.63.0__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 (358) hide show
  1. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/METADATA +2 -1
  2. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/RECORD +250 -238
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/2263583b0e44_add_shared_monitor_config.py +82 -0
  5. fides/api/alembic/migrations/versions/440a5b9a3493_add_fides_user_respondent_email_.py +80 -0
  6. fides/api/alembic/migrations/versions/5474a47c77da_create_staged_resource_ancestor_link_table.py +72 -0
  7. fides/api/alembic/migrations/versions/bf713b5a021d_staged_resource_ancestor_link_data_.py +259 -0
  8. fides/api/alembic/migrations/versions/c586a56c25e7_remove_child_diff_statuses.py +40 -0
  9. fides/api/api/v1/endpoints/privacy_request_endpoints.py +2 -2
  10. fides/api/db/base.py +3 -0
  11. fides/api/main.py +4 -1
  12. fides/api/migrations/post_upgrade_index_creation.py +269 -0
  13. fides/api/models/attachment.py +117 -10
  14. fides/api/models/audit_log.py +0 -3
  15. fides/api/models/detection_discovery.py +189 -24
  16. fides/api/models/fides_user.py +51 -4
  17. fides/api/models/fides_user_permissions.py +25 -7
  18. fides/api/models/fides_user_respondent_email_verification.py +112 -0
  19. fides/api/models/privacy_request/privacy_request.py +40 -1
  20. fides/api/oauth/roles.py +19 -0
  21. fides/api/service/connectors/query_configs/saas_query_config.py +3 -8
  22. fides/api/service/connectors/saas_connector.py +7 -4
  23. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +4 -2
  24. fides/api/service/privacy_request/request_runner_service.py +47 -18
  25. fides/api/service/privacy_request/request_service.py +4 -15
  26. fides/api/service/storage/s3.py +40 -15
  27. fides/api/tasks/storage.py +6 -5
  28. fides/api/util/lock.py +44 -0
  29. fides/api/util/storage_util.py +14 -8
  30. fides/common/api/scope_registry.py +6 -0
  31. fides/config/config_proxy.py +0 -1
  32. fides/config/execution_settings.py +0 -4
  33. fides/ui-build/static/admin/404.html +1 -1
  34. fides/ui-build/static/admin/_next/static/chunks/1099-667e84655846e78c.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/1100-0b01f500b1eaf60d.js +1 -0
  36. fides/ui-build/static/admin/_next/static/chunks/{1817-721fdeb29c07c6be.js → 1817-951f58ddd5d46081.js} +1 -1
  37. fides/ui-build/static/admin/_next/static/chunks/{1904-7e5354990377a849.js → 1904-361e37a5811ed7fc.js} +1 -1
  38. fides/ui-build/static/admin/_next/static/chunks/2310-744354001d01f366.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/2921-49af55ad7c631c93.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/3119-e36ae5071c8f27a5.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/3505-113f9c95d34b7aae.js +1 -0
  42. fides/ui-build/static/admin/_next/static/chunks/3513-5c2d412a84a78971.js +1 -0
  43. fides/ui-build/static/admin/_next/static/chunks/3662-f6a1ddca5ee42076.js +1 -0
  44. fides/ui-build/static/admin/_next/static/chunks/3670-2abd9b2f17770872.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/3872-45cc725e241211f0.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/3923-b4f701ada3ef0ee0.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/3983-17ae9c232bddc413.js +1 -0
  48. fides/ui-build/static/admin/_next/static/chunks/401-7e800aed05537126.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/4060-90a52a9afc655bfc.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/4121-66b0e00d5e7ae817.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/4132-9b1731bfec6ee537.js +1 -0
  52. fides/ui-build/static/admin/_next/static/chunks/4481-7f6710c928bb0cb0.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/5258-2079138c8cc34f6c.js +1 -0
  54. fides/ui-build/static/admin/_next/static/chunks/5404-2694509cf5fa96da.js +1 -0
  55. fides/ui-build/static/admin/_next/static/chunks/5487-2cbd8d2169eb2a65.js +1 -0
  56. fides/ui-build/static/admin/_next/static/chunks/5683-37137111b3e769fb.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/6202-081545c7822d09af.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/6277-459e054b2702c60e.js +1 -0
  59. fides/ui-build/static/admin/_next/static/chunks/641-7e4eef3222cbda70.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/6659-b2088f525bf13c17.js +1 -0
  61. fides/ui-build/static/admin/_next/static/chunks/{6853-0cee00c9da26a40e.js → 6853-688df0b88fe65fd5.js} +1 -1
  62. fides/ui-build/static/admin/_next/static/chunks/69-00cba94689b9e740.js +1 -0
  63. fides/ui-build/static/admin/_next/static/chunks/6954-4e313b4599b8763d.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/7553-08bc3d9f66695111.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/79-fc548561beed136f.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/796-d6586308ed44334b.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/7980-736f9fd1e749ddd2.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/8032-74d94f7bd5b81c89.js +1 -0
  69. fides/ui-build/static/admin/_next/static/chunks/8433-51870336908fb253.js +1 -0
  70. fides/ui-build/static/admin/_next/static/chunks/8499-1fd392d0be9e8ee4.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/9033-fdd87182c15b91e2.js +1 -0
  72. fides/ui-build/static/admin/_next/static/chunks/9327-6a53461c9764b16f.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/{9392.bfca299d4f39a9e0.js → 9392.81edc11e3a175275.js} +1 -1
  74. fides/ui-build/static/admin/_next/static/chunks/9494-1ffb888b95289891.js +1 -0
  75. fides/ui-build/static/admin/_next/static/chunks/9676.61cf5f6d6a083175.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/9767-afd674014a1d1152.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/pages/404-ec04f826f3dd79ea.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-371b155655c83a1e.js → _app-33bc23b79bffe07c.js} +69 -69
  79. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-1bec086d567aacff.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-f68bf100e4e60e88.js +1 -0
  81. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-effde5cfe49de55f.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/add-vendors-ec95ed8cb0712828.js +1 -0
  83. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-4cc195e15e0c3cc8.js +1 -0
  84. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-be8972c79fb39705.js +1 -0
  85. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-7f38473ce267348a.js → new-a0039f216fb3eb93.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-ccf96207de3b74ea.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/[id]-b9823cc008372cee.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/new-373f5772ab41bc93.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-b9beeee1bde5ca79.js +1 -0
  90. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-6ab3a5baafebd199.js +1 -0
  91. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-8562790ae07f17c9.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/consent-42d4d2d6e0253671.js +1 -0
  93. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-7ddf45ffd49533b0.js → [resourceUrn]-18e3faf7963962e4.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-9d1df6d890671b0c.js +1 -0
  95. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-7eb08af333baaa8e.js +1 -0
  96. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-ed213bc1b7041aa2.js → [resourceUrn]-7320524a47104798.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-1f033ca5a0702018.js → resources-51d99174c8006eb5.js} +1 -1
  98. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-bb57eed84f59a932.js +1 -0
  99. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-47eb34aef3e31ac6.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-76cefefc53e84c7f.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9d8e84a8b4bf568d.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-c3eaadd88a2e6caa.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-f38b3ef885a29ea6.js → [resourceUrn]-4c526db0c30c488a.js} +1 -1
  104. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-29fd0d5a73f13a00.js → detection-6f27dbb7c8edc69d.js} +1 -1
  105. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-9a80241f1028c470.js → [resourceUrn]-562d2b8ae90dd1f0.js} +1 -1
  106. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-c58333981b1522c9.js → discovery-fe7f51502eda57c9.js} +1 -1
  107. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-db45aa864e9dda8a.js +1 -0
  108. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-d5cfdebc74654337.js +1 -0
  109. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-618b89228f83435e.js +1 -0
  110. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-12fc86f15a4c764e.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-c23d18a9b56c2e3c.js +1 -0
  112. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-e3b2d8e3980ab093.js +1 -0
  113. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-6e27257eccf65f01.js +1 -0
  114. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-bbac1f624424282d.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-84eb56f5a07bdf4f.js +1 -0
  116. fides/ui-build/static/admin/_next/static/chunks/pages/index-773182b5e35d0045.js +1 -0
  117. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-eb28c927da5bd653.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-781808bca01f8048.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-b51bee8680d66b20.js +1 -0
  120. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-1de479533f733fbd.js +1 -0
  121. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-7dc295b3ed3d2224.js +1 -0
  122. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-f64dac3392f5ded7.js +1 -0
  123. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-eb020bfac4bee532.js +1 -0
  124. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-0bd62e28b539e114.js +1 -0
  125. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-936877004113c2a6.js +1 -0
  126. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-6416f01524482af9.js +1 -0
  127. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-3f4e1313d1f2969b.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-1db7a54437db7db0.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-64236fd0141414fd.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-8cab04871908cfeb.js +1 -0
  131. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-150d40428245ee0c.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-b6c876dceb16ad1b.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-20cdb2c8a03deae1.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/pages/properties/[id]-54bcc875592d1fb9.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-644dc669b508a79a.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/pages/properties-9a88220d03e7e02f.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-70dc1081df37ea69.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-3c71b4dbcb6fd6c9.js +1 -0
  139. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-7cb16e0000dd16c9.js +1 -0
  140. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-a18d8f12ee8dcf5d.js +1 -0
  141. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-dc220e116ad5c09e.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-55ddc5f25b86f28e.js +1 -0
  143. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-5ca7decded228bc8.js +1 -0
  144. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-a6fafa1be2834c40.js +1 -0
  145. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-e633750d2b45ddd6.js +1 -0
  146. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-4fbab6716326060d.js → locations-3948686cbd372969.js} +1 -1
  147. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-04ece499c22d23f4.js +1 -0
  148. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-7752305084280cca.js +1 -0
  149. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-9e5f9066be6f218d.js +1 -0
  150. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-86de9e6d72098e45.js +1 -0
  151. fides/ui-build/static/admin/_next/static/chunks/pages/systems-cac52e6c3abf6a15.js +1 -0
  152. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-60d5930b6855679b.js +1 -0
  153. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-b0f4c34752d32c73.js +1 -0
  154. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-c0b2113b44f46112.js → user-management-7dee83dd6d9292aa.js} +1 -1
  155. fides/ui-build/static/admin/_next/static/chunks/{webpack-abd3efcb23c0bb03.js → webpack-8457bad7859c44f0.js} +1 -1
  156. fides/ui-build/static/admin/_next/static/css/1fdf5c593349dbc6.css +1 -0
  157. fides/ui-build/static/admin/_next/static/css/5ded47c57dae5baf.css +1 -0
  158. fides/ui-build/static/admin/_next/static/css/e458b5f1afdbb7fc.css +1 -0
  159. fides/ui-build/static/admin/_next/static/lb6RRZ8JumokYwsENumlw/_buildManifest.js +1 -0
  160. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  161. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  162. fides/ui-build/static/admin/add-systems.html +1 -1
  163. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  164. fides/ui-build/static/admin/consent/configure.html +1 -1
  165. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  166. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  167. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  168. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  169. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  170. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  171. fides/ui-build/static/admin/consent/properties.html +1 -1
  172. fides/ui-build/static/admin/consent/reporting.html +1 -1
  173. fides/ui-build/static/admin/consent.html +1 -1
  174. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  175. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  176. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  177. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  178. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  179. fides/ui-build/static/admin/data-catalog.html +1 -1
  180. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  181. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  182. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  183. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  184. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  185. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  186. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  187. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  188. fides/ui-build/static/admin/datamap.html +1 -1
  189. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  190. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  191. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  192. fides/ui-build/static/admin/dataset/new.html +1 -1
  193. fides/ui-build/static/admin/dataset.html +1 -1
  194. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  195. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  196. fides/ui-build/static/admin/datastore-connection.html +1 -1
  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 -0
  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 -0
  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/service/error_handling/__init__.py +0 -0
  246. fides/service/error_handling/error_handler.py +0 -202
  247. fides/ui-build/static/admin/_next/static/K1_4-1GhwfL7h4fYYQBvB/_buildManifest.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/1099-98458e8e9ff67508.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/1100-4106d99f5e1ebd75.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/1327-92a38135ee8d55ec.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/2310-0d63c66c2685e83c.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/2921-ca04a0476e2e56c5.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/3119-e441b14cdab4320e.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/3426-e49cb4766324b2dd.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/3505-e58b93f9c1cbdcad.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/3513-87b54d931698986f.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/355-e4340980d72b4faa.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/3872-6b828cb00fb2ce93.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/4060-9593a3f98e600487.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/4121-5c3af879cdd8b3be.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/4294-5b3aa9d605217915.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/4481-8398edf74aabb8ea.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/4723-4c3c7a375e998c15.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/5258-e000d07844eccf7e.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/5487-62955c11bab63734.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/5626-1b636798faad78e1.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/5683-44966a05fa5ad566.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/570-c99f07161bd339cd.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/5826-ce34f25ac2eeb807.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/5973-56d90405c3616068.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/6277-c35c8cc806f7571f.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/6834-dcda0a8ed484775e.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/69-dc52e39d26a4ad14.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/6954-d02d474ba30756b2.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/79-e5884e6878fc1bbb.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/7980-e17dda2f50ec76b8.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/8433-a77c2cd1c1a6887e.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/8499-34a34015c91fc38b.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/9327-a25347d72bfbe680.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/9494-0df032fe6ee531a5.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/9676.97fdbec9c2a48c68.js +0 -1
  284. fides/ui-build/static/admin/_next/static/chunks/9767-74320abc2e9a4550.js +0 -1
  285. fides/ui-build/static/admin/_next/static/chunks/pages/404-c00773c4c6e930af.js +0 -1
  286. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-7d789458fb296270.js +0 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-90320455052466cd.js +0 -1
  288. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-a69f8946466471aa.js +0 -1
  289. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/add-vendors-bcc515a765c0119d.js +0 -1
  290. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-49b9f1b56262dfdc.js +0 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-d4137bb7fdc1ac6e.js +0 -1
  292. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-5ef03041a530b0e2.js +0 -1
  293. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/[id]-a5a95ac63b1ce206.js +0 -1
  294. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/new-946ce1a2aa1500d4.js +0 -1
  295. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-12f3ba4609bc2ba5.js +0 -1
  296. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-ffa15d7ff64a9f05.js +0 -1
  297. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-b959d61c2a3682b3.js +0 -1
  298. fides/ui-build/static/admin/_next/static/chunks/pages/consent-7797e367dd946a18.js +0 -1
  299. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-ecf23116a845188a.js +0 -1
  300. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-79f8e613827c55c1.js +0 -1
  301. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-e950d41b75f86c85.js +0 -1
  302. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-84ead584a88ab662.js +0 -1
  303. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-90f1975f559fff3e.js +0 -1
  304. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-4b820a3173f35504.js +0 -1
  305. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-beedbc38ee2b0094.js +0 -1
  306. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-2d6f95b2769a0936.js +0 -1
  307. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-3536ae978741b659.js +0 -1
  308. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-8b5afe14cf42a4ac.js +0 -1
  309. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-b8dca4298b5bb085.js +0 -1
  310. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-1e26702b1a7e0e12.js +0 -1
  311. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-1f0c4e2e5d0b5bf6.js +0 -1
  312. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-ebf54ea9874c59ae.js +0 -1
  313. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-c39e8e2269883796.js +0 -1
  314. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-9db81467fa254996.js +0 -1
  315. fides/ui-build/static/admin/_next/static/chunks/pages/index-868b60407eae35da.js +0 -1
  316. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-ebc41649161f7fb9.js +0 -1
  317. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-b89b9f68ccc69c1b.js +0 -1
  318. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-22812f08e81bd4f3.js +0 -1
  319. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-ca22869201847ccc.js +0 -1
  320. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-5f41afae411cd8a4.js +0 -1
  321. fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-173bd3ad45ea61c6.js +0 -1
  322. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-4dfe984ad80927cd.js +0 -1
  323. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-f790e1ea5cbc26c0.js +0 -1
  324. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-af9e682ec620e990.js +0 -1
  325. fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-6ce407101daa6000.js +0 -1
  326. fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-9ee8cf14a93eaa4a.js +0 -1
  327. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-928430cd40c35ef2.js +0 -1
  328. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-07ef58b04404479d.js +0 -1
  329. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-595ed9f6ca438020.js +0 -1
  330. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-25a3add8e7982e43.js +0 -1
  331. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-b3384299166bcd1e.js +0 -1
  332. fides/ui-build/static/admin/_next/static/chunks/pages/properties/[id]-081f13526443e0a6.js +0 -1
  333. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-17fb474e458b63e7.js +0 -1
  334. fides/ui-build/static/admin/_next/static/chunks/pages/properties-f00530710b699afd.js +0 -1
  335. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6a6016708efb5f4f.js +0 -1
  336. fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-177919b4ccf8f660.js +0 -1
  337. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ba15c12c89ee10f8.js +0 -1
  338. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-0f2daeec241bd1a2.js +0 -1
  339. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-0401208a3128fa4d.js +0 -1
  340. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-0daa256958675a23.js +0 -1
  341. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-26810d1ffedcd156.js +0 -1
  342. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-eb78b645d0c1d4ea.js +0 -1
  343. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-9404a6b0b2951992.js +0 -1
  344. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-0a3aa951ef4a44ba.js +0 -1
  345. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-48be14ad09ed4133.js +0 -1
  346. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-b03403fed4dd8805.js +0 -1
  347. fides/ui-build/static/admin/_next/static/chunks/pages/systems-ae591953b24e2fc9.js +0 -1
  348. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-913efe5371344de6.js +0 -1
  349. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-dc11ba29dbd4708b.js +0 -1
  350. fides/ui-build/static/admin/_next/static/css/92c81f666644c594.css +0 -1
  351. fides/ui-build/static/admin/_next/static/css/b89fc4b36b501cf6.css +0 -1
  352. fides/ui-build/static/admin/_next/static/css/c0c2eb63ad3e7390.css +0 -1
  353. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/WHEEL +0 -0
  354. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/entry_points.txt +0 -0
  355. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/licenses/LICENSE +0 -0
  356. {ethyca_fides-2.62.1rc0.dist-info → ethyca_fides-2.63.0.dist-info}/top_level.txt +0 -0
  357. /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-69176abe09cf9b52.js → new-b124cc24b930c9e1.js} +0 -0
  358. /fides/ui-build/static/admin/_next/static/{K1_4-1GhwfL7h4fYYQBvB → lb6RRZ8JumokYwsENumlw}/_ssgManifest.js +0 -0
@@ -0,0 +1,269 @@
1
+ import json
2
+ from typing import Dict, List
3
+
4
+ from loguru import logger
5
+ from redis.lock import Lock
6
+ from sqlalchemy import text
7
+ from sqlalchemy.orm import Session
8
+
9
+ from fides.api.db.session import get_db_session
10
+ from fides.api.tasks.scheduled.scheduler import scheduler
11
+ from fides.api.util.lock import redis_lock
12
+ from fides.config import CONFIG
13
+
14
+ """
15
+ This utility is used to detect indices or constraints that were deferred as part
16
+ of a standard Fides/Alembic migration.
17
+
18
+ The standard approach for creating indices or constraints on large tables is a blocking operation,
19
+ meaning reads and write can't run while the indices and constraints are being created.
20
+ A non-blocking approach is to use the CONCURRENTLY keyword for index creation then adding
21
+ the constraints with ADD CONSTRAINT USING INDEX.
22
+
23
+ However these approaches cannot run in a transaction, which is what Fides/Alembic uses to
24
+ apply migrations. The approach here is to run these commands after the application has started
25
+ up and commit the changes immediately, outside of a transaction.
26
+
27
+ The commands that need to run are denoted in the `TABLE_OBJECT_MAP`. Indices that are used
28
+ to create constraints also include the `constraint_name` value since either the presence of
29
+ the index or the constraint can be used to determine if an index has executed.
30
+ When using the ADD CONSTRAINT USING INDEX syntax, the index specified in the command is
31
+ automatically renamed to match the name of the constraint being added.
32
+ This means that after the constraint is created, the index will have the same name as the constraint.
33
+ """
34
+
35
+ POST_UPGRADE_INDEX_CREATION = "post_upgrade_index_creation"
36
+
37
+ TABLE_OBJECT_MAP: Dict[str, List[Dict[str, str]]] = {
38
+ "currentprivacypreferencev2": [
39
+ {
40
+ "name": "ix_currentprivacypreferencev2_email_property_id",
41
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_currentprivacypreferencev2_email_property_id ON currentprivacypreferencev2 (email, property_id)",
42
+ "type": "index",
43
+ "constraint_name": "last_saved_for_email_per_property_id",
44
+ },
45
+ {
46
+ "name": "ix_currentprivacypreferencev2_external_id_property_id",
47
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_currentprivacypreferencev2_external_id_property_id ON currentprivacypreferencev2 (external_id, property_id)",
48
+ "type": "index",
49
+ "constraint_name": "last_saved_for_external_id_per_property_id",
50
+ },
51
+ {
52
+ "name": "ix_currentprivacypreferencev2_fides_user_device_property_id",
53
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_currentprivacypreferencev2_fides_user_device_property_id ON currentprivacypreferencev2 (fides_user_device, property_id)",
54
+ "type": "index",
55
+ "constraint_name": "last_saved_for_fides_user_device_per_property_id",
56
+ },
57
+ {
58
+ "name": "ix_currentprivacypreferencev2_phone_number_property_id",
59
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_currentprivacypreferencev2_phone_number_property_id ON currentprivacypreferencev2 (phone_number, property_id)",
60
+ "type": "index",
61
+ "constraint_name": "last_saved_for_phone_number_per_property_id",
62
+ },
63
+ {
64
+ "name": "ix_currentprivacypreferencev2_hashed_external_id",
65
+ "statement": "CREATE INDEX CONCURRENTLY ix_currentprivacypreferencev2_hashed_external_id ON currentprivacypreferencev2 (hashed_external_id)",
66
+ "type": "index",
67
+ },
68
+ {
69
+ "name": "last_saved_for_email_per_property_id",
70
+ "statement": "ALTER TABLE currentprivacypreferencev2 ADD CONSTRAINT last_saved_for_email_per_property_id UNIQUE USING INDEX ix_currentprivacypreferencev2_email_property_id",
71
+ "type": "constraint",
72
+ },
73
+ {
74
+ "name": "last_saved_for_external_id_per_property_id",
75
+ "statement": "ALTER TABLE currentprivacypreferencev2 ADD CONSTRAINT last_saved_for_external_id_per_property_id UNIQUE USING INDEX ix_currentprivacypreferencev2_external_id_property_id",
76
+ "type": "constraint",
77
+ },
78
+ {
79
+ "name": "last_saved_for_fides_user_device_per_property_id",
80
+ "statement": "ALTER TABLE currentprivacypreferencev2 ADD CONSTRAINT last_saved_for_fides_user_device_per_property_id UNIQUE USING INDEX ix_currentprivacypreferencev2_fides_user_device_property_id",
81
+ "type": "constraint",
82
+ },
83
+ {
84
+ "name": "last_saved_for_phone_number_per_property_id",
85
+ "statement": "ALTER TABLE currentprivacypreferencev2 ADD CONSTRAINT last_saved_for_phone_number_per_property_id UNIQUE USING INDEX ix_currentprivacypreferencev2_phone_number_property_id",
86
+ "type": "constraint",
87
+ },
88
+ ],
89
+ "privacypreferencehistory": [
90
+ {
91
+ "name": "ix_privacypreferencehistory_hashed_external_id",
92
+ "statement": "CREATE INDEX CONCURRENTLY ix_privacypreferencehistory_hashed_external_id ON privacypreferencehistory (hashed_external_id)",
93
+ "type": "index",
94
+ },
95
+ ],
96
+ "servednoticehistory": [
97
+ {
98
+ "name": "ix_servednoticehistory_hashed_external_id",
99
+ "statement": "CREATE INDEX CONCURRENTLY ix_servednoticehistory_hashed_external_id ON servednoticehistory (hashed_external_id)",
100
+ "type": "index",
101
+ },
102
+ ],
103
+ "stagedresourceancestor": [
104
+ # primary key index
105
+ {
106
+ "name": "ix_staged_resource_ancestor_pkey",
107
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_staged_resource_ancestor_pkey ON stagedresourceancestor (id)",
108
+ "type": "index",
109
+ },
110
+ # unique constraint + index
111
+ {
112
+ "name": "ix_staged_resource_ancestor_unique",
113
+ "statement": "CREATE UNIQUE INDEX CONCURRENTLY ix_staged_resource_ancestor_unique ON stagedresourceancestor (ancestor_urn, descendant_urn)",
114
+ "type": "index",
115
+ "constraint_name": "uq_staged_resource_ancestor",
116
+ },
117
+ {
118
+ "name": "uq_staged_resource_ancestor",
119
+ "statement": "ALTER TABLE stagedresourceancestor ADD CONSTRAINT uq_staged_resource_ancestor UNIQUE USING INDEX ix_staged_resource_ancestor_unique",
120
+ "type": "constraint",
121
+ },
122
+ # foreign key constraints
123
+ {
124
+ "name": "fk_staged_resource_ancestor_ancestor",
125
+ "statement": "ALTER TABLE stagedresourceancestor ADD CONSTRAINT fk_staged_resource_ancestor_ancestor FOREIGN KEY (ancestor_urn) REFERENCES stagedresource (urn) ON DELETE CASCADE",
126
+ "type": "constraint",
127
+ },
128
+ {
129
+ "name": "fk_staged_resource_ancestor_descendant",
130
+ "statement": "ALTER TABLE stagedresourceancestor ADD CONSTRAINT fk_staged_resource_ancestor_descendant FOREIGN KEY (descendant_urn) REFERENCES stagedresource (urn) ON DELETE CASCADE",
131
+ "type": "constraint",
132
+ },
133
+ # column indexes
134
+ {
135
+ "name": "ix_staged_resource_ancestor_ancestor",
136
+ "statement": "CREATE INDEX CONCURRENTLY ix_staged_resource_ancestor_ancestor ON stagedresourceancestor (ancestor_urn)",
137
+ "type": "index",
138
+ },
139
+ {
140
+ "name": "ix_staged_resource_ancestor_descendant",
141
+ "statement": "CREATE INDEX CONCURRENTLY ix_staged_resource_ancestor_descendant ON stagedresourceancestor (descendant_urn)",
142
+ "type": "index",
143
+ },
144
+ ],
145
+ }
146
+
147
+
148
+ def check_object_exists(db: Session, object_name: str) -> bool:
149
+ """Checks Postgres' system catalogs to verify the existence of a given index or constraint in a specific table."""
150
+ object_query = text(
151
+ """
152
+ SELECT EXISTS (
153
+ SELECT 1
154
+ FROM pg_indexes
155
+ WHERE indexname = :object_name
156
+ ) OR EXISTS (
157
+ SELECT 1
158
+ FROM pg_constraint
159
+ WHERE conname = :object_name
160
+ )
161
+ """
162
+ )
163
+ result = db.execute(
164
+ object_query,
165
+ {
166
+ "object_name": object_name,
167
+ },
168
+ ).scalar()
169
+ return result
170
+
171
+
172
+ def create_object(db: Session, object_statement: str, object_name: str) -> None:
173
+ """Executes the index or constraint creation statement."""
174
+ logger.info(f"Creating index/constraint object: '{object_name}'...")
175
+ with db.bind.connect().execution_options(
176
+ isolation_level="AUTOCOMMIT"
177
+ ) as connection:
178
+ connection.execute(text(object_statement))
179
+ logger.info(f"Successfully created index/constraint object: '{object_name}'")
180
+
181
+
182
+ def check_and_create_objects(
183
+ db: Session, table_object_map: Dict[str, List[Dict[str, str]]], lock: Lock
184
+ ) -> Dict[str, str]:
185
+ """Returns a dictionary of any indices or constraints that were created."""
186
+ object_info: Dict[str, str] = {}
187
+ for _, objects in table_object_map.items():
188
+ for object_data in objects:
189
+ object_name = object_data["name"]
190
+ object_statement = object_data["statement"]
191
+ object_type = object_data["type"]
192
+ object_exists = check_object_exists(db, object_name)
193
+
194
+ if not object_exists:
195
+ if object_type == "index":
196
+ constraint_name = object_data.get("constraint_name")
197
+ if constraint_name:
198
+ constraint_exists = check_object_exists(db, constraint_name)
199
+ if constraint_exists:
200
+ logger.debug(
201
+ f"Constraint {constraint_name} already exists, skipping index creation for {object_name}"
202
+ )
203
+ continue
204
+
205
+ create_object(db, object_statement, object_name)
206
+ object_info[object_name] = "created"
207
+ else:
208
+ logger.debug(
209
+ f"Object {object_name} already exists, skipping index/constraint creation"
210
+ )
211
+ lock.reacquire()
212
+
213
+ return object_info
214
+
215
+
216
+ # Lock key for the post upgrade index creation
217
+ POST_UPGRADE_INDEX_CREATION_LOCK = "post_upgrade_index_creation_lock"
218
+ # The timeout of the lock for the post upgrade index creation, in seconds
219
+ POST_UPGRADE_INDEX_CREATION_LOCK_TIMEOUT_SECONDS = 600 # 10 minutes
220
+
221
+
222
+ def post_upgrade_index_creation_task() -> None:
223
+ """
224
+ Task for creating indices and constraints that were deferred
225
+ as part of a standard Fides/Alembic migration.
226
+
227
+ This task is to be kicked off as a background task during application startup,
228
+ after standard migrations have been applied.
229
+
230
+ If all specified indexes and constraints are created, the task is effectively
231
+ a no-op, as it checks for the presence of the objects in the database before
232
+ creating them.
233
+ """
234
+ with redis_lock(
235
+ POST_UPGRADE_INDEX_CREATION_LOCK,
236
+ POST_UPGRADE_INDEX_CREATION_LOCK_TIMEOUT_SECONDS,
237
+ ) as lock:
238
+ if not lock:
239
+ return
240
+
241
+ SessionLocal = get_db_session(CONFIG)
242
+ with SessionLocal() as db:
243
+ object_info: Dict[str, str] = check_and_create_objects(
244
+ db, TABLE_OBJECT_MAP, lock
245
+ )
246
+ if object_info:
247
+ logger.info(
248
+ f"Post upgrade index creation output: {json.dumps(object_info)}"
249
+ )
250
+ else:
251
+ logger.debug("All indices and constraints already created")
252
+
253
+
254
+ def initiate_post_upgrade_index_creation() -> None:
255
+ """Initiates scheduler to migrate all non-credential tables using a bcrypt hash to use a SHA-256 hash"""
256
+
257
+ if CONFIG.test_mode:
258
+ logger.debug("Skipping post upgrade index creation in test mode")
259
+ return
260
+
261
+ assert (
262
+ scheduler.running
263
+ ), "Scheduler is not running! Cannot migrate tables with bcrypt hashes."
264
+
265
+ logger.info("Initiating scheduler for hash migration")
266
+ scheduler.add_job(
267
+ func=post_upgrade_index_creation_task,
268
+ id=POST_UPGRADE_INDEX_CREATION,
269
+ )
@@ -12,12 +12,14 @@ 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
15
16
  from fides.api.service.storage.s3 import (
16
17
  generic_delete_from_s3,
17
18
  generic_retrieve_from_s3,
18
19
  generic_upload_to_s3,
19
20
  )
20
- from fides.api.service.storage.util import get_local_filename
21
+ from fides.api.service.storage.util import AllowedFileType, get_local_filename
22
+ from fides.config import CONFIG
21
23
 
22
24
  if TYPE_CHECKING:
23
25
  from fides.api.models.comment import Comment
@@ -115,8 +117,13 @@ class Attachment(Base):
115
117
  uselist=False,
116
118
  )
117
119
 
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
+
118
125
  def upload(self, attachment: IO[bytes]) -> None:
119
- """Uploads an attachment to S3 or local storage."""
126
+ """Uploads an attachment to S3, GCS, or local storage."""
120
127
  if self.config.type == StorageType.s3:
121
128
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
122
129
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
@@ -130,6 +137,23 @@ class Attachment(Base):
130
137
  log.info(f"Uploaded {self.file_name} to S3 bucket {bucket_name}/{self.id}")
131
138
  return
132
139
 
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
+
133
157
  if self.config.type == StorageType.local:
134
158
  filename = get_local_filename(f"{self.id}/{self.file_name}")
135
159
 
@@ -164,13 +188,16 @@ class Attachment(Base):
164
188
  self,
165
189
  ) -> Tuple[int, AnyHttpUrlString]:
166
190
  """
167
- Retrieves a the size of the attachment and the presigned URL to retrieve it.
191
+ Retrieves the size of the attachment and a presigned/signed URL.
168
192
  - For s3:
169
193
  - the size is retrieved from the s3 object metadata
170
- - the presigned URL is retrieved from the s3 client
194
+ - returns presigned URL
195
+ - For gcs:
196
+ - the size is retrieved from the blob metadata
197
+ - returns signed URL
171
198
  - For local:
172
199
  - the size is retrieved from the file size
173
- - the URL is the local file path
200
+ - returns the local file path
174
201
  """
175
202
  if self.config.type == StorageType.s3:
176
203
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
@@ -180,19 +207,81 @@ class Attachment(Base):
180
207
  bucket_name=bucket_name,
181
208
  file_key=f"{self.id}/{self.file_name}",
182
209
  auth_method=auth_method,
210
+ get_content=False,
183
211
  )
184
212
  return size, url
185
213
 
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
+
186
274
  if self.config.type == StorageType.local:
187
275
  filename = get_local_filename(f"{self.id}/{self.file_name}")
188
276
  with open(filename, "rb") as file:
189
- size = len(file.read())
190
- return size, filename
277
+ content = file.read()
278
+ size = len(content)
279
+ return size, content
191
280
 
192
281
  raise ValueError(f"Unsupported storage type: {self.config.type}")
193
282
 
194
283
  def delete_attachment_from_storage(self) -> None:
195
- """Deletes an attachment from S3 or local storage."""
284
+ """Deletes an attachment from S3, GCS, or local storage."""
196
285
  if self.config.type == StorageType.s3:
197
286
  bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
198
287
  auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
@@ -204,9 +293,27 @@ class Attachment(Base):
204
293
  )
205
294
  return
206
295
 
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
+
207
309
  if self.config.type == StorageType.local:
208
- filename = get_local_filename(f"{self.id}/{self.file_name}")
209
- os.remove(filename)
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)
210
317
  return
211
318
 
212
319
  raise ValueError(f"Unsupported storage type: {self.config.type}")
@@ -11,9 +11,6 @@ class AuditLogAction(str, EnumType):
11
11
  """Enum for audit log actions, reflecting what a user did."""
12
12
 
13
13
  approved = "approved"
14
- attachment_uploaded = "attachment_uploaded"
15
- attachment_deleted = "attachment_deleted"
16
- attachment_retrieved = "attachment_retrieved"
17
14
  denied = "denied"
18
15
  email_sent = "email_sent"
19
16
  finished = "finished"