ethyca-fides 2.62.1b2__py2.py3-none-any.whl → 2.62.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.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/METADATA +1 -2
- {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/RECORD +221 -223
- fides/_version.py +3 -3
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +2 -2
- fides/api/main.py +1 -0
- fides/api/models/attachment.py +10 -117
- fides/api/models/detection_discovery.py +1 -66
- fides/api/models/privacy_request/privacy_request.py +1 -40
- fides/api/service/connectors/query_configs/saas_query_config.py +8 -3
- fides/api/service/connectors/saas_connector.py +4 -7
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +2 -4
- fides/api/service/storage/s3.py +15 -40
- fides/api/tasks/storage.py +2 -2
- fides/api/util/storage_util.py +8 -14
- fides/config/config_proxy.py +1 -0
- fides/config/execution_settings.py +4 -0
- fides/service/error_handling/__init__.py +0 -0
- fides/service/error_handling/error_handler.py +202 -0
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/K1_4-1GhwfL7h4fYYQBvB/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1327-92a38135ee8d55ec.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1817-721fdeb29c07c6be.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1904-7e5354990377a849.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{2310-6a5fb2f76f7b6491.js → 2310-0d63c66c2685e83c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/3119-e441b14cdab4320e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3426-e49cb4766324b2dd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3513-293b1e54699cf3e7.js → 3513-87b54d931698986f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/355-e4340980d72b4faa.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3872-99da5bb6140ff810.js → 3872-6b828cb00fb2ce93.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/4060-9593a3f98e600487.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4121-5c3af879cdd8b3be.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4481-8398edf74aabb8ea.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4723-4c3c7a375e998c15.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-e000d07844eccf7e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5487-218e4847b8250fbb.js → 5487-62955c11bab63734.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/5626-1b636798faad78e1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5683-44966a05fa5ad566.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5826-ce34f25ac2eeb807.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5973-56d90405c3616068.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6277-c35c8cc806f7571f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6853-0cee00c9da26a40e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6954-04030a21a0c8cf5a.js → 6954-d02d474ba30756b2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/79-e5884e6878fc1bbb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7980-e17dda2f50ec76b8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9494-d1fd4fb83c3d4836.js → 9494-0df032fe6ee531a5.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9767-74320abc2e9a4550.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-94950df9c97cd079.js → _app-371b155655c83a1e.js} +69 -69
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-1292fd216f2839c7.js → manual-7d789458fb296270.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-2ffc37614e9d1fa9.js → multiple-90320455052466cd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-a69f8946466471aa.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-c8033d6560635046.js → add-vendors-bcc515a765c0119d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-49b9f1b56262dfdc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-fd71fb440dbe60e4.js → privacy-experience-5ef03041a530b0e2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-12f3ba4609bc2ba5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-5960170d492acb03.js → properties-ffa15d7ff64a9f05.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-b959d61c2a3682b3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-18e3faf7963962e4.js → [resourceUrn]-7ddf45ffd49533b0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-a10a0f3e6592f350.js → [projectUrn]-ecf23116a845188a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-6971531bb09dff3a.js → projects-79f8e613827c55c1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-7320524a47104798.js → [resourceUrn]-ed213bc1b7041aa2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-51d99174c8006eb5.js → resources-1f033ca5a0702018.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-4dbc71d8be9765f3.js → data-catalog-e950d41b75f86c85.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-84ead584a88ab662.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-90f1975f559fff3e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-4b820a3173f35504.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-db3853a09933097a.js → activity-beedbc38ee2b0094.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-4c526db0c30c488a.js → [resourceUrn]-f38b3ef885a29ea6.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-6f27dbb7c8edc69d.js → detection-29fd0d5a73f13a00.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-562d2b8ae90dd1f0.js → [resourceUrn]-9a80241f1028c470.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-fe7f51502eda57c9.js → discovery-c58333981b1522c9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-3aaa99709d83a1f6.js → datamap-2d6f95b2769a0936.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c08363922838022a.js → [...subfieldNames]-3536ae978741b659.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-f12df2140e309dfb.js → [collectionName]-8b5afe14cf42a4ac.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-3f564c8d6cfb03d4.js → [datasetId]-b8dca4298b5bb085.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-1e26702b1a7e0e12.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-1f0c4e2e5d0b5bf6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b078218865a8fd28.js → [id]-ebf54ea9874c59ae.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-c39e8e2269883796.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-9db81467fa254996.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{index-2e6ba5382358fcf8.js → index-868b60407eae35da.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-ebc41649161f7fb9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-b89b9f68ccc69c1b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-71166bf207804754.js → messaging-5f41afae411cd8a4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-928430cd40c35ef2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-07ef58b04404479d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-595ed9f6ca438020.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-b3384299166bcd1e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-4a5e8ec41574c6b5.js → properties-f00530710b699afd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6a6016708efb5f4f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ba15c12c89ee10f8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-0f2daeec241bd1a2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-0401208a3128fa4d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-92e8246170b492b5.js → domain-records-0daa256958675a23.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-4fbab6716326060d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-b235f961f9ca39a6.js → organization-9404a6b0b2951992.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-99cd1a12ae0373b0.js → test-datasets-48be14ad09ed4133.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-01006a55ac873135.js → [id]-b03403fed4dd8805.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{systems-45990d85a4c5739b.js → systems-ae591953b24e2fc9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-913efe5371344de6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-dc11ba29dbd4708b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-c0b2113b44f46112.js +1 -0
- fides/ui-build/static/admin/_next/static/css/b89fc4b36b501cf6.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{1b227ba7eabbfe2f.css → c0c2eb63ad3e7390.css} +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/lib/fides-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +2 -2
- fides/ui-build/static/admin/lib/fides.js +2 -2
- 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/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.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/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/alembic/migrations/versions/2263583b0e44_add_shared_monitor_config.py +0 -82
- fides/ui-build/static/admin/_next/static/chunks/1327-da0303f70d12fb20.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-d2543e460cec0dcb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1904-25e5d4f1b8146fb3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3119-b5e40d8d24af1e79.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3426-77fccf2c9a5e10cd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3923-c6dcaeaa3267f254.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/401-a882199f6c94a4dc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4060-c657e58514e91e91.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4121-ec1d8faa3cf5783c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4481-9357e3930d35073b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5258-49e73e5998c01254.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5683-3d5c4194b1b1493e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5973-d776c0029db45971.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6277-db781b6c1dde3c84.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6853-348fe2ba132b400c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7553-0f3e9e7eaf1a8b62.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-d877d3bde220da44.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-7424eb6391142ccd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7980-041df432c4d3a68b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9767-f8ea7d0127f81294.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9965-92f4a28823a5e623.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-0234733a90ed5127.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-2ba21b95aa3bb15e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-5a63fc903408412e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-80bd51f8217edae4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-67ddc090cf949af4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-07ff657ee49e5742.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-dbc8c95c22b9f2aa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-157b00d23b651d12.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-9d29dd6cf109891d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-b01f89d250ff52af.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-9fc15228581786e6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-43abc599f0768331.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-d69c9f1007e76046.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-fec150afcfeb3fb5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-2862630f0e9e484b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-35e58b5ed6b12b2b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bb02092af39446da.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6baa485385ce0678.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-707551df97d5eebd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-e4df123bef1ff2b1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-2fd6b0ff9b6741fc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-3a829c53d5d723d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/locations-4194ce716b81480d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-ec739e169cd5eafe.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-603c2bdbd8dc00ca.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-592e497369673e1a.js +0 -1
- fides/ui-build/static/admin/_next/static/css/5ded47c57dae5baf.css +0 -1
- fides/ui-build/static/admin/_next/static/ulYEH5vwbFjKDz3nI321R/_buildManifest.js +0 -1
- fides/ui-build/static/admin/poc/table-migration.html +0 -1
- {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.62.1b2.dist-info → ethyca_fides-2.62.1rc0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{ulYEH5vwbFjKDz3nI321R → K1_4-1GhwfL7h4fYYQBvB}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{1099-b652e6f9a0cd778b.js → 1099-98458e8e9ff67508.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{1100-e19e94b0a6486255.js → 1100-4106d99f5e1ebd75.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2921-771dc5d9e95dc6b4.js → 2921-ca04a0476e2e56c5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3505-313087fc1744a0ca.js → 3505-e58b93f9c1cbdcad.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{69-ef4c11c574b4e6dd.js → 69-dc52e39d26a4ad14.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{8433-755359b501d32eaa.js → 8433-a77c2cd1c1a6887e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{8499-06ab15acbfec037c.js → 8499-34a34015c91fc38b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9327-b691be8352e31b58.js → 9327-a25347d72bfbe680.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{404-e868487119cd14fc.js → 404-c00773c4c6e930af.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-94391554a7607c5b.js → [id]-d4137bb7fdc1ac6e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-596dd2a35b455f21.js → [id]-a5a95ac63b1ce206.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-fa7f0d2639e12a5a.js → new-946ce1a2aa1500d4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-dd2a0e3b536b8b42.js → consent-7797e367dd946a18.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-111b07344f1ee9e4.js → [id]-22812f08e81bd4f3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-c41f368fb6b35de4.js → add-template-ca22869201847ccc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-3dabaf6828acb2cb.js → ant-components-173bd3ad45ea61c6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-784081c774042249.js → AntForm-4dfe984ad80927cd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-63905f2382f158cd.js → FormikAntFormItem-f790e1ea5cbc26c0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-43f6eab28eae7b56.js → FormikControlled-af9e682ec620e990.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-e4a07abc908fc9b5.js → FormikField-6ce407101daa6000.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-71a3bfb94280fc49.js → forms-9ee8cf14a93eaa4a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-42213855a0a8c209.js → configure-25a3add8e7982e43.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d547a1da0b74f00f.js → [id]-081f13526443e0a6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-a7de6f8409a76358.js → add-property-17fb474e458b63e7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-704fc28e61b17247.js → about-177919b4ccf8f660.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-f0e9ee8756a65540.js → domains-26810d1ffedcd156.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-a4771098466af1ed.js → email-templates-eb78b645d0c1d4ea.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-8cff97fe57f42ed3.js → regulations-0a3aa951ef4a44ba.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-b124cc24b930c9e1.js → new-69176abe09cf9b52.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{webpack-3a61b934ba2fb620.js → webpack-abd3efcb23c0bb03.js} +0 -0
fides/_version.py
CHANGED
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2025-06-
|
11
|
+
"date": "2025-06-06T15:00:50-0400",
|
12
12
|
"dirty": false,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "2.62.
|
14
|
+
"full-revisionid": "4fca3c3a4592528e57449b8ee9cafed8010d6052",
|
15
|
+
"version": "2.62.1rc0"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
@@ -120,7 +120,7 @@ from fides.api.util.collection_util import Row
|
|
120
120
|
from fides.api.util.endpoint_utils import validate_start_and_end_filters
|
121
121
|
from fides.api.util.enums import ColumnSort
|
122
122
|
from fides.api.util.fuzzy_search_utils import get_decrypted_identities_automaton
|
123
|
-
from fides.api.util.storage_util import
|
123
|
+
from fides.api.util.storage_util import storage_json_encoder
|
124
124
|
from fides.common.api.scope_registry import (
|
125
125
|
PRIVACY_REQUEST_CALLBACK_RESUME,
|
126
126
|
PRIVACY_REQUEST_CREATE,
|
@@ -2129,7 +2129,7 @@ def get_test_privacy_request_results(
|
|
2129
2129
|
|
2130
2130
|
# Escape datetime and ObjectId values
|
2131
2131
|
raw_data = privacy_request.get_raw_access_results()
|
2132
|
-
escaped_json = json.dumps(raw_data, indent=2,
|
2132
|
+
escaped_json = json.dumps(raw_data, indent=2, default=storage_json_encoder)
|
2133
2133
|
results = json.loads(escaped_json)
|
2134
2134
|
|
2135
2135
|
filtered_results: Dict[str, Any] = filter_access_results(
|
fides/api/main.py
CHANGED
@@ -240,6 +240,7 @@ async def log_request(request: Request, call_next: Callable) -> Response:
|
|
240
240
|
status_code=response.status_code,
|
241
241
|
handler_time=f"{total_time}ms",
|
242
242
|
path=request.url.path,
|
243
|
+
fides_client=request.headers.get("Fides-Client", "unknown"),
|
243
244
|
).info("Request received")
|
244
245
|
return response
|
245
246
|
|
fides/api/models/attachment.py
CHANGED
@@ -12,14 +12,12 @@ from sqlalchemy.orm import Session, relationship
|
|
12
12
|
|
13
13
|
from fides.api.db.base_class import Base
|
14
14
|
from fides.api.schemas.storage.storage import StorageDetails, StorageType
|
15
|
-
from fides.api.service.storage.gcs import get_gcs_client
|
16
15
|
from fides.api.service.storage.s3 import (
|
17
16
|
generic_delete_from_s3,
|
18
17
|
generic_retrieve_from_s3,
|
19
18
|
generic_upload_to_s3,
|
20
19
|
)
|
21
|
-
from fides.api.service.storage.util import
|
22
|
-
from fides.config import CONFIG
|
20
|
+
from fides.api.service.storage.util import get_local_filename
|
23
21
|
|
24
22
|
if TYPE_CHECKING:
|
25
23
|
from fides.api.models.comment import Comment
|
@@ -117,13 +115,8 @@ class Attachment(Base):
|
|
117
115
|
uselist=False,
|
118
116
|
)
|
119
117
|
|
120
|
-
@property
|
121
|
-
def content_type(self) -> str:
|
122
|
-
"""Returns the content type of the attachment."""
|
123
|
-
return AllowedFileType[self.file_name.split(".")[-1]].value
|
124
|
-
|
125
118
|
def upload(self, attachment: IO[bytes]) -> None:
|
126
|
-
"""Uploads an attachment to S3
|
119
|
+
"""Uploads an attachment to S3 or local storage."""
|
127
120
|
if self.config.type == StorageType.s3:
|
128
121
|
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
129
122
|
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
@@ -137,23 +130,6 @@ class Attachment(Base):
|
|
137
130
|
log.info(f"Uploaded {self.file_name} to S3 bucket {bucket_name}/{self.id}")
|
138
131
|
return
|
139
132
|
|
140
|
-
if self.config.type == StorageType.gcs:
|
141
|
-
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
142
|
-
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
143
|
-
storage_client = get_gcs_client(auth_method, self.config.secrets)
|
144
|
-
bucket = storage_client.bucket(bucket_name)
|
145
|
-
blob = bucket.blob(f"{self.id}/{self.file_name}")
|
146
|
-
|
147
|
-
# Reset the file pointer to the beginning
|
148
|
-
try:
|
149
|
-
attachment.seek(0)
|
150
|
-
except Exception as e:
|
151
|
-
raise ValueError(f"Failed to reset file pointer for attachment: {e}")
|
152
|
-
|
153
|
-
blob.upload_from_file(attachment)
|
154
|
-
log.info(f"Uploaded {self.file_name} to GCS bucket {bucket_name}/{self.id}")
|
155
|
-
return
|
156
|
-
|
157
133
|
if self.config.type == StorageType.local:
|
158
134
|
filename = get_local_filename(f"{self.id}/{self.file_name}")
|
159
135
|
|
@@ -188,16 +164,13 @@ class Attachment(Base):
|
|
188
164
|
self,
|
189
165
|
) -> Tuple[int, AnyHttpUrlString]:
|
190
166
|
"""
|
191
|
-
Retrieves the size of the attachment and
|
167
|
+
Retrieves a the size of the attachment and the presigned URL to retrieve it.
|
192
168
|
- For s3:
|
193
169
|
- the size is retrieved from the s3 object metadata
|
194
|
-
-
|
195
|
-
- For gcs:
|
196
|
-
- the size is retrieved from the blob metadata
|
197
|
-
- returns signed URL
|
170
|
+
- the presigned URL is retrieved from the s3 client
|
198
171
|
- For local:
|
199
172
|
- the size is retrieved from the file size
|
200
|
-
-
|
173
|
+
- the URL is the local file path
|
201
174
|
"""
|
202
175
|
if self.config.type == StorageType.s3:
|
203
176
|
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
@@ -207,81 +180,19 @@ class Attachment(Base):
|
|
207
180
|
bucket_name=bucket_name,
|
208
181
|
file_key=f"{self.id}/{self.file_name}",
|
209
182
|
auth_method=auth_method,
|
210
|
-
get_content=False,
|
211
183
|
)
|
212
184
|
return size, url
|
213
185
|
|
214
|
-
if self.config.type == StorageType.gcs:
|
215
|
-
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
216
|
-
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
217
|
-
storage_client = get_gcs_client(auth_method, self.config.secrets)
|
218
|
-
bucket = storage_client.bucket(bucket_name)
|
219
|
-
blob = bucket.blob(f"{self.id}/{self.file_name}")
|
220
|
-
|
221
|
-
# Ensure we have the blob metadata
|
222
|
-
blob.reload()
|
223
|
-
url = blob.generate_signed_url(
|
224
|
-
version="v4",
|
225
|
-
expiration=CONFIG.security.subject_request_download_link_ttl_seconds,
|
226
|
-
method="GET",
|
227
|
-
)
|
228
|
-
return blob.size, url
|
229
|
-
|
230
|
-
if self.config.type == StorageType.local:
|
231
|
-
filename = get_local_filename(f"{self.id}/{self.file_name}")
|
232
|
-
size = os.path.getsize(filename)
|
233
|
-
return size, filename
|
234
|
-
|
235
|
-
raise ValueError(f"Unsupported storage type: {self.config.type}")
|
236
|
-
|
237
|
-
def retrieve_attachment_content(
|
238
|
-
self,
|
239
|
-
) -> Tuple[int, bytes]:
|
240
|
-
"""
|
241
|
-
Retrieves the size of the attachment and its actual content.
|
242
|
-
- For s3:
|
243
|
-
- the size is retrieved from the s3 object metadata
|
244
|
-
- returns the actual content
|
245
|
-
- For gcs:
|
246
|
-
- the size is retrieved from the blob metadata
|
247
|
-
- returns the actual content
|
248
|
-
- For local:
|
249
|
-
- the size is retrieved from the file size
|
250
|
-
- returns the actual content
|
251
|
-
"""
|
252
|
-
if self.config.type == StorageType.s3:
|
253
|
-
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
254
|
-
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
255
|
-
size, content = generic_retrieve_from_s3(
|
256
|
-
storage_secrets=self.config.secrets,
|
257
|
-
bucket_name=bucket_name,
|
258
|
-
file_key=f"{self.id}/{self.file_name}",
|
259
|
-
auth_method=auth_method,
|
260
|
-
get_content=True,
|
261
|
-
)
|
262
|
-
return size, content
|
263
|
-
|
264
|
-
if self.config.type == StorageType.gcs:
|
265
|
-
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
266
|
-
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
267
|
-
storage_client = get_gcs_client(auth_method, self.config.secrets)
|
268
|
-
bucket = storage_client.bucket(bucket_name)
|
269
|
-
blob = bucket.blob(f"{self.id}/{self.file_name}")
|
270
|
-
|
271
|
-
content = blob.download_as_bytes()
|
272
|
-
return len(content), content
|
273
|
-
|
274
186
|
if self.config.type == StorageType.local:
|
275
187
|
filename = get_local_filename(f"{self.id}/{self.file_name}")
|
276
188
|
with open(filename, "rb") as file:
|
277
|
-
|
278
|
-
size
|
279
|
-
return size, content
|
189
|
+
size = len(file.read())
|
190
|
+
return size, filename
|
280
191
|
|
281
192
|
raise ValueError(f"Unsupported storage type: {self.config.type}")
|
282
193
|
|
283
194
|
def delete_attachment_from_storage(self) -> None:
|
284
|
-
"""Deletes an attachment from S3
|
195
|
+
"""Deletes an attachment from S3 or local storage."""
|
285
196
|
if self.config.type == StorageType.s3:
|
286
197
|
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
287
198
|
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
@@ -293,27 +204,9 @@ class Attachment(Base):
|
|
293
204
|
)
|
294
205
|
return
|
295
206
|
|
296
|
-
if self.config.type == StorageType.gcs:
|
297
|
-
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
298
|
-
auth_method = self.config.details[StorageDetails.AUTH_METHOD.value]
|
299
|
-
storage_client = get_gcs_client(auth_method, self.config.secrets)
|
300
|
-
bucket = storage_client.bucket(bucket_name)
|
301
|
-
|
302
|
-
# List and delete all blobs in the folder
|
303
|
-
prefix = f"{self.id}/"
|
304
|
-
blobs = bucket.list_blobs(prefix=prefix)
|
305
|
-
for blob in blobs:
|
306
|
-
blob.delete()
|
307
|
-
return
|
308
|
-
|
309
207
|
if self.config.type == StorageType.local:
|
310
|
-
|
311
|
-
|
312
|
-
)
|
313
|
-
if os.path.exists(folder_path):
|
314
|
-
import shutil
|
315
|
-
|
316
|
-
shutil.rmtree(folder_path)
|
208
|
+
filename = get_local_filename(f"{self.id}/{self.file_name}")
|
209
|
+
os.remove(filename)
|
317
210
|
return
|
318
211
|
|
319
212
|
raise ValueError(f"Unsupported storage type: {self.config.type}")
|
@@ -9,7 +9,6 @@ from loguru import logger
|
|
9
9
|
from sqlalchemy import ARRAY, Boolean, Column, DateTime, ForeignKey, String, func
|
10
10
|
from sqlalchemy.dialects.postgresql import JSONB
|
11
11
|
from sqlalchemy.ext.asyncio import AsyncSession
|
12
|
-
from sqlalchemy.ext.declarative import declared_attr
|
13
12
|
from sqlalchemy.ext.mutable import MutableDict
|
14
13
|
from sqlalchemy.future import select
|
15
14
|
from sqlalchemy.orm import Session, relationship
|
@@ -48,29 +47,6 @@ class MonitorFrequency(Enum):
|
|
48
47
|
QUARTERLY_MONTH_PATTERN = r"^\d+,\d+,\d+,\d+$"
|
49
48
|
|
50
49
|
|
51
|
-
class SharedMonitorConfig(Base, FidesBase):
|
52
|
-
"""SQL model for shareable monitor configurations"""
|
53
|
-
|
54
|
-
@declared_attr
|
55
|
-
def __tablename__(self) -> str:
|
56
|
-
return "shared_monitor_config"
|
57
|
-
|
58
|
-
# Basic info
|
59
|
-
name = Column(String, nullable=False)
|
60
|
-
key = Column(String, unique=True, nullable=False)
|
61
|
-
description = Column(String, nullable=True)
|
62
|
-
|
63
|
-
# Classification parameters (including regex patterns)
|
64
|
-
classify_params = Column(
|
65
|
-
MutableDict.as_mutable(JSONB),
|
66
|
-
index=False,
|
67
|
-
unique=False,
|
68
|
-
nullable=False,
|
69
|
-
server_default="{}",
|
70
|
-
default=dict,
|
71
|
-
)
|
72
|
-
|
73
|
-
|
74
50
|
class MonitorConfig(Base):
|
75
51
|
"""
|
76
52
|
Monitor configuration used for data detection and discovery.
|
@@ -111,9 +87,7 @@ class MonitorConfig(Base):
|
|
111
87
|
) # stores the cron-based kwargs for scheduling the monitor execution.
|
112
88
|
# see https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html
|
113
89
|
|
114
|
-
|
115
|
-
_classify_params = Column(
|
116
|
-
"classify_params",
|
90
|
+
classify_params = Column(
|
117
91
|
MutableDict.as_mutable(JSONB),
|
118
92
|
index=False,
|
119
93
|
unique=False,
|
@@ -150,45 +124,6 @@ class MonitorConfig(Base):
|
|
150
124
|
backref="monitor_config",
|
151
125
|
)
|
152
126
|
|
153
|
-
shared_config_id = Column(
|
154
|
-
String,
|
155
|
-
ForeignKey(SharedMonitorConfig.id_field_path, ondelete="RESTRICT"),
|
156
|
-
nullable=True,
|
157
|
-
index=True,
|
158
|
-
)
|
159
|
-
|
160
|
-
shared_config = relationship(SharedMonitorConfig)
|
161
|
-
|
162
|
-
@property
|
163
|
-
def classify_params(self) -> dict:
|
164
|
-
"""
|
165
|
-
Returns the merged classify parameters from both the monitor config and
|
166
|
-
the shared config (if it exists).
|
167
|
-
|
168
|
-
The shared config parameters take precedence over the monitor's own parameters,
|
169
|
-
but only for values that are not falsy (None, empty, etc.).
|
170
|
-
"""
|
171
|
-
# Start with an empty dict
|
172
|
-
merged_params = {}
|
173
|
-
|
174
|
-
# Add this monitor's params if available
|
175
|
-
if self._classify_params:
|
176
|
-
merged_params.update(self._classify_params)
|
177
|
-
|
178
|
-
# Add/override with shared config params if available
|
179
|
-
if self.shared_config and self.shared_config.classify_params:
|
180
|
-
# Only update with non-falsy values from shared config
|
181
|
-
for key, value in self.shared_config.classify_params.items():
|
182
|
-
if value: # Only override if the value is not falsy
|
183
|
-
merged_params[key] = value
|
184
|
-
|
185
|
-
return merged_params
|
186
|
-
|
187
|
-
@classify_params.setter
|
188
|
-
def classify_params(self, value: Dict[str, Any]) -> None:
|
189
|
-
"""Setter for the classify_params to maintain compatibility with existing code"""
|
190
|
-
self._classify_params = value
|
191
|
-
|
192
127
|
@property
|
193
128
|
def connection_config_key(self) -> str:
|
194
129
|
"""Derives the `connection_config_key`"""
|
@@ -1089,46 +1089,6 @@ class PrivacyRequest(
|
|
1089
1089
|
if attachment:
|
1090
1090
|
attachment.delete(db)
|
1091
1091
|
|
1092
|
-
def _get_manual_webhook_attachments(
|
1093
|
-
self, db: Session, manual_webhook_id: str, reference_type: str
|
1094
|
-
) -> List[Attachment]:
|
1095
|
-
"""Helper method to get attachments that have references to both this privacy request and the specified manual webhook"""
|
1096
|
-
query = """
|
1097
|
-
SELECT DISTINCT a.*
|
1098
|
-
FROM attachment a
|
1099
|
-
INNER JOIN attachment_reference ar1 ON a.id = ar1.attachment_id
|
1100
|
-
INNER JOIN attachment_reference ar2 ON a.id = ar2.attachment_id
|
1101
|
-
WHERE ar1.reference_id = :privacy_request_id
|
1102
|
-
AND ar1.reference_type = 'privacy_request'
|
1103
|
-
AND ar2.reference_id = :manual_webhook_id
|
1104
|
-
AND ar2.reference_type = :reference_type
|
1105
|
-
"""
|
1106
|
-
result = db.execute(
|
1107
|
-
query,
|
1108
|
-
{
|
1109
|
-
"privacy_request_id": self.id,
|
1110
|
-
"manual_webhook_id": manual_webhook_id,
|
1111
|
-
"reference_type": reference_type,
|
1112
|
-
},
|
1113
|
-
)
|
1114
|
-
return [Attachment(**row) for row in result]
|
1115
|
-
|
1116
|
-
def get_access_manual_webhook_attachments(
|
1117
|
-
self, db: Session, manual_webhook_id: str
|
1118
|
-
) -> List[Attachment]:
|
1119
|
-
"""Get all attachments that have references to both this privacy request and the specified access manual webhook"""
|
1120
|
-
return self._get_manual_webhook_attachments(
|
1121
|
-
db, manual_webhook_id, "access_manual_webhook"
|
1122
|
-
)
|
1123
|
-
|
1124
|
-
def get_erasure_manual_webhook_attachments(
|
1125
|
-
self, db: Session, manual_webhook_id: str
|
1126
|
-
) -> List[Attachment]:
|
1127
|
-
"""Get all attachments that have references to both this privacy request and the specified erasure manual webhook"""
|
1128
|
-
return self._get_manual_webhook_attachments(
|
1129
|
-
db, manual_webhook_id, "erasure_manual_webhook"
|
1130
|
-
)
|
1131
|
-
|
1132
1092
|
def get_existing_request_task(
|
1133
1093
|
self,
|
1134
1094
|
db: Session,
|
@@ -1268,6 +1228,7 @@ class PrivacyRequest(
|
|
1268
1228
|
"""
|
1269
1229
|
if not self.policy.get_rules_for_action(action_type=ActionType.access):
|
1270
1230
|
return None
|
1231
|
+
|
1271
1232
|
self.filtered_final_upload = results
|
1272
1233
|
self.save(db)
|
1273
1234
|
|
@@ -52,6 +52,7 @@ from fides.api.util.saas_util import (
|
|
52
52
|
get_identities,
|
53
53
|
)
|
54
54
|
from fides.common.api.v1.urn_registry import REQUEST_TASK_CALLBACK, V1_URL_PREFIX
|
55
|
+
from fides.config.config_proxy import ConfigProxy
|
55
56
|
|
56
57
|
T = TypeVar("T")
|
57
58
|
|
@@ -143,12 +144,16 @@ class SaaSQueryConfig(QueryConfig[SaaSRequestParams]):
|
|
143
144
|
"""
|
144
145
|
Returns a tuple of the preferred action and SaaSRequest to use for masking.
|
145
146
|
An update request is preferred, but we can use a gdpr delete endpoint or
|
146
|
-
delete endpoint.
|
147
|
+
delete endpoint if not MASKING_STRICT.
|
147
148
|
"""
|
148
149
|
|
149
150
|
update: Optional[SaaSRequest] = self.get_erasure_request_by_action("update")
|
150
|
-
gdpr_delete: Optional[SaaSRequest] =
|
151
|
-
delete: Optional[SaaSRequest] =
|
151
|
+
gdpr_delete: Optional[SaaSRequest] = None
|
152
|
+
delete: Optional[SaaSRequest] = None
|
153
|
+
|
154
|
+
if not ConfigProxy(db).execution.masking_strict:
|
155
|
+
gdpr_delete = self.data_protection_request
|
156
|
+
delete = self.get_erasure_request_by_action("delete")
|
152
157
|
|
153
158
|
try:
|
154
159
|
# Return first viable option
|
@@ -530,15 +530,11 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
|
|
530
530
|
|
531
531
|
session = Session.object_session(privacy_request)
|
532
532
|
masking_request = query_config.get_masking_request(session)
|
533
|
-
rows_updated = 0
|
534
|
-
|
535
533
|
if not masking_request:
|
536
|
-
|
537
|
-
"
|
538
|
-
|
539
|
-
self.saas_config.fides_key, # type: ignore
|
534
|
+
raise Exception(
|
535
|
+
f"Either no masking request configured or no valid masking request for {node.address.collection}. "
|
536
|
+
f"Check that MASKING_STRICT env var is appropriately set"
|
540
537
|
)
|
541
|
-
return rows_updated
|
542
538
|
|
543
539
|
self.set_saas_request_state(masking_request)
|
544
540
|
|
@@ -569,6 +565,7 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
|
|
569
565
|
cast(Optional[List[PostProcessorStrategy]], masking_request.postprocessors),
|
570
566
|
)
|
571
567
|
|
568
|
+
rows_updated = 0
|
572
569
|
client = self.create_client()
|
573
570
|
for row in rows:
|
574
571
|
try:
|
@@ -11,7 +11,7 @@ from jinja2 import Environment, FileSystemLoader
|
|
11
11
|
|
12
12
|
from fides.api.models.privacy_request import PrivacyRequest
|
13
13
|
from fides.api.schemas.policy import ActionType
|
14
|
-
from fides.api.util.storage_util import
|
14
|
+
from fides.api.util.storage_util import storage_json_encoder
|
15
15
|
|
16
16
|
DSR_DIRECTORY = Path(__file__).parent.resolve()
|
17
17
|
|
@@ -41,9 +41,7 @@ class DsrReportBuilder:
|
|
41
41
|
|
42
42
|
# Jinja template environment initialization
|
43
43
|
def pretty_print(value: str, indent: int = 4) -> str:
|
44
|
-
return json.dumps(
|
45
|
-
value, indent=indent, default=StorageJSONEncoder().default
|
46
|
-
)
|
44
|
+
return json.dumps(value, indent=indent, default=storage_json_encoder)
|
47
45
|
|
48
46
|
jinja2.filters.FILTERS["pretty_print"] = pretty_print
|
49
47
|
self.template_loader = Environment(
|
fides/api/service/storage/s3.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import IO, Any, Dict, Tuple
|
3
|
+
from typing import IO, Any, Dict, Tuple
|
4
4
|
|
5
5
|
from boto3.s3.transfer import TransferConfig
|
6
6
|
from botocore.exceptions import ClientError, ParamValidationError
|
@@ -129,38 +129,25 @@ def generic_retrieve_from_s3(
|
|
129
129
|
bucket_name: str,
|
130
130
|
file_key: str,
|
131
131
|
auth_method: str,
|
132
|
-
|
133
|
-
) -> Tuple[int, Union[str, bytes]]:
|
132
|
+
) -> Tuple[int, AnyHttpUrlString]:
|
134
133
|
"""
|
135
|
-
Retrieves
|
136
|
-
|
137
|
-
Args:
|
138
|
-
storage_secrets: Dictionary containing S3 credentials
|
139
|
-
bucket_name: Name of the S3 bucket
|
140
|
-
file_key: Key of the file in the bucket
|
141
|
-
auth_method: Authentication method to use
|
142
|
-
get_content: If True, returns the actual content instead of a presigned URL
|
134
|
+
Retrieves file metadata and generates a presigned URL for downloading an S3 object.
|
143
135
|
|
144
|
-
|
145
|
-
|
136
|
+
:param storage_secrets: S3 storage secrets
|
137
|
+
:param bucket_name: Name of the S3 bucket
|
138
|
+
:param file_key: Key of the file in the bucket
|
139
|
+
:param auth_method: Authentication method for S3
|
140
|
+
:return: Tuple containing (file_size, presigned_url)
|
146
141
|
"""
|
147
142
|
logger.info("Retrieving S3 object: {}", file_key)
|
148
|
-
s3_client = get_s3_client(auth_method, storage_secrets)
|
149
143
|
|
144
|
+
s3_client = maybe_get_s3_client(auth_method, storage_secrets)
|
150
145
|
try:
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
# Get presigned URL
|
158
|
-
presigned_url = create_presigned_url_for_s3(s3_client, bucket_name, file_key)
|
159
|
-
# Get file size
|
160
|
-
response = s3_client.head_object(Bucket=bucket_name, Key=file_key)
|
161
|
-
return int(response["ContentLength"]), str(presigned_url)
|
162
|
-
except ClientError as e:
|
163
|
-
logger.error(f"Error retrieving file from S3: {e}")
|
146
|
+
get_allowed_file_type_or_raise(file_key)
|
147
|
+
file_size = get_file_size(s3_client, bucket_name, file_key)
|
148
|
+
return file_size, create_presigned_url_for_s3(s3_client, bucket_name, file_key)
|
149
|
+
except Exception as e:
|
150
|
+
logger.error("Encountered error while retrieving S3 object: {}", e)
|
164
151
|
raise e
|
165
152
|
|
166
153
|
|
@@ -171,8 +158,7 @@ def generic_delete_from_s3(
|
|
171
158
|
auth_method: str,
|
172
159
|
) -> None:
|
173
160
|
"""
|
174
|
-
Deletes arbitrary data from s3
|
175
|
-
If file_key ends with a '/', deletes all objects with that prefix.
|
161
|
+
Deletes arbitrary data from s3
|
176
162
|
|
177
163
|
:param storage_secrets: S3 storage secrets
|
178
164
|
:param bucket_name: Name of the S3 bucket
|
@@ -183,17 +169,6 @@ def generic_delete_from_s3(
|
|
183
169
|
|
184
170
|
s3_client = maybe_get_s3_client(auth_method, storage_secrets)
|
185
171
|
try:
|
186
|
-
# If the file_key ends with a '/', it's a folder prefix
|
187
|
-
if file_key.endswith("/"):
|
188
|
-
# List all objects with the prefix, handling pagination
|
189
|
-
paginator = s3_client.get_paginator("list_objects_v2")
|
190
|
-
for page in paginator.paginate(Bucket=bucket_name, Prefix=file_key):
|
191
|
-
if "Contents" in page:
|
192
|
-
for obj in page["Contents"]:
|
193
|
-
s3_client.delete_object(Bucket=bucket_name, Key=obj["Key"])
|
194
|
-
return
|
195
|
-
|
196
|
-
# Delete single object
|
197
172
|
s3_client.delete_object(Bucket=bucket_name, Key=file_key)
|
198
173
|
except Exception as e:
|
199
174
|
logger.error("Encountered error while deleting s3 object: {}", e)
|
fides/api/tasks/storage.py
CHANGED
@@ -30,7 +30,7 @@ from fides.api.util.cache import get_cache, get_encryption_cache_key
|
|
30
30
|
from fides.api.util.encryption.aes_gcm_encryption_scheme import (
|
31
31
|
encrypt_to_bytes_verify_secrets_length,
|
32
32
|
)
|
33
|
-
from fides.api.util.storage_util import
|
33
|
+
from fides.api.util.storage_util import storage_json_encoder
|
34
34
|
from fides.config import CONFIG
|
35
35
|
|
36
36
|
if TYPE_CHECKING:
|
@@ -75,7 +75,7 @@ def write_to_in_memory_buffer(
|
|
75
75
|
logger.debug("Writing data to in-memory buffer")
|
76
76
|
|
77
77
|
if resp_format == ResponseFormat.json.value:
|
78
|
-
json_str = json.dumps(data, indent=2, default=
|
78
|
+
json_str = json.dumps(data, indent=2, default=storage_json_encoder)
|
79
79
|
return BytesIO(
|
80
80
|
encrypt_access_request_results(json_str, privacy_request.id).encode(
|
81
81
|
CONFIG.security.encoding
|
fides/api/util/storage_util.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from datetime import datetime
|
2
|
-
from typing import Any, Union
|
2
|
+
from typing import Any, Dict, Union
|
3
3
|
|
4
4
|
from bson import ObjectId
|
5
5
|
from pydantic import ValidationError
|
@@ -11,7 +11,6 @@ from fides.api.schemas.storage.storage import (
|
|
11
11
|
StorageType,
|
12
12
|
)
|
13
13
|
from fides.api.schemas.storage.storage_secrets_docs_only import possible_storage_secrets
|
14
|
-
from fides.api.util.custom_json_encoder import CustomJSONEncoder
|
15
14
|
|
16
15
|
|
17
16
|
def get_schema_for_secrets(
|
@@ -49,15 +48,10 @@ def get_schema_for_secrets(
|
|
49
48
|
raise ValueError(errors)
|
50
49
|
|
51
50
|
|
52
|
-
|
53
|
-
"""
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
if isinstance(o, datetime):
|
60
|
-
return o.strftime("%Y-%m-%dT%H:%M:%S")
|
61
|
-
if isinstance(o, ObjectId):
|
62
|
-
return {"$oid": str(o)}
|
63
|
-
return super().default(o)
|
51
|
+
def storage_json_encoder(field: Any) -> Union[str, Dict[str, str]]:
|
52
|
+
"""Specify str format for datetime objects"""
|
53
|
+
if isinstance(field, datetime):
|
54
|
+
return field.strftime("%Y-%m-%dT%H:%M:%S")
|
55
|
+
if isinstance(field, ObjectId):
|
56
|
+
return {"$oid": str(field)}
|
57
|
+
return field
|
fides/config/config_proxy.py
CHANGED
@@ -106,6 +106,7 @@ class ExecutionSettingsProxy(ConfigProxyBase):
|
|
106
106
|
subject_identity_verification_required: bool
|
107
107
|
disable_consent_identity_verification: bool
|
108
108
|
require_manual_request_approval: bool
|
109
|
+
masking_strict: bool
|
109
110
|
|
110
111
|
def __getattribute__(self, name: str) -> Any:
|
111
112
|
"""
|
@@ -11,6 +11,10 @@ ENV_PREFIX = "FIDES__EXECUTION__"
|
|
11
11
|
class ExecutionSettings(FidesSettings):
|
12
12
|
"""Configuration settings for DSR execution."""
|
13
13
|
|
14
|
+
masking_strict: bool = Field(
|
15
|
+
default=True,
|
16
|
+
description="If set to True, only use UPDATE requests to mask data. If False, Fides will use any defined DELETE or GDPR DELETE endpoints to remove PII, which may extend beyond the specific data categories that configured in your execution policy.",
|
17
|
+
)
|
14
18
|
privacy_request_delay_timeout: int = Field(
|
15
19
|
default=3600,
|
16
20
|
description="The amount of time to wait for actions which delay privacy requests (e.g., pre- and post-processing webhooks).",
|
File without changes
|