ethyca-fides 2.68.1b2__py2.py3-none-any.whl → 2.68.1b4__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.
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/METADATA +3 -1
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/RECORD +253 -232
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/90502bcda282_update_request_tasks_add_polling_async.py +35 -0
- fides/api/alembic/migrations/versions/b1a2c3d4e5f6_add_location_to_privacy_request.py +26 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/dsr_package_link.py +167 -0
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +31 -1
- fides/api/api/v1/endpoints/user_endpoints.py +4 -0
- fides/api/common_exceptions.py +12 -3
- fides/api/models/detection_discovery/core.py +6 -0
- fides/api/models/privacy_request/privacy_request.py +1 -0
- fides/api/models/privacy_request/request_task.py +25 -0
- fides/api/models/privacy_request/webhook.py +33 -1
- fides/api/oauth/utils.py +122 -57
- fides/api/schemas/application_config.py +7 -0
- fides/api/schemas/connection_configuration/connection_type_system_map.py +6 -0
- fides/api/schemas/enums/__init__.py +0 -0
- fides/api/schemas/enums/connection_category.py +20 -0
- fides/api/schemas/enums/integration_feature.py +23 -0
- fides/api/schemas/external_https.py +9 -0
- fides/api/schemas/privacy_center_config.py +48 -19
- fides/api/schemas/privacy_request.py +16 -0
- fides/api/schemas/saas/display_info.py +19 -0
- fides/api/schemas/saas/saas_config.py +2 -0
- fides/api/schemas/storage/storage.py +4 -0
- fides/api/service/async_dsr/__init__.py +0 -0
- fides/api/service/async_dsr/async_dsr_service.py +75 -0
- fides/api/service/connectors/saas_connector.py +5 -6
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +6 -4
- fides/api/service/privacy_request/request_runner_service.py +41 -4
- fides/api/service/privacy_request/request_service.py +50 -2
- fides/api/service/storage/storage_uploader_service.py +80 -5
- fides/api/service/storage/streaming/__init__.py +42 -0
- fides/api/service/storage/streaming/base_storage_client.py +61 -0
- fides/api/service/storage/streaming/dsr_storage.py +98 -0
- fides/api/service/storage/streaming/retry.py +282 -0
- fides/api/service/storage/streaming/s3/__init__.py +5 -0
- fides/api/service/storage/streaming/s3/s3_storage_client.py +113 -0
- fides/api/service/storage/streaming/s3/streaming_s3.py +196 -0
- fides/api/service/storage/streaming/schemas.py +173 -0
- fides/api/service/storage/streaming/smart_open_client.py +265 -0
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +998 -0
- fides/api/service/storage/streaming/storage_client_factory.py +60 -0
- fides/api/task/graph_task.py +4 -4
- fides/api/task/manual/manual_task_graph_task.py +3 -4
- fides/api/util/connection_type.py +20 -0
- fides/api/util/text.py +51 -0
- fides/common/api/v1/urn_registry.py +3 -0
- fides/config/execution_settings.py +4 -0
- fides/service/privacy_request/privacy_request_service.py +84 -9
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/LRCvfOqg1kP5kGnkD84G4/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1099-b973dfdfc5c3de90.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1345-b60d1f3442379c73.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1817-c90365325f8a3d75.js → 1817-74692de5d760a664.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{1975.e5cc7a1ccd477671.js → 1975.78e719130cfe3fd6.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{2921-46f9465c2852a46b.js → 2921-2d9261e8e2e127c0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/3620-ebd89f91b82661e8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3729-ccf90cdaae158f39.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3847-2759bf1f47a1d29e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3855-4174a4d4c205d6e8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3872-660aba76572c811b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3923-a33633feba5e655e.js → 3923-c6cdc2e5278ae9a7.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{401-741bb31b586b7c96.js → 401-8bc2c6c84172c096.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{4121-94354b50a41f8497.js → 4121-9a4ebceff9accb7f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4608-4d31340b0d0157c1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4786-aaef673b30c19e2e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4808-a654c7f7a1ca62c8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4844-cd7e1d0c7bb94094.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-bc4a25d43e4aa07d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-37c78c4799ba5223.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-2213dc1c34143cda.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6084-02abe12327fc3dbc.js → 6084-55cc66e7c94f0686.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6853-270261ef5537a106.js → 6853-313ce974d33432fb.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-021bd06d0ab59c3c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7476-2fc286c2a9125eb8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7630-b9a41262a69edf5e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/768-034e121688a3bbdd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{787-5ba991cad1f7664a.js → 787-8df7118742e84908.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/79-d2ace89108ead8ae.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/796-2de6dac5f311d54a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8002-cfdc6574bd841892.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9046-c44e41da49338c6c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9676.b7d5d1d90b9da224.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9826-8c81c97a72510fcf.js → 9826-d9addbd5ac990fa4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-6ee5c0a23951a07f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{404-9174cdb70126c2c5.js → 404-9644eb282f2dcd71.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-2c10f6b217b7978b.js → _app-284cba7174fa1f16.js} +136 -135
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-621416493c89ef01.js → manual-42b7fd34712f49bd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-0b9908c3e1dfe49e.js → multiple-4f164eab0960bbe0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-985d3c9179e69d7f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-5bb1b31ae8752250.js → add-vendors-61090926e5f98a5d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-17ffe691b91cee2e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-4e4d9426743b5cb4.js → [id]-95c13bca5c1e575e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-d72460348fadcab8.js → privacy-experience-609399510a60beb9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-3e7ddc252da00c98.js → [id]-d7d8f228ac74b26e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-35a7c305beee9428.js → new-821c0f82d5a2b7d4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-8365782543cf6ab9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-ab96939421639153.js → properties-40a7aa65f4d13cf9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-e4bacfc5c2ed2324.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{consent-13240e3ca77acfeb.js → consent-70c5c6aa5389d99f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-aad6047a4604b945.js → [resourceUrn]-adc500a03e239857.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-bd37b407c80c6986.js → [projectUrn]-3207f62e5012611b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-7b42dee0fb696658.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b6b98cea25dd94fa.js → [resourceUrn]-c8b3d090e4ba60d3.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-31a45ea2ca2a7f04.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-6172c2eb539319fd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-945d354ff057fb03.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-d9795e00f39cf4e9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-657833fd8528280f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-31e6c54794a9883e.js → [resourceUrn]-22eec362dfbb1d2a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-2822a423a7ad0550.js → detection-4decce5ef996e563.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-f98dd251babb7e28.js → [resourceUrn]-01acdd1ad492fd89.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-56eb4c014f0d96a3.js → discovery-85fdbf4cde60d910.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-8f88dc31c5144ea8.js → datamap-3a4b89fb21d14753.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-cb8d303f56091bd5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-401c8be76d9daec7.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-97e2d375b21cfe43.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-40ef544ca1f2c9b9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-e3c763f8e71f8e24.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-67a7fe58b96ea739.js → [id]-152e5d15705ec072.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-651b10cae0e99a05.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-03c54bc9fb18d2b0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{index-876bfd7210040cec.js → index-3d19b9ffa15a928a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4b0bb4ccfb237d41.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-78d4e0c14654148b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-6e796c3fe632280b.js → [id]-72cb360a6d14e701.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-fa0f3841c5bdfdeb.js → add-template-0ed67cf774d5cbf5.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-b06a2204e2a5b667.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-7050899b3f792129.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-11503454a62d8d7b.js → AntForm-7c3466f4d5797e55.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-a504941807bdb7f1.js → FormikAntFormItem-8de252f25871bab9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-0119403c8ff97f83.js → FormikControlled-cd6de0da47f980cf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-94f6d57d6c94ddf7.js → FormikField-7c238a881fe30e28.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-ed1a3ae09d72df89.js → forms-d4f3e8f67f76f146.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-c9220e20c1d93758.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-b9d6886a3f157120.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-9c1fd7867b2d80d7.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-fc959ed21dbce38c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-44a4a638dcb2722a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-1433c9f9501a884f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-41976b28503623cd.js → [id]-16e0b42cb342aa5f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-cb438d8f5ec6007a.js → add-property-ebd114a86b809391.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-b6db7036993709b3.js → properties-901be5fa4a48f48c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-da9ced1e20681154.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-0174554c0ac5958f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6f45ddbf675e66d2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-275c49e6089c5c9f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-1a8d05e19f06d857.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-49d86b9ca4523ca6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-386368bf7cb31771.js → domain-records-f71b4b95d91db926.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-a595cad18cf04673.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-6f7f9751689b042c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-b41fb5ad277088ab.js → locations-e2c88d7f779fe604.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-c65acd2b7ab04753.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-a94dfeea43fbca7d.js → regulations-c1c699eeb40a9dc0.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-a274e2191b87e315.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-18b316e2dad73731.js → [id]-4a48b4f996a64957.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-30debc87925634d9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-ca625b1296a029f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-3237881945acc0ee.js → [id]-7a3180b235eb8846.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-a3a50d9d79066935.js → user-management-5e2d0acf575252ca.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{webpack-69658aeaf6155d89.js → webpack-4502d4d67006b48f.js} +1 -1
- fides/ui-build/static/admin/_next/static/css/43d0c0fc207767eb.css +1 -0
- 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-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.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/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/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/ui-build/static/admin/_next/static/chunks/203-0c6cadcda98bdd33.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3450-9314e1b15df8a8da.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-4267fd8193e7f525.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3872-ac5feefd40b61ae3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/409-5bc4369b80a8c11d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4230-1ebc8c0ab293a077.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-a34d7ceff17c2169.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-557fb24665b2e4bf.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5309-ffdec884eec79d29.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5574-831167a8da90e2e6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6662-499c189f932a35aa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-7d28e030f6516e5d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6882-7cc1d14e27a80c10.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-7784e8d5ad6b8110.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7476-4de465016d3433b4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7630-2a5c57787632693d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7725-c79513b04113112b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-98cfab20bb831137.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-0b768155bf20505f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8735-f84afcc50885883c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-97a972cc8a8ed24d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9226-318dadf1c050ecda.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9676.9e6828b42ef05e06.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-4df2b67e0def5500.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-18e96ce81dab51a4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-54d7c7310763c66d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-6bc3b73a21576869.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-fe3d6887fecf0f86.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-e4770acf7044e2f5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-0db635c3483c9da8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-0c0e0a7798345541.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-3c56e5fe072a44c6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-58827eb86516931f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6a90131dcecd694c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-145fe9e4cfcb231d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]-8a1e5d140785c1e9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-227b5db4b472a6a7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-8401f17fe5d9a1dc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7d77b3ad069be268.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-90a8df230cb89877.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cfb25b02abb8da71.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4e286a1e501a0c73.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-3fdc55d4c129e618.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-8f9c006b6166f002.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-6ba7ae4f26c06cb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-e8db3ad525e7ddbd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-c14dd24592369467.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-100d7d03930629a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6f8d1b3ec83cfcf0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-3ce15577435d47cb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-709bcb0bc6a5382d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-4bc3e281409265cc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-1ea40fcd6b4268bf.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-65c7600fadc6e55a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-33dab986141b3663.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-1195042727c399ed.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-71b98858ecb4e097.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-cf427e04f862b5d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-eabeeec5bf2773c6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-ee56698ae3a6a78b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-0e2e98cc38ee5499.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-c32589c86081b750.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-a8f09bf8f3204ca7.js +0 -1
- fides/ui-build/static/admin/_next/static/css/a72179b1754aadd3.css +0 -1
- fides/ui-build/static/admin/_next/static/qvk5eMANVfwYkdURE7fgG/_buildManifest.js +0 -1
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.68.1b2.dist-info → ethyca_fides-2.68.1b4.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{qvk5eMANVfwYkdURE7fgG → LRCvfOqg1kP5kGnkD84G4}/_ssgManifest.js +0 -0
fides/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-08-
|
|
11
|
+
"date": "2025-08-27T12:07:27-0600",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.68.
|
|
14
|
+
"full-revisionid": "062904c4ee33fadc4f937ccfd3fd2f2e2a2cbae8",
|
|
15
|
+
"version": "2.68.1b4"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Update Request Tasks
|
|
2
|
+
|
|
3
|
+
Revision ID: 90502bcda282
|
|
4
|
+
Revises: 3baf42d251a6
|
|
5
|
+
Create Date: 2025-08-05 16:31:45.335384
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = "90502bcda282"
|
|
14
|
+
down_revision = "3baf42d251a6"
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
async_task_type = sa.Enum("manual", "polling", "callback", name="asynctasktype")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def upgrade():
|
|
22
|
+
async_task_type.create(op.get_bind(), checkfirst=True)
|
|
23
|
+
op.add_column(
|
|
24
|
+
"requesttask",
|
|
25
|
+
sa.Column(
|
|
26
|
+
"async_type",
|
|
27
|
+
async_task_type,
|
|
28
|
+
nullable=True,
|
|
29
|
+
),
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def downgrade():
|
|
34
|
+
op.drop_column("requesttask", "async_type")
|
|
35
|
+
async_task_type.drop(op.get_bind(), checkfirst=True)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""add location to privacy request
|
|
2
|
+
|
|
3
|
+
Revision ID: b1a2c3d4e5f6
|
|
4
|
+
Revises: 2f3c1a2d6b10
|
|
5
|
+
Create Date: 2025-08-06 18:15:00.000000
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
|
|
12
|
+
# revision identifiers, used by Alembic.
|
|
13
|
+
revision = "b1a2c3d4e5f6"
|
|
14
|
+
down_revision = "90502bcda282"
|
|
15
|
+
branch_labels = None
|
|
16
|
+
depends_on = None
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def upgrade():
|
|
20
|
+
# Add location column to privacyrequest table
|
|
21
|
+
op.add_column("privacyrequest", sa.Column("location", sa.String(), nullable=True))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def downgrade():
|
|
25
|
+
# Remove location column from privacyrequest table
|
|
26
|
+
op.drop_column("privacyrequest", "location")
|
fides/api/api/v1/api.py
CHANGED
|
@@ -5,6 +5,7 @@ from fides.api.api.v1.endpoints import (
|
|
|
5
5
|
consent_request_endpoints,
|
|
6
6
|
dataset_config_endpoints,
|
|
7
7
|
drp_endpoints,
|
|
8
|
+
dsr_package_link,
|
|
8
9
|
encryption_endpoints,
|
|
9
10
|
identity_verification_endpoints,
|
|
10
11
|
manual_webhook_endpoints,
|
|
@@ -32,6 +33,7 @@ api_router.include_router(connection_endpoints.router)
|
|
|
32
33
|
api_router.include_router(consent_request_endpoints.router)
|
|
33
34
|
api_router.include_router(dataset_config_endpoints.router)
|
|
34
35
|
api_router.include_router(drp_endpoints.router)
|
|
36
|
+
api_router.include_router(dsr_package_link.router)
|
|
35
37
|
api_router.include_router(encryption_endpoints.router)
|
|
36
38
|
api_router.include_router(masking_endpoints.router)
|
|
37
39
|
api_router.include_router(oauth_endpoints.router)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
|
|
3
|
+
from fastapi import Depends, HTTPException, Request, Response
|
|
4
|
+
from fastapi.responses import RedirectResponse
|
|
5
|
+
from sqlalchemy.orm import Session
|
|
6
|
+
from starlette.status import (
|
|
7
|
+
HTTP_302_FOUND,
|
|
8
|
+
HTTP_400_BAD_REQUEST,
|
|
9
|
+
HTTP_401_UNAUTHORIZED,
|
|
10
|
+
HTTP_403_FORBIDDEN,
|
|
11
|
+
HTTP_404_NOT_FOUND,
|
|
12
|
+
HTTP_422_UNPROCESSABLE_ENTITY,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from fides.api.api.deps import get_db
|
|
16
|
+
from fides.api.common_exceptions import AuthenticationError, AuthorizationError
|
|
17
|
+
from fides.api.models.privacy_request import PrivacyRequest
|
|
18
|
+
from fides.api.models.storage import get_active_default_storage_config
|
|
19
|
+
from fides.api.oauth.utils import validate_download_token
|
|
20
|
+
from fides.api.schemas.privacy_request import PrivacyRequestStatus
|
|
21
|
+
from fides.api.schemas.storage.storage import StorageType
|
|
22
|
+
from fides.api.service.storage.streaming.s3 import S3StorageClient
|
|
23
|
+
from fides.api.util.api_router import APIRouter
|
|
24
|
+
from fides.api.util.endpoint_utils import fides_limiter
|
|
25
|
+
from fides.common.api.v1.urn_registry import PRIVACY_CENTER_DSR_PACKAGE, V1_URL_PREFIX
|
|
26
|
+
from fides.config import CONFIG
|
|
27
|
+
|
|
28
|
+
router = APIRouter(tags=["Privacy Center"], prefix=V1_URL_PREFIX)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_privacy_request_or_error(
|
|
32
|
+
privacy_request_id: str, db: Session
|
|
33
|
+
) -> PrivacyRequest:
|
|
34
|
+
"""Load the privacy request or throw a 404"""
|
|
35
|
+
# Note: UUID format validation is now done earlier in the endpoint
|
|
36
|
+
privacy_request = PrivacyRequest.get(db, object_id=privacy_request_id)
|
|
37
|
+
|
|
38
|
+
if not privacy_request:
|
|
39
|
+
raise HTTPException(
|
|
40
|
+
status_code=HTTP_404_NOT_FOUND,
|
|
41
|
+
detail=f"No privacy request found with id '{privacy_request_id}'.",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
if privacy_request.deleted_at is not None:
|
|
45
|
+
raise HTTPException(
|
|
46
|
+
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
|
|
47
|
+
detail=f"Privacy request with id {privacy_request_id} has been deleted.",
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return privacy_request
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def raise_error(status_code: int, detail: str) -> None:
|
|
54
|
+
"""Raise an HTTPException with the given status code and detail"""
|
|
55
|
+
raise HTTPException(
|
|
56
|
+
status_code=status_code,
|
|
57
|
+
detail=detail,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@router.get(
|
|
62
|
+
PRIVACY_CENTER_DSR_PACKAGE,
|
|
63
|
+
status_code=HTTP_302_FOUND,
|
|
64
|
+
)
|
|
65
|
+
@fides_limiter.limit(CONFIG.security.public_request_rate_limit)
|
|
66
|
+
def get_access_results_urls(
|
|
67
|
+
privacy_request_id: str,
|
|
68
|
+
token: str,
|
|
69
|
+
db: Session = Depends(get_db),
|
|
70
|
+
*,
|
|
71
|
+
request: Request, # required for rate limiting
|
|
72
|
+
response: Response, # required for rate limiting
|
|
73
|
+
) -> RedirectResponse:
|
|
74
|
+
"""
|
|
75
|
+
Public endpoint for retrieving access results URLs for a privacy request.
|
|
76
|
+
This endpoint generates fresh presigned URLs and redirects to the first available result.
|
|
77
|
+
This endpoint is designed to be accessible via email links sent to end users.
|
|
78
|
+
No authentication is required, but a valid download token is required for security.
|
|
79
|
+
Rate limiting is applied for additional security.
|
|
80
|
+
|
|
81
|
+
privacy_request_id parameter is required in the URL path.
|
|
82
|
+
token parameter is required as a query parameter for security.
|
|
83
|
+
"""
|
|
84
|
+
# --------------Security checks--------------
|
|
85
|
+
# First validate the privacy request ID format to prevent SSRF attacks
|
|
86
|
+
# This is a simple string check that doesn't require database access
|
|
87
|
+
if not privacy_request_id.startswith("pri_"):
|
|
88
|
+
raise_error(
|
|
89
|
+
HTTP_400_BAD_REQUEST,
|
|
90
|
+
f"Invalid privacy request ID format: '{privacy_request_id}'. Must start with 'pri_' followed by a valid UUID v4.",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Extract the UUID part after the prefix
|
|
94
|
+
uuid_part = privacy_request_id[4:] # Remove "pri_" prefix
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
uuid.UUID(uuid_part, version=4)
|
|
98
|
+
except ValueError:
|
|
99
|
+
raise_error(
|
|
100
|
+
HTTP_400_BAD_REQUEST,
|
|
101
|
+
f"Invalid privacy request ID format: '{privacy_request_id}'. Must start with 'pri_' followed by a valid UUID v4.",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
try:
|
|
105
|
+
# Validate the download token before proceeding
|
|
106
|
+
validate_download_token(token, privacy_request_id)
|
|
107
|
+
except AuthenticationError as e:
|
|
108
|
+
raise_error(HTTP_401_UNAUTHORIZED, str(e.detail))
|
|
109
|
+
except AuthorizationError as e:
|
|
110
|
+
raise_error(HTTP_403_FORBIDDEN, str(e.detail))
|
|
111
|
+
|
|
112
|
+
# --------------Data checks--------------
|
|
113
|
+
storage_config = get_active_default_storage_config(db)
|
|
114
|
+
privacy_request = get_privacy_request_or_error(privacy_request_id, db)
|
|
115
|
+
|
|
116
|
+
if not storage_config:
|
|
117
|
+
raise_error(
|
|
118
|
+
HTTP_400_BAD_REQUEST, "No active default storage configuration found."
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if privacy_request.status != PrivacyRequestStatus.complete:
|
|
122
|
+
raise_error(
|
|
123
|
+
HTTP_400_BAD_REQUEST,
|
|
124
|
+
f"Access results for privacy request '{privacy_request.id}' are not available because the request is not complete.",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
if (
|
|
128
|
+
not privacy_request.access_result_urls
|
|
129
|
+
or not privacy_request.access_result_urls.get("access_result_urls")
|
|
130
|
+
):
|
|
131
|
+
raise_error(
|
|
132
|
+
HTTP_404_NOT_FOUND,
|
|
133
|
+
f"No access results found for privacy request '{privacy_request.id}'.",
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# --------------Processing--------------
|
|
137
|
+
file_name = f"{privacy_request.id}.zip"
|
|
138
|
+
|
|
139
|
+
# At this point, storage_config is guaranteed to exist due to earlier validation
|
|
140
|
+
# and we've already checked that it's not None above
|
|
141
|
+
assert storage_config is not None
|
|
142
|
+
|
|
143
|
+
if storage_config.type != StorageType.s3:
|
|
144
|
+
# Handle all other storage types (transcend, ethyca, local, etc.)
|
|
145
|
+
raise_error(
|
|
146
|
+
HTTP_400_BAD_REQUEST,
|
|
147
|
+
f"Storage type '{storage_config.type}' is not supported for download redirects. "
|
|
148
|
+
"Only S3 storage is supported for this endpoint.",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Get bucket name from storage config
|
|
152
|
+
bucket_name = storage_config.details.get("bucket")
|
|
153
|
+
if not bucket_name:
|
|
154
|
+
raise_error(HTTP_400_BAD_REQUEST, "S3 bucket name not found in storage config.")
|
|
155
|
+
|
|
156
|
+
try:
|
|
157
|
+
# Use S3StorageClient for cleaner presigned URL generation
|
|
158
|
+
s3_storage_client = S3StorageClient(storage_config.secrets)
|
|
159
|
+
result_url = s3_storage_client.generate_presigned_url(
|
|
160
|
+
bucket=bucket_name,
|
|
161
|
+
key=file_name,
|
|
162
|
+
)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
raise_error(HTTP_400_BAD_REQUEST, f"Failed to generate presigned URL: {str(e)}")
|
|
165
|
+
|
|
166
|
+
# Convert the URL to string for RedirectResponse
|
|
167
|
+
return RedirectResponse(url=str(result_url), status_code=HTTP_302_FOUND)
|
|
@@ -50,6 +50,7 @@ from fides.api.common_exceptions import (
|
|
|
50
50
|
IdentityVerificationException,
|
|
51
51
|
ManualWebhookFieldsUnset,
|
|
52
52
|
NoCachedManualWebhookEntry,
|
|
53
|
+
PrivacyRequestError,
|
|
53
54
|
TraversalError,
|
|
54
55
|
ValidationError,
|
|
55
56
|
)
|
|
@@ -123,6 +124,7 @@ from fides.api.util.endpoint_utils import validate_start_and_end_filters
|
|
|
123
124
|
from fides.api.util.enums import ColumnSort
|
|
124
125
|
from fides.api.util.fuzzy_search_utils import get_decrypted_identities_automaton
|
|
125
126
|
from fides.api.util.storage_util import StorageJSONEncoder
|
|
127
|
+
from fides.api.util.text import normalize_location_code
|
|
126
128
|
from fides.common.api.scope_registry import (
|
|
127
129
|
PRIVACY_REQUEST_CALLBACK_RESUME,
|
|
128
130
|
PRIVACY_REQUEST_CREATE,
|
|
@@ -175,7 +177,6 @@ from fides.service.dataset.dataset_config_service import (
|
|
|
175
177
|
)
|
|
176
178
|
from fides.service.messaging.messaging_service import MessagingService
|
|
177
179
|
from fides.service.privacy_request.privacy_request_service import (
|
|
178
|
-
PrivacyRequestError,
|
|
179
180
|
PrivacyRequestService,
|
|
180
181
|
_process_privacy_request_restart,
|
|
181
182
|
_requeue_privacy_request,
|
|
@@ -403,6 +404,7 @@ def _filter_privacy_request_queryset(
|
|
|
403
404
|
errored_lt: Optional[datetime] = None,
|
|
404
405
|
errored_gt: Optional[datetime] = None,
|
|
405
406
|
external_id: Optional[str] = None,
|
|
407
|
+
location: Optional[str] = None,
|
|
406
408
|
action_type: Optional[ActionType] = None,
|
|
407
409
|
include_consent_webhook_requests: Optional[bool] = False,
|
|
408
410
|
include_deleted_requests: Optional[bool] = False,
|
|
@@ -539,6 +541,29 @@ def _filter_privacy_request_queryset(
|
|
|
539
541
|
query = query.filter(PrivacyRequest.id.ilike(f"%{request_id}%"))
|
|
540
542
|
if external_id:
|
|
541
543
|
query = query.filter(PrivacyRequest.external_id.ilike(f"{external_id}%"))
|
|
544
|
+
if location:
|
|
545
|
+
# Support filtering by exact location match or country prefix
|
|
546
|
+
# e.g., "US" matches both "US" and "US-CA", "US-NY", etc.
|
|
547
|
+
# "US-CA" matches only "US-CA"
|
|
548
|
+
# Also normalize input to handle underscores and case insensitivity
|
|
549
|
+
|
|
550
|
+
try:
|
|
551
|
+
normalized_location = normalize_location_code(location)
|
|
552
|
+
except ValueError:
|
|
553
|
+
# If normalization fails, treat as no results to prevent errors
|
|
554
|
+
query = query.filter(False)
|
|
555
|
+
else:
|
|
556
|
+
if "-" in normalized_location:
|
|
557
|
+
# Exact match for subdivision codes
|
|
558
|
+
query = query.filter(PrivacyRequest.location == normalized_location)
|
|
559
|
+
else:
|
|
560
|
+
# Country code - match country or any subdivision of that country
|
|
561
|
+
query = query.filter(
|
|
562
|
+
or_(
|
|
563
|
+
PrivacyRequest.location == normalized_location,
|
|
564
|
+
PrivacyRequest.location.ilike(f"{normalized_location}-%"),
|
|
565
|
+
)
|
|
566
|
+
)
|
|
542
567
|
if status:
|
|
543
568
|
query = query.filter(PrivacyRequest.status.in_(status))
|
|
544
569
|
if created_lt:
|
|
@@ -685,6 +710,7 @@ def _shared_privacy_request_search(
|
|
|
685
710
|
errored_lt: Optional[datetime] = None,
|
|
686
711
|
errored_gt: Optional[datetime] = None,
|
|
687
712
|
external_id: Optional[str] = None,
|
|
713
|
+
location: Optional[str] = None,
|
|
688
714
|
action_type: Optional[ActionType] = None,
|
|
689
715
|
verbose: Optional[bool] = False,
|
|
690
716
|
include_identities: Optional[bool] = False,
|
|
@@ -723,6 +749,7 @@ def _shared_privacy_request_search(
|
|
|
723
749
|
errored_lt,
|
|
724
750
|
errored_gt,
|
|
725
751
|
external_id,
|
|
752
|
+
location,
|
|
726
753
|
action_type,
|
|
727
754
|
None,
|
|
728
755
|
include_deleted_requests,
|
|
@@ -796,6 +823,7 @@ def get_request_status(
|
|
|
796
823
|
errored_lt: Optional[datetime] = None,
|
|
797
824
|
errored_gt: Optional[datetime] = None,
|
|
798
825
|
external_id: Optional[str] = None,
|
|
826
|
+
location: Optional[str] = None,
|
|
799
827
|
action_type: Optional[ActionType] = None,
|
|
800
828
|
verbose: Optional[bool] = False,
|
|
801
829
|
include_identities: Optional[bool] = False,
|
|
@@ -836,6 +864,7 @@ def get_request_status(
|
|
|
836
864
|
errored_lt=errored_lt,
|
|
837
865
|
errored_gt=errored_gt,
|
|
838
866
|
external_id=external_id,
|
|
867
|
+
location=location,
|
|
839
868
|
action_type=action_type,
|
|
840
869
|
verbose=verbose,
|
|
841
870
|
include_identities=include_identities,
|
|
@@ -890,6 +919,7 @@ def privacy_request_search(
|
|
|
890
919
|
errored_lt=privacy_request_filter.errored_lt,
|
|
891
920
|
errored_gt=privacy_request_filter.errored_gt,
|
|
892
921
|
external_id=privacy_request_filter.external_id,
|
|
922
|
+
location=privacy_request_filter.location,
|
|
893
923
|
action_type=privacy_request_filter.action_type,
|
|
894
924
|
verbose=privacy_request_filter.verbose,
|
|
895
925
|
include_identities=privacy_request_filter.include_identities,
|
|
@@ -250,6 +250,10 @@ def logout_oauth_client(
|
|
|
250
250
|
if authorization is None:
|
|
251
251
|
raise AuthenticationError(detail="Authentication Failure")
|
|
252
252
|
|
|
253
|
+
# Validate that the token looks like a valid JWE token (5 segments separated by dots)
|
|
254
|
+
if not authorization or authorization.count(".") != 4:
|
|
255
|
+
return None
|
|
256
|
+
|
|
253
257
|
try:
|
|
254
258
|
token_data = json.loads(
|
|
255
259
|
extract_payload(authorization, CONFIG.security.app_encryption_key)
|
fides/api/common_exceptions.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import List
|
|
3
|
+
from typing import Dict, List, Optional
|
|
4
4
|
|
|
5
5
|
from fastapi import HTTPException, status
|
|
6
6
|
from starlette.status import (
|
|
@@ -175,8 +175,8 @@ class RequestTaskNotFound(BaseException):
|
|
|
175
175
|
"""Privacy Request Task Not Found"""
|
|
176
176
|
|
|
177
177
|
|
|
178
|
-
class
|
|
179
|
-
"""Request Task is Awaiting Processing - Awaiting Async Task
|
|
178
|
+
class AwaitingAsyncTask(BaseException):
|
|
179
|
+
"""Request Task is Awaiting Processing - Awaiting Async Task"""
|
|
180
180
|
|
|
181
181
|
|
|
182
182
|
class UpstreamTasksNotReady(BaseException):
|
|
@@ -373,6 +373,15 @@ class InvalidScopeError(HTTPException):
|
|
|
373
373
|
)
|
|
374
374
|
|
|
375
375
|
|
|
376
|
+
class PrivacyRequestError(Exception):
|
|
377
|
+
"""Base exception for privacy request operations."""
|
|
378
|
+
|
|
379
|
+
def __init__(self, message: str, data: Optional[Dict] = None):
|
|
380
|
+
self.message = message
|
|
381
|
+
self.data = data
|
|
382
|
+
super().__init__(message)
|
|
383
|
+
|
|
384
|
+
|
|
376
385
|
class KeyOrNameAlreadyExists(Exception):
|
|
377
386
|
"""A resource already exists with this key or name."""
|
|
378
387
|
|
|
@@ -432,11 +432,17 @@ class StagedResourceAncestor(Base):
|
|
|
432
432
|
|
|
433
433
|
# Execute batch when it reaches the desired size
|
|
434
434
|
if len(current_batch) >= batch_size:
|
|
435
|
+
logger.debug(
|
|
436
|
+
f"Inserting batch of {len(current_batch)} staged resource ancestor links"
|
|
437
|
+
)
|
|
435
438
|
db.execute(stmt_text, current_batch)
|
|
436
439
|
current_batch = []
|
|
437
440
|
|
|
438
441
|
# Execute any remaining items in the final batch
|
|
439
442
|
if current_batch:
|
|
443
|
+
logger.debug(
|
|
444
|
+
f"Inserting batch of {len(current_batch)} staged resource ancestor links"
|
|
445
|
+
)
|
|
440
446
|
db.execute(stmt_text, current_batch)
|
|
441
447
|
|
|
442
448
|
|
|
@@ -222,6 +222,7 @@ class PrivacyRequest(
|
|
|
222
222
|
canceled_at = Column(DateTime(timezone=True), nullable=True)
|
|
223
223
|
consent_preferences = Column(MutableList.as_mutable(JSONB), nullable=True)
|
|
224
224
|
source = Column(EnumColumn(PrivacyRequestSource), nullable=True)
|
|
225
|
+
location = Column(String, nullable=True)
|
|
225
226
|
|
|
226
227
|
# A PrivacyRequest can be soft deleted, so we store when it was deleted
|
|
227
228
|
deleted_at = Column(DateTime(timezone=True), nullable=True)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from enum import Enum as EnumType
|
|
5
6
|
from typing import TYPE_CHECKING, List, Optional, Tuple
|
|
6
7
|
|
|
7
8
|
from loguru import logger
|
|
@@ -15,6 +16,7 @@ from sqlalchemy_utils.types.encrypted.encrypted_type import (
|
|
|
15
16
|
)
|
|
16
17
|
|
|
17
18
|
from fides.api.db.base_class import Base, JSONTypeOverride # type: ignore[attr-defined]
|
|
19
|
+
from fides.api.db.util import EnumColumn
|
|
18
20
|
from fides.api.graph.config import (
|
|
19
21
|
ROOT_COLLECTION_ADDRESS,
|
|
20
22
|
TERMINATOR_ADDRESS,
|
|
@@ -67,6 +69,24 @@ class TraversalDetails(FidesSchema):
|
|
|
67
69
|
)
|
|
68
70
|
|
|
69
71
|
|
|
72
|
+
class AsyncTaskType(EnumType):
|
|
73
|
+
"""
|
|
74
|
+
Enum for asynchronous RequestTask types
|
|
75
|
+
|
|
76
|
+
These tasks differ from our regular tasks in that they are not finished on the same process that they are created,
|
|
77
|
+
but rather are put into a pause state and then triggered to completion by a different process
|
|
78
|
+
|
|
79
|
+
manual: A task that is manually triggered by the user
|
|
80
|
+
polling: A task that is triggered by a polling mechanism
|
|
81
|
+
callback: A task that is triggered by a callback from an external system
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
manual = "manual"
|
|
86
|
+
polling = "polling"
|
|
87
|
+
callback = "callback"
|
|
88
|
+
|
|
89
|
+
|
|
70
90
|
# TODO: At some point we will refactor this model to store all task types in a common table that links to tables with specific task attributes.
|
|
71
91
|
class RequestTask(WorkerTask, Base):
|
|
72
92
|
"""
|
|
@@ -145,6 +165,11 @@ class RequestTask(WorkerTask, Base):
|
|
|
145
165
|
|
|
146
166
|
# For async tasks awaiting callback
|
|
147
167
|
callback_succeeded = Column(Boolean)
|
|
168
|
+
# to recognize Polling async task
|
|
169
|
+
async_type = Column(
|
|
170
|
+
EnumColumn(AsyncTaskType, native_enum=True),
|
|
171
|
+
nullable=True,
|
|
172
|
+
)
|
|
148
173
|
|
|
149
174
|
# Stores a serialized collection that can be transformed back into a Collection to help
|
|
150
175
|
# execute the current task
|
|
@@ -13,12 +13,17 @@ from fides.api.models.policy import PolicyPreWebhook, WebhookDirection
|
|
|
13
13
|
from fides.api.models.pre_approval_webhook import PreApprovalWebhook
|
|
14
14
|
from fides.api.models.privacy_request.request_task import RequestTask
|
|
15
15
|
from fides.api.oauth.jwt import generate_jwe
|
|
16
|
-
from fides.api.schemas.external_https import
|
|
16
|
+
from fides.api.schemas.external_https import (
|
|
17
|
+
DownloadTokenJWE,
|
|
18
|
+
RequestTaskJWE,
|
|
19
|
+
WebhookJWE,
|
|
20
|
+
)
|
|
17
21
|
from fides.api.schemas.policy import ActionType
|
|
18
22
|
from fides.api.schemas.privacy_request import PrivacyRequestStatus
|
|
19
23
|
from fides.api.schemas.redis_cache import Identity
|
|
20
24
|
from fides.common.api.scope_registry import (
|
|
21
25
|
PRIVACY_REQUEST_CALLBACK_RESUME,
|
|
26
|
+
PRIVACY_REQUEST_READ_ACCESS_RESULTS,
|
|
22
27
|
PRIVACY_REQUEST_REVIEW,
|
|
23
28
|
)
|
|
24
29
|
from fides.config import CONFIG
|
|
@@ -92,3 +97,30 @@ def generate_request_task_callback_jwe(request_task: RequestTask) -> str:
|
|
|
92
97
|
json.dumps(jwe.model_dump(mode="json")),
|
|
93
98
|
CONFIG.security.app_encryption_key,
|
|
94
99
|
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def generate_privacy_request_download_token(privacy_request_id: str) -> str:
|
|
103
|
+
"""
|
|
104
|
+
Generate a JWE token for users to download their privacy request access package.
|
|
105
|
+
This is currently used for the DSR package link endpoint which provides a redirect
|
|
106
|
+
to a presigned URL for the access results.
|
|
107
|
+
This token expires based on the configured TTL for security.
|
|
108
|
+
"""
|
|
109
|
+
from datetime import timedelta
|
|
110
|
+
|
|
111
|
+
now = datetime.now()
|
|
112
|
+
# Use the configured TTL from security settings
|
|
113
|
+
expiration = now + timedelta(
|
|
114
|
+
seconds=CONFIG.security.subject_request_download_link_ttl_seconds
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
jwe = DownloadTokenJWE(
|
|
118
|
+
privacy_request_id=privacy_request_id,
|
|
119
|
+
scopes=[PRIVACY_REQUEST_READ_ACCESS_RESULTS],
|
|
120
|
+
iat=now.isoformat(),
|
|
121
|
+
exp=expiration.isoformat(),
|
|
122
|
+
)
|
|
123
|
+
return generate_jwe(
|
|
124
|
+
json.dumps(jwe.model_dump(mode="json")),
|
|
125
|
+
CONFIG.security.app_encryption_key,
|
|
126
|
+
)
|