ethyca-fides 2.58.2b5__py2.py3-none-any.whl → 2.58.2rc0__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 (213) hide show
  1. {ethyca_fides-2.58.2b5.dist-info → ethyca_fides-2.58.2rc0.dist-info}/METADATA +11 -20
  2. {ethyca_fides-2.58.2b5.dist-info → ethyca_fides-2.58.2rc0.dist-info}/RECORD +178 -188
  3. {ethyca_fides-2.58.2b5.dist-info → ethyca_fides-2.58.2rc0.dist-info}/WHEEL +1 -1
  4. {ethyca_fides-2.58.2b5.dist-info → ethyca_fides-2.58.2rc0.dist-info}/entry_points.txt +1 -0
  5. fides/_version.py +3 -3
  6. fides/api/api/deps.py +2 -8
  7. fides/api/api/v1/endpoints/user_endpoints.py +12 -8
  8. fides/api/cryptography/identity_salt.py +13 -12
  9. fides/api/custom_types.py +1 -6
  10. fides/api/db/base.py +0 -5
  11. fides/api/db/system.py +3 -1
  12. fides/api/migrations/hash_migration_job.py +2 -2
  13. fides/api/models/attachment.py +11 -80
  14. fides/api/models/comment.py +15 -45
  15. fides/api/models/detection_discovery.py +0 -31
  16. fides/api/models/fides_user.py +9 -26
  17. fides/api/models/fides_user_invite.py +0 -2
  18. fides/api/models/privacy_experience.py +0 -68
  19. fides/api/models/privacy_request/privacy_request.py +6 -23
  20. fides/api/schemas/connection_configuration/connection_config.py +16 -30
  21. fides/api/schemas/user.py +1 -5
  22. fides/api/service/deps.py +0 -9
  23. fides/api/service/storage/s3.py +1 -14
  24. fides/api/service/user/fides_user_service.py +128 -0
  25. fides/api/task/graph_task.py +1 -1
  26. fides/api/util/collection_util.py +9 -48
  27. fides/cli/commands/pull.py +13 -77
  28. fides/core/api.py +1 -2
  29. fides/core/pull.py +7 -38
  30. fides/ui-build/static/admin/404.html +1 -1
  31. fides/ui-build/static/admin/_next/static/chunks/1150-035a721a04f4451e.js +1 -0
  32. fides/ui-build/static/admin/_next/static/chunks/1376-5cea5ef9362215e8.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/{2397-0d1c289b788fcc11.js → 2397-ee53235fb21b5e97.js} +1 -1
  34. fides/ui-build/static/admin/_next/static/chunks/3412-7ec8751b8182e1bf.js +1 -0
  35. fides/ui-build/static/admin/_next/static/chunks/{3855-63495367531cb776.js → 3855-b6b7865dedd7bc2a.js} +1 -1
  36. fides/ui-build/static/admin/_next/static/chunks/{3872-472bb47eb34d8fdb.js → 3872-4e053c20d546f027.js} +1 -1
  37. fides/ui-build/static/admin/_next/static/chunks/{4060-53a5c6347690a8fa.js → 4060-8d165e1236ea521a.js} +1 -1
  38. fides/ui-build/static/admin/_next/static/chunks/4450-36234280bee624ff.js +1 -0
  39. fides/ui-build/static/admin/_next/static/chunks/4481-aab99ff80f707473.js +1 -0
  40. fides/ui-build/static/admin/_next/static/chunks/{5258-cf7b27ef51f38392.js → 5258-0658dc2274df6832.js} +1 -1
  41. fides/ui-build/static/admin/_next/static/chunks/{5480-52dc446be40725f5.js → 5480-f49696df5e8ae500.js} +1 -1
  42. fides/ui-build/static/admin/_next/static/chunks/{5487-8678d75ee1d1ef09.js → 5487-3ad50d21cdbc9209.js} +1 -1
  43. fides/ui-build/static/admin/_next/static/chunks/5973-52aee296edc44f7e.js +1 -0
  44. fides/ui-build/static/admin/_next/static/chunks/6315-fa1519cdf080f42d.js +1 -0
  45. fides/ui-build/static/admin/_next/static/chunks/{6372-e0bb9f8d07cc3b04.js → 6372-ca9c12ac8902365b.js} +1 -1
  46. fides/ui-build/static/admin/_next/static/chunks/{6853-09e831e9dff7fd3b.js → 6853-8941824350c3c1a8.js} +1 -1
  47. fides/ui-build/static/admin/_next/static/chunks/{6954-ec5276bb464d42b2.js → 6954-3b887fb444f9228c.js} +1 -1
  48. fides/ui-build/static/admin/_next/static/chunks/7453-39761c38da31257e.js +1 -0
  49. fides/ui-build/static/admin/_next/static/chunks/{7751-a70fe0e5f67f5538.js → 7751-a8f31c062d4cb09d.js} +1 -1
  50. fides/ui-build/static/admin/_next/static/chunks/{79-8e060d36d36c752c.js → 79-f9b948ebb186900f.js} +1 -1
  51. fides/ui-build/static/admin/_next/static/chunks/{7980-72f745bff9fabcc9.js → 7980-4bd08957448dea32.js} +1 -1
  52. fides/ui-build/static/admin/_next/static/chunks/{9046-a69fa8f99c414570.js → 9046-04bd7becea207cb1.js} +1 -1
  53. fides/ui-build/static/admin/_next/static/chunks/9767-1a23925d2cb27b51.js +1 -0
  54. fides/ui-build/static/admin/_next/static/chunks/{main-090643377c8254e6.js → main-24f422f93845a596.js} +1 -1
  55. fides/ui-build/static/admin/_next/static/chunks/{main-app-59156a9331ac7bce.js → main-app-94a0711202e08b15.js} +1 -1
  56. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-0c1548ca3b158123.js → _app-fc89ce7bed454c84.js} +1 -1
  57. fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-9f9500c639362aa6.js → manual-9acaab973dfe86e2.js} +1 -1
  58. fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-fac606150b65d494.js → add-systems-d258f0c25fa020bf.js} +1 -1
  59. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-fb75fa0aea77678d.js +1 -0
  60. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-c02b14c50b19bd91.js → new-a9d9402c219d13e5.js} +1 -1
  61. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-c946b33b0322b8ad.js +1 -0
  62. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-ea57f9d6ad17e957.js +1 -0
  63. fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-100234c23a85d235.js → reporting-788cf0e34829af46.js} +1 -1
  64. fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-49bffaf07973fead.js → data-catalog-900004e402c31797.js} +1 -1
  65. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-727f1f5d06be674b.js → [systemId]-b66831fdafcdf67c.js} +1 -1
  66. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5f9ef1f99818117c.js +1 -0
  67. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-d001337d1bb73bd1.js +1 -0
  68. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-11b3ce9f61d9bfe9.js +1 -0
  69. fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-4d4a31d0186a4a5b.js → new-803c1b577ab17ae3.js} +1 -1
  70. fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-29317d18ce34adfe.js → dataset-fa743ddc7f89d76b.js} +1 -1
  71. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-14c57e5069e9cccd.js → [id]-bbe1ca2793798e6b.js} +1 -1
  72. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f0a4e385c1ad8fee.js → new-abc17fef69cd951b.js} +1 -1
  73. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-a78a73b65929853a.js +1 -0
  74. fides/ui-build/static/admin/_next/static/chunks/pages/{index-b70def65e264270e.js → index-bfaacdb55a5a6c9f.js} +1 -1
  75. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-d4329043219fed9b.js +1 -0
  76. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-1e60754abec1ee6b.js +1 -0
  77. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-72d64a02b7ef175e.js → [id]-fe765154315782cf.js} +1 -1
  78. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-f5f7a8069909ef24.js +1 -0
  79. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-9f7eaad05e5b9292.js +1 -0
  80. fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-fd81714d811db7b3.js → privacy-requests-d85c0d16ba09ba35.js} +1 -1
  81. fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-f035cddf17f4d898.js → datamap-afedc48ef4e7f858.js} +1 -1
  82. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-89524101b7279f6e.js +1 -0
  83. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-dfcd7a4b6aa773bd.js → custom-fields-52d030b1db2ca1b9.js} +1 -1
  84. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-24cba38685dc872c.js +1 -0
  85. fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-0e0aa552f520f913.js → organization-a08693d0d1e10bc8.js} +1 -1
  86. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-1d83d5178b3eb216.js → test-datasets-151571cff4e85894.js} +1 -1
  87. fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-a158fa77df288523.js → [id]-4f5a28226575c976.js} +1 -1
  88. fides/ui-build/static/admin/_next/static/chunks/pages/{systems-8490aaaee9d76a4a.js → systems-abd68fc5ddde5482.js} +1 -1
  89. fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-be1ffe267b1602e1.js → taxonomy-16b4d75c49276add.js} +1 -1
  90. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-082c3156175f9267.js → new-be690621a944bfe2.js} +1 -1
  91. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-78eaf933f755bfe8.js +1 -0
  92. fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-a1db56f1cbfba373.js → user-management-6c9ad62479a7d03e.js} +1 -1
  93. fides/ui-build/static/admin/_next/static/css/{cf2744a40308fc4a.css → 113d823fe71f6af0.css} +1 -1
  94. fides/ui-build/static/admin/_next/static/o0mKeH0cB6eAYV6qOlVD0/_buildManifest.js +1 -0
  95. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  96. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  97. fides/ui-build/static/admin/add-systems.html +1 -1
  98. fides/ui-build/static/admin/ant-poc.html +1 -1
  99. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  100. fides/ui-build/static/admin/consent/configure.html +1 -1
  101. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  102. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  103. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  104. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  105. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  106. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  107. fides/ui-build/static/admin/consent/properties.html +1 -1
  108. fides/ui-build/static/admin/consent/reporting.html +1 -1
  109. fides/ui-build/static/admin/consent.html +1 -1
  110. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  111. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  112. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  113. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  114. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  115. fides/ui-build/static/admin/data-catalog.html +1 -1
  116. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  117. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  118. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  119. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  120. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  121. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  122. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  123. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  124. fides/ui-build/static/admin/datamap.html +1 -1
  125. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  126. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  127. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  128. fides/ui-build/static/admin/dataset/new.html +1 -1
  129. fides/ui-build/static/admin/dataset.html +1 -1
  130. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  131. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  132. fides/ui-build/static/admin/datastore-connection.html +1 -1
  133. fides/ui-build/static/admin/index.html +1 -1
  134. fides/ui-build/static/admin/integrations/[id].html +1 -1
  135. fides/ui-build/static/admin/integrations.html +1 -1
  136. fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
  137. fides/ui-build/static/admin/lib/fides-headless.js +1 -1
  138. fides/ui-build/static/admin/lib/fides-tcf.js +4 -4
  139. fides/ui-build/static/admin/lib/fides.js +3 -3
  140. fides/ui-build/static/admin/login/[provider].html +1 -1
  141. fides/ui-build/static/admin/login.html +1 -1
  142. fides/ui-build/static/admin/messaging/[id].html +1 -1
  143. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  144. fides/ui-build/static/admin/messaging.html +1 -1
  145. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  146. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  147. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  148. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  149. fides/ui-build/static/admin/privacy-requests.html +1 -1
  150. fides/ui-build/static/admin/properties/[id].html +1 -1
  151. fides/ui-build/static/admin/properties/add-property.html +1 -1
  152. fides/ui-build/static/admin/properties.html +1 -1
  153. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  154. fides/ui-build/static/admin/settings/about.html +1 -1
  155. fides/ui-build/static/admin/settings/consent.html +1 -1
  156. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  157. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  158. fides/ui-build/static/admin/settings/domains.html +1 -1
  159. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  160. fides/ui-build/static/admin/settings/locations.html +1 -1
  161. fides/ui-build/static/admin/settings/organization.html +1 -1
  162. fides/ui-build/static/admin/settings/regulations.html +1 -1
  163. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  164. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  165. fides/ui-build/static/admin/systems.html +1 -1
  166. fides/ui-build/static/admin/taxonomy.html +1 -1
  167. fides/ui-build/static/admin/user-management/new.html +1 -1
  168. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  169. fides/ui-build/static/admin/user-management.html +1 -1
  170. fides/api/alembic/migrations/versions/67d01c4e124e_add_reject_all_mechanism_to_privacy_.py +0 -56
  171. fides/api/alembic/migrations/versions/6e565c16dae1_add_tcf_publisher_restrictions.py +0 -107
  172. fides/api/alembic/migrations/versions/9288f729cac4_add_tcf_configuration_fk_to_experience_.py +0 -62
  173. fides/api/alembic/migrations/versions/99c603c1b8f9_add_password_login_enabled_and_totp_secret_to_fidesuser.py +0 -45
  174. fides/api/models/tcf_publisher_restrictions.py +0 -465
  175. fides/service/error_handling/__init__.py +0 -0
  176. fides/service/error_handling/error_handler.py +0 -202
  177. fides/service/user/__init__.py +0 -0
  178. fides/service/user/user_service.py +0 -140
  179. fides/ui-build/static/admin/_next/static/_o6WH0hDzNEhnUJyvLex7/_buildManifest.js +0 -1
  180. fides/ui-build/static/admin/_next/static/chunks/1376-87058e04584cff20.js +0 -1
  181. fides/ui-build/static/admin/_next/static/chunks/146-0ae2d30ec71fce09.js +0 -1
  182. fides/ui-build/static/admin/_next/static/chunks/1817-48e1c9d3504e18f0.js +0 -1
  183. fides/ui-build/static/admin/_next/static/chunks/3938-6a1c07d06a80cf4c.js +0 -1
  184. fides/ui-build/static/admin/_next/static/chunks/4121-4d5273d7a354994d.js +0 -1
  185. fides/ui-build/static/admin/_next/static/chunks/4450-9c3086ccb55c66aa.js +0 -1
  186. fides/ui-build/static/admin/_next/static/chunks/4481-275aa9f4c10bce53.js +0 -1
  187. fides/ui-build/static/admin/_next/static/chunks/5973-d3d3872692c1d0fa.js +0 -1
  188. fides/ui-build/static/admin/_next/static/chunks/6315-24a0483ee1cab6cc.js +0 -1
  189. fides/ui-build/static/admin/_next/static/chunks/9767-8179ce7336727141.js +0 -1
  190. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-ab3ef485f6101697.js +0 -1
  191. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-ba5325035c71a97e.js +0 -1
  192. fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-ef31c181cac86c64.js +0 -1
  193. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-53efbed54d230f07.js +0 -1
  194. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-17d1525551d8904f.js +0 -1
  195. fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-7d2cb947eee11262.js +0 -1
  196. fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-d2f88a8fc68944db.js +0 -1
  197. fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-b75ab4ee677f118d.js +0 -1
  198. fides/ui-build/static/admin/_next/static/chunks/pages/messaging-26407674949bcbc4.js +0 -1
  199. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-28d4bdf060ec8cb2.js +0 -1
  200. fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-208e49ef43361d6f.js +0 -1
  201. fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-ff1985f72d50ef47.js +0 -1
  202. fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-5a0b10ec955097d4.js +0 -1
  203. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-af83245e9373a064.js +0 -1
  204. fides/ui-build/static/admin/images/connector-logos/website.svg +0 -10
  205. {ethyca_fides-2.58.2b5.dist-info/licenses → ethyca_fides-2.58.2rc0.dist-info}/LICENSE +0 -0
  206. {ethyca_fides-2.58.2b5.dist-info → ethyca_fides-2.58.2rc0.dist-info}/top_level.txt +0 -0
  207. /fides/ui-build/static/admin/_next/static/chunks/{4723-1dd1d16f404d56a2.js → 4723-0a3c5e2ce143a7d0.js} +0 -0
  208. /fides/ui-build/static/admin/_next/static/chunks/{5826-ef0aa43ffad83acc.js → 5826-e5dcb4e68cfe6289.js} +0 -0
  209. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-a4e636eecaba5324.js → configure-723cc3d4f5740ea6.js} +0 -0
  210. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-606457ef5bd1eb04.js → [id]-72251b48e2e03a1e.js} +0 -0
  211. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-2ae030f3a28f057a.js → about-a49d0f84cf0cf05e.js} +0 -0
  212. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-72ec54ee8755a503.js → domain-records-fa42d8f18df44927.js} +0 -0
  213. /fides/ui-build/static/admin/_next/static/{_o6WH0hDzNEhnUJyvLex7 → o0mKeH0cB6eAYV6qOlVD0}/_ssgManifest.js +0 -0
@@ -20,7 +20,6 @@ from fides.api.models import (
20
20
  from fides.api.models.location_regulation_selections import PrivacyNoticeRegion
21
21
  from fides.api.models.privacy_notice import PrivacyNotice
22
22
  from fides.api.models.property import Property
23
- from fides.api.models.tcf_publisher_restrictions import TCFConfiguration
24
23
  from fides.api.schemas.language import SupportedLanguage
25
24
 
26
25
 
@@ -47,21 +46,6 @@ class Layer1ButtonOption(Enum):
47
46
 
48
47
  ACKNOWLEDGE = "acknowledge"
49
48
  OPT_IN_OPT_OUT = "opt_in_opt_out"
50
- OPT_IN_ONLY = "opt_in_only"
51
-
52
-
53
- class RejectAllMechanism(Enum):
54
- """
55
- Reject all mechanism options - not formalized in the db.
56
- Used to configure the behavior of the reject all button in TCF experiences
57
- """
58
-
59
- # Reject both consent and legitimate interest preferences (all purposes, special features, vendors)
60
- # This is the default behavior
61
- REJECT_ALL = "reject_all"
62
- # Reject only consent preferences (all purposes, special features, vendors).
63
- # Do not reject any legitimate interest preferences.
64
- REJECT_CONSENT_ONLY = "reject_consent_only"
65
49
 
66
50
 
67
51
  # Fides JS UX Types - there should only be one of these defined per region
@@ -195,10 +179,6 @@ class PrivacyExperienceConfig(PrivacyExperienceConfigBase, Base):
195
179
  The Privacy Experience Configuration model that stores shared configuration for Privacy Experiences.
196
180
 
197
181
  - Translations, Notices, and Regions (via Privacy Experiences) are linked to this resource.
198
-
199
- If you're adding a new PrivacyExperienceConfig, make sure to use the `create` method since it has
200
- custom logic that ensures other resources are created/updated as needed, as well as setting the
201
- expected values for some fields in the experience config itself.
202
182
  """
203
183
 
204
184
  allow_language_selection = Column(
@@ -223,20 +203,6 @@ class PrivacyExperienceConfig(PrivacyExperienceConfigBase, Base):
223
203
  String, ForeignKey(ExperienceConfigTemplate.id_field_path)
224
204
  ) # The template from which this config was created if applicable
225
205
 
226
- # Mechanism to use when the reject all button is clicked in a TCF experience
227
- # Nullable because this is not applicable for other experience types
228
- reject_all_mechanism = Column(
229
- EnumColumn(RejectAllMechanism),
230
- nullable=True,
231
- )
232
- # Optional FK to a TCF Configuration
233
-
234
- tcf_configuration_id = Column(
235
- String,
236
- ForeignKey(TCFConfiguration.id_field_path, ondelete="SET NULL"),
237
- nullable=True,
238
- )
239
-
240
206
  # Relationships
241
207
  experiences = relationship(
242
208
  "PrivacyExperience",
@@ -266,12 +232,6 @@ class PrivacyExperienceConfig(PrivacyExperienceConfigBase, Base):
266
232
  lazy="selectin",
267
233
  )
268
234
 
269
- tcf_configuration: RelationshipProperty[Optional[TCFConfiguration]] = relationship(
270
- "TCFConfiguration",
271
- back_populates="privacy_experience_configs",
272
- lazy="selectin",
273
- )
274
-
275
235
  @property
276
236
  def regions(self) -> List[PrivacyNoticeRegion]:
277
237
  """Return the regions using this experience config"""
@@ -344,15 +304,6 @@ class PrivacyExperienceConfig(PrivacyExperienceConfigBase, Base):
344
304
  # Link Properties to this Privacy Experience config via the PrivacyExperienceConfigProperty table
345
305
  link_properties_to_experience_config(db, properties, experience_config)
346
306
 
347
- # If the reject all mechanism is not set and the experience config is a TCF experience,
348
- # set the reject all mechanism to REJECT_ALL
349
- if (
350
- experience_config.component == ComponentType.tcf_overlay
351
- and experience_config.reject_all_mechanism is None
352
- ):
353
- experience_config.reject_all_mechanism = RejectAllMechanism.REJECT_ALL # type: ignore
354
- experience_config.save(db)
355
-
356
307
  return experience_config
357
308
 
358
309
  def update(self, db: Session, *, data: dict[str, Any]) -> PrivacyExperienceConfig:
@@ -556,24 +507,6 @@ class PrivacyExperienceConfigHistory(
556
507
  index=True,
557
508
  ) # If a translation is deleted, this is set to null, but the overall record remains in the database for reporting purposes
558
509
 
559
- # Mechanism to use when the reject all button is clicked in a TCF experience
560
- # Nullable because this is not applicable for other experience types
561
- reject_all_mechanism = Column(
562
- EnumColumn(RejectAllMechanism),
563
- nullable=True,
564
- )
565
- # Optional FK to a TCF Configuration
566
- tcf_configuration_id = Column(
567
- String,
568
- ForeignKey(TCFConfiguration.id_field_path, ondelete="SET NULL"),
569
- nullable=True,
570
- )
571
-
572
- tcf_configuration: RelationshipProperty[Optional[TCFConfiguration]] = relationship(
573
- "TCFConfiguration",
574
- lazy="selectin",
575
- )
576
-
577
510
  version = Column(Float, nullable=False, default=1.0)
578
511
 
579
512
 
@@ -636,7 +569,6 @@ class PrivacyExperience(Base):
636
569
  tcf_special_features: List = []
637
570
  tcf_system_consents: List = []
638
571
  tcf_system_legitimate_interests: List = []
639
- tcf_publisher_restrictions: List = []
640
572
  gvl: Optional[Dict] = {}
641
573
  # TCF Developer-Friendly Meta added at runtime as the result of build_tc_data_for_mobile
642
574
  meta: Dict = {}
@@ -39,14 +39,10 @@ from fides.api.graph.config import (
39
39
  CollectionAddress,
40
40
  )
41
41
  from fides.api.migrations.hash_migration_mixin import HashMigrationMixin
42
- from fides.api.models.attachment import (
43
- Attachment,
44
- AttachmentReference,
45
- AttachmentReferenceType,
46
- )
42
+ from fides.api.models.attachment import Attachment, AttachmentReference
47
43
  from fides.api.models.audit_log import AuditLog
48
44
  from fides.api.models.client import ClientDetail
49
- from fides.api.models.comment import Comment, CommentReference, CommentReferenceType
45
+ from fides.api.models.comment import Comment, CommentReference
50
46
  from fides.api.models.fides_user import FidesUser
51
47
  from fides.api.models.manual_webhook import AccessManualWebhook
52
48
  from fides.api.models.policy import (
@@ -173,25 +169,18 @@ class PrivacyRequest(
173
169
  backref="privacy_requests",
174
170
  )
175
171
  attachments = relationship(
176
- "Attachment",
172
+ Attachment,
177
173
  secondary="attachment_reference",
178
- primaryjoin="and_(PrivacyRequest.id == AttachmentReference.reference_id, "
179
- "AttachmentReference.reference_type == 'privacy_request')",
174
+ primaryjoin="PrivacyRequest.id == AttachmentReference.reference_id",
180
175
  secondaryjoin="Attachment.id == AttachmentReference.attachment_id",
181
176
  order_by="Attachment.created_at",
182
- viewonly=True,
183
- uselist=True,
184
177
  )
185
-
186
178
  comments = relationship(
187
- "Comment",
179
+ Comment,
188
180
  secondary="comment_reference",
189
- primaryjoin="and_(PrivacyRequest.id == CommentReference.reference_id, "
190
- "CommentReference.reference_type == 'privacy_request')",
181
+ primaryjoin="PrivacyRequest.id == CommentReference.reference_id",
191
182
  secondaryjoin="Comment.id == CommentReference.comment_id",
192
183
  order_by="Comment.created_at",
193
- viewonly=True,
194
- uselist=True,
195
184
  )
196
185
  property_id = Column(String, nullable=True)
197
186
 
@@ -334,12 +323,6 @@ class PrivacyRequest(
334
323
  deleting this object from the database
335
324
  """
336
325
  self.clear_cached_values()
337
- Attachment.delete_attachments_for_reference_and_type(
338
- db, self.id, AttachmentReferenceType.privacy_request
339
- )
340
- Comment.delete_comments_for_reference_and_type(
341
- db, self.id, CommentReferenceType.privacy_request
342
- )
343
326
 
344
327
  for provided_identity in self.provided_identities: # type: ignore[attr-defined]
345
328
  provided_identity.delete(db=db)
@@ -71,23 +71,29 @@ def mask_sensitive_fields(
71
71
  return new_connection_secrets
72
72
 
73
73
 
74
- class ConnectionConfigSecretsMixin(BaseModel):
74
+ class ConnectionConfigurationResponse(BaseModel):
75
75
  """
76
- A schema mixin to declare a connection config `secrets` attribute
77
- and handle masking of sensitive values based on `connection_type`
78
- and (optionally) a `saas_config`.
76
+ Describes the returned schema for a ConnectionConfiguration.
79
77
  """
80
78
 
79
+ name: Optional[str] = None
80
+ key: FidesKey
81
+ description: Optional[str] = None
81
82
  connection_type: ConnectionType
82
- secrets: Optional[Dict[str, Any]] = None
83
+ access: AccessLevel
84
+ created_at: datetime
85
+ updated_at: Optional[datetime] = None
86
+ disabled: Optional[bool] = False
87
+ last_test_timestamp: Optional[datetime] = None
88
+ last_test_succeeded: Optional[bool] = None
83
89
  saas_config: Optional[SaaSConfigBase] = None
90
+ secrets: Optional[Dict[str, Any]] = None
91
+ authorized: Optional[bool] = False
92
+ enabled_actions: Optional[List[ActionType]] = None
84
93
 
85
94
  @model_validator(mode="after")
86
- def mask_sensitive_values(self) -> "ConnectionConfigSecretsMixin":
87
- """
88
- Mask sensitive values in the `secrets` attribute based on `connection_type`
89
- and (optionally) a `saas_config`.
90
- """
95
+ def mask_sensitive_values(self) -> "ConnectionConfigurationResponse":
96
+ """Mask sensitive values in the response."""
91
97
  if self.secrets is None:
92
98
  return self
93
99
 
@@ -110,26 +116,6 @@ class ConnectionConfigSecretsMixin(BaseModel):
110
116
  self.secrets = mask_sensitive_fields(cast(dict, self.secrets), secret_schema)
111
117
  return self
112
118
 
113
-
114
- class ConnectionConfigurationResponse(ConnectionConfigSecretsMixin):
115
- """
116
- Describes the returned schema for a ConnectionConfiguration.
117
-
118
- The mixin base class ensures that `secrets` sensitive values are masked.
119
- """
120
-
121
- name: Optional[str] = None
122
- key: FidesKey
123
- description: Optional[str] = None
124
- access: AccessLevel
125
- created_at: datetime
126
- updated_at: Optional[datetime] = None
127
- disabled: Optional[bool] = False
128
- last_test_timestamp: Optional[datetime] = None
129
- last_test_succeeded: Optional[bool] = None
130
- authorized: Optional[bool] = False
131
- enabled_actions: Optional[List[ActionType]] = None
132
-
133
119
  model_config = ConfigDict(from_attributes=True)
134
120
 
135
121
 
fides/api/schemas/user.py CHANGED
@@ -3,7 +3,7 @@ from datetime import datetime
3
3
  from enum import Enum
4
4
  from typing import Optional
5
5
 
6
- from pydantic import ConfigDict, EmailStr, field_validator
6
+ from pydantic import EmailStr, field_validator
7
7
 
8
8
  from fides.api.cryptography.cryptographic_util import decode_password
9
9
  from fides.api.schemas.base_class import FidesSchema
@@ -27,8 +27,6 @@ class UserCreate(FidesSchema):
27
27
  last_name: Optional[str] = None
28
28
  disabled: bool = False
29
29
 
30
- model_config = ConfigDict(extra="ignore")
31
-
32
30
  @field_validator("username")
33
31
  @classmethod
34
32
  def validate_username(cls, username: str) -> str:
@@ -142,8 +140,6 @@ class UserUpdate(FidesSchema):
142
140
  first_name: Optional[str] = None
143
141
  last_name: Optional[str] = None
144
142
 
145
- model_config = ConfigDict(extra="ignore")
146
-
147
143
 
148
144
  class DisabledReason(Enum):
149
145
  """Reasons for why a user is disabled"""
fides/api/service/deps.py CHANGED
@@ -8,7 +8,6 @@ from fides.service.dataset.dataset_config_service import DatasetConfigService
8
8
  from fides.service.dataset.dataset_service import DatasetService
9
9
  from fides.service.messaging.messaging_service import MessagingService
10
10
  from fides.service.privacy_request.privacy_request_service import PrivacyRequestService
11
- from fides.service.user.user_service import UserService
12
11
 
13
12
 
14
13
  def get_messaging_service(
@@ -33,11 +32,3 @@ def get_dataset_service(db: Session = Depends(get_db)) -> DatasetService:
33
32
 
34
33
  def get_dataset_config_service(db: Session = Depends(get_db)) -> DatasetConfigService:
35
34
  return DatasetConfigService(db)
36
-
37
-
38
- def get_user_service(
39
- db: Session = Depends(get_db),
40
- config: FidesConfig = Depends(get_config),
41
- config_proxy: ConfigProxy = Depends(get_config_proxy),
42
- ) -> UserService:
43
- return UserService(db, config, config_proxy)
@@ -64,7 +64,7 @@ def generic_upload_to_s3( # pylint: disable=R0913
64
64
  size_threshold: int = LARGE_FILE_THRESHOLD, # 5 MB threshold
65
65
  ) -> Optional[AnyHttpUrlString]:
66
66
  """
67
- Uploads file like objects to S3.
67
+ Uploads arbitrary data to S3 returned from an access request.
68
68
  Handles both small and large uploads.
69
69
 
70
70
  :param storage_secrets: S3 storage secrets
@@ -75,19 +75,6 @@ def generic_upload_to_s3( # pylint: disable=R0913
75
75
  """
76
76
  logger.info("Starting S3 Upload of {}", file_key)
77
77
 
78
- # Validate that the document is a file-like object
79
- if not hasattr(document, "read") or not hasattr(document, "seek"):
80
- raise TypeError(
81
- f"The 'document' parameter must be a file-like object supporting 'read' and 'seek'. "
82
- f"Received: {type(document)}"
83
- )
84
-
85
- # Ensure the file pointer is at the beginning
86
- try:
87
- document.seek(0)
88
- except Exception as e:
89
- raise ValueError(f"Failed to reset file pointer for document: {e}")
90
-
91
78
  s3_client = maybe_get_s3_client(auth_method, storage_secrets)
92
79
 
93
80
  # Define a transfer configuration for multipart uploads
@@ -0,0 +1,128 @@
1
+ import uuid
2
+ from datetime import datetime
3
+ from typing import Optional, Tuple
4
+
5
+ from loguru import logger
6
+ from sqlalchemy.orm import Session
7
+
8
+ from fides.api.api.v1.endpoints.messaging_endpoints import user_email_invite_status
9
+ from fides.api.common_exceptions import AuthorizationError
10
+ from fides.api.models.client import ClientDetail
11
+ from fides.api.models.fides_user import FidesUser
12
+ from fides.api.models.fides_user_invite import FidesUserInvite
13
+ from fides.api.schemas.messaging.messaging import (
14
+ MessagingActionType,
15
+ UserInviteBodyParams,
16
+ )
17
+ from fides.api.schemas.redis_cache import Identity
18
+ from fides.api.service.messaging.message_dispatch_service import dispatch_message
19
+ from fides.config import FidesConfig
20
+ from fides.config.config_proxy import ConfigProxy
21
+
22
+
23
+ def invite_user(db: Session, config_proxy: ConfigProxy, user: FidesUser) -> None:
24
+ """
25
+ Generates a user invite and sends the invite code to the user via email.
26
+
27
+ This is a no-op if email messaging isn't configured.
28
+ """
29
+
30
+ # invite user via email if email messaging is enabled and the Admin UI URL is defined
31
+ if user_email_invite_status(db=db, config_proxy=config_proxy).enabled:
32
+ invite_code = str(uuid.uuid4())
33
+ FidesUserInvite.create(
34
+ db=db, data={"username": user.username, "invite_code": invite_code}
35
+ )
36
+ user.update(db, data={"disabled": True})
37
+ dispatch_message(
38
+ db,
39
+ action_type=MessagingActionType.USER_INVITE,
40
+ to_identity=Identity(email=user.email_address),
41
+ service_type=config_proxy.notifications.notification_service_type,
42
+ message_body_params=UserInviteBodyParams(
43
+ username=user.username, invite_code=invite_code
44
+ ),
45
+ )
46
+
47
+
48
+ def accept_invite(
49
+ db: Session, config: FidesConfig, user: FidesUser, new_password: str
50
+ ) -> Tuple[FidesUser, str]:
51
+ """
52
+ Updates the user password and enables the user. Also removes the user invite from the database.
53
+ Returns a tuple of the updated user and their access code.
54
+ """
55
+
56
+ # update password and enable
57
+ user.update_password(db=db, new_password=new_password)
58
+ user.update(
59
+ db,
60
+ data={"disabled": False, "disabled_reason": None},
61
+ )
62
+ db.refresh(user)
63
+
64
+ # delete invite
65
+ if user.username:
66
+ invite = FidesUserInvite.get_by(db=db, field="username", value=user.username)
67
+ if invite:
68
+ invite.delete(db)
69
+ else:
70
+ logger.warning("Username is missing, skipping invite deletion.")
71
+
72
+ client = perform_login(
73
+ db,
74
+ config.security.oauth_client_id_length_bytes,
75
+ config.security.oauth_client_secret_length_bytes,
76
+ user,
77
+ )
78
+
79
+ logger.info("Creating login access token")
80
+ access_code = client.create_access_code_jwe(config.security.app_encryption_key)
81
+
82
+ return user, access_code
83
+
84
+
85
+ def perform_login(
86
+ db: Session,
87
+ client_id_byte_length: int,
88
+ client_secret_byte_length: int,
89
+ user: FidesUser,
90
+ skip_save: Optional[bool] = False,
91
+ ) -> ClientDetail:
92
+ """Performs a login by updating the FidesUser instance and creating and returning
93
+ an associated ClientDetail.
94
+
95
+ If the username or password was bad, skip_save should be True. We still run through
96
+ parallel operations to keep the timing of operations similar, but should skip
97
+ saving to the database.
98
+ """
99
+
100
+ client = user.client
101
+ if not client:
102
+ logger.info("Creating client for login")
103
+ client, _ = ClientDetail.create_client_and_secret(
104
+ db,
105
+ client_id_byte_length,
106
+ client_secret_byte_length,
107
+ scopes=[], # type: ignore
108
+ roles=user.permissions.roles, # type: ignore
109
+ systems=user.system_ids, # type: ignore
110
+ user_id=user.id,
111
+ in_memory=skip_save, # If login flow has already errored, don't persist this to the database
112
+ )
113
+ else:
114
+ # Refresh the client just in case - for example, scopes and roles were added via the db directly.
115
+ client.roles = user.permissions.roles # type: ignore
116
+ client.systems = user.system_ids # type: ignore
117
+ if not skip_save:
118
+ client.save(db)
119
+
120
+ if user.permissions and (not user.permissions.roles and not user.systems): # type: ignore
121
+ logger.warning("User {} needs roles or systems to login.", user.id)
122
+ raise AuthorizationError(detail="Not Authorized for this action")
123
+
124
+ if not skip_save:
125
+ user.last_login_at = datetime.utcnow()
126
+ user.save(db)
127
+
128
+ return client
@@ -10,7 +10,7 @@ from loguru import logger
10
10
  from ordered_set import OrderedSet
11
11
  from sqlalchemy.orm import Session
12
12
 
13
- from fides.api.api.deps import get_autoclose_db_session as get_db
13
+ from fides.api.api.deps import get_db_contextmanager as get_db
14
14
  from fides.api.common_exceptions import (
15
15
  ActionDisabled,
16
16
  AwaitingAsyncTaskCallback,
@@ -122,7 +122,6 @@ def extract_key_for_address(
122
122
  return f"{dataset}:{collection}"
123
123
 
124
124
 
125
- # pylint: disable=too-many-branches
126
125
  def unflatten_dict(flat_dict: Dict[str, Any], separator: str = ".") -> Dict[str, Any]:
127
126
  """
128
127
  Converts a dictionary of paths/values into a nested dictionary
@@ -150,29 +149,17 @@ def unflatten_dict(flat_dict: Dict[str, Any], separator: str = ".") -> Dict[str,
150
149
  for i, current_key in enumerate(keys[:-1]):
151
150
  next_key = keys[i + 1]
152
151
  if next_key.isdigit():
153
- if isinstance(target, dict): # Only call setdefault on dictionaries
154
- target = target.setdefault(current_key, [])
155
- elif isinstance(
156
- target, list
157
- ): # If target is a list, handle differently
158
- idx = int(current_key)
159
- while len(target) <= idx:
160
- target.append([]) # Add a list since next_key is a digit
161
- target = target[idx]
152
+ target = target.setdefault(current_key, [])
162
153
  else:
163
154
  if isinstance(target, dict):
164
155
  target = target.setdefault(current_key, {})
165
156
  elif isinstance(target, list):
166
- idx = int(current_key)
167
- while len(target) <= idx:
157
+ while len(target) <= int(current_key):
168
158
  target.append({})
169
- target = target[idx]
159
+ target = target[int(current_key)]
170
160
  try:
171
161
  if isinstance(target, list):
172
- idx = int(keys[-1]) if keys[-1].isdigit() else len(target)
173
- while len(target) <= idx:
174
- target.append(None)
175
- target[idx] = value
162
+ target.append(value)
176
163
  else:
177
164
  # If the value is a dictionary, add its components to the queue for processing
178
165
  if isinstance(value, dict):
@@ -189,12 +176,10 @@ def unflatten_dict(flat_dict: Dict[str, Any], separator: str = ".") -> Dict[str,
189
176
  return output
190
177
 
191
178
 
192
- # pylint: disable=too-many-branches
193
179
  def flatten_dict(data: Any, prefix: str = "", separator: str = ".") -> Dict[str, Any]:
194
180
  """
195
181
  Recursively flatten a dictionary or list into a flat dictionary with dot-notation keys.
196
182
  Handles nested dictionaries and arrays with proper indices.
197
- Preserves empty lists and dictionaries.
198
183
 
199
184
  example:
200
185
 
@@ -206,9 +191,7 @@ def flatten_dict(data: Any, prefix: str = "", separator: str = ".") -> Dict[str,
206
191
  "D": [
207
192
  {"E": "3"},
208
193
  {"E": "4"}
209
- ],
210
- "E": [],
211
- "F": {}
194
+ ]
212
195
  }
213
196
 
214
197
  becomes
@@ -217,9 +200,7 @@ def flatten_dict(data: Any, prefix: str = "", separator: str = ".") -> Dict[str,
217
200
  "A.B": "1",
218
201
  "A.C": "2",
219
202
  "D.0.E": "3",
220
- "D.1.E": "4",
221
- "E": [],
222
- "F": {}
203
+ "D.1.E": "4"
223
204
  }
224
205
 
225
206
  Args:
@@ -230,40 +211,20 @@ def flatten_dict(data: Any, prefix: str = "", separator: str = ".") -> Dict[str,
230
211
  Returns:
231
212
  A flattened dictionary with dot-notation keys
232
213
  """
233
- items: Dict[str, Any] = {}
214
+ items = {}
234
215
 
235
216
  if isinstance(data, dict):
236
- # Handle top-level empty dictionary case
237
- if not data and not prefix:
238
- return {}
239
-
240
- # If the dictionary is empty but has a prefix, store it as is
241
- if not data:
242
- items[prefix] = {}
243
- return items
244
-
245
217
  for k, v in data.items():
246
218
  new_key = f"{prefix}{separator}{k}" if prefix else k
247
219
  if isinstance(v, (dict, list)):
248
- if not v: # Handle empty dict or list
249
- items[new_key] = v
250
- else:
251
- items.update(flatten_dict(v, new_key, separator))
220
+ items.update(flatten_dict(v, new_key, separator))
252
221
  else:
253
222
  items[new_key] = v
254
223
  elif isinstance(data, list):
255
- # If the list is empty, store it as is
256
- if not data:
257
- items[prefix] = []
258
- return items
259
-
260
224
  for i, v in enumerate(data):
261
225
  new_key = f"{prefix}{separator}{i}"
262
226
  if isinstance(v, (dict, list)):
263
- if not v: # Handle empty dict or list
264
- items[new_key] = v
265
- else:
266
- items.update(flatten_dict(v, new_key, separator))
227
+ items.update(flatten_dict(v, new_key, separator))
267
228
  else:
268
229
  items[new_key] = v
269
230
  else: