ethyca-fides 2.69.1b2__py2.py3-none-any.whl → 2.69.1rc0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/METADATA +2 -2
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/RECORD +204 -197
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/78dbe23d8204_adding_privacy_request_redaction_patterns.py +52 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/oauth_endpoints.py +18 -6
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +5 -3
- fides/api/api/v1/endpoints/privacy_request_redaction_patterns_endpoints.py +95 -0
- fides/api/api/v1/endpoints/user_endpoints.py +26 -3
- fides/api/db/base.py +3 -0
- fides/api/models/client.py +1 -0
- fides/api/models/privacy_request_redaction_pattern.py +64 -0
- fides/api/oauth/utils.py +117 -6
- fides/api/schemas/privacy_request_redaction_patterns.py +55 -0
- fides/api/service/privacy_request/dsr_package/dsr_data_preprocessor.py +231 -0
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +286 -120
- fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +4 -2
- fides/api/service/privacy_request/dsr_package/templates/collection_index.html +3 -1
- fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +1 -1
- fides/api/service/privacy_request/dsr_package/utils.py +268 -0
- fides/api/service/privacy_request/request_runner_service.py +8 -2
- fides/api/service/privacy_request/request_service.py +1 -1
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +107 -170
- fides/api/service/storage/util.py +579 -0
- fides/api/task/graph_runners.py +32 -2
- fides/api/task/graph_task.py +2 -4
- fides/api/task/manual/manual_task_graph_task.py +11 -9
- fides/api/tasks/storage.py +2 -2
- fides/common/api/scope_registry.py +8 -0
- fides/common/api/v1/urn_registry.py +3 -0
- fides/config/execution_settings.py +4 -0
- fides/config/security_settings.py +1 -4
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/OmXHlY9MvjoZH9jDkAytl/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5258-e880b606a2293803.js → 5258-b0de22a8521686ab.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-ef8e1c986bc5b795.js → _app-fcdad91f6f66292b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-de8cb3739ab99c09.js → new-92f52c43f522a350.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-05d61c80a556b2d5.js → [id]-64452dfae2c5e614.js} +1 -1
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- fides/ui-build/static/admin/poc/ant-components.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/AntForm.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikAntFormItem.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikControlled.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikField.html +1 -1
- fides/ui-build/static/admin/poc/form-experiments/FormikSpreadField.html +1 -1
- fides/ui-build/static/admin/poc/forms.html +1 -1
- fides/ui-build/static/admin/poc/table-migration.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/settings/about/alpha.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent/[configuration_id]/[purpose_id].html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/privacy-requests.html +1 -0
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/task/scheduler_utils.py +0 -39
- fides/ui-build/static/admin/_next/static/0agWtBSaxTBxQfxPA99Ra/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4121-c8d5d717e31899e1.js +0 -1
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.69.1b2.dist-info → ethyca_fides-2.69.1rc0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{0agWtBSaxTBxQfxPA99Ra → OmXHlY9MvjoZH9jDkAytl}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{1817-3d9e110e007853f0.js → 1817-0ca16d288fad916d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3620-31ebb43dba84cbbd.js → 3620-602eb74dc896d556.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3729-a1ca1608efc11ac4.js → 3729-c17ac8031a4c4fd1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3872-a91143aa35fa8ef8.js → 3872-f78dec02f0d959ae.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4608-23bbd4c3c4a59f42.js → 4608-be8cba73f5d7c326.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4786-0827aae7aceadd22.js → 4786-61154adf88e448e1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4808-78ca630f2d2503cd.js → 4808-dd4157aa72648068.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5487-8c635883dcaa9c2a.js → 5487-02d00bad7c6830e0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6084-0096d7de64ef8015.js → 6084-c153669d5567e242.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6954-9d46e2276c461c26.js → 6954-5296188c19d7d0ac.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7476-d1b0af9ade392e5b.js → 7476-45c5088baa8b66af.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-da0a7ce4e3a0d62c.js → 7630-7ed6c6117775dffe.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{787-3499983fa346b380.js → 787-a8c7eab617e2fceb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{79-f197fc4db8d530e5.js → 79-65674011d455af4d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{796-db1e30119ea973c7.js → 796-9e1ca1a4030707c5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{8002-971e29181f72edd1.js → 8002-24af20d679efc04e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-b0b3d3cfb13bfbc1.js → 9826-dbae8dee941a7fac.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-9dc7e70ab5b05723.js → manual-ace203dfacacbdc4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-4b79a1652297ed9a.js → multiple-920fb469e0dda1d2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-1632a59203fe8eab.js → add-systems-bd0d82078e67cac3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-1ca9df7ca91bd101.js → add-vendors-406170eaae4329c6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-07bdbc9ae4137db4.js → configure-7207ab23bdb36ce8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-2795cd4115a77c94.js → privacy-experience-9dda4de5ec580279.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-e02921dc82dccbb1.js → [id]-b378576cba255609.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-98f9e4ba3610628a.js → new-2ca1de7b88094ab0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-17ed82777810d1c6.js → privacy-notices-0d4844d0b808e6e4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-09610b10923d9268.js → consent-3e8bdefe714254ec.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-da1a48336daff6f8.js → [resourceUrn]-2c29ff7a01198f30.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-d8e776f1e64e4ba8.js → [projectUrn]-04cfe2cfba7b7cd8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-75b9629b0d9cdf96.js → projects-5f2d7b24804f861f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-470da05db63767cd.js → [resourceUrn]-8eb581024bc0172f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-6c3714ee97a718c1.js → resources-de704de849960f01.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6984c033b8fe3a13.js → data-catalog-30108b00ac769fc3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-2f0a33ef9ba1f1da.js → [systemId]-e1ba213fb666b3f4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/{[monitorId]-e9d4f25b20ff6781.js → [monitorId]-6d133580045abdda.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9c428d3ef0985915.js → action-center-9a81d42a474e1e48.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-c3a97e6721ca0abe.js → [resourceUrn]-8f736b078e9842da.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-a0a7de552ef71f5b.js → detection-eb814e3c22807871.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-109754fec0755339.js → [resourceUrn]-6875b7783fcfda2f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-88654783b06b3b21.js → discovery-172dbd7740e212ca.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-89136e6800dc9369.js → datamap-c7390e046b2e2b7f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-8f58192dcb54883d.js → [...subfieldNames]-dfd71c1e9c458b89.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-dcb4ab380a77aa1e.js → [collectionName]-7cdc42ec5493b83d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-6f16d43071fb9c11.js → [datasetId]-e12b11ba15bc3fc1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-97f06e21580f1f6a.js → new-e32fccc4ca520d2b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-674bb3940f088ecc.js → dataset-7c59a6abf6ba6207.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-6f77d8647fca71e0.js → [id]-927b7e476c4b47d0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-821dd1269834cfa2.js → new-cbe100d50df34285.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-23e4caf79faa8106.js → datastore-connection-cce20440b177050b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-23eb64eed81dcb69.js → index-6cd8708106331b8d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-3a4cd3fe9094fba3.js → [id]-4c3c413a2668df53.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-57e618d7b16ac69a.js → integrations-95402b5001c07ef2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-c9a323eb6a929476.js → [id]-3c6dc2f6e6bae960.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-b9bb09e46921a590.js → add-template-4a6d4023a7791be8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-82c631a12b5a008c.js → messaging-76b204c9b98d656f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-38360083348c3d6c.js → table-migration-48500551fd6a7602.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-0d0bb9eb004a3336.js → [id]-0f25a76dd18c5e20.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-f9320a58f489f5b7.js → messaging-ad6ad3e5bd72765d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-d0cfa8aeddd43a40.js → storage-6032d82f0fc2893d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-72ca94ec5ed85733.js → configure-d83e5bd52a638234.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-5a5edc8a4aa7c30a.js → privacy-requests-baf31c3e4b081046.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-5ec775c4904fdbfe.js → [id]-e784c05d056b2371.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-a6812c0916f2949e.js → add-property-0a7a2db148a7561a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-3e72e9f91991c119.js → alpha-a82f3df840d5c1b5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-6aab092f4871cecb.js → about-d06fb16487705b9d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-be47008304106395.js → consent-93a978443bf299db.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-ae1b57589da7b175.js → custom-fields-9ecb803099082bf4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-23a6d7a921150188.js → domain-records-16fdd91a81074dd1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2a9e8859ab4d9de6.js → domains-4cdd6001e7cb9aee.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-4f9f0fdf9925ae90.js → email-templates-1914de830ce5cfc4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-46f7af35cee4a8bb.js → locations-2e635dcd11b78224.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-a596a96cb8d0aa8e.js → organization-f547f1f33c12faf3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-6ed5fc2410e00857.js → regulations-7c02e469d8c5bd74.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-86811e3cda277e77.js → test-datasets-20b1193ed76c56b0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-5a43f108d8047d5b.js → [id]-6e15332935f6b538.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-045a841e22e85ea8.js → systems-fbc8761ef4d55516.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-1b3f2d4bcb0e164d.js → taxonomy-4d7827fc9c46b6b8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-2cab41659f1ee7da.js → user-management-9cec020f89544426.js} +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Any, Dict, List, Literal, Optional, Set, Tuple
|
|
3
|
+
|
|
4
|
+
from loguru import logger
|
|
5
|
+
from sqlalchemy.orm import Session
|
|
6
|
+
|
|
7
|
+
from fides.api.models.privacy_request_redaction_pattern import (
|
|
8
|
+
PrivacyRequestRedactionPattern,
|
|
9
|
+
)
|
|
10
|
+
from fides.api.service.privacy_request.dsr_package.utils import (
|
|
11
|
+
get_redaction_entities_map_db,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DSRDataPreprocessor:
|
|
16
|
+
"""
|
|
17
|
+
Processes DSR data to apply name redaction before report generation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, db: Session):
|
|
21
|
+
self.db = db
|
|
22
|
+
self.redaction_patterns: List[str] = (
|
|
23
|
+
PrivacyRequestRedactionPattern.get_patterns(db) or []
|
|
24
|
+
)
|
|
25
|
+
self.entities_to_redact: Set[str] = get_redaction_entities_map_db(db)
|
|
26
|
+
|
|
27
|
+
def process_dsr_data(self, dsr_data: dict[str, Any]) -> dict[str, Any]:
|
|
28
|
+
"""Process the DSR data to apply all redaction upfront."""
|
|
29
|
+
if not self.redaction_patterns and not self.entities_to_redact:
|
|
30
|
+
return dsr_data
|
|
31
|
+
|
|
32
|
+
# First pass: collect and map dataset names
|
|
33
|
+
dataset_mapping = self._create_dataset_mapping(dsr_data)
|
|
34
|
+
|
|
35
|
+
# Second pass: process data with redaction
|
|
36
|
+
processed_data = {}
|
|
37
|
+
collection_indices: Dict[str, Dict[str, int]] = (
|
|
38
|
+
{}
|
|
39
|
+
) # Track collection indices within each dataset
|
|
40
|
+
|
|
41
|
+
for key, rows in dsr_data.items():
|
|
42
|
+
# The "attachment" key is used to pass in the privacy request's attachments into `dsr_data`.
|
|
43
|
+
# We don't need to redact these.
|
|
44
|
+
if key == "attachments":
|
|
45
|
+
processed_data[key] = rows
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
dataset_name, collection_name = self._parse_key(key, rows)
|
|
49
|
+
|
|
50
|
+
# Get redacted dataset name
|
|
51
|
+
redacted_dataset = dataset_mapping.get(dataset_name, dataset_name)
|
|
52
|
+
|
|
53
|
+
# Get redacted collection name (index per dataset)
|
|
54
|
+
if dataset_name not in collection_indices:
|
|
55
|
+
collection_indices[dataset_name] = {}
|
|
56
|
+
|
|
57
|
+
if collection_name not in collection_indices[dataset_name]:
|
|
58
|
+
collection_indices[dataset_name][collection_name] = (
|
|
59
|
+
len(collection_indices[dataset_name]) + 1
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
collection_index = collection_indices[dataset_name][collection_name]
|
|
63
|
+
redacted_collection = self._redact_name(
|
|
64
|
+
"collection", collection_name, collection_index, dataset_name
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Process rows
|
|
68
|
+
new_key = f"{redacted_dataset}:{redacted_collection}"
|
|
69
|
+
processed_data[new_key] = [
|
|
70
|
+
self._process_row(row, dataset_name, collection_name) for row in rows
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
return processed_data
|
|
74
|
+
|
|
75
|
+
def _create_dataset_mapping(self, dsr_data: dict[str, Any]) -> Dict[str, str]:
|
|
76
|
+
"""Create dataset name mapping with ordered numbering for redacted datasets."""
|
|
77
|
+
|
|
78
|
+
# Extract unique dataset names in order of appearance
|
|
79
|
+
dataset_names = []
|
|
80
|
+
for key, rows in dsr_data.items():
|
|
81
|
+
if key not in ["attachments", "dataset"]:
|
|
82
|
+
dataset_name, _ = self._parse_key(key, rows)
|
|
83
|
+
dataset_names.append(dataset_name)
|
|
84
|
+
|
|
85
|
+
unique_datasets = list(dict.fromkeys(dataset_names))
|
|
86
|
+
|
|
87
|
+
# Create mapping using position-based numbering for redacted datasets
|
|
88
|
+
mapping = {}
|
|
89
|
+
|
|
90
|
+
# Handle regular datasets
|
|
91
|
+
for index, name in enumerate(unique_datasets, 1):
|
|
92
|
+
hierarchical_key = self._build_hierarchical_key("dataset", name)
|
|
93
|
+
if self._should_redact(name, hierarchical_key):
|
|
94
|
+
mapping[name] = f"dataset_{index}"
|
|
95
|
+
else:
|
|
96
|
+
mapping[name] = name # Keep original name
|
|
97
|
+
|
|
98
|
+
# Special "dataset" and "attachment" cases comes last
|
|
99
|
+
# These keys are reserved for additional data and do not need to be redacted
|
|
100
|
+
if "dataset" in dsr_data.keys():
|
|
101
|
+
mapping["dataset"] = "dataset"
|
|
102
|
+
|
|
103
|
+
if "attachments" in dsr_data.keys():
|
|
104
|
+
mapping["attachments"] = "attachments"
|
|
105
|
+
|
|
106
|
+
return mapping
|
|
107
|
+
|
|
108
|
+
def _parse_key(self, key: str, rows: List[dict]) -> Tuple[str, str]:
|
|
109
|
+
"""Parse a key into dataset and collection names."""
|
|
110
|
+
if ":" in key:
|
|
111
|
+
parts = key.split(":", 1)
|
|
112
|
+
return parts[0], parts[1]
|
|
113
|
+
|
|
114
|
+
# Fallback logic
|
|
115
|
+
for row in rows:
|
|
116
|
+
if "system_name" in row:
|
|
117
|
+
return row["system_name"], key
|
|
118
|
+
return "manual", key
|
|
119
|
+
|
|
120
|
+
def _should_redact(self, name: str, hierarchical_key: str) -> bool:
|
|
121
|
+
"""Check if a name should be redacted."""
|
|
122
|
+
if hierarchical_key in self.entities_to_redact:
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
for pattern in self.redaction_patterns:
|
|
126
|
+
try:
|
|
127
|
+
if re.search(pattern, name, re.IGNORECASE):
|
|
128
|
+
return True
|
|
129
|
+
except re.error:
|
|
130
|
+
logger.warning(f"Invalid regex pattern: {pattern}")
|
|
131
|
+
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
def _redact_name(
|
|
135
|
+
self,
|
|
136
|
+
name_type: Literal["dataset", "collection", "field"],
|
|
137
|
+
name: str,
|
|
138
|
+
index: int,
|
|
139
|
+
dataset_name: Optional[str] = None,
|
|
140
|
+
collection_name: Optional[str] = None,
|
|
141
|
+
) -> str:
|
|
142
|
+
"""Apply redaction to a name based on patterns and configurations."""
|
|
143
|
+
hierarchical_key = self._build_hierarchical_key(
|
|
144
|
+
name_type, name, dataset_name, collection_name
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
if self._should_redact(name, hierarchical_key):
|
|
148
|
+
return f"{name_type}_{index}"
|
|
149
|
+
|
|
150
|
+
return name
|
|
151
|
+
|
|
152
|
+
def _build_hierarchical_key(
|
|
153
|
+
self,
|
|
154
|
+
name_type: Literal["dataset", "collection", "field"],
|
|
155
|
+
name: str,
|
|
156
|
+
dataset_name: Optional[str] = None,
|
|
157
|
+
collection_name: Optional[str] = None,
|
|
158
|
+
) -> str:
|
|
159
|
+
"""Build hierarchical key for entity lookup."""
|
|
160
|
+
if name_type == "dataset":
|
|
161
|
+
return name
|
|
162
|
+
if name_type == "collection" and dataset_name:
|
|
163
|
+
return f"{dataset_name}.{name}"
|
|
164
|
+
if name_type == "field" and dataset_name and collection_name:
|
|
165
|
+
return f"{dataset_name}.{collection_name}.{name}"
|
|
166
|
+
return name
|
|
167
|
+
|
|
168
|
+
def _process_row(
|
|
169
|
+
self, row: dict[str, Any], dataset_name: str, collection_name: str
|
|
170
|
+
) -> dict[str, Any]:
|
|
171
|
+
"""Process a single row with field redaction."""
|
|
172
|
+
processed = {}
|
|
173
|
+
|
|
174
|
+
# Use enumerate for positional indexing (matches original)
|
|
175
|
+
for field_index, (field_name, value) in enumerate(row.items(), start=1):
|
|
176
|
+
redacted_field = self._redact_name(
|
|
177
|
+
"field", field_name, field_index, dataset_name, collection_name
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Process nested values
|
|
181
|
+
base_path = f"{dataset_name}.{collection_name}.{field_name}"
|
|
182
|
+
processed[redacted_field] = self._process_nested_value(value, base_path)
|
|
183
|
+
|
|
184
|
+
return processed
|
|
185
|
+
|
|
186
|
+
def _process_nested_value(
|
|
187
|
+
self,
|
|
188
|
+
value: Any,
|
|
189
|
+
current_path: str,
|
|
190
|
+
field_index_counter: Optional[Dict[str, Dict[str, int]]] = None,
|
|
191
|
+
) -> Any:
|
|
192
|
+
"""Recursively process nested values matching original logic."""
|
|
193
|
+
if field_index_counter is None:
|
|
194
|
+
field_index_counter = {}
|
|
195
|
+
|
|
196
|
+
if isinstance(value, dict):
|
|
197
|
+
processed = {}
|
|
198
|
+
level_key = f"{current_path}_fields"
|
|
199
|
+
|
|
200
|
+
if level_key not in field_index_counter:
|
|
201
|
+
field_index_counter[level_key] = {}
|
|
202
|
+
|
|
203
|
+
for field_name, field_value in value.items():
|
|
204
|
+
full_path = f"{current_path}.{field_name}"
|
|
205
|
+
|
|
206
|
+
# Get or create index for this field at this level
|
|
207
|
+
if field_name not in field_index_counter[level_key]:
|
|
208
|
+
field_index_counter[level_key][field_name] = (
|
|
209
|
+
len(field_index_counter[level_key]) + 1
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
if self._should_redact(field_name, full_path):
|
|
213
|
+
redacted_name = (
|
|
214
|
+
f"field_{field_index_counter[level_key][field_name]}"
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
redacted_name = field_name
|
|
218
|
+
|
|
219
|
+
processed[redacted_name] = self._process_nested_value(
|
|
220
|
+
field_value, full_path, field_index_counter
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
return processed
|
|
224
|
+
|
|
225
|
+
if isinstance(value, list):
|
|
226
|
+
return [
|
|
227
|
+
self._process_nested_value(item, current_path, field_index_counter)
|
|
228
|
+
for item in value
|
|
229
|
+
]
|
|
230
|
+
|
|
231
|
+
return value
|