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/api/oauth/utils.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
-
from datetime import datetime
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
5
|
from functools import update_wrapper
|
|
6
6
|
from types import FunctionType
|
|
7
7
|
from typing import Any, Callable, Dict, List, Optional, Tuple
|
|
@@ -32,7 +32,11 @@ from fides.api.models.pre_approval_webhook import PreApprovalWebhook
|
|
|
32
32
|
from fides.api.models.privacy_request import RequestTask
|
|
33
33
|
from fides.api.oauth.roles import get_scopes_from_roles
|
|
34
34
|
from fides.api.request_context import set_user_id
|
|
35
|
-
from fides.api.schemas.external_https import
|
|
35
|
+
from fides.api.schemas.external_https import (
|
|
36
|
+
DownloadTokenJWE,
|
|
37
|
+
RequestTaskJWE,
|
|
38
|
+
WebhookJWE,
|
|
39
|
+
)
|
|
36
40
|
from fides.api.schemas.oauth import OAuth2ClientCredentialsBearer
|
|
37
41
|
from fides.common.api.v1.urn_registry import TOKEN, V1_URL_PREFIX
|
|
38
42
|
from fides.config import CONFIG, FidesConfig
|
|
@@ -49,63 +53,28 @@ oauth2_scheme = OAuth2ClientCredentialsBearer(
|
|
|
49
53
|
|
|
50
54
|
def extract_payload(jwe_string: str, encryption_key: str) -> str:
|
|
51
55
|
"""Given a jwe, extracts the payload and returns it in string form."""
|
|
52
|
-
|
|
56
|
+
try:
|
|
57
|
+
decrypted_payload = jwe.decrypt(jwe_string, encryption_key)
|
|
58
|
+
return decrypted_payload.decode("utf-8")
|
|
59
|
+
except exceptions.JWEError as e:
|
|
60
|
+
logger.debug("Failed to decrypt JWE: {}", e)
|
|
61
|
+
raise e
|
|
53
62
|
|
|
54
63
|
|
|
55
|
-
def is_token_expired(
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
def is_token_expired(
|
|
65
|
+
issued_at: Optional[datetime], token_duration_minutes: int
|
|
66
|
+
) -> bool:
|
|
67
|
+
"""Check if a token has expired based on its issued_at timestamp and duration."""
|
|
68
|
+
if issued_at is None:
|
|
58
69
|
return True
|
|
70
|
+
expiration_time = issued_at + timedelta(minutes=token_duration_minutes)
|
|
71
|
+
return datetime.now() > expiration_time
|
|
59
72
|
|
|
60
|
-
return (datetime.now() - issued_at).total_seconds() / 60.0 > token_duration_min
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def copy_func(source_function: Callable) -> Callable:
|
|
64
|
-
"""Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
|
|
65
|
-
target_function = FunctionType(
|
|
66
|
-
source_function.__code__,
|
|
67
|
-
source_function.__globals__,
|
|
68
|
-
name=source_function.__name__,
|
|
69
|
-
argdefs=source_function.__defaults__,
|
|
70
|
-
closure=source_function.__closure__,
|
|
71
|
-
)
|
|
72
|
-
updated_target_function: Callable = update_wrapper(target_function, source_function)
|
|
73
|
-
updated_target_function.__kwdefaults__ = source_function.__kwdefaults__
|
|
74
|
-
return updated_target_function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
async def get_current_user(
|
|
78
|
-
security_scopes: SecurityScopes,
|
|
79
|
-
authorization: str = Security(oauth2_scheme),
|
|
80
|
-
db: Session = Depends(get_db),
|
|
81
|
-
) -> FidesUser:
|
|
82
|
-
"""A wrapper around verify_oauth_client that returns that client's user if one exists."""
|
|
83
|
-
client = await verify_oauth_client(
|
|
84
|
-
security_scopes=security_scopes,
|
|
85
|
-
authorization=authorization,
|
|
86
|
-
db=db,
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
if client.id == CONFIG.security.oauth_root_client_id:
|
|
90
|
-
return FidesUser(
|
|
91
|
-
id=CONFIG.security.oauth_root_client_id,
|
|
92
|
-
username=CONFIG.security.root_username,
|
|
93
|
-
created_at=datetime.utcnow(),
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
return client.user # type: ignore[attr-defined]
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def is_callback_token_expired(issued_at: datetime | None) -> bool:
|
|
100
|
-
"""Returns True if the token is older than the expiration of the redis cache. We
|
|
101
|
-
can't resume executing the privacy request if the identity data is gone.
|
|
102
|
-
"""
|
|
103
|
-
if not issued_at:
|
|
104
|
-
return True
|
|
105
73
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
74
|
+
def is_callback_token_expired(issued_at: datetime) -> bool:
|
|
75
|
+
"""Check if a callback token has expired (24 hours)."""
|
|
76
|
+
expiration_time = issued_at + timedelta(hours=24)
|
|
77
|
+
return datetime.now() > expiration_time
|
|
109
78
|
|
|
110
79
|
|
|
111
80
|
def _get_webhook_jwe_or_error(
|
|
@@ -114,9 +83,13 @@ def _get_webhook_jwe_or_error(
|
|
|
114
83
|
if authorization is None:
|
|
115
84
|
raise AuthenticationError(detail="Authentication Failure")
|
|
116
85
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
86
|
+
try:
|
|
87
|
+
token_data = json.loads(
|
|
88
|
+
extract_payload(authorization, CONFIG.security.app_encryption_key)
|
|
89
|
+
)
|
|
90
|
+
except exceptions.JWEError:
|
|
91
|
+
raise AuthorizationError(detail="Not Authorized for this action")
|
|
92
|
+
|
|
120
93
|
try:
|
|
121
94
|
token = WebhookJWE(**token_data)
|
|
122
95
|
except ValidationError:
|
|
@@ -160,6 +133,98 @@ def _get_request_task_jwe_or_error(
|
|
|
160
133
|
return token
|
|
161
134
|
|
|
162
135
|
|
|
136
|
+
def validate_download_token(token: str, privacy_request_id: str) -> DownloadTokenJWE:
|
|
137
|
+
"""
|
|
138
|
+
Validate a download token for accessing privacy request packages.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
token: The JWE token to validate
|
|
142
|
+
privacy_request_id: The privacy request ID the token should grant access to
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
The validated DownloadTokenJWE object
|
|
146
|
+
|
|
147
|
+
Raises:
|
|
148
|
+
AuthenticationError: If token is invalid or expired
|
|
149
|
+
AuthorizationError: If token doesn't grant access to the requested privacy request
|
|
150
|
+
"""
|
|
151
|
+
if not token:
|
|
152
|
+
raise AuthenticationError(detail="Download token is required")
|
|
153
|
+
|
|
154
|
+
# Check if token looks like a JWE (should have 5 parts separated by dots)
|
|
155
|
+
if token.count(".") != 4:
|
|
156
|
+
raise AuthenticationError(detail="Invalid download token format")
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
token_data = json.loads(
|
|
160
|
+
extract_payload(token, CONFIG.security.app_encryption_key)
|
|
161
|
+
)
|
|
162
|
+
except exceptions.JWEError:
|
|
163
|
+
raise AuthenticationError(detail="Invalid download token format")
|
|
164
|
+
|
|
165
|
+
try:
|
|
166
|
+
download_token = DownloadTokenJWE(**token_data)
|
|
167
|
+
except ValidationError:
|
|
168
|
+
raise AuthenticationError(detail="Invalid download token structure")
|
|
169
|
+
|
|
170
|
+
# Verify the token grants access to the requested privacy request
|
|
171
|
+
if download_token.privacy_request_id != privacy_request_id:
|
|
172
|
+
raise AuthorizationError(
|
|
173
|
+
detail="Download token does not grant access to this privacy request"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Verify the token has the required scope
|
|
177
|
+
required_scope = "privacy-request-access-results:read"
|
|
178
|
+
if required_scope not in download_token.scopes:
|
|
179
|
+
raise AuthorizationError(detail="Download token lacks required permissions")
|
|
180
|
+
|
|
181
|
+
# Check if the token has expired
|
|
182
|
+
try:
|
|
183
|
+
expiration_time = datetime.fromisoformat(download_token.exp)
|
|
184
|
+
if datetime.now() > expiration_time:
|
|
185
|
+
raise AuthenticationError(detail="Download token has expired")
|
|
186
|
+
except (ValueError, TypeError):
|
|
187
|
+
raise AuthenticationError(detail="Invalid token expiration format")
|
|
188
|
+
|
|
189
|
+
return download_token
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def copy_func(source_function: Callable) -> Callable:
|
|
193
|
+
"""Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
|
|
194
|
+
target_function = FunctionType(
|
|
195
|
+
source_function.__code__,
|
|
196
|
+
source_function.__globals__,
|
|
197
|
+
name=source_function.__name__,
|
|
198
|
+
argdefs=source_function.__defaults__,
|
|
199
|
+
closure=source_function.__closure__,
|
|
200
|
+
)
|
|
201
|
+
updated_target_function: Callable = update_wrapper(target_function, source_function)
|
|
202
|
+
updated_target_function.__kwdefaults__ = source_function.__kwdefaults__
|
|
203
|
+
return updated_target_function
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
async def get_current_user(
|
|
207
|
+
security_scopes: SecurityScopes,
|
|
208
|
+
authorization: str = Security(oauth2_scheme),
|
|
209
|
+
db: Session = Depends(get_db),
|
|
210
|
+
) -> FidesUser:
|
|
211
|
+
"""A wrapper around verify_oauth_client that returns that client's user if one exists."""
|
|
212
|
+
client = await verify_oauth_client(
|
|
213
|
+
security_scopes=security_scopes,
|
|
214
|
+
authorization=authorization,
|
|
215
|
+
db=db,
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if client.id == CONFIG.security.oauth_root_client_id:
|
|
219
|
+
return FidesUser(
|
|
220
|
+
id=CONFIG.security.oauth_root_client_id,
|
|
221
|
+
username=CONFIG.security.root_username,
|
|
222
|
+
created_at=datetime.utcnow(),
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
return client.user # type: ignore[attr-defined]
|
|
226
|
+
|
|
227
|
+
|
|
163
228
|
def verify_callback_oauth_policy_pre_webhook(
|
|
164
229
|
security_scopes: SecurityScopes,
|
|
165
230
|
authorization: str = Security(oauth2_scheme),
|
|
@@ -87,6 +87,12 @@ class AdminUIConfig(FidesSchema):
|
|
|
87
87
|
model_config = ConfigDict(extra="forbid")
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
class PrivacyCenterConfig(FidesSchema):
|
|
91
|
+
url: SerializeAsAny[Optional[AnyHttpUrlStringRemovesSlash]] = None
|
|
92
|
+
|
|
93
|
+
model_config = ConfigDict(extra="forbid")
|
|
94
|
+
|
|
95
|
+
|
|
90
96
|
class ConsentConfig(FidesSchema):
|
|
91
97
|
override_vendor_purposes: Optional[bool]
|
|
92
98
|
model_config = ConfigDict(extra="forbid")
|
|
@@ -119,6 +125,7 @@ class ApplicationConfig(FidesSchema):
|
|
|
119
125
|
security: Optional[SecurityApplicationConfig] = None
|
|
120
126
|
consent: Optional[ConsentConfig] = None
|
|
121
127
|
admin_ui: Optional[AdminUIConfig] = None
|
|
128
|
+
privacy_center: Optional[PrivacyCenterConfig] = None
|
|
122
129
|
|
|
123
130
|
@model_validator(mode="before")
|
|
124
131
|
@classmethod
|
|
@@ -4,6 +4,8 @@ from pydantic import BaseModel, ConfigDict
|
|
|
4
4
|
|
|
5
5
|
from fides.api.models.connectionconfig import ConnectionType
|
|
6
6
|
from fides.api.schemas.connection_configuration.enums.system_type import SystemType
|
|
7
|
+
from fides.api.schemas.enums.connection_category import ConnectionCategory
|
|
8
|
+
from fides.api.schemas.enums.integration_feature import IntegrationFeature
|
|
7
9
|
from fides.api.schemas.policy import ActionType
|
|
8
10
|
|
|
9
11
|
|
|
@@ -19,4 +21,8 @@ class ConnectionSystemTypeMap(BaseModel):
|
|
|
19
21
|
authorization_required: Optional[bool] = False
|
|
20
22
|
user_guide: Optional[str] = None
|
|
21
23
|
supported_actions: List[ActionType]
|
|
24
|
+
# New fields for enhanced display information
|
|
25
|
+
category: Optional[ConnectionCategory] = None
|
|
26
|
+
tags: Optional[List[str]] = None
|
|
27
|
+
enabled_features: Optional[List[IntegrationFeature]] = None
|
|
22
28
|
model_config = ConfigDict(use_enum_values=True, from_attributes=True)
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ConnectionCategory(str, Enum):
|
|
5
|
+
"""
|
|
6
|
+
Categories for connection types, matching frontend ConnectionCategory enum
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
DATA_CATALOG = "DATA_CATALOG"
|
|
10
|
+
DATA_WAREHOUSE = "DATA_WAREHOUSE"
|
|
11
|
+
DATABASE = "DATABASE"
|
|
12
|
+
IDENTITY_PROVIDER = "IDENTITY_PROVIDER"
|
|
13
|
+
WEBSITE = "WEBSITE"
|
|
14
|
+
CRM = "CRM"
|
|
15
|
+
MANUAL = "MANUAL"
|
|
16
|
+
MARKETING = "MARKETING"
|
|
17
|
+
ANALYTICS = "ANALYTICS"
|
|
18
|
+
ECOMMERCE = "ECOMMERCE"
|
|
19
|
+
COMMUNICATION = "COMMUNICATION"
|
|
20
|
+
CUSTOM = "CUSTOM" # Fallback for uncategorized/custom uploaded integrations
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class IntegrationFeature(str, Enum):
|
|
5
|
+
"""
|
|
6
|
+
Features that can be enabled for different integration types.
|
|
7
|
+
These control which tabs and functionality are available in the integration detail view.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Enables data discovery and monitoring functionality - shows "Data discovery" tab
|
|
11
|
+
DATA_DISCOVERY = "DATA_DISCOVERY"
|
|
12
|
+
|
|
13
|
+
# Enables data synchronization to external systems - shows "Data sync" tab
|
|
14
|
+
DATA_SYNC = "DATA_SYNC"
|
|
15
|
+
|
|
16
|
+
# Enables task/workflow management for manual processes - shows "Tasks" tab
|
|
17
|
+
TASKS = "TASKS"
|
|
18
|
+
|
|
19
|
+
# Indicates integration doesn't require connection testing - shows "Details" tab instead of "Connection" tab
|
|
20
|
+
WITHOUT_CONNECTION = "WITHOUT_CONNECTION"
|
|
21
|
+
|
|
22
|
+
# Enables Data Subject Request automation for SAAS integrations
|
|
23
|
+
DSR_AUTOMATION = "DSR_AUTOMATION"
|
|
@@ -39,3 +39,12 @@ class RequestTaskJWE(BaseModel):
|
|
|
39
39
|
request_task_id: str
|
|
40
40
|
scopes: List[str]
|
|
41
41
|
iat: str
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class DownloadTokenJWE(BaseModel):
|
|
45
|
+
"""Describes JWE that is given to users to access their privacy request download package"""
|
|
46
|
+
|
|
47
|
+
privacy_request_id: str
|
|
48
|
+
scopes: List[str]
|
|
49
|
+
iat: str
|
|
50
|
+
exp: str
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from abc import ABC
|
|
1
2
|
from typing import Any, Dict, List, Literal, Optional, Union
|
|
2
3
|
|
|
3
4
|
from pydantic import ConfigDict, Field, field_validator, model_validator
|
|
@@ -12,22 +13,10 @@ class CustomIdentity(FidesSchema):
|
|
|
12
13
|
label: str
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
class LocationIdentityField(FidesSchema):
|
|
16
|
-
"""Location field configuration that extends the useful parts of CustomPrivacyRequestField"""
|
|
17
|
-
|
|
18
|
-
label: str
|
|
19
|
-
required: Optional[bool] = True
|
|
20
|
-
default_value: Optional[str] = None
|
|
21
|
-
query_param_key: Optional[str] = None
|
|
22
|
-
ip_geolocation_hint: Optional[bool] = False
|
|
23
|
-
# Note: We intentionally omit 'hidden' field as it doesn't make sense for location identity input
|
|
24
|
-
|
|
25
|
-
|
|
26
16
|
class IdentityInputs(FidesSchema):
|
|
27
17
|
name: Optional[RequiredType] = None
|
|
28
18
|
email: Optional[RequiredType] = None
|
|
29
19
|
phone: Optional[RequiredType] = None
|
|
30
|
-
location: Optional[Union[RequiredType, LocationIdentityField]] = None
|
|
31
20
|
model_config = ConfigDict(extra="allow")
|
|
32
21
|
|
|
33
22
|
def __init__(self, **data: Any):
|
|
@@ -42,13 +31,12 @@ class IdentityInputs(FidesSchema):
|
|
|
42
31
|
f'Custom identity "{field}" must be an instance of CustomIdentity '
|
|
43
32
|
'(e.g. {"label": "Field label"})'
|
|
44
33
|
)
|
|
45
|
-
elif field == "location" and isinstance(value, dict):
|
|
46
|
-
# Handle location field as LocationIdentityField
|
|
47
|
-
data[field] = LocationIdentityField(**value)
|
|
48
34
|
super().__init__(**data)
|
|
49
35
|
|
|
50
36
|
|
|
51
|
-
class
|
|
37
|
+
class BaseCustomPrivacyRequestField(FidesSchema, ABC):
|
|
38
|
+
"""Abstract base class for all custom privacy request fields"""
|
|
39
|
+
|
|
52
40
|
label: str
|
|
53
41
|
required: Optional[bool] = True
|
|
54
42
|
default_value: Optional[str] = None
|
|
@@ -69,6 +57,41 @@ class CustomPrivacyRequestField(FidesSchema):
|
|
|
69
57
|
return values
|
|
70
58
|
|
|
71
59
|
|
|
60
|
+
class CustomPrivacyRequestField(BaseCustomPrivacyRequestField):
|
|
61
|
+
"""Regular custom privacy request field supporting text, select, and multiselect types"""
|
|
62
|
+
|
|
63
|
+
field_type: Optional[Literal["text", "select", "multiselect"]] = None
|
|
64
|
+
options: Optional[List[str]] = None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class LocationCustomPrivacyRequestField(BaseCustomPrivacyRequestField):
|
|
68
|
+
"""Location field that doesn't support options and includes IP geolocation hint"""
|
|
69
|
+
|
|
70
|
+
field_type: Literal["location"] = "location"
|
|
71
|
+
ip_geolocation_hint: Optional[bool] = False
|
|
72
|
+
|
|
73
|
+
@model_validator(mode="before")
|
|
74
|
+
@classmethod
|
|
75
|
+
def validate_location_field(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
|
76
|
+
# Ensure options is not provided for location fields
|
|
77
|
+
if "options" in values:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
"LocationCustomPrivacyRequestField does not support options"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# This field cannot be hidden
|
|
83
|
+
if values.get("hidden"):
|
|
84
|
+
raise ValueError("Custom location fields cannot be hidden")
|
|
85
|
+
|
|
86
|
+
return values
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# Create a simple union type - Pydantic will use the field_type to determine which model to use
|
|
90
|
+
CustomPrivacyRequestFieldUnion = Union[
|
|
91
|
+
LocationCustomPrivacyRequestField, CustomPrivacyRequestField
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
|
|
72
95
|
class PrivacyRequestOption(FidesSchema):
|
|
73
96
|
locations: Optional[Union[List[PrivacyNoticeRegion], Literal["fallback"]]] = None
|
|
74
97
|
policy_key: Optional[str] = None
|
|
@@ -79,7 +102,9 @@ class PrivacyRequestOption(FidesSchema):
|
|
|
79
102
|
confirm_button_text: Optional[str] = Field(alias="confirmButtonText", default=None)
|
|
80
103
|
cancel_button_text: Optional[str] = Field(alias="cancelButtonText", default=None)
|
|
81
104
|
identity_inputs: Optional[IdentityInputs] = None
|
|
82
|
-
custom_privacy_request_fields: Optional[
|
|
105
|
+
custom_privacy_request_fields: Optional[
|
|
106
|
+
Dict[str, CustomPrivacyRequestFieldUnion]
|
|
107
|
+
] = None
|
|
83
108
|
|
|
84
109
|
|
|
85
110
|
class ConsentConfigButton(FidesSchema):
|
|
@@ -89,7 +114,9 @@ class ConsentConfigButton(FidesSchema):
|
|
|
89
114
|
cancel_button_text: Optional[str] = Field(alias="cancelButtonText", default=None)
|
|
90
115
|
icon_path: str
|
|
91
116
|
identity_inputs: IdentityInputs
|
|
92
|
-
custom_privacy_request_fields: Optional[
|
|
117
|
+
custom_privacy_request_fields: Optional[
|
|
118
|
+
Dict[str, CustomPrivacyRequestFieldUnion]
|
|
119
|
+
] = None
|
|
93
120
|
title: str
|
|
94
121
|
modal_title: Optional[str] = Field(alias="modalTitle", default=None)
|
|
95
122
|
|
|
@@ -174,7 +201,9 @@ class PartialPrivacyRequestOption(FidesSchema):
|
|
|
174
201
|
policy_key: str
|
|
175
202
|
title: str
|
|
176
203
|
identity_inputs: Optional[IdentityInputs] = None
|
|
177
|
-
custom_privacy_request_fields: Optional[
|
|
204
|
+
custom_privacy_request_fields: Optional[
|
|
205
|
+
Dict[str, CustomPrivacyRequestFieldUnion]
|
|
206
|
+
] = None
|
|
178
207
|
|
|
179
208
|
|
|
180
209
|
class PartialPrivacyCenterConfig(FidesSchema):
|
|
@@ -18,6 +18,7 @@ from fides.api.schemas.user import PrivacyRequestReviewer
|
|
|
18
18
|
from fides.api.util.collection_util import Row
|
|
19
19
|
from fides.api.util.encryption.aes_gcm_encryption_scheme import verify_encryption_key
|
|
20
20
|
from fides.api.util.enums import ColumnSort
|
|
21
|
+
from fides.api.util.text import normalize_location_code
|
|
21
22
|
from fides.config import CONFIG
|
|
22
23
|
|
|
23
24
|
|
|
@@ -103,6 +104,7 @@ class PrivacyRequestCreate(FidesSchema):
|
|
|
103
104
|
property_id: Optional[str] = None
|
|
104
105
|
consent_preferences: Optional[List[Consent]] = None # TODO Slated for deprecation
|
|
105
106
|
source: Optional[PrivacyRequestSource] = None
|
|
107
|
+
location: Optional[str] = None
|
|
106
108
|
|
|
107
109
|
@field_validator("encryption_key")
|
|
108
110
|
@classmethod
|
|
@@ -114,6 +116,18 @@ class PrivacyRequestCreate(FidesSchema):
|
|
|
114
116
|
verify_encryption_key(value.encode(CONFIG.security.encoding))
|
|
115
117
|
return value
|
|
116
118
|
|
|
119
|
+
@field_validator("location")
|
|
120
|
+
@classmethod
|
|
121
|
+
def validate_location(
|
|
122
|
+
cls: Type["PrivacyRequestCreate"], value: Optional[str] = None
|
|
123
|
+
) -> Optional[str]:
|
|
124
|
+
"""Validate and normalize location to ISO 3166 format"""
|
|
125
|
+
if value is None:
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
# nuance here is the validator will coalesce values from the less strict format to ISO 3166 (i.e. "us_ca" -> "US-CA")
|
|
129
|
+
return normalize_location_code(value)
|
|
130
|
+
|
|
117
131
|
|
|
118
132
|
class PrivacyRequestResubmit(PrivacyRequestCreate):
|
|
119
133
|
"""Schema used to copy a privacy request for resubmission"""
|
|
@@ -321,6 +335,7 @@ class PrivacyRequestResponse(FidesSchema):
|
|
|
321
335
|
custom_privacy_request_fields_approved_by: Optional[str] = None
|
|
322
336
|
custom_privacy_request_fields_approved_at: Optional[datetime] = None
|
|
323
337
|
source: Optional[PrivacyRequestSource] = None
|
|
338
|
+
location: Optional[str] = None
|
|
324
339
|
deleted_at: Optional[datetime] = None
|
|
325
340
|
deleted_by: Optional[str] = None
|
|
326
341
|
finalized_at: Optional[datetime] = None
|
|
@@ -437,6 +452,7 @@ class PrivacyRequestFilter(FidesSchema):
|
|
|
437
452
|
errored_lt: Optional[datetime] = None
|
|
438
453
|
errored_gt: Optional[datetime] = None
|
|
439
454
|
external_id: Optional[str] = None
|
|
455
|
+
location: Optional[str] = None
|
|
440
456
|
action_type: Optional[ActionType] = None
|
|
441
457
|
verbose: Optional[bool] = False
|
|
442
458
|
include_identities: Optional[bool] = False
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict
|
|
4
|
+
|
|
5
|
+
from fides.api.schemas.enums.connection_category import ConnectionCategory
|
|
6
|
+
from fides.api.schemas.enums.integration_feature import IntegrationFeature
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SaaSDisplayInfo(BaseModel):
|
|
10
|
+
"""
|
|
11
|
+
Optional display information for SAAS integrations to enhance frontend presentation.
|
|
12
|
+
When not provided, smart defaults will be inferred based on the integration type.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
category: Optional[ConnectionCategory] = None
|
|
16
|
+
tags: Optional[List[str]] = None
|
|
17
|
+
enabled_features: Optional[List[IntegrationFeature]] = None
|
|
18
|
+
|
|
19
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
@@ -17,6 +17,7 @@ from fides.api.graph.config import (
|
|
|
17
17
|
from fides.api.schemas.base_class import FidesSchema
|
|
18
18
|
from fides.api.schemas.limiter.rate_limit_config import RateLimitConfig
|
|
19
19
|
from fides.api.schemas.policy import ActionType
|
|
20
|
+
from fides.api.schemas.saas.display_info import SaaSDisplayInfo
|
|
20
21
|
from fides.api.schemas.saas.shared_schemas import HTTPMethod
|
|
21
22
|
from fides.api.service.saas_request.saas_request_override_factory import (
|
|
22
23
|
SaaSRequestOverrideFactory,
|
|
@@ -428,6 +429,7 @@ class SaaSConfig(SaaSConfigBase):
|
|
|
428
429
|
rate_limit_config: Optional[RateLimitConfig] = None
|
|
429
430
|
consent_requests: Optional[ConsentRequestMap] = None
|
|
430
431
|
user_guide: Optional[str] = None
|
|
432
|
+
display_info: Optional[SaaSDisplayInfo] = None
|
|
431
433
|
|
|
432
434
|
@property
|
|
433
435
|
def top_level_endpoint_dict(self) -> Dict[str, Endpoint]:
|
|
@@ -37,6 +37,8 @@ class StorageDetails(Enum):
|
|
|
37
37
|
NAMING = "naming"
|
|
38
38
|
MAX_RETRIES = "max_retries"
|
|
39
39
|
AUTH_METHOD = "auth_method"
|
|
40
|
+
ENABLE_STREAMING = "enable_streaming"
|
|
41
|
+
ENABLE_ACCESS_PACKAGE_REDIRECT = "enable_access_package_redirect"
|
|
40
42
|
model_config = ConfigDict(extra="forbid")
|
|
41
43
|
|
|
42
44
|
|
|
@@ -58,6 +60,8 @@ class StorageDetailsS3(FileBasedStorageDetails):
|
|
|
58
60
|
auth_method: AWSAuthMethod
|
|
59
61
|
bucket: str
|
|
60
62
|
max_retries: Optional[int] = 0
|
|
63
|
+
enable_streaming: Optional[bool] = False
|
|
64
|
+
enable_access_package_redirect: Optional[bool] = False
|
|
61
65
|
model_config = ConfigDict(use_enum_values=True)
|
|
62
66
|
|
|
63
67
|
|
|
File without changes
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from loguru import logger
|
|
2
|
+
from sqlalchemy.orm import Session
|
|
3
|
+
|
|
4
|
+
from fides.api.common_exceptions import PrivacyRequestError
|
|
5
|
+
from fides.api.models.connectionconfig import ConnectionConfig
|
|
6
|
+
from fides.api.models.datasetconfig import DatasetConfig
|
|
7
|
+
from fides.api.models.privacy_request import PrivacyRequest, RequestTask
|
|
8
|
+
from fides.api.schemas.privacy_request import PrivacyRequestStatus
|
|
9
|
+
from fides.api.task.task_resources import TaskResources
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def requeue_polling_request(
|
|
13
|
+
db: Session,
|
|
14
|
+
async_task: RequestTask,
|
|
15
|
+
) -> None:
|
|
16
|
+
"""Re-queue a Privacy request that polls async tasks for a given privacy request"""
|
|
17
|
+
# Check that the privacy request is approved or in processing
|
|
18
|
+
privacy_request: PrivacyRequest = async_task.privacy_request
|
|
19
|
+
|
|
20
|
+
if privacy_request.status not in [
|
|
21
|
+
PrivacyRequestStatus.approved,
|
|
22
|
+
PrivacyRequestStatus.in_processing,
|
|
23
|
+
]:
|
|
24
|
+
raise PrivacyRequestError(
|
|
25
|
+
f"Cannot re-queue privacy request {privacy_request.id} with status {privacy_request.status.value}"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
logger.info(
|
|
29
|
+
"Polling starting for {} task {} {}",
|
|
30
|
+
async_task.action_type,
|
|
31
|
+
async_task.collection_address,
|
|
32
|
+
async_task.id,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
connection_config = get_connection_config_from_task(db, async_task)
|
|
36
|
+
|
|
37
|
+
with TaskResources(
|
|
38
|
+
privacy_request,
|
|
39
|
+
privacy_request.policy,
|
|
40
|
+
[connection_config],
|
|
41
|
+
async_task,
|
|
42
|
+
db,
|
|
43
|
+
) as resources:
|
|
44
|
+
# graph_task: GraphTask = create_graph_task(db, async_task, resources)
|
|
45
|
+
# Currently, upstream tasks and "input keys" (which are built by data dependencies)
|
|
46
|
+
# are the same, but they may not be the same in the future.
|
|
47
|
+
# upstream_tasks = async_task.upstream_tasks_objects(db)
|
|
48
|
+
# upstream_access_data: List[List[Row]] = _build_upstream_access_data(
|
|
49
|
+
# graph_task.execution_node.input_keys, upstream_tasks
|
|
50
|
+
# )
|
|
51
|
+
# TODO: Implement the polling strategy
|
|
52
|
+
logger.info(f"found resources: {resources}")
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def get_connection_config_from_task(
|
|
57
|
+
db: Session, request_task: RequestTask
|
|
58
|
+
) -> ConnectionConfig:
|
|
59
|
+
dataset_config = DatasetConfig.filter(
|
|
60
|
+
db=db,
|
|
61
|
+
conditions=(DatasetConfig.fides_key == request_task.dataset_name),
|
|
62
|
+
).first()
|
|
63
|
+
if not dataset_config:
|
|
64
|
+
raise PrivacyRequestError(
|
|
65
|
+
f"DatasetConfig with fides_key {request_task.dataset_name} not found."
|
|
66
|
+
)
|
|
67
|
+
connection_config = ConnectionConfig.get(
|
|
68
|
+
db=db, object_id=dataset_config.connection_config_id
|
|
69
|
+
)
|
|
70
|
+
if not connection_config:
|
|
71
|
+
raise PrivacyRequestError(
|
|
72
|
+
f"ConnectionConfig with id {dataset_config.connection_config_id} not found."
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return connection_config
|
|
@@ -11,7 +11,7 @@ from sqlalchemy.orm import Session
|
|
|
11
11
|
from starlette.status import HTTP_204_NO_CONTENT
|
|
12
12
|
|
|
13
13
|
from fides.api.common_exceptions import (
|
|
14
|
-
|
|
14
|
+
AwaitingAsyncTask,
|
|
15
15
|
FidesopsException,
|
|
16
16
|
PostProcessingException,
|
|
17
17
|
SkippingConsentPropagation,
|
|
@@ -229,7 +229,6 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
|
|
|
229
229
|
query_config: SaaSQueryConfig = self.query_config(node)
|
|
230
230
|
|
|
231
231
|
# generate initial set of requests if read request is defined, otherwise raise an exception
|
|
232
|
-
|
|
233
232
|
# An endpoint can be defined with multiple 'read' requests if the data for a single
|
|
234
233
|
# collection can be accessed in multiple ways for example:
|
|
235
234
|
#
|
|
@@ -336,8 +335,8 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
|
|
|
336
335
|
if awaiting_async_callback:
|
|
337
336
|
# If a read request was marked to expect async results, original response data here is ignored.
|
|
338
337
|
# We'll instead use the data received in the callback URL later.
|
|
339
|
-
# Raising an
|
|
340
|
-
raise
|
|
338
|
+
# Raising an AwaitingAsyncTask to put this task in an awaiting_processing state
|
|
339
|
+
raise AwaitingAsyncTask()
|
|
341
340
|
|
|
342
341
|
return rows
|
|
343
342
|
|
|
@@ -641,8 +640,8 @@ class SaaSConnector(BaseConnector[AuthenticatedClient], Contextualizable):
|
|
|
641
640
|
if awaiting_async_callback:
|
|
642
641
|
# Asynchronous masking request detected in saas config.
|
|
643
642
|
# If the masking request was marked to expect async results, original responses are ignored
|
|
644
|
-
# and we raise an
|
|
645
|
-
raise
|
|
643
|
+
# and we raise an AwaitingAsyncTask to put this task in an awaiting_processing state.
|
|
644
|
+
raise AwaitingAsyncTask()
|
|
646
645
|
return rows_updated
|
|
647
646
|
|
|
648
647
|
@staticmethod
|