ethyca-fides 2.69.0rc10__py2.py3-none-any.whl → 2.69.1__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.

Potentially problematic release.


This version of ethyca-fides might be problematic. Click here for more details.

Files changed (200) hide show
  1. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/METADATA +2 -2
  2. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/RECORD +198 -189
  3. fides/_version.py +3 -3
  4. fides/api/alembic/migrations/versions/78dbe23d8204_adding_privacy_request_redaction_patterns.py +52 -0
  5. fides/api/api/v1/api.py +2 -0
  6. fides/api/api/v1/endpoints/dsr_package_link.py +2 -2
  7. fides/api/api/v1/endpoints/oauth_endpoints.py +20 -6
  8. fides/api/api/v1/endpoints/privacy_request_redaction_patterns_endpoints.py +95 -0
  9. fides/api/api/v1/endpoints/user_endpoints.py +28 -1
  10. fides/api/app_setup.py +16 -2
  11. fides/api/db/base.py +3 -0
  12. fides/api/main.py +22 -0
  13. fides/api/models/client.py +1 -0
  14. fides/api/models/privacy_request_redaction_pattern.py +64 -0
  15. fides/api/oauth/utils.py +117 -6
  16. fides/api/schemas/privacy_request_redaction_patterns.py +55 -0
  17. fides/api/service/privacy_request/dsr_package/dsr_data_preprocessor.py +231 -0
  18. fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +31 -47
  19. fides/api/service/privacy_request/dsr_package/utils.py +268 -0
  20. fides/api/service/storage/streaming/smart_open_streaming_storage.py +3 -3
  21. fides/api/tasks/storage.py +2 -2
  22. fides/api/util/endpoint_utils.py +0 -13
  23. fides/api/util/rate_limit.py +194 -0
  24. fides/common/api/scope_registry.py +8 -0
  25. fides/common/api/v1/urn_registry.py +3 -0
  26. fides/config/redis_settings.py +27 -3
  27. fides/config/security_settings.py +31 -9
  28. fides/ui-build/static/admin/404.html +1 -1
  29. fides/ui-build/static/admin/_next/static/1TigfgzjzHeoVqRLNIMYa/_buildManifest.js +1 -0
  30. fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +1 -0
  31. fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ef8e1c986bc5b795.js → _app-fcdad91f6f66292b.js} +1 -1
  32. fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +1 -0
  33. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-de8cb3739ab99c09.js → new-92f52c43f522a350.js} +1 -1
  34. fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-05d61c80a556b2d5.js → [id]-64452dfae2c5e614.js} +1 -1
  35. fides/ui-build/static/admin/add-systems/manual.html +1 -1
  36. fides/ui-build/static/admin/add-systems/multiple.html +1 -1
  37. fides/ui-build/static/admin/add-systems.html +1 -1
  38. fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
  39. fides/ui-build/static/admin/consent/configure.html +1 -1
  40. fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
  41. fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
  42. fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
  43. fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
  44. fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
  45. fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
  46. fides/ui-build/static/admin/consent/properties.html +1 -1
  47. fides/ui-build/static/admin/consent/reporting.html +1 -1
  48. fides/ui-build/static/admin/consent.html +1 -1
  49. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
  50. fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
  51. fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
  52. fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
  53. fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
  54. fides/ui-build/static/admin/data-catalog.html +1 -1
  55. fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
  56. fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
  57. fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
  58. fides/ui-build/static/admin/data-discovery/activity.html +1 -1
  59. fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
  60. fides/ui-build/static/admin/data-discovery/detection.html +1 -1
  61. fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
  62. fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
  63. fides/ui-build/static/admin/datamap.html +1 -1
  64. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
  65. fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
  66. fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
  67. fides/ui-build/static/admin/dataset/new.html +1 -1
  68. fides/ui-build/static/admin/dataset.html +1 -1
  69. fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
  70. fides/ui-build/static/admin/datastore-connection/new.html +1 -1
  71. fides/ui-build/static/admin/datastore-connection.html +1 -1
  72. fides/ui-build/static/admin/index.html +1 -1
  73. fides/ui-build/static/admin/integrations/[id].html +1 -1
  74. fides/ui-build/static/admin/integrations.html +1 -1
  75. fides/ui-build/static/admin/login/[provider].html +1 -1
  76. fides/ui-build/static/admin/login.html +1 -1
  77. fides/ui-build/static/admin/messaging/[id].html +1 -1
  78. fides/ui-build/static/admin/messaging/add-template.html +1 -1
  79. fides/ui-build/static/admin/messaging.html +1 -1
  80. fides/ui-build/static/admin/poc/ant-components.html +1 -1
  81. fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
  82. fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
  83. fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
  84. fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
  85. fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
  86. fides/ui-build/static/admin/poc/forms.html +1 -1
  87. fides/ui-build/static/admin/poc/table-migration.html +1 -1
  88. fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
  89. fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
  90. fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
  91. fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
  92. fides/ui-build/static/admin/privacy-requests.html +1 -1
  93. fides/ui-build/static/admin/properties/[id].html +1 -1
  94. fides/ui-build/static/admin/properties/add-property.html +1 -1
  95. fides/ui-build/static/admin/properties.html +1 -1
  96. fides/ui-build/static/admin/reporting/datamap.html +1 -1
  97. fides/ui-build/static/admin/settings/about/alpha.html +1 -1
  98. fides/ui-build/static/admin/settings/about.html +1 -1
  99. fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
  100. fides/ui-build/static/admin/settings/consent.html +1 -1
  101. fides/ui-build/static/admin/settings/custom-fields.html +1 -1
  102. fides/ui-build/static/admin/settings/domain-records.html +1 -1
  103. fides/ui-build/static/admin/settings/domains.html +1 -1
  104. fides/ui-build/static/admin/settings/email-templates.html +1 -1
  105. fides/ui-build/static/admin/settings/locations.html +1 -1
  106. fides/ui-build/static/admin/settings/organization.html +1 -1
  107. fides/ui-build/static/admin/settings/privacy-requests.html +1 -0
  108. fides/ui-build/static/admin/settings/regulations.html +1 -1
  109. fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
  110. fides/ui-build/static/admin/systems/configure/[id].html +1 -1
  111. fides/ui-build/static/admin/systems.html +1 -1
  112. fides/ui-build/static/admin/taxonomy.html +1 -1
  113. fides/ui-build/static/admin/user-management/new.html +1 -1
  114. fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
  115. fides/ui-build/static/admin/user-management.html +1 -1
  116. fides/ui-build/static/admin/_next/static/8qfO1Ol3G3QbcXpHAnPlU/_buildManifest.js +0 -1
  117. fides/ui-build/static/admin/_next/static/chunks/4121-c8d5d717e31899e1.js +0 -1
  118. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/WHEEL +0 -0
  119. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/entry_points.txt +0 -0
  120. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/licenses/LICENSE +0 -0
  121. {ethyca_fides-2.69.0rc10.dist-info → ethyca_fides-2.69.1.dist-info}/top_level.txt +0 -0
  122. /fides/ui-build/static/admin/_next/static/{8qfO1Ol3G3QbcXpHAnPlU → 1TigfgzjzHeoVqRLNIMYa}/_ssgManifest.js +0 -0
  123. /fides/ui-build/static/admin/_next/static/chunks/{1817-3d9e110e007853f0.js → 1817-0ca16d288fad916d.js} +0 -0
  124. /fides/ui-build/static/admin/_next/static/chunks/{3620-31ebb43dba84cbbd.js → 3620-602eb74dc896d556.js} +0 -0
  125. /fides/ui-build/static/admin/_next/static/chunks/{3729-a1ca1608efc11ac4.js → 3729-c17ac8031a4c4fd1.js} +0 -0
  126. /fides/ui-build/static/admin/_next/static/chunks/{3872-a91143aa35fa8ef8.js → 3872-f78dec02f0d959ae.js} +0 -0
  127. /fides/ui-build/static/admin/_next/static/chunks/{4608-23bbd4c3c4a59f42.js → 4608-be8cba73f5d7c326.js} +0 -0
  128. /fides/ui-build/static/admin/_next/static/chunks/{4786-0827aae7aceadd22.js → 4786-61154adf88e448e1.js} +0 -0
  129. /fides/ui-build/static/admin/_next/static/chunks/{4808-78ca630f2d2503cd.js → 4808-dd4157aa72648068.js} +0 -0
  130. /fides/ui-build/static/admin/_next/static/chunks/{5487-8c635883dcaa9c2a.js → 5487-02d00bad7c6830e0.js} +0 -0
  131. /fides/ui-build/static/admin/_next/static/chunks/{6084-0096d7de64ef8015.js → 6084-c153669d5567e242.js} +0 -0
  132. /fides/ui-build/static/admin/_next/static/chunks/{6954-9d46e2276c461c26.js → 6954-5296188c19d7d0ac.js} +0 -0
  133. /fides/ui-build/static/admin/_next/static/chunks/{7476-d1b0af9ade392e5b.js → 7476-45c5088baa8b66af.js} +0 -0
  134. /fides/ui-build/static/admin/_next/static/chunks/{7630-da0a7ce4e3a0d62c.js → 7630-7ed6c6117775dffe.js} +0 -0
  135. /fides/ui-build/static/admin/_next/static/chunks/{787-3499983fa346b380.js → 787-a8c7eab617e2fceb.js} +0 -0
  136. /fides/ui-build/static/admin/_next/static/chunks/{79-f197fc4db8d530e5.js → 79-65674011d455af4d.js} +0 -0
  137. /fides/ui-build/static/admin/_next/static/chunks/{796-db1e30119ea973c7.js → 796-9e1ca1a4030707c5.js} +0 -0
  138. /fides/ui-build/static/admin/_next/static/chunks/{8002-971e29181f72edd1.js → 8002-24af20d679efc04e.js} +0 -0
  139. /fides/ui-build/static/admin/_next/static/chunks/{9826-b0b3d3cfb13bfbc1.js → 9826-dbae8dee941a7fac.js} +0 -0
  140. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-9dc7e70ab5b05723.js → manual-ace203dfacacbdc4.js} +0 -0
  141. /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-4b79a1652297ed9a.js → multiple-920fb469e0dda1d2.js} +0 -0
  142. /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-1632a59203fe8eab.js → add-systems-bd0d82078e67cac3.js} +0 -0
  143. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-1ca9df7ca91bd101.js → add-vendors-406170eaae4329c6.js} +0 -0
  144. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-07bdbc9ae4137db4.js → configure-7207ab23bdb36ce8.js} +0 -0
  145. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-2795cd4115a77c94.js → privacy-experience-9dda4de5ec580279.js} +0 -0
  146. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-e02921dc82dccbb1.js → [id]-b378576cba255609.js} +0 -0
  147. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-98f9e4ba3610628a.js → new-2ca1de7b88094ab0.js} +0 -0
  148. /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-17ed82777810d1c6.js → privacy-notices-0d4844d0b808e6e4.js} +0 -0
  149. /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-09610b10923d9268.js → consent-3e8bdefe714254ec.js} +0 -0
  150. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-da1a48336daff6f8.js → [resourceUrn]-2c29ff7a01198f30.js} +0 -0
  151. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-d8e776f1e64e4ba8.js → [projectUrn]-04cfe2cfba7b7cd8.js} +0 -0
  152. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-75b9629b0d9cdf96.js → projects-5f2d7b24804f861f.js} +0 -0
  153. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-470da05db63767cd.js → [resourceUrn]-8eb581024bc0172f.js} +0 -0
  154. /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-6c3714ee97a718c1.js → resources-de704de849960f01.js} +0 -0
  155. /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6984c033b8fe3a13.js → data-catalog-30108b00ac769fc3.js} +0 -0
  156. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-2f0a33ef9ba1f1da.js → [systemId]-e1ba213fb666b3f4.js} +0 -0
  157. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/{[monitorId]-e9d4f25b20ff6781.js → [monitorId]-6d133580045abdda.js} +0 -0
  158. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9c428d3ef0985915.js → action-center-9a81d42a474e1e48.js} +0 -0
  159. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-c3a97e6721ca0abe.js → [resourceUrn]-8f736b078e9842da.js} +0 -0
  160. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-a0a7de552ef71f5b.js → detection-eb814e3c22807871.js} +0 -0
  161. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-109754fec0755339.js → [resourceUrn]-6875b7783fcfda2f.js} +0 -0
  162. /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-88654783b06b3b21.js → discovery-172dbd7740e212ca.js} +0 -0
  163. /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-89136e6800dc9369.js → datamap-c7390e046b2e2b7f.js} +0 -0
  164. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-8f58192dcb54883d.js → [...subfieldNames]-dfd71c1e9c458b89.js} +0 -0
  165. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-dcb4ab380a77aa1e.js → [collectionName]-7cdc42ec5493b83d.js} +0 -0
  166. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-6f16d43071fb9c11.js → [datasetId]-e12b11ba15bc3fc1.js} +0 -0
  167. /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-97f06e21580f1f6a.js → new-e32fccc4ca520d2b.js} +0 -0
  168. /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-674bb3940f088ecc.js → dataset-7c59a6abf6ba6207.js} +0 -0
  169. /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-6f77d8647fca71e0.js → [id]-927b7e476c4b47d0.js} +0 -0
  170. /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-821dd1269834cfa2.js → new-cbe100d50df34285.js} +0 -0
  171. /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-23e4caf79faa8106.js → datastore-connection-cce20440b177050b.js} +0 -0
  172. /fides/ui-build/static/admin/_next/static/chunks/pages/{index-23eb64eed81dcb69.js → index-6cd8708106331b8d.js} +0 -0
  173. /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-3a4cd3fe9094fba3.js → [id]-4c3c413a2668df53.js} +0 -0
  174. /fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-57e618d7b16ac69a.js → integrations-95402b5001c07ef2.js} +0 -0
  175. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-c9a323eb6a929476.js → [id]-3c6dc2f6e6bae960.js} +0 -0
  176. /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-b9bb09e46921a590.js → add-template-4a6d4023a7791be8.js} +0 -0
  177. /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-82c631a12b5a008c.js → messaging-76b204c9b98d656f.js} +0 -0
  178. /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-38360083348c3d6c.js → table-migration-48500551fd6a7602.js} +0 -0
  179. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-0d0bb9eb004a3336.js → [id]-0f25a76dd18c5e20.js} +0 -0
  180. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-f9320a58f489f5b7.js → messaging-ad6ad3e5bd72765d.js} +0 -0
  181. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-d0cfa8aeddd43a40.js → storage-6032d82f0fc2893d.js} +0 -0
  182. /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-72ca94ec5ed85733.js → configure-d83e5bd52a638234.js} +0 -0
  183. /fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-5a5edc8a4aa7c30a.js → privacy-requests-baf31c3e4b081046.js} +0 -0
  184. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-5ec775c4904fdbfe.js → [id]-e784c05d056b2371.js} +0 -0
  185. /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-a6812c0916f2949e.js → add-property-0a7a2db148a7561a.js} +0 -0
  186. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-3e72e9f91991c119.js → alpha-a82f3df840d5c1b5.js} +0 -0
  187. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-6aab092f4871cecb.js → about-d06fb16487705b9d.js} +0 -0
  188. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-be47008304106395.js → consent-93a978443bf299db.js} +0 -0
  189. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-ae1b57589da7b175.js → custom-fields-9ecb803099082bf4.js} +0 -0
  190. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-23a6d7a921150188.js → domain-records-16fdd91a81074dd1.js} +0 -0
  191. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2a9e8859ab4d9de6.js → domains-4cdd6001e7cb9aee.js} +0 -0
  192. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-4f9f0fdf9925ae90.js → email-templates-1914de830ce5cfc4.js} +0 -0
  193. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-46f7af35cee4a8bb.js → locations-2e635dcd11b78224.js} +0 -0
  194. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-a596a96cb8d0aa8e.js → organization-f547f1f33c12faf3.js} +0 -0
  195. /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-6ed5fc2410e00857.js → regulations-7c02e469d8c5bd74.js} +0 -0
  196. /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-86811e3cda277e77.js → test-datasets-20b1193ed76c56b0.js} +0 -0
  197. /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-5a43f108d8047d5b.js → [id]-6e15332935f6b538.js} +0 -0
  198. /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-045a841e22e85ea8.js → systems-fbc8761ef4d55516.js} +0 -0
  199. /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-1b3f2d4bcb0e164d.js → taxonomy-4d7827fc9c46b6b8.js} +0 -0
  200. /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-2cab41659f1ee7da.js → user-management-9cec020f89544426.js} +0 -0
fides/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-09-03T03:15:58-0600",
11
+ "date": "2025-09-03T13:05:01-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "a5e1c1d6e27ce01f06c74fd8456a51722714706f",
15
- "version": "2.69.0rc10"
14
+ "full-revisionid": "239cb598ba6d808dd1d221506b13f5a2912c8357",
15
+ "version": "2.69.1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,52 @@
1
+ """adding privacy requeste redaction patterns
2
+
3
+ Revision ID: 78dbe23d8204
4
+ Revises: b1a2c3d4e5f6
5
+ Create Date: 2025-08-30 05:40:17.816172
6
+
7
+ """
8
+
9
+ import sqlalchemy as sa
10
+ from alembic import op
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = "78dbe23d8204"
14
+ down_revision = "b1a2c3d4e5f6"
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade():
20
+ op.create_table(
21
+ "privacy_request_redaction_pattern",
22
+ sa.Column("id", sa.String(length=255), nullable=False),
23
+ sa.Column(
24
+ "created_at",
25
+ sa.DateTime(timezone=True),
26
+ server_default=sa.text("now()"),
27
+ nullable=True,
28
+ ),
29
+ sa.Column(
30
+ "updated_at",
31
+ sa.DateTime(timezone=True),
32
+ server_default=sa.text("now()"),
33
+ nullable=True,
34
+ ),
35
+ sa.Column("pattern", sa.String(), nullable=False),
36
+ sa.PrimaryKeyConstraint("id"),
37
+ sa.UniqueConstraint("pattern"),
38
+ )
39
+ op.create_index(
40
+ op.f("ix_privacy_request_redaction_pattern_id"),
41
+ "privacy_request_redaction_pattern",
42
+ ["id"],
43
+ unique=False,
44
+ )
45
+
46
+
47
+ def downgrade():
48
+ op.drop_index(
49
+ op.f("ix_privacy_request_redaction_pattern_id"),
50
+ table_name="privacy_request_redaction_pattern",
51
+ )
52
+ op.drop_table("privacy_request_redaction_pattern")
fides/api/api/v1/api.py CHANGED
@@ -17,6 +17,7 @@ from fides.api.api.v1.endpoints import (
17
17
  policy_webhook_endpoints,
18
18
  pre_approval_webhook_endpoints,
19
19
  privacy_request_endpoints,
20
+ privacy_request_redaction_patterns_endpoints,
20
21
  registration_endpoints,
21
22
  saas_config_endpoints,
22
23
  storage_endpoints,
@@ -41,6 +42,7 @@ api_router.include_router(policy_endpoints.router)
41
42
  api_router.include_router(policy_webhook_endpoints.router)
42
43
  api_router.include_router(pre_approval_webhook_endpoints.router)
43
44
  api_router.include_router(privacy_request_endpoints.router)
45
+ api_router.include_router(privacy_request_redaction_patterns_endpoints.router)
44
46
  api_router.include_router(identity_verification_endpoints.router)
45
47
  api_router.include_router(storage_endpoints.router)
46
48
  api_router.include_router(messaging_endpoints.router)
@@ -21,7 +21,7 @@ from fides.api.schemas.privacy_request import PrivacyRequestStatus
21
21
  from fides.api.schemas.storage.storage import StorageType
22
22
  from fides.api.service.storage.streaming.s3 import S3StorageClient
23
23
  from fides.api.util.api_router import APIRouter
24
- from fides.api.util.endpoint_utils import fides_limiter
24
+ from fides.api.util.rate_limit import fides_limiter
25
25
  from fides.common.api.v1.urn_registry import PRIVACY_CENTER_DSR_PACKAGE, V1_URL_PREFIX
26
26
  from fides.config import CONFIG
27
27
 
@@ -62,7 +62,7 @@ def raise_error(status_code: int, detail: str) -> None:
62
62
  PRIVACY_CENTER_DSR_PACKAGE,
63
63
  status_code=HTTP_302_FOUND,
64
64
  )
65
- @fides_limiter.limit(CONFIG.security.public_request_rate_limit)
65
+ @fides_limiter.limit(CONFIG.security.request_rate_limit)
66
66
  def get_access_results_urls(
67
67
  privacy_request_id: str,
68
68
  token: str,
@@ -8,8 +8,8 @@ from loguru import logger
8
8
  from sqlalchemy.orm import Session
9
9
  from starlette.status import (
10
10
  HTTP_400_BAD_REQUEST,
11
+ HTTP_403_FORBIDDEN,
11
12
  HTTP_404_NOT_FOUND,
12
- HTTP_422_UNPROCESSABLE_ENTITY,
13
13
  )
14
14
 
15
15
  from fides.api.api.deps import get_db
@@ -26,7 +26,7 @@ from fides.api.models.client import ClientDetail
26
26
  from fides.api.models.connectionconfig import ConnectionConfig, ConnectionTestStatus
27
27
  from fides.api.models.fides_user import FidesUser
28
28
  from fides.api.oauth.roles import ROLES_TO_SCOPES_MAPPING
29
- from fides.api.oauth.utils import verify_oauth_client
29
+ from fides.api.oauth.utils import verify_client_can_assign_scopes, verify_oauth_client
30
30
  from fides.api.schemas.client import ClientCreatedResponse
31
31
  from fides.api.schemas.oauth import AccessToken, OAuth2ClientCredentialsRequestForm
32
32
  from fides.api.service.authentication.authentication_strategy import (
@@ -37,6 +37,7 @@ from fides.api.service.authentication.authentication_strategy_oauth2_authorizati
37
37
  )
38
38
  from fides.api.util.api_router import APIRouter
39
39
  from fides.api.util.connection_util import connection_status
40
+ from fides.api.util.rate_limit import fides_limiter
40
41
  from fides.common.api.scope_registry import (
41
42
  CLIENT_CREATE,
42
43
  CLIENT_DELETE,
@@ -65,6 +66,7 @@ router = APIRouter(tags=["OAuth"], prefix=V1_URL_PREFIX)
65
66
  TOKEN,
66
67
  response_model=AccessToken,
67
68
  )
69
+ @fides_limiter.limit(CONFIG.security.auth_rate_limit)
68
70
  async def acquire_access_token(
69
71
  request: Request,
70
72
  response: Response,
@@ -121,22 +123,28 @@ async def acquire_access_token(
121
123
 
122
124
  @router.post(
123
125
  CLIENT,
124
- dependencies=[Security(verify_oauth_client, scopes=[CLIENT_CREATE])],
125
126
  response_model=ClientCreatedResponse,
126
127
  )
127
128
  def create_client(
128
129
  *,
130
+ request: Request,
129
131
  db: Session = Depends(get_db),
130
132
  scopes: List[str] = Body([]),
133
+ requesting_client: ClientDetail = Security(
134
+ verify_oauth_client, scopes=[CLIENT_CREATE]
135
+ ),
131
136
  ) -> ClientCreatedResponse:
132
137
  """Creates a new client and returns the credentials. Only direct scopes can be added to the client via this endpoint."""
133
138
  logger.info("Creating new client")
134
139
  if not all(scope in SCOPE_REGISTRY for scope in scopes):
135
140
  raise HTTPException(
136
- status_code=HTTP_422_UNPROCESSABLE_ENTITY,
141
+ status_code=HTTP_403_FORBIDDEN,
137
142
  detail=f"Invalid Scope. Scopes must be one of {SCOPE_REGISTRY}.",
138
143
  )
139
144
 
145
+ # Security check: Verify that the requesting client has all the scopes they're trying to assign
146
+ verify_client_can_assign_scopes(request, requesting_client, scopes, db)
147
+
140
148
  client, secret = ClientDetail.create_client_and_secret(
141
149
  db,
142
150
  CONFIG.security.oauth_client_id_length_bytes,
@@ -178,13 +186,16 @@ def get_client_scopes(client_id: str, db: Session = Depends(get_db)) -> List[str
178
186
 
179
187
  @router.put(
180
188
  CLIENT_SCOPE,
181
- dependencies=[Security(verify_oauth_client, scopes=[CLIENT_UPDATE])],
182
189
  response_model=None,
183
190
  )
184
191
  def set_client_scopes(
185
192
  client_id: str,
186
193
  scopes: List[str],
194
+ request: Request,
187
195
  db: Session = Depends(get_db),
196
+ requesting_client: ClientDetail = Security(
197
+ verify_oauth_client, scopes=[CLIENT_UPDATE]
198
+ ),
188
199
  ) -> None:
189
200
  """Overwrites the client's directly-assigned scopes with those provided.
190
201
  Roles cannot be edited via this endpoint.
@@ -195,10 +206,13 @@ def set_client_scopes(
195
206
 
196
207
  if not all(elem in SCOPE_REGISTRY for elem in scopes):
197
208
  raise HTTPException(
198
- status_code=HTTP_422_UNPROCESSABLE_ENTITY,
209
+ status_code=HTTP_403_FORBIDDEN,
199
210
  detail=f"Invalid Scope. Scopes must be one of {SCOPE_REGISTRY}.",
200
211
  )
201
212
 
213
+ # Security check: Verify that the requesting client has all the scopes they're trying to assign
214
+ verify_client_can_assign_scopes(request, requesting_client, scopes, db)
215
+
202
216
  logger.info("Updating client scopes")
203
217
  client.update(db, data={"scopes": scopes})
204
218
 
@@ -0,0 +1,95 @@
1
+ from fastapi import Depends, HTTPException, Security
2
+ from fastapi.routing import APIRouter
3
+ from loguru import logger
4
+ from sqlalchemy.orm import Session
5
+ from starlette.status import HTTP_200_OK
6
+
7
+ from fides.api.api.deps import get_db
8
+ from fides.api.models.privacy_request_redaction_pattern import (
9
+ PrivacyRequestRedactionPattern,
10
+ )
11
+ from fides.api.oauth.utils import verify_oauth_client
12
+ from fides.api.schemas.privacy_request_redaction_patterns import (
13
+ PrivacyRequestRedactionPatternsRequest,
14
+ PrivacyRequestRedactionPatternsResponse,
15
+ )
16
+ from fides.common.api.scope_registry import (
17
+ PRIVACY_REQUEST_REDACTION_PATTERNS_READ,
18
+ PRIVACY_REQUEST_REDACTION_PATTERNS_UPDATE,
19
+ )
20
+ from fides.common.api.v1.urn_registry import (
21
+ PRIVACY_REQUEST_REDACTION_PATTERNS,
22
+ V1_URL_PREFIX,
23
+ )
24
+
25
+ router = APIRouter(
26
+ tags=["Privacy Request Redaction Patterns"],
27
+ prefix=V1_URL_PREFIX,
28
+ )
29
+
30
+
31
+ @router.get(
32
+ PRIVACY_REQUEST_REDACTION_PATTERNS,
33
+ status_code=HTTP_200_OK,
34
+ response_model=PrivacyRequestRedactionPatternsResponse,
35
+ dependencies=[
36
+ Security(verify_oauth_client, scopes=[PRIVACY_REQUEST_REDACTION_PATTERNS_READ])
37
+ ],
38
+ )
39
+ def get_privacy_request_redaction_patterns(
40
+ *, db: Session = Depends(get_db)
41
+ ) -> PrivacyRequestRedactionPatternsResponse:
42
+ """
43
+ Get the current privacy request redaction patterns configuration.
44
+
45
+ Returns the list of regex patterns used to mask dataset, collection,
46
+ and field names in privacy request package reports.
47
+ """
48
+ logger.info("Getting privacy request redaction patterns configuration")
49
+
50
+ patterns = PrivacyRequestRedactionPattern.get_patterns(db)
51
+ return PrivacyRequestRedactionPatternsResponse(patterns=patterns)
52
+
53
+
54
+ @router.put(
55
+ PRIVACY_REQUEST_REDACTION_PATTERNS,
56
+ status_code=HTTP_200_OK,
57
+ response_model=PrivacyRequestRedactionPatternsResponse,
58
+ dependencies=[
59
+ Security(
60
+ verify_oauth_client, scopes=[PRIVACY_REQUEST_REDACTION_PATTERNS_UPDATE]
61
+ )
62
+ ],
63
+ )
64
+ def update_privacy_request_redaction_patterns(
65
+ *,
66
+ db: Session = Depends(get_db),
67
+ request: PrivacyRequestRedactionPatternsRequest,
68
+ ) -> PrivacyRequestRedactionPatternsResponse:
69
+ """
70
+ Update the privacy request redaction patterns configuration.
71
+
72
+ This is a complete replacement of the patterns list. To clear all patterns,
73
+ send an empty list.
74
+ """
75
+ logger.info(
76
+ "Updating privacy request redaction patterns configuration with {} patterns",
77
+ len(request.patterns),
78
+ )
79
+
80
+ try:
81
+ updated = PrivacyRequestRedactionPattern.replace_patterns(
82
+ db=db, patterns=request.patterns
83
+ )
84
+
85
+ logger.info("Successfully updated privacy request redaction patterns")
86
+ return PrivacyRequestRedactionPatternsResponse(patterns=updated)
87
+
88
+ except Exception as exc:
89
+ logger.exception(
90
+ "Failed to update privacy request redaction patterns: {}", str(exc)
91
+ )
92
+ raise HTTPException(
93
+ status_code=500,
94
+ detail="Failed to update privacy request redaction patterns",
95
+ ) from exc
@@ -5,7 +5,7 @@ from datetime import datetime
5
5
  from typing import List, Optional
6
6
 
7
7
  import jose.exceptions
8
- from fastapi import Depends, HTTPException, Security
8
+ from fastapi import Depends, HTTPException, Request, Response, Security
9
9
  from fastapi.security import SecurityScopes
10
10
  from fastapi_pagination import Page, Params
11
11
  from fastapi_pagination.bases import AbstractPage
@@ -59,6 +59,7 @@ from fides.api.schemas.user import (
59
59
  )
60
60
  from fides.api.service.deps import get_user_service
61
61
  from fides.api.util.api_router import APIRouter
62
+ from fides.api.util.rate_limit import fides_limiter
62
63
  from fides.common.api.scope_registry import (
63
64
  SCOPE_REGISTRY,
64
65
  SYSTEM_MANAGER_DELETE,
@@ -207,6 +208,17 @@ def update_user_password(
207
208
 
208
209
  current_user.update_password(db=db, new_password=data.new_password)
209
210
 
211
+ # Delete the user's associated OAuth client to invalidate all existing sessions
212
+ if current_user.client:
213
+ try:
214
+ current_user.client.delete(db)
215
+ except Exception as exc:
216
+ logger.exception(
217
+ "Unable to delete user client during password reset for user {}: {}",
218
+ current_user.id,
219
+ exc,
220
+ )
221
+
210
222
  logger.info("Updated user with id: '{}'.", current_user.id)
211
223
  return current_user
212
224
 
@@ -235,6 +247,18 @@ def force_update_password(
235
247
  )
236
248
 
237
249
  user.update_password(db=db, new_password=data.new_password)
250
+
251
+ # Delete the user's associated OAuth client to invalidate all existing sessions
252
+ if user.client:
253
+ try:
254
+ user.client.delete(db)
255
+ except Exception as exc:
256
+ logger.exception(
257
+ "Unable to delete user client during admin-forced password reset for user {}: {}",
258
+ user.id,
259
+ exc,
260
+ )
261
+
238
262
  logger.info("Updated user with id: '{}'.", user.id)
239
263
  return user
240
264
 
@@ -617,8 +641,11 @@ def get_users(
617
641
  status_code=HTTP_200_OK,
618
642
  response_model=UserLoginResponse,
619
643
  )
644
+ @fides_limiter.limit(CONFIG.security.auth_rate_limit)
620
645
  def user_login(
621
646
  *,
647
+ request: Request,
648
+ response: Response,
622
649
  db: Session = Depends(get_db),
623
650
  config: FidesConfig = Depends(get_config),
624
651
  user_data: UserLogin,
fides/api/app_setup.py CHANGED
@@ -48,9 +48,13 @@ from fides.api.service.saas_request.override_implementations import *
48
48
  from fides.api.util.api_router import APIRouter
49
49
  from fides.api.util.cache import get_cache
50
50
  from fides.api.util.consent_util import create_default_tcf_purpose_overrides_on_startup
51
- from fides.api.util.endpoint_utils import fides_limiter
52
51
  from fides.api.util.errors import FidesError
53
52
  from fides.api.util.logger import setup as setup_logging
53
+ from fides.api.util.rate_limit import (
54
+ RateLimitIPValidationMiddleware,
55
+ fides_limiter,
56
+ is_rate_limit_enabled,
57
+ )
54
58
  from fides.config import CONFIG
55
59
  from fides.config.config_proxy import ConfigProxy
56
60
 
@@ -88,7 +92,17 @@ def create_fides_app(
88
92
  for handler in ExceptionHandlers.get_handlers():
89
93
  # Starlette bug causing this to fail mypy
90
94
  fastapi_app.add_exception_handler(RedisNotConfigured, handler) # type: ignore
91
- fastapi_app.add_middleware(SlowAPIMiddleware)
95
+
96
+ if is_rate_limit_enabled:
97
+ # Validate header before SlowAPI processes the request
98
+ fastapi_app.add_middleware(RateLimitIPValidationMiddleware)
99
+ # Required for default rate limiting to work
100
+ fastapi_app.add_middleware(SlowAPIMiddleware)
101
+ else:
102
+ logger.warning(
103
+ "Rate limiting client IPs is disabled because the FIDES__SECURITY__RATE_LIMIT_CLIENT_IP_HEADER env var is not configured."
104
+ )
105
+
92
106
  fastapi_app.add_middleware(
93
107
  GZipMiddleware, minimum_size=1000, compresslevel=5
94
108
  ) # minimum_size is in bytes
fides/api/db/base.py CHANGED
@@ -66,6 +66,9 @@ from fides.api.models.privacy_preference import (
66
66
  ServedNoticeHistory,
67
67
  )
68
68
  from fides.api.models.privacy_request import PrivacyRequest
69
+ from fides.api.models.privacy_request_redaction_pattern import (
70
+ PrivacyRequestRedactionPattern,
71
+ )
69
72
  from fides.api.models.property import (
70
73
  MessagingTemplateToProperty,
71
74
  PrivacyExperienceConfigProperty,
fides/api/main.py CHANGED
@@ -18,6 +18,8 @@ from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
18
18
  from fideslog.sdk.python.event import AnalyticsEvent
19
19
  from loguru import logger
20
20
  from pyinstrument import Profiler
21
+ from slowapi import _rate_limit_exceeded_handler
22
+ from slowapi.errors import RateLimitExceeded
21
23
  from starlette.background import BackgroundTask
22
24
  from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
23
25
  from uvicorn import Config, Server
@@ -60,6 +62,7 @@ from fides.api.ui import (
60
62
  )
61
63
  from fides.api.util.endpoint_utils import API_PREFIX
62
64
  from fides.api.util.logger import _log_exception
65
+ from fides.api.util.rate_limit import safe_rate_limit_key
63
66
  from fides.cli.utils import FIDES_ASCII_ART
64
67
  from fides.config import CONFIG, check_required_webserver_config_values
65
68
 
@@ -388,3 +391,22 @@ async def request_validation_exception_handler(
388
391
  "detail": jsonable_encoder(exc.errors(), exclude={"input", "url", "ctx"})
389
392
  },
390
393
  )
394
+
395
+
396
+ @app.exception_handler(RateLimitExceeded)
397
+ async def rate_limit_handler(request: Request, exc: RateLimitExceeded) -> Response:
398
+ """Log rate limit violations and delegate to default handler."""
399
+ client_ip = safe_rate_limit_key(
400
+ request
401
+ ) # non exception-raising, falls back to source IP
402
+
403
+ # Log the rate limit event
404
+ logger.warning(
405
+ "Rate limit exceeded - IP: %s, Path: %s, Method: %s",
406
+ client_ip,
407
+ request.url.path,
408
+ request.method,
409
+ )
410
+
411
+ # Use the default handler to generate the proper response
412
+ return _rate_limit_exceeded_handler(request, exc)
@@ -51,6 +51,7 @@ class ClientDetail(Base):
51
51
  user_id = Column(
52
52
  String, ForeignKey(FidesUser.id_field_path), nullable=True, unique=True
53
53
  )
54
+ user: Optional["FidesUser"]
54
55
 
55
56
  @classmethod
56
57
  def create_client_and_secret(
@@ -0,0 +1,64 @@
1
+ from typing import List, Set
2
+
3
+ from sqlalchemy import Column, String
4
+ from sqlalchemy.ext.declarative import declared_attr
5
+ from sqlalchemy.orm import Session
6
+
7
+ from fides.api.db.base_class import Base
8
+
9
+
10
+ class PrivacyRequestRedactionPattern(Base):
11
+ """
12
+ Stores one regex pattern per row for masking dataset, collection, and field names
13
+ in DSR package reports.
14
+ """
15
+
16
+ @declared_attr
17
+ def __tablename__(self) -> str:
18
+ return "privacy_request_redaction_pattern"
19
+
20
+ # One pattern per row; unique to prevent duplicates
21
+ pattern = Column(String, nullable=False, unique=True)
22
+
23
+ @classmethod
24
+ def get_patterns(cls, db: Session) -> List[str]:
25
+ """
26
+ Get the current list of masking patterns ordered by creation time.
27
+
28
+ Returns:
29
+ List of regex pattern strings, or None if no patterns are configured
30
+ """
31
+ rows = db.query(cls).order_by(cls.created_at.asc()).all()
32
+ if not rows:
33
+ return []
34
+ return [row.pattern for row in rows]
35
+
36
+ @classmethod
37
+ def replace_patterns(cls, db: Session, patterns: List[str]) -> List[str]:
38
+ """
39
+ Replace the set of stored patterns with the provided list using set reconciliation.
40
+
41
+ - Adds patterns that are not present
42
+ - Removes patterns that are no longer desired
43
+ - Returns the resulting canonical list in deterministic order
44
+ """
45
+ # Normalize: trim whitespace, remove empties and duplicates
46
+ desired: Set[str] = {p.strip() for p in patterns if p and p.strip()}
47
+
48
+ # Fetch existing patterns from DB as a set
49
+ existing: Set[str] = set(p for (p,) in db.query(cls.pattern).all())
50
+
51
+ to_add = desired - existing
52
+ to_remove = existing - desired
53
+
54
+ if to_remove:
55
+ db.query(cls).filter(cls.pattern.in_(list(to_remove))).delete(
56
+ synchronize_session=False
57
+ )
58
+
59
+ if to_add:
60
+ db.bulk_save_objects([cls(pattern=p) for p in to_add])
61
+
62
+ db.commit()
63
+
64
+ return sorted(desired)