ethyca-fides 2.56.2rc3__py2.py3-none-any.whl → 2.56.3b0__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 (311) hide show
  1. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/METADATA +1 -2
  2. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/RECORD +221 -217
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/3c58001ad310_add_messages_to_monitor_execution.py +32 -0
  5. fides/api/alembic/migrations/versions/bd875a8b5d96_add_attachments_and_.py +96 -0
  6. fides/api/api/v1/endpoints/privacy_request_endpoints.py +2 -14
  7. fides/api/graph/node_filters.py +112 -5
  8. fides/api/graph/traversal.py +34 -4
  9. fides/api/models/attachment.py +153 -0
  10. fides/api/models/audit_log.py +3 -0
  11. fides/api/models/detection_discovery.py +7 -0
  12. fides/api/models/privacy_request.py +26 -3
  13. fides/api/task/create_request_tasks.py +27 -9
  14. fides/api/task/deprecated_graph_task.py +28 -10
  15. fides/api/util/logger.py +19 -1
  16. fides/config/execution_settings.py +1 -1
  17. fides/data/sample_project/sample_connections/sample_connections.yml +29 -29
  18. fides/service/dataset/dataset_config_service.py +4 -2
  19. fides/service/privacy_request/privacy_request_service.py +32 -14
  20. fides/ui-build/static/admin/404.html +1 -1
  21. fides/ui-build/static/admin/_next/static/chunks/1150-73440d7b319558e8.js +1 -0
  22. fides/ui-build/static/admin/_next/static/chunks/2201-abd6092e6df98c26.js +1 -0
  23. fides/ui-build/static/admin/_next/static/chunks/{5728-7be08c654c024baa.js → 2397-7177ecf4ebe68feb.js} +1 -1
  24. fides/ui-build/static/admin/_next/static/chunks/{255-69ac1bcb5a52b022.js → 255-bf1797f78249d090.js} +1 -1
  25. fides/ui-build/static/admin/_next/static/chunks/{3005-137ef60b77c71ce1.js → 3005-373de16453ed7eea.js} +1 -1
  26. fides/ui-build/static/admin/_next/static/chunks/3086-be6b52546c3efc90.js +1 -0
  27. fides/ui-build/static/admin/_next/static/chunks/3320-87c75df57a47487e.js +1 -0
  28. fides/ui-build/static/admin/_next/static/chunks/{5318-1bfde23609ea3718.js → 3627-fb83adac32c128e6.js} +1 -1
  29. fides/ui-build/static/admin/_next/static/chunks/3662-420d9807c30008ab.js +1 -0
  30. fides/ui-build/static/admin/_next/static/chunks/3855-5c7b11871f59e0e0.js +1 -0
  31. fides/ui-build/static/admin/_next/static/chunks/{4456-67c8d5b2d96dea1d.js → 3872-f3d5054bdc584eaa.js} +1 -1
  32. fides/ui-build/static/admin/_next/static/chunks/{8141-55187bd207f5ea9e.js → 3949-9888699e2ac564c4.js} +1 -1
  33. fides/ui-build/static/admin/_next/static/chunks/{4294-3e67d7ef3d390c2f.js → 4294-5b3aa9d605217915.js} +1 -1
  34. fides/ui-build/static/admin/_next/static/chunks/4481-ca8d2c75d634b6bc.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/4723-81d28e5be5c7b6d7.js +1 -0
  36. fides/ui-build/static/admin/_next/static/chunks/5246-9fc6af1a6499e0a4.js +1 -0
  37. fides/ui-build/static/admin/_next/static/chunks/5258-3a650be9142cf914.js +1 -0
  38. fides/ui-build/static/admin/_next/static/chunks/5480-f5bec5e881f72f8d.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/5487-d96e1abc93f92631.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/5826-16e497af363a0cbc.js +1 -0
  41. fides/ui-build/static/admin/_next/static/chunks/5908-532dfbc9d930f635.js +1 -0
  42. fides/ui-build/static/admin/_next/static/chunks/5960-8895f51b30c35798.js +1 -0
  43. fides/ui-build/static/admin/_next/static/chunks/{618f8807-5792121b4eda076b.js → 618f8807-d15c33d1d6c8b961.js} +1 -1
  44. fides/ui-build/static/admin/_next/static/chunks/6277-b55810d66362f56e.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/6315-dee79f6861c94d2d.js +1 -0
  46. fides/ui-build/static/admin/_next/static/chunks/6362-8f79e403fdc2404a.js +1 -0
  47. fides/ui-build/static/admin/_next/static/chunks/{5632-b98308c17b9cd230.js → 6372-f1b54f3cb4888660.js} +1 -1
  48. fides/ui-build/static/admin/_next/static/chunks/{6834-5082b5702e80b531.js → 6834-dcda0a8ed484775e.js} +1 -1
  49. fides/ui-build/static/admin/_next/static/chunks/6853-cacea421af3bfc26.js +1 -0
  50. fides/ui-build/static/admin/_next/static/chunks/6954-6eb480eb132239c3.js +1 -0
  51. fides/ui-build/static/admin/_next/static/chunks/7044-9dc90893067f38ae.js +1 -0
  52. fides/ui-build/static/admin/_next/static/chunks/7495-a61f0c9fcb458664.js +1 -0
  53. fides/ui-build/static/admin/_next/static/chunks/{7548-b3992b0c7fb852c9.js → 7751-25e0c1307988ffd7.js} +1 -1
  54. fides/ui-build/static/admin/_next/static/chunks/79-ba88d0cf4c65aaa2.js +1 -0
  55. fides/ui-build/static/admin/_next/static/chunks/{5973-c0b74d6cf14833cb.js → 7980-2597c279c30fbcda.js} +1 -1
  56. fides/ui-build/static/admin/_next/static/chunks/8433-969280d321d1c3a2.js +1 -0
  57. fides/ui-build/static/admin/_next/static/chunks/8499-07507004e8275df2.js +1 -0
  58. fides/ui-build/static/admin/_next/static/chunks/{8837-2b785a4e5bad4813.js → 8837-cf26e5ca1ae5aaf5.js} +1 -1
  59. fides/ui-build/static/admin/_next/static/chunks/9046-80f1ea44f89fe32c.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/{9255-2b1bafefb091a640.js → 9255-336a890ada321f89.js} +1 -1
  61. fides/ui-build/static/admin/_next/static/chunks/9282-1a5a2f6f4d9ed586.js +1 -0
  62. fides/ui-build/static/admin/_next/static/chunks/{2800.40212c25719a2351.js → 9392.97b2e3327dceb7c9.js} +1 -1
  63. fides/ui-build/static/admin/_next/static/chunks/9676.f4d5977a5f148797.js +1 -0
  64. fides/ui-build/static/admin/_next/static/chunks/9999-f2e40d5b13343220.js +1 -0
  65. fides/ui-build/static/admin/_next/static/chunks/main-app-2650f704701c6a7b.js +1 -0
  66. fides/ui-build/static/admin/_next/static/chunks/main-ce7f38a12ea8c223.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/pages/404-1087258931760074.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-8021f4b202818ba2.js → _app-54e64129c5f3042a.js} +14 -14
  69. fides/ui-build/static/admin/_next/static/chunks/pages/{_error-c91b5eabd7ac9382.js → _error-bede3a8288930dcf.js} +1 -1
  70. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-d7f60624cbc12217.js +1 -0
  71. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-17b38b57adc62ed2.js → multiple-18b0b521255289a3.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-136bcbd20ac59bf5.js +1 -0
  73. fides/ui-build/static/admin/_next/static/chunks/pages/ant-poc-b3b4d0a98450ffd1.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-7469901adf64d0e2.js → add-vendors-64f83e9a2b777bf3.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-e11ace4f273ebb47.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-fdbafb5a47a6a28c.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/new-fc4635c6eea7165f.js +1 -0
  78. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-35e9df60b21e21a6.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-a2713f5a7a2c45e5.js → [id]-bdc686761a0d2d60.js} +1 -1
  80. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-b67c3c8c25e7051b.js → new-8618ab5fa45cd074.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-da37afbe5ec81339.js +1 -0
  82. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-c57b209feef7c2da.js +1 -0
  83. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-97fea4ac45093cbd.js +1 -0
  84. fides/ui-build/static/admin/_next/static/chunks/pages/{consent-a3233ad24a82465a.js → consent-24bef021ee71e36c.js} +1 -1
  85. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-6cbd79481199812d.js +1 -0
  86. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-46b9790da2fec05a.js +1 -0
  87. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-1f965b9c496071d1.js +1 -0
  88. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-e7833c1c606081a9.js +1 -0
  89. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-6563b9d6f77d0690.js → resources-bed368d048ea6883.js} +1 -1
  90. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-942d68a88b321067.js +1 -0
  91. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-00526324583139ab.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/{[monitorId]-8e6f4b1b5b89aff0.js → [monitorId]-f0ab51d0d5f995de.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-a6a9bbfac5ca8d0b.js → action-center-2220c30c3863b5a5.js} +1 -1
  94. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-1d7936f05d23097f.js +1 -0
  95. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-c575c057b35b958e.js → [resourceUrn]-68122dbf449a11b4.js} +1 -1
  96. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-c1d2018f3ab3e39c.js → detection-0ceaf3c555e84714.js} +1 -1
  97. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/[resourceUrn]-22c27fe0f898ad2a.js +1 -0
  98. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery-8f2b102e19b0b8f2.js +1 -0
  99. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-9cd0c40bef77b120.js +1 -0
  100. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-ab9bc1a3640547db.js +1 -0
  101. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-17ec8385bb1fa6d4.js +1 -0
  102. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e14c1c07658f8a10.js +1 -0
  103. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-fc00dbeb18a7b731.js +1 -0
  104. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-295756e1fd640b59.js +1 -0
  105. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-a6e793e9a8ed00a9.js +1 -0
  106. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-7d314bb7238af067.js +1 -0
  107. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-b8eaa9b9d3832b30.js +1 -0
  108. fides/ui-build/static/admin/_next/static/chunks/pages/index-c9fa68dc0fa42c81.js +1 -0
  109. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-20489bceb7b068b8.js +1 -0
  110. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-21c9902e7b098b39.js +1 -0
  111. fides/ui-build/static/admin/_next/static/chunks/pages/login/{[provider]-cac9584cefa85a09.js → [provider]-c58beef131c3a82d.js} +1 -1
  112. fides/ui-build/static/admin/_next/static/chunks/pages/{login-e55849091751c65a.js → login-0cb0eb44bf2dd24c.js} +1 -1
  113. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-6b032de0a6c2c400.js +1 -0
  114. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-c0d6ae68ff7979c6.js +1 -0
  115. fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-910372bec245ba5d.js → messaging-f263e6bacf0f2d19.js} +1 -1
  116. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-c685d19a131d6960.js +1 -0
  117. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-b96ee3fea3920fcf.js +1 -0
  118. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-1b0f9469cb65abfc.js +1 -0
  119. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-e0ca944878ef12e8.js → configure-4bad69cd42c9722c.js} +1 -1
  120. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-eebd2f4ead19cfd6.js +1 -0
  121. fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-e780943ac4ce5bf1.js → [id]-b4c808a8a0287d11.js} +1 -1
  122. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-5a701477b006a63b.js +1 -0
  123. fides/ui-build/static/admin/_next/static/chunks/pages/properties-9a1899dfe052023e.js +1 -0
  124. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-a3fa3ad77730a03b.js +1 -0
  125. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-bfe2495fb54933ee.js → about-d073be113e9ca7b0.js} +1 -1
  126. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-815497f4f12600ec.js +1 -0
  127. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-744e7bbc200557e7.js +1 -0
  128. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-c5cd5fb578de9515.js +1 -0
  129. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-775f55b3f80cd452.js +1 -0
  130. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-39c7ae3602ac69b2.js +1 -0
  131. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-45e33ba111f8f8b0.js +1 -0
  132. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-14def4ca3cc9cda5.js +1 -0
  133. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-94975aeab348528e.js +1 -0
  134. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-21f26c0dc4d09e9f.js +1 -0
  135. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-c6396feeefca887b.js +1 -0
  136. fides/ui-build/static/admin/_next/static/chunks/pages/systems-c320df35d51dc537.js +1 -0
  137. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-181ea5b0ac975239.js +1 -0
  138. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/new-d6717378b42982d5.js +1 -0
  139. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-622e16a17a11c096.js +1 -0
  140. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-aa872b21bb835d34.js +1 -0
  141. fides/ui-build/static/admin/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  142. fides/ui-build/static/admin/_next/static/chunks/{webpack-c51aa6524c2716b8.js → webpack-4df2ba5ee2d40f0a.js} +1 -1
  143. fides/ui-build/static/admin/_next/static/css/15fb7d4837a1de34.css +1 -0
  144. fides/ui-build/static/admin/_next/static/css/bd5a72c010fa9c14.css +1 -0
  145. fides/ui-build/static/admin/_next/static/o6oSu0mrMicc3b7f8nyq5/_buildManifest.js +1 -0
  146. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  147. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  148. fides/ui-build/static/admin/add-systems.html +1 -1
  149. fides/ui-build/static/admin/ant-poc.html +1 -1
  150. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  151. fides/ui-build/static/admin/consent/configure.html +1 -1
  152. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  153. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  154. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  155. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  156. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  157. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  158. fides/ui-build/static/admin/consent/properties.html +1 -1
  159. fides/ui-build/static/admin/consent/reporting.html +1 -1
  160. fides/ui-build/static/admin/consent.html +1 -1
  161. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  162. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  163. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  164. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  165. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  166. fides/ui-build/static/admin/data-catalog.html +1 -1
  167. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  168. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  169. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  170. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  171. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  172. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  173. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  174. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  175. fides/ui-build/static/admin/datamap.html +1 -1
  176. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  177. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  178. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  179. fides/ui-build/static/admin/dataset/new.html +1 -1
  180. fides/ui-build/static/admin/dataset.html +1 -1
  181. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  182. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  183. fides/ui-build/static/admin/datastore-connection.html +1 -1
  184. fides/ui-build/static/admin/index.html +1 -1
  185. fides/ui-build/static/admin/integrations/[id].html +1 -1
  186. fides/ui-build/static/admin/integrations.html +1 -1
  187. fides/ui-build/static/admin/login/[provider].html +1 -1
  188. fides/ui-build/static/admin/login.html +1 -1
  189. fides/ui-build/static/admin/messaging/[id].html +1 -1
  190. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  191. fides/ui-build/static/admin/messaging.html +1 -1
  192. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  193. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  194. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  195. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  196. fides/ui-build/static/admin/privacy-requests.html +1 -1
  197. fides/ui-build/static/admin/properties/[id].html +1 -1
  198. fides/ui-build/static/admin/properties/add-property.html +1 -1
  199. fides/ui-build/static/admin/properties.html +1 -1
  200. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  201. fides/ui-build/static/admin/settings/about.html +1 -1
  202. fides/ui-build/static/admin/settings/consent.html +1 -1
  203. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  204. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  205. fides/ui-build/static/admin/settings/domains.html +1 -1
  206. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  207. fides/ui-build/static/admin/settings/locations.html +1 -1
  208. fides/ui-build/static/admin/settings/organization.html +1 -1
  209. fides/ui-build/static/admin/settings/regulations.html +1 -1
  210. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  211. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  212. fides/ui-build/static/admin/systems.html +1 -1
  213. fides/ui-build/static/admin/taxonomy.html +1 -1
  214. fides/ui-build/static/admin/user-management/new.html +1 -1
  215. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  216. fides/ui-build/static/admin/user-management.html +1 -1
  217. fides/ui-build/static/admin/_next/static/_A05_bEFykI6pEGrDmq4n/_buildManifest.js +0 -1
  218. fides/ui-build/static/admin/_next/static/chunks/1241-5f9673b3a7fd9469.js +0 -1
  219. fides/ui-build/static/admin/_next/static/chunks/1288-84c330c47e031622.js +0 -1
  220. fides/ui-build/static/admin/_next/static/chunks/1827-db04b6d4756e3a25.js +0 -1
  221. fides/ui-build/static/admin/_next/static/chunks/2017-99f489b3e0279798.js +0 -1
  222. fides/ui-build/static/admin/_next/static/chunks/2025-b6a78063b47b0607.js +0 -1
  223. fides/ui-build/static/admin/_next/static/chunks/2163-9631ae84deb6560b.js +0 -1
  224. fides/ui-build/static/admin/_next/static/chunks/2556-1d0c02e14299bf23.js +0 -1
  225. fides/ui-build/static/admin/_next/static/chunks/2973-2d9d761cc3aeda1d.js +0 -1
  226. fides/ui-build/static/admin/_next/static/chunks/3163-5fe20dd3d43cef46.js +0 -1
  227. fides/ui-build/static/admin/_next/static/chunks/3309-db63287718ef9694.js +0 -1
  228. fides/ui-build/static/admin/_next/static/chunks/3528-30fc61a98d99a66b.js +0 -1
  229. fides/ui-build/static/admin/_next/static/chunks/3990-146beccde8afea98.js +0 -1
  230. fides/ui-build/static/admin/_next/static/chunks/4321-1bf69f1e83baf995.js +0 -1
  231. fides/ui-build/static/admin/_next/static/chunks/4981-8d81ec3b6031f0f9.js +0 -1
  232. fides/ui-build/static/admin/_next/static/chunks/53-eb32dc5d8571cb7b.js +0 -1
  233. fides/ui-build/static/admin/_next/static/chunks/6182-1949666cc9179015.js +0 -1
  234. fides/ui-build/static/admin/_next/static/chunks/637-3f7f3e47e69e75fe.js +0 -1
  235. fides/ui-build/static/admin/_next/static/chunks/6546-aa6826fdd0356505.js +0 -1
  236. fides/ui-build/static/admin/_next/static/chunks/7080-051d67719049e77a.js +0 -1
  237. fides/ui-build/static/admin/_next/static/chunks/7269-aaa4ad906c8bf8f7.js +0 -1
  238. fides/ui-build/static/admin/_next/static/chunks/7528.dff66491009d309b.js +0 -1
  239. fides/ui-build/static/admin/_next/static/chunks/7636-b2dadd026c1fe754.js +0 -1
  240. fides/ui-build/static/admin/_next/static/chunks/7871-0a9b00bc8760d091.js +0 -1
  241. fides/ui-build/static/admin/_next/static/chunks/7996-23e83b8ca562a06c.js +0 -1
  242. fides/ui-build/static/admin/_next/static/chunks/8001-3fdc7b543233f717.js +0 -1
  243. fides/ui-build/static/admin/_next/static/chunks/8540-a7c91bdbe1bb48fb.js +0 -1
  244. fides/ui-build/static/admin/_next/static/chunks/8986-c24a626d90c8be1d.js +0 -1
  245. fides/ui-build/static/admin/_next/static/chunks/9659-478f2eaaf48a8943.js +0 -1
  246. fides/ui-build/static/admin/_next/static/chunks/9822-88b7435d5868e1ef.js +0 -1
  247. fides/ui-build/static/admin/_next/static/chunks/main-6880a3888740c515.js +0 -1
  248. fides/ui-build/static/admin/_next/static/chunks/main-app-de538a24cbd2733c.js +0 -1
  249. fides/ui-build/static/admin/_next/static/chunks/pages/404-5c601b7b9c17b770.js +0 -1
  250. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-2bfb79fc5d16caa4.js +0 -1
  251. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-4e54aefa8b7f554f.js +0 -1
  252. fides/ui-build/static/admin/_next/static/chunks/pages/ant-poc-6048ddeee842c93b.js +0 -1
  253. fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-833ab451ff99ba12.js +0 -1
  254. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-b796be4c70e08aa0.js +0 -1
  255. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/new-35bc7b42751bb78a.js +0 -1
  256. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-089a73cd8a34dbec.js +0 -1
  257. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-cfe92d1c2e95d917.js +0 -1
  258. fides/ui-build/static/admin/_next/static/chunks/pages/consent/properties-059c82d3b8ccdaf6.js +0 -1
  259. fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-54c762b6fe38c20e.js +0 -1
  260. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-e1bd1bdd2c310ecc.js +0 -1
  261. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-c9032d9e0c1dfe1a.js +0 -1
  262. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-62087de19ac179b3.js +0 -1
  263. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-c7614c7742e41151.js +0 -1
  264. fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-9b33b5875445751e.js +0 -1
  265. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-c299a8bd5e1c1def.js +0 -1
  266. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-a9a864cb621d65c6.js +0 -1
  267. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/[resourceUrn]-9ae2adfc68b95d78.js +0 -1
  268. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery-a617ddfa3dfdab23.js +0 -1
  269. fides/ui-build/static/admin/_next/static/chunks/pages/datamap-6a0e22b9ce8f5332.js +0 -1
  270. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-3e506baace396803.js +0 -1
  271. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-6bb9fbe3d41c3127.js +0 -1
  272. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-a358b344095573a9.js +0 -1
  273. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-b328f9aab79dd734.js +0 -1
  274. fides/ui-build/static/admin/_next/static/chunks/pages/dataset-3c0b2ccfa442b79d.js +0 -1
  275. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-102772521ee4a69a.js +0 -1
  276. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-754926e02c1e0ab0.js +0 -1
  277. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-1e81b412b5837755.js +0 -1
  278. fides/ui-build/static/admin/_next/static/chunks/pages/index-aa7b15f51ccbdf8b.js +0 -1
  279. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-2436e6c6406e5f4f.js +0 -1
  280. fides/ui-build/static/admin/_next/static/chunks/pages/integrations-b6c0f9648f6fa298.js +0 -1
  281. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-d1e96f12c1a12d4d.js +0 -1
  282. fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-3ff3a7c3c76a208e.js +0 -1
  283. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-7b13b42d1b23f93b.js +0 -1
  284. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-6971c7e98c00390a.js +0 -1
  285. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-71386e3e260a9220.js +0 -1
  286. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-be0c167fa1565e38.js +0 -1
  287. fides/ui-build/static/admin/_next/static/chunks/pages/properties/add-property-fc660bc2a3641cd3.js +0 -1
  288. fides/ui-build/static/admin/_next/static/chunks/pages/properties-1a35fd97f2510989.js +0 -1
  289. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-b9fe3f3bb16a14eb.js +0 -1
  290. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-7eec113882c35c3f.js +0 -1
  291. fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-aaf29e3dd2c7e955.js +0 -1
  292. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-8b7e71fe1307c5a3.js +0 -1
  293. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-0b9e78e671540cef.js +0 -1
  294. fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-eb04e1584d98edb3.js +0 -1
  295. fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-195f7ddfc3768ece.js +0 -1
  296. fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-22cb683d203ea7fb.js +0 -1
  297. fides/ui-build/static/admin/_next/static/chunks/pages/settings/regulations-3eede241c9df1476.js +0 -1
  298. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-54d7c6fcc4c79635.js +0 -1
  299. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-8271db0c80e6e154.js +0 -1
  300. fides/ui-build/static/admin/_next/static/chunks/pages/systems-7d81df09a0b4eb23.js +0 -1
  301. fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-7abe76200e4519d8.js +0 -1
  302. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/new-a59a02634d672703.js +0 -1
  303. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-269b17114579510b.js +0 -1
  304. fides/ui-build/static/admin/_next/static/chunks/pages/user-management-f7e75911c071a20e.js +0 -1
  305. fides/ui-build/static/admin/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js +0 -1
  306. fides/ui-build/static/admin/_next/static/css/918de8c66b18ce6b.css +0 -1
  307. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/LICENSE +0 -0
  308. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/WHEEL +0 -0
  309. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/entry_points.txt +0 -0
  310. {ethyca_fides-2.56.2rc3.dist-info → ethyca_fides-2.56.3b0.dist-info}/top_level.txt +0 -0
  311. /fides/ui-build/static/admin/_next/static/{_A05_bEFykI6pEGrDmq4n → o6oSu0mrMicc3b7f8nyq5}/_ssgManifest.js +0 -0
fides/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-03-10T02:03:21-0400",
11
+ "date": "2025-03-10T08:30:39-0400",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "9880864b483d2a61286e5e387cc99fa99f3098f1",
15
- "version": "2.56.2rc3"
14
+ "full-revisionid": "fb9dcf03471ea234b9b23a5925590aa995bdb8f5",
15
+ "version": "2.56.3b0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,32 @@
1
+ """add errors to monitor execution
2
+
3
+ Revision ID: 3c58001ad310
4
+ Revises: bd875a8b5d96
5
+ Create Date: 2025-02-27 20:45:38.462604
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "3c58001ad310"
14
+ down_revision = "bd875a8b5d96"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ op.add_column(
21
+ "monitorexecution",
22
+ sa.Column(
23
+ "messages",
24
+ sa.ARRAY(sa.String()),
25
+ nullable=False,
26
+ server_default="{}",
27
+ ),
28
+ )
29
+
30
+
31
+ def downgrade() -> None:
32
+ op.drop_column("monitorexecution", "messages")
@@ -0,0 +1,96 @@
1
+ """Add Attachment and AttachmentReference tables
2
+
3
+ Revision ID: bd875a8b5d96
4
+ Revises: 82883b0df5e4
5
+ Create Date: 2025-02-19 14:09:07.124680
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+ from sqlalchemy.dialects import postgresql
12
+
13
+ # revision identifiers, used by Alembic.
14
+ revision = "bd875a8b5d96"
15
+ down_revision = "82883b0df5e4"
16
+ branch_labels = None
17
+ depends_on = None
18
+
19
+
20
+ def upgrade():
21
+ # ### commands auto generated by Alembic - please adjust! ###
22
+ # create attachment table
23
+ op.create_table(
24
+ "attachment",
25
+ sa.Column("id", sa.String(length=255), nullable=False),
26
+ sa.Column("user_id", sa.String(), nullable=True),
27
+ sa.Column("file_name", sa.String(), nullable=False),
28
+ sa.Column("attachment_type", sa.String(), nullable=False),
29
+ sa.Column("storage_key", sa.String(), nullable=False),
30
+ sa.Column(
31
+ "created_at",
32
+ sa.DateTime(timezone=True),
33
+ server_default=sa.text("now()"),
34
+ nullable=False,
35
+ ),
36
+ sa.Column(
37
+ "updated_at",
38
+ sa.DateTime(timezone=True),
39
+ server_default=sa.text("now()"),
40
+ nullable=True,
41
+ ),
42
+ sa.ForeignKeyConstraint(
43
+ ["user_id"],
44
+ ["fidesuser.id"],
45
+ ondelete="SET NULL",
46
+ ),
47
+ sa.PrimaryKeyConstraint("id"),
48
+ )
49
+ op.create_index(op.f("ix_attachment_id"), "attachment", ["id"], unique=False)
50
+
51
+ # create attachment_reference table
52
+ op.create_table(
53
+ "attachment_reference",
54
+ sa.Column("id", sa.String(length=255), nullable=False),
55
+ sa.Column(
56
+ "created_at",
57
+ sa.DateTime(timezone=True),
58
+ server_default=sa.text("now()"),
59
+ nullable=False,
60
+ ),
61
+ sa.Column(
62
+ "updated_at",
63
+ sa.DateTime(timezone=True),
64
+ server_default=sa.text("now()"),
65
+ nullable=True,
66
+ ),
67
+ sa.Column("attachment_id", sa.String(), nullable=False),
68
+ sa.Column("reference_id", sa.String(), nullable=False),
69
+ sa.Column("reference_type", sa.String(), nullable=False),
70
+ sa.ForeignKeyConstraint(
71
+ ["attachment_id"],
72
+ ["attachment.id"],
73
+ ),
74
+ sa.PrimaryKeyConstraint("id"),
75
+ )
76
+ op.create_index(
77
+ op.f("ix_attachment_reference_id"),
78
+ "attachment_reference",
79
+ ["id"],
80
+ unique=False,
81
+ )
82
+ op.create_unique_constraint(
83
+ "_attachment_reference_uc",
84
+ "attachment_reference",
85
+ ["attachment_id", "reference_id"],
86
+ )
87
+ # ### end Alembic commands ###
88
+
89
+
90
+ def downgrade():
91
+ # ### commands auto generated by Alembic - please adjust! ###
92
+ op.drop_index(op.f("ix_attachment_reference_id"), table_name="attachment_reference")
93
+ op.drop_table("attachment_reference")
94
+ op.drop_index(op.f("ix_attachment_id"), table_name="attachment")
95
+ op.drop_table("attachment")
96
+ # ### end Alembic commands ###
@@ -174,7 +174,7 @@ from fides.service.privacy_request.privacy_request_service import (
174
174
  PrivacyRequestService,
175
175
  _process_privacy_request_restart,
176
176
  _requeue_privacy_request,
177
- _trigger_pre_approval_webhooks,
177
+ handle_approval,
178
178
  queue_privacy_request,
179
179
  )
180
180
 
@@ -1310,19 +1310,7 @@ def verify_identification_code(
1310
1310
 
1311
1311
  logger.info("Identity verified for {}.", privacy_request.id)
1312
1312
 
1313
- if config_proxy.execution.require_manual_request_approval:
1314
- _trigger_pre_approval_webhooks(db, privacy_request)
1315
- else:
1316
- AuditLog.create(
1317
- db=db,
1318
- data={
1319
- "user_id": "system",
1320
- "privacy_request_id": privacy_request.id,
1321
- "action": AuditLogAction.approved,
1322
- "message": "",
1323
- },
1324
- )
1325
- queue_privacy_request(privacy_request.id)
1313
+ handle_approval(db, config_proxy, privacy_request)
1326
1314
 
1327
1315
  return privacy_request # type: ignore[return-value]
1328
1316
 
@@ -1,19 +1,27 @@
1
- from typing import TYPE_CHECKING, Optional, Protocol
1
+ from abc import ABC, abstractmethod
2
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set
2
3
 
4
+ from fides.api.common_exceptions import TraversalError, UnreachableNodesError
5
+ from fides.api.graph.graph import DatasetGraph
3
6
  from fides.api.models.policy import Policy
7
+ from fides.api.util.logger import suppress_logging
4
8
 
5
9
  if TYPE_CHECKING:
6
10
  from fides.api.graph.traversal import TraversalNode
7
11
 
8
12
 
9
- class NodeFilter(Protocol):
10
- """Protocol for node filters that determine if nodes should be excluded from traversal"""
13
+ class NodeFilter(ABC):
14
+ """Abstract base class for node filters that determine if nodes should be excluded from traversal"""
11
15
 
16
+ def __init__(self) -> None:
17
+ self.skipped_nodes: Dict[str, str] = {}
18
+
19
+ @abstractmethod
12
20
  def exclude_node(self, node: "TraversalNode") -> bool:
13
21
  """Returns True if the node should be excluded from traversal requirements"""
14
22
 
15
23
 
16
- class CustomRequestFieldFilter:
24
+ class CustomRequestFieldFilter(NodeFilter):
17
25
  """
18
26
  Remove nodes that have custom request fields, since we don't care if these are reachable or not.
19
27
  They will be used independently by the Dynamic Email Erasure Connector.
@@ -26,16 +34,115 @@ class CustomRequestFieldFilter:
26
34
  return bool(node.node.collection.custom_request_fields())
27
35
 
28
36
 
29
- class PolicyDataCategoryFilter:
37
+ class PolicyDataCategoryFilter(NodeFilter):
30
38
  """
31
39
  If a policy is provided, we will allow collections without relevant
32
40
  data categories to remain unreachable without raising any exceptions.
33
41
  """
34
42
 
35
43
  def __init__(self, policy: Optional[Policy]):
44
+ super().__init__()
36
45
  self.policy = policy
37
46
 
38
47
  def exclude_node(self, node: "TraversalNode") -> bool:
39
48
  if not self.policy:
40
49
  return False
41
50
  return not self.policy.applies_to(node)
51
+
52
+
53
+ class OptionalIdentityFilter(NodeFilter):
54
+
55
+ def __init__(self, graph: DatasetGraph, identities: Dict[str, Any]):
56
+ """
57
+ Filter that excludes nodes that are reachable by an optional identity.
58
+ This prevents traversal errors for nodes that would be reachable if the required identities were provided.
59
+ """
60
+
61
+ super().__init__()
62
+ self.graph = graph
63
+ self.identities = identities
64
+ self.skipped_nodes: Dict[str, str] = {}
65
+
66
+ # Pre-compute which nodes are reachable with each identity
67
+ self.reachable_by_identity: Dict[str, Set[str]] = {}
68
+
69
+ # Get all collection addresses as strings
70
+ all_collection_addresses = {str(addr) for addr in graph.nodes.keys()}
71
+
72
+ # Test reachability with each possible identity seed
73
+ for identity_key in graph.identity_keys.values():
74
+ self._compute_reachable_nodes(identity_key, all_collection_addresses)
75
+
76
+ def exclude_node(self, node: "TraversalNode") -> bool:
77
+ """
78
+ Exclude nodes that are reachable by any identity, provided or optional.
79
+ Nodes (collections) not reachable by any identities should not be excluded and still be considered an error.
80
+ """
81
+ node_address = str(node.address)
82
+
83
+ # Check if node is reachable by any provided identity
84
+ for identity_key in self.identities:
85
+ if node_address in self.reachable_by_identity.get(identity_key, set()):
86
+ return True
87
+
88
+ # Find all optional identities that can reach this node
89
+ reaching_identities = []
90
+ for identity_key, reachable_nodes in self.reachable_by_identity.items():
91
+ if identity_key not in self.identities and node_address in reachable_nodes:
92
+ reaching_identities.append(identity_key)
93
+
94
+ # If any optional identities can reach this node, record them and exclude
95
+ if reaching_identities:
96
+ self.skipped_nodes[node_address] = self._format_skip_message(
97
+ node.address.value, reaching_identities
98
+ )
99
+ return True
100
+
101
+ # Node isn't reachable by any identity, don't exclude it (will be an error)
102
+ return False
103
+
104
+ def _compute_reachable_nodes(
105
+ self, identity_key: str, all_addresses: Set[str]
106
+ ) -> None:
107
+ """Helper method to compute which nodes are reachable with a given identity key"""
108
+
109
+ from fides.api.graph.traversal import BaseTraversal
110
+
111
+ try:
112
+ # Create a traversal object with just this identity
113
+ with suppress_logging():
114
+ # Suppress the logs since we don't want to flood the logs
115
+ # with traversal info for each identity we want to evaluate
116
+ BaseTraversal(self.graph, {identity_key: "dummy_value"})
117
+
118
+ # If successful, all nodes are reachable
119
+ self.reachable_by_identity[identity_key] = all_addresses
120
+ except UnreachableNodesError as exc:
121
+ # Get reachable nodes by removing unreachable ones from all nodes
122
+ unreachable = set(exc.errors)
123
+ self.reachable_by_identity[identity_key] = all_addresses - unreachable
124
+ except TraversalError:
125
+ # If traversal fails for other reasons, no nodes are reachable
126
+ self.reachable_by_identity[identity_key] = set()
127
+
128
+ def _format_skip_message(
129
+ self, node_address: str, reaching_identities: List[str]
130
+ ) -> str:
131
+ """
132
+ Format the skip message with proper grammar based on identity counts.
133
+ """
134
+
135
+ # Format lists of quoted identities
136
+ reachable_ids_str = ", ".join(f'"{id}"' for id in reaching_identities)
137
+ provided_ids = list(self.identities.keys())
138
+ provided_ids_str = ", ".join(f'"{id}"' for id in provided_ids)
139
+
140
+ # Determine singular/plural forms based on counts
141
+ reachable_term = "identity" if len(reaching_identities) == 1 else "identities"
142
+ provided_term = "identity" if len(provided_ids) == 1 else "identities"
143
+ was_were = "was" if len(provided_ids) == 1 else "were"
144
+
145
+ return (
146
+ f'Skipping the "{node_address}" collection, it is reachable by the {reachable_ids_str} '
147
+ f"{reachable_term} but only the {provided_ids_str} {provided_term} {was_were} provided"
148
+ )
@@ -28,6 +28,7 @@ from fides.api.graph.graph import DatasetGraph, Edge, Node
28
28
  from fides.api.graph.node_filters import (
29
29
  CustomRequestFieldFilter,
30
30
  NodeFilter,
31
+ OptionalIdentityFilter,
31
32
  PolicyDataCategoryFilter,
32
33
  )
33
34
  from fides.api.models.policy import Policy
@@ -64,7 +65,7 @@ def artificial_traversal_node(address: CollectionAddress) -> TraversalNode:
64
65
  return TraversalNode(node)
65
66
 
66
67
 
67
- class Traversal:
68
+ class BaseTraversal:
68
69
  """Handling for a single reified traversal of a graph based on input (seed) data."""
69
70
 
70
71
  def extract_seed_field_addresses(
@@ -83,6 +84,7 @@ class Traversal:
83
84
  self,
84
85
  graph: DatasetGraph,
85
86
  data: Dict[str, Any],
87
+ *,
86
88
  policy: Optional[Policy] = None,
87
89
  node_filters: Optional[List[NodeFilter]] = None,
88
90
  ):
@@ -93,9 +95,6 @@ class Traversal:
93
95
  # Node filters are used to allow unreachable nodes to be ignored
94
96
  # if they don't apply to the given scenario
95
97
  self.node_filters = node_filters or []
96
- self.node_filters.append(CustomRequestFieldFilter())
97
- if policy:
98
- self.node_filters.append(PolicyDataCategoryFilter(policy))
99
98
 
100
99
  self.traversal_node_dict = {k: TraversalNode(v) for k, v in graph.nodes.items()}
101
100
  self.edges: Set[Edge] = graph.edges.copy()
@@ -289,6 +288,37 @@ class Traversal:
289
288
  logger.debug("Found {} end nodes: {}", len(end_nodes), end_nodes)
290
289
  return end_nodes
291
290
 
291
+ @property
292
+ def skipped_nodes(self) -> Dict[str, str]:
293
+ """
294
+ Returns a dictionary of node addresses to skip reasons from all node filters.
295
+ """
296
+ result = {}
297
+ for node_filter in self.node_filters:
298
+ result.update(node_filter.skipped_nodes)
299
+ return result
300
+
301
+
302
+ class Traversal(BaseTraversal):
303
+ """Handling for a single reified traversal of a graph based on input (seed) data."""
304
+
305
+ def __init__(
306
+ self,
307
+ graph: DatasetGraph,
308
+ data: Dict[str, Any],
309
+ *,
310
+ policy: Optional[Policy] = None,
311
+ node_filters: Optional[List[NodeFilter]] = None,
312
+ ):
313
+ filters = node_filters or []
314
+
315
+ filters.append(CustomRequestFieldFilter())
316
+ filters.append(OptionalIdentityFilter(graph, data))
317
+ if policy:
318
+ filters.append(PolicyDataCategoryFilter(policy))
319
+
320
+ super().__init__(graph, data, policy=policy, node_filters=filters)
321
+
292
322
 
293
323
  def log_traversal_error_and_update_privacy_request(
294
324
  privacy_request: PrivacyRequest, session: Session, err: TraversalError
@@ -0,0 +1,153 @@
1
+ from enum import Enum as EnumType
2
+ from typing import Any, Optional
3
+
4
+ from sqlalchemy import Column
5
+ from sqlalchemy import Enum as EnumColumn
6
+ from sqlalchemy import ForeignKey, String, UniqueConstraint
7
+ from sqlalchemy.ext.declarative import declared_attr
8
+ from sqlalchemy.orm import Session, relationship
9
+
10
+ from fides.api.db.base_class import Base
11
+ from fides.api.models.fides_user import FidesUser # pylint: disable=unused-import
12
+
13
+
14
+ class AttachmentType(str, EnumType):
15
+ """
16
+ Enum for attachment types. Indicates attachment usage.
17
+ """
18
+
19
+ internal_use_only = "internal_use_only"
20
+ include_with_access_package = "include_with_access_package"
21
+
22
+
23
+ class AttachmentReferenceType(str, EnumType):
24
+ """
25
+ Enum for attachment reference types. Indicates where attachment is referenced.
26
+ """
27
+
28
+ manual_step = "manual_step"
29
+ privacy_request = "privacy_request"
30
+ comment = "comment"
31
+
32
+
33
+ class AttachmentReference(Base):
34
+ """
35
+ Stores information about an Attachment and any other element which may reference that attachment.
36
+ """
37
+
38
+ @declared_attr
39
+ def __tablename__(cls) -> str:
40
+ """Overriding base class method to set the table name."""
41
+ return "attachment_reference"
42
+
43
+ attachment_id = Column(String, ForeignKey("attachment.id"), nullable=False)
44
+ reference_id = Column(String, nullable=False)
45
+ reference_type = Column(EnumColumn(AttachmentReferenceType), nullable=False)
46
+
47
+ __table_args__ = (
48
+ UniqueConstraint(
49
+ "attachment_id", "reference_id", name="_attachment_reference_uc"
50
+ ),
51
+ )
52
+
53
+ attachment = relationship(
54
+ "Attachment",
55
+ back_populates="references",
56
+ uselist=False,
57
+ )
58
+
59
+ @classmethod
60
+ def create(
61
+ cls, db: Session, *, data: dict[str, Any], check_name: bool = False
62
+ ) -> "AttachmentReference":
63
+ """Creates a new attachment reference record in the database."""
64
+ return super().create(db=db, data=data, check_name=check_name)
65
+
66
+
67
+ class Attachment(Base):
68
+ """
69
+ Stores information about an Attachment.
70
+ """
71
+
72
+ user_id = Column(
73
+ String, ForeignKey("fidesuser.id", ondelete="SET NULL"), nullable=True
74
+ )
75
+ file_name = Column(String, nullable=False)
76
+ attachment_type = Column(EnumColumn(AttachmentType), nullable=False)
77
+ storage_key = Column(String, nullable=False)
78
+
79
+ user = relationship(
80
+ "FidesUser",
81
+ backref="attachments",
82
+ lazy="selectin",
83
+ uselist=False,
84
+ )
85
+
86
+ references = relationship(
87
+ "AttachmentReference",
88
+ back_populates="attachment",
89
+ cascade="all, delete",
90
+ uselist=True,
91
+ )
92
+
93
+ async def upload_attachment_to_s3(self, attachment: bytes) -> None:
94
+ """Upload an attachment to S3 to the storage_url."""
95
+ raise NotImplementedError("This method is not yet implemented")
96
+ # AuditLog.create(
97
+ # db=db,
98
+ # data={
99
+ # "user_id": "system",
100
+ # "privacy_request_id": privacy_request.id,
101
+ # "action": AuditLogAction.attachment_uploaded,
102
+ # "message": "",
103
+ # },
104
+ # )
105
+
106
+ async def retrieve_attachment_from_s3(self) -> bytes:
107
+ """Retrieve an attachment from S3."""
108
+ raise NotImplementedError("This method is not yet implemented")
109
+ # AuditLog.create(
110
+ # db=db,
111
+ # data={
112
+ # "user_id": "system",
113
+ # "privacy_request_id": privacy_request.id,
114
+ # "action": AuditLogAction.attachment_retrieved,
115
+ # "message": "",
116
+ # },
117
+ # )
118
+
119
+ async def delete_attachment_from_s3(self) -> None:
120
+ """Delete an attachment from S3."""
121
+ raise NotImplementedError("This method is not yet implemented")
122
+ # AuditLog.create(
123
+ # db=db,
124
+ # data={
125
+ # "user_id": "system",
126
+ # "privacy_request_id": privacy_request.id,
127
+ # "action": AuditLogAction.attachment_deleted,
128
+ # "message": "",
129
+ # },
130
+ # )
131
+
132
+ @classmethod
133
+ def create(
134
+ cls,
135
+ db: Session,
136
+ *,
137
+ data: dict[str, Any],
138
+ check_name: bool = False,
139
+ attachment: Optional[
140
+ bytes
141
+ ] = None, # This will not be optional once the upload method is implemented.
142
+ ) -> "Attachment":
143
+ """Creates a new attachment record in the database and uploads the attachment to S3."""
144
+ # attachment_record.upload_attachment_to_s3(db, attachment)
145
+ # log.info(f"Uploaded attachment {attachment_record.id} to S3")
146
+ return super().create(db=db, data=data, check_name=check_name)
147
+
148
+ def delete(self, db: Session) -> None:
149
+ """Deletes an attachment record from the database and deletes the attachment from S3."""
150
+ # attachment_record = cls.get(db, id)
151
+ # attachment_record.delete_attachment_from_s3(db)
152
+ # log.info(f"Deleted attachment {attachment_record.id} from S3")
153
+ super().delete(db=db)
@@ -11,6 +11,9 @@ 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"
14
17
  denied = "denied"
15
18
  email_sent = "email_sent"
16
19
  finished = "finished"
@@ -398,6 +398,13 @@ class MonitorExecution(Base):
398
398
  nullable=False,
399
399
  default=list,
400
400
  )
401
+ # stores additional information from monitor execution failures as an array of strings,
402
+ # e.g. error messages, stack traces, etc.
403
+ messages = Column(
404
+ ARRAY(String),
405
+ nullable=False,
406
+ default=list,
407
+ )
401
408
  created_at = Column(DateTime(timezone=True), server_default=func.now())
402
409
  updated_at = Column(
403
410
  DateTime(timezone=True),
@@ -1278,6 +1278,28 @@ class PrivacyRequest(
1278
1278
  },
1279
1279
  )
1280
1280
 
1281
+ def add_skipped_execution_log(
1282
+ self,
1283
+ db: Session,
1284
+ connection_key: Optional[str],
1285
+ dataset_name: Optional[str],
1286
+ collection_name: Optional[str],
1287
+ message: str,
1288
+ action_type: ActionType,
1289
+ ) -> ExecutionLog:
1290
+ return ExecutionLog.create(
1291
+ db=db,
1292
+ data={
1293
+ "privacy_request_id": self.id,
1294
+ "connection_key": connection_key,
1295
+ "dataset_name": dataset_name,
1296
+ "collection_name": collection_name,
1297
+ "status": ExecutionLogStatus.skipped,
1298
+ "message": message,
1299
+ "action_type": action_type,
1300
+ },
1301
+ )
1302
+
1281
1303
  def add_error_execution_log(
1282
1304
  self,
1283
1305
  db: Session,
@@ -1861,6 +1883,7 @@ class TraversalDetails(FidesSchema):
1861
1883
  incoming_edges: List[Tuple[str, str]]
1862
1884
  outgoing_edges: List[Tuple[str, str]]
1863
1885
  input_keys: List[str]
1886
+ skipped_nodes: Optional[List[Tuple[str, str]]] = None
1864
1887
 
1865
1888
  # TODO: remove this method once we support custom request fields in DSR graph.
1866
1889
  @classmethod
@@ -1868,15 +1891,15 @@ class TraversalDetails(FidesSchema):
1868
1891
  """
1869
1892
  Creates an "empty" TraversalDetails object that only has the dataset connection key set.
1870
1893
  This is a bit of a hacky workaround needed to implement the Dynamic Erasure Emails feature,
1871
- and should be needed only until we support custom request fields as entry points to the DSR graph.
1872
- This is needed because custom request field nodes aren't currently reachable, so they don't have
1873
- a real TraversalNode associated to them.
1894
+ but we should no longer need it once the custom_request_fields are included in our graph
1895
+ traversal
1874
1896
  """
1875
1897
  return cls(
1876
1898
  dataset_connection_key=connection_key,
1877
1899
  incoming_edges=[],
1878
1900
  outgoing_edges=[],
1879
1901
  input_keys=[],
1902
+ skipped_nodes=[],
1880
1903
  )
1881
1904
 
1882
1905
 
@@ -451,7 +451,7 @@ def run_access_request(
451
451
  )
452
452
  else:
453
453
  try:
454
- traversal: Traversal = Traversal(graph, identity, policy)
454
+ traversal: Traversal = Traversal(graph, identity, policy=policy)
455
455
 
456
456
  # Traversal.traverse populates traversal_nodes in place, adding parents and children to each traversal_node.
457
457
  traversal_nodes: Dict[CollectionAddress, TraversalNode] = {}
@@ -485,14 +485,32 @@ def run_access_request(
485
485
  connection_configs,
486
486
  )
487
487
  )
488
- privacy_request.add_success_execution_log(
489
- session,
490
- connection_key=None,
491
- dataset_name="Dataset traversal",
492
- collection_name=None,
493
- message=f"Traversal successful for privacy request: {privacy_request.id}",
494
- action_type=ActionType.access,
495
- )
488
+
489
+ # Add execution logs for skipped nodes
490
+ if traversal.skipped_nodes:
491
+ logger.warning(
492
+ "Some nodes were skipped, the identities provided were not sufficient to reach them"
493
+ )
494
+ for node_address, skip_message in traversal.skipped_nodes.items():
495
+ logger.debug(skip_message)
496
+ privacy_request.add_skipped_execution_log(
497
+ session,
498
+ connection_key=None,
499
+ dataset_name="Dataset traversal",
500
+ collection_name=node_address.replace(":", "."),
501
+ message=skip_message,
502
+ action_type=ActionType.access,
503
+ )
504
+ # Or log success if all collections are reachable
505
+ else:
506
+ privacy_request.add_success_execution_log(
507
+ session,
508
+ connection_key=None,
509
+ dataset_name="Dataset traversal",
510
+ collection_name=None,
511
+ message=f"Traversal successful for privacy request: {privacy_request.id}",
512
+ action_type=ActionType.access,
513
+ )
496
514
  except TraversalError as err:
497
515
  log_traversal_error_and_update_privacy_request(
498
516
  privacy_request, session, err