ethyca-fides 2.66.1b1__py2.py3-none-any.whl → 2.66.2__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.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/METADATA +1 -1
- {ethyca_fides-2.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/RECORD +229 -236
- fides/_version.py +3 -3
- fides/api/api/v1/endpoints/dataset_config_endpoints.py +5 -13
- fides/api/api/v1/endpoints/user_endpoints.py +7 -83
- fides/api/db/base.py +0 -1
- fides/api/graph/execution.py +0 -30
- fides/api/models/{manual_task/manual_task.py → manual_task.py} +0 -10
- fides/api/oauth/roles.py +0 -2
- fides/api/schemas/application_config.py +1 -11
- fides/api/service/connectors/base_connector.py +0 -1
- fides/api/service/connectors/bigquery_connector.py +19 -67
- fides/api/service/connectors/dynamodb_connector.py +1 -2
- fides/api/service/connectors/fides_connector.py +0 -1
- fides/api/service/connectors/http_connector.py +0 -1
- fides/api/service/connectors/manual_task_connector.py +0 -1
- fides/api/service/connectors/manual_webhook_connector.py +1 -2
- fides/api/service/connectors/mongodb_connector.py +0 -1
- fides/api/service/connectors/okta_connector.py +0 -1
- fides/api/service/connectors/query_configs/bigquery_query_config.py +20 -45
- fides/api/service/connectors/rds_mysql_connector.py +0 -1
- fides/api/service/connectors/rds_postgres_connector.py +0 -1
- fides/api/service/connectors/s3_connector.py +0 -1
- fides/api/service/connectors/saas_connector.py +0 -1
- fides/api/service/connectors/scylla_connector.py +0 -1
- fides/api/service/connectors/sql_connector.py +4 -36
- fides/api/service/connectors/website_connector.py +0 -1
- fides/api/task/deprecated_graph_task.py +6 -24
- fides/api/task/execute_request_tasks.py +11 -88
- fides/api/task/graph_task.py +0 -11
- fides/api/task/manual/manual_task_graph_task.py +0 -1
- fides/common/api/scope_registry.py +0 -3
- fides/config/utils.py +0 -1
- fides/data/language/languages.yml +3 -1
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-34f0b91c26f8d9ab.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5309-b2c4803370634ff8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6780-e3d40aa17a4bf2e9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9046-5c4c22c375de25b1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-a152f52351c84ef4.js → _app-39ccb07327c2c5d5.js} +56 -56
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2265ecb899d45fbc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5d522637871ac6c8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-0a58aee2d1e7fa01.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-0f91eae539d47163.js → integrations-e2d5d7e2a5265e68.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-8bfde56c86128ec3.js → table-migration-69ad86b7a8a9a115.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-32600543eb7b584f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-cbe4c8f9096b6543.js +1 -0
- fides/ui-build/static/admin/_next/static/css/2cadb5f62dcd7c2b.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{23cf870196941c9a.css → 5bfb2473e5701527.css} +1 -1
- fides/ui-build/static/admin/_next/static/mhmdqaI-QPF2AVHotzucw/_buildManifest.js +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-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-preview.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +3 -3
- fides/ui-build/static/admin/lib/fides.js +3 -3
- 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/api/alembic/migrations/versions/d0031087eacb_create_manualtaskconditionaldependency_.py +0 -106
- fides/api/models/manual_task/__init__.py +0 -2
- fides/api/models/manual_task/conditional_dependency.py +0 -144
- fides/api/task/conditional_dependencies/__init__.py +0 -0
- fides/api/task/conditional_dependencies/evaluator.py +0 -109
- fides/api/task/conditional_dependencies/schemas.py +0 -54
- fides/ui-build/static/admin/_next/static/cUz9aQNEfv77_K6F0m_Ja/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-0e77abba7e220e31.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5309-67bdf9001531e972.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-4b687168dd8daa84.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8237-55049f8f5fd5e058.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-54877976a0529de2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-031d7589a07fde30.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-efcbfd52186591bc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-2f9efedecc4b9273.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-444ec9b3fec6e428.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-7eb7d26fa4b5cf17.js +0 -1
- fides/ui-build/static/admin/_next/static/css/b81194f2c3930152.css +0 -1
- {ethyca_fides-2.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.66.1b1.dist-info → ethyca_fides-2.66.2.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{1817-10f6ab6da28df4d2.js → 1817-e601e737e3cc7a0e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{203-d9fe5384a6e94799.js → 203-5a663f465ba26bb4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2921-86f1547ac40a5cdf.js → 2921-455e6357b74d2f76.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3450-24041e1b2a846739.js → 3450-0ba194991d0cca88.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3855-e2fa6db53d32c3de.js → 3855-e172870d3e21b0dd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3872-b97dd7695d6532bc.js → 3872-46cebf7ec1b31a2b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3923-13a6b4da2d51bf8f.js → 3923-6cc911dafccc5f63.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{401-3cc1fee61494e3bd.js → 401-1b529d5800aa1f3a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{409-45a125437261580c.js → 409-a257e14acebcd73b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4121-c4747258599705d0.js → 4121-2bc09fc4ddbfe5cb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4230-840c287045c88b34.js → 4230-60100f7ef3ddcde1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4608-b2d8a76e3a680db4.js → 4608-bbb7bf511a05c3c2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5574-0b7c88e3f81b08fb.js → 5574-b13021775a15bfd2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6084-7bc3756bd23c3a4c.js → 6084-7178ff6ea6822475.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6662-8c43dd2b75e0264c.js → 6662-507be5d46e5b719b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6853-4f8bf6558f8c6a46.js → 6853-2ad3e08fe6f9f5f2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6882-0fa957731918160e.js → 6882-6af16fef26c21e06.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6954-d30c6dff440d46b0.js → 6954-bb875d9ac89f6030.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7476-2d2c80dfe64c0f90.js → 7476-281ee9a8286556f3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-06f4207597225cbb.js → 7630-9aac73191ed5ed13.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{787-32ca132be974eaf9.js → 787-fb41002f797eb2df.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{79-056290dba15480c2.js → 79-7e87aff851423d4a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{796-00487f9036709b7b.js → 796-329a5f823ec258a5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9226-081cb18771536d64.js → 9226-746771d47dff6266.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-e77d5e5b8458fe77.js → 9826-111aaee8bd8dbd09.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9951-595d0f1588215081.js → 9951-9b753ad7c3f51bdf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{404-2d803dab6a00f353.js → 404-aece2c920ea14514.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-a539d34e7c9ab0ee.js → manual-98777246bec9dc2a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-fa0c254854fbf79c.js → multiple-dc75dc6e37e52f05.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-9c86d99f81d128ac.js → add-systems-a71c0aff4e0e6535.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-3a77a92d2a94426a.js → add-vendors-24d226b5a8de5c74.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-886518c906a28271.js → configure-6a8ef51138ac926a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-fc3a011154a2e1de.js → [id]-1edf582ba3cd3bbb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-a333f503aa057e06.js → privacy-experience-685771e5f7196d87.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-7a1c8073262ff0b4.js → [id]-6ccedc70dc447089.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-39ef289b3c88ebd4.js → new-944bca1cc57985b5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-deeb59b8332261c1.js → privacy-notices-84f4bd14ce8673bc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-057cad65e7414a44.js → properties-6f86ab63a08a6528.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-8f891957c8944137.js → reporting-afdbd4665657cfa1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-7507764f89f9d9c8.js → consent-73d3cbf68f7c3a31.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-6020cd361c57b387.js → [projectUrn]-6ba9e160dae64695.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-2fc76749940a06fd.js → projects-32eac8bbd217615a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-7d1c53686a9a5d73.js → data-catalog-6f630d42ac9fb6b4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-94acf9cc27209714.js → action-center-9ddb52ebb7ac4c71.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-5af9381f02b2aff6.js → activity-9aa744d56cdacb0d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-e48f4ef032791c1d.js → datamap-7674b97d655c193b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-24f87303adb9428e.js → [...subfieldNames]-c0d2bfd465df20e0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-41aa4e51bd73d13e.js → [collectionName]-28280a8a39a6e37c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-b296323ed0922fd5.js → [datasetId]-006b695e5af5ef24.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-cbb409d1bc89d10b.js → new-82fb246d87e58ebd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-07df9c4896721e9f.js → dataset-20165c31ab1bc7cf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-0a60fe49678a3ece.js → [id]-b4a6bcc87d126840.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-c903ab62611245d8.js → new-f95d7b0bbfc58f5a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-33b01e2ab2d5ce7e.js → datastore-connection-c391c6fad56eec48.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-ca1c9d4de5abec7a.js → index-1919aab9e5834b51.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-8b20a058d18181b9.js → [id]-53fecfb9dd6a1e0c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-c7054125338aee6c.js → add-template-76b01cec5fde10a9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-a4fdfa9047bb5770.js → messaging-5094ffea13f32ed9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-64a322d01aae5ca7.js → ant-components-5c08e8447c45ce44.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-8bca16a7726e7eb2.js → AntForm-06ad5f34585480aa.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-b0f246fc3b67ebf7.js → FormikAntFormItem-6f071c2bc9446cb0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-1a0852b090bfc392.js → FormikControlled-efcc38c58991ac9e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-11f3de1b45e36583.js → FormikField-430ba5c979abfb7c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-1b73a1c2b6c6285f.js → forms-5c561880bf131afb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-08a6d60bb9230d5f.js → messaging-10ce53ea356f8bad.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-29d47f1bdd08c45d.js → storage-5501bbb129fee9c4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-2806f3458fe85897.js → configure-d888a69a3bbe040e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-568620fc7e239e7b.js → [id]-d3d8e3d7583ec635.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-394043fd823d69f5.js → add-property-1af10ed303815d46.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-e959378bb32b6b73.js → properties-cebc0dc186be499a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-2a98bd257edd8f47.js → datamap-e130c0197362e8f3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-92d7f12a95a1adc5.js → alpha-5e1322de868d615e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-70fb68b7519d5222.js → about-241f95e372b65d0f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-668d74c041d74650.js → [purpose_id]-fc201657f4a782c7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-7c8bda96813441c5.js → consent-c2d39cba8396ef3a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-b773691516488006.js → custom-fields-d992103cc55901ae.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-21f14d9141a5ad8a.js → domain-records-41242f805599feda.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-3022368d5438dfb7.js → domains-2e885f74c92f669c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-89903d6f579b1aeb.js → email-templates-ff112655ad5f41e5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-14621f32ad4f9120.js → locations-023e1895552817de.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-5106ff9a9403ee92.js → organization-ac403c0886b20e20.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-0927740524f79b02.js → regulations-86062a18e081a52a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-47284d49803f8b3b.js → test-datasets-7a3396ac819c7904.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-7bc2d6b23d5bb71f.js → [id]-8314a819837f5b2a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-c3a536901d6b445d.js → systems-21f423a7c417aa9d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-ab4f4d260c01163b.js → taxonomy-6387fcc8cce872eb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-79fe68f1eb3add49.js → [id]-ff5738706da07801.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-6111bb65a2607dc5.js → user-management-173ac3a1ed2b05a6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{webpack-ff4c22c9f0840531.js → webpack-ff0cd6bff75588da.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{cUz9aQNEfv77_K6F0m_Ja → mhmdqaI-QPF2AVHotzucw}/_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-07-
|
|
11
|
+
"date": "2025-07-29T14:18:39-0400",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.66.
|
|
14
|
+
"full-revisionid": "15db4e93dd6f5c214b575e480682ef72be3172ef",
|
|
15
|
+
"version": "2.66.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Annotated, Any, Dict, List, Optional
|
|
2
2
|
|
|
3
3
|
import yaml
|
|
4
|
-
from fastapi import Depends, HTTPException,
|
|
4
|
+
from fastapi import Depends, HTTPException, Request
|
|
5
5
|
from fastapi.encoders import jsonable_encoder
|
|
6
6
|
from fastapi.params import Security
|
|
7
7
|
from fastapi_pagination import Page, Params
|
|
@@ -68,18 +68,10 @@ from fides.api.models.sql_models import ( # type: ignore[attr-defined] # isort:
|
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
X_YAML = "application/x-yaml"
|
|
71
|
-
MAX_DATASET_CONFIGS_FOR_INTEGRATION_FORM = 1000
|
|
72
71
|
|
|
73
72
|
router = APIRouter(tags=["Dataset Configs"], prefix=V1_URL_PREFIX)
|
|
74
73
|
|
|
75
74
|
|
|
76
|
-
# Custom Params class with higher limit for dataset configs
|
|
77
|
-
class DatasetConfigParams(Params):
|
|
78
|
-
size: int = Query(
|
|
79
|
-
50, ge=1, le=MAX_DATASET_CONFIGS_FOR_INTEGRATION_FORM, description="Page size"
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
|
|
83
75
|
# Helper method to inject the parent ConnectionConfig into these child routes
|
|
84
76
|
def _get_connection_config(
|
|
85
77
|
connection_key: FidesKey, db: Session = Depends(deps.get_db)
|
|
@@ -139,7 +131,7 @@ def validate_dataset(
|
|
|
139
131
|
response_model=BulkPutDataset,
|
|
140
132
|
)
|
|
141
133
|
def put_dataset_configs(
|
|
142
|
-
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=
|
|
134
|
+
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=50)], # type: ignore
|
|
143
135
|
db: Session = Depends(deps.get_db),
|
|
144
136
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
145
137
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
@@ -189,7 +181,7 @@ def put_dataset_configs(
|
|
|
189
181
|
response_model=BulkPutDataset,
|
|
190
182
|
)
|
|
191
183
|
def patch_dataset_configs(
|
|
192
|
-
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=
|
|
184
|
+
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=50)], # type: ignore
|
|
193
185
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
194
186
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
195
187
|
) -> BulkPutDataset:
|
|
@@ -225,7 +217,7 @@ def patch_dataset_configs(
|
|
|
225
217
|
response_model=BulkPutDataset,
|
|
226
218
|
)
|
|
227
219
|
def patch_datasets(
|
|
228
|
-
datasets: Annotated[List[FideslangDataset], Field(max_length=
|
|
220
|
+
datasets: Annotated[List[FideslangDataset], Field(max_length=50)], # type: ignore
|
|
229
221
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
230
222
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
231
223
|
) -> BulkPutDataset:
|
|
@@ -375,7 +367,7 @@ def get_dataset(
|
|
|
375
367
|
)
|
|
376
368
|
def get_dataset_configs(
|
|
377
369
|
db: Session = Depends(deps.get_db),
|
|
378
|
-
params:
|
|
370
|
+
params: Params = Depends(),
|
|
379
371
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
380
372
|
) -> AbstractPage[DatasetConfig]:
|
|
381
373
|
"""Returns all Dataset Configs attached to current Connection Config."""
|
|
@@ -6,7 +6,6 @@ from typing import List, Optional
|
|
|
6
6
|
|
|
7
7
|
import jose.exceptions
|
|
8
8
|
from fastapi import Depends, HTTPException, Security
|
|
9
|
-
from fastapi.security import SecurityScopes
|
|
10
9
|
from fastapi_pagination import Page, Params
|
|
11
10
|
from fastapi_pagination.bases import AbstractPage
|
|
12
11
|
from fastapi_pagination.ext.sqlalchemy import paginate
|
|
@@ -40,9 +39,7 @@ from fides.api.oauth.roles import APPROVER, VIEWER
|
|
|
40
39
|
from fides.api.oauth.utils import (
|
|
41
40
|
create_temporary_user_for_login_flow,
|
|
42
41
|
extract_payload,
|
|
43
|
-
extract_token_and_load_client,
|
|
44
42
|
get_current_user,
|
|
45
|
-
has_permissions,
|
|
46
43
|
oauth2_scheme,
|
|
47
44
|
verify_oauth_client,
|
|
48
45
|
)
|
|
@@ -68,7 +65,6 @@ from fides.common.api.scope_registry import (
|
|
|
68
65
|
USER_DELETE,
|
|
69
66
|
USER_PASSWORD_RESET,
|
|
70
67
|
USER_READ,
|
|
71
|
-
USER_READ_OWN,
|
|
72
68
|
USER_UPDATE,
|
|
73
69
|
)
|
|
74
70
|
from fides.common.api.v1 import urn_registry as urls
|
|
@@ -111,37 +107,6 @@ def _validate_current_user(user_id: str, user_from_token: FidesUser) -> None:
|
|
|
111
107
|
)
|
|
112
108
|
|
|
113
109
|
|
|
114
|
-
def verify_user_read_scopes(
|
|
115
|
-
authorization: str = Security(oauth2_scheme),
|
|
116
|
-
db: Session = Depends(get_db),
|
|
117
|
-
) -> ClientDetail:
|
|
118
|
-
"""
|
|
119
|
-
Custom dependency that verifies the user has either USER_READ or USER_READ_OWN scope.
|
|
120
|
-
Returns the client if authorized.
|
|
121
|
-
"""
|
|
122
|
-
token_data, client = extract_token_and_load_client(authorization, db)
|
|
123
|
-
|
|
124
|
-
# Try USER_READ first
|
|
125
|
-
if has_permissions(
|
|
126
|
-
token_data=token_data,
|
|
127
|
-
client=client,
|
|
128
|
-
endpoint_scopes=SecurityScopes([USER_READ]),
|
|
129
|
-
):
|
|
130
|
-
return client
|
|
131
|
-
|
|
132
|
-
if has_permissions(
|
|
133
|
-
token_data=token_data,
|
|
134
|
-
client=client,
|
|
135
|
-
endpoint_scopes=SecurityScopes([USER_READ_OWN]),
|
|
136
|
-
):
|
|
137
|
-
return client
|
|
138
|
-
|
|
139
|
-
raise HTTPException(
|
|
140
|
-
status_code=HTTP_403_FORBIDDEN,
|
|
141
|
-
detail="Not authorized.",
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
110
|
@router.put(
|
|
146
111
|
urls.USER_DETAIL,
|
|
147
112
|
dependencies=[Security(verify_oauth_client)],
|
|
@@ -533,38 +498,14 @@ def delete_user(
|
|
|
533
498
|
|
|
534
499
|
@router.get(
|
|
535
500
|
urls.USER_DETAIL,
|
|
536
|
-
dependencies=[Security(
|
|
501
|
+
dependencies=[Security(verify_oauth_client, scopes=[USER_READ])],
|
|
537
502
|
response_model=UserResponse,
|
|
538
503
|
)
|
|
539
|
-
def get_user(
|
|
540
|
-
|
|
541
|
-
db: Session = Depends(get_db),
|
|
542
|
-
user_id: str,
|
|
543
|
-
client: ClientDetail = Security(verify_user_read_scopes),
|
|
544
|
-
authorization: str = Security(oauth2_scheme),
|
|
545
|
-
) -> FidesUser:
|
|
546
|
-
"""Returns a User based on an Id. Users with USER_READ_OWN scope can only access their own data."""
|
|
504
|
+
def get_user(*, db: Session = Depends(get_db), user_id: str) -> FidesUser:
|
|
505
|
+
"""Returns a User based on an Id"""
|
|
547
506
|
user: Optional[FidesUser] = FidesUser.get_by_key_or_id(db, data={"id": user_id})
|
|
548
507
|
if user is None:
|
|
549
508
|
raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="User not found")
|
|
550
|
-
token_data, _ = extract_token_and_load_client(authorization, db)
|
|
551
|
-
# Check if user has USER_READ_OWN scope and is trying to access someone else's data
|
|
552
|
-
# The verify_user_read_scopes dependency already verified the user has either USER_READ or USER_READ_OWN
|
|
553
|
-
# We need to check if they have USER_READ_OWN and are accessing their own data
|
|
554
|
-
if has_permissions(
|
|
555
|
-
token_data=token_data,
|
|
556
|
-
client=client,
|
|
557
|
-
endpoint_scopes=SecurityScopes([USER_READ]),
|
|
558
|
-
):
|
|
559
|
-
logger.debug("Returning user with id: '{}'.", user_id)
|
|
560
|
-
return user
|
|
561
|
-
|
|
562
|
-
# User has USER_READ_OWN scope, check if they're accessing their own data
|
|
563
|
-
if user.id != client.user_id:
|
|
564
|
-
raise HTTPException(
|
|
565
|
-
status_code=HTTP_403_FORBIDDEN,
|
|
566
|
-
detail="You can only access your own user data with USER_READ_OWN scope.",
|
|
567
|
-
)
|
|
568
509
|
|
|
569
510
|
logger.debug("Returning user with id: '{}'.", user_id)
|
|
570
511
|
return user
|
|
@@ -572,7 +513,7 @@ def get_user(
|
|
|
572
513
|
|
|
573
514
|
@router.get(
|
|
574
515
|
urls.USERS,
|
|
575
|
-
dependencies=[Security(
|
|
516
|
+
dependencies=[Security(verify_oauth_client, scopes=[USER_READ])],
|
|
576
517
|
response_model=Page[UserResponse],
|
|
577
518
|
)
|
|
578
519
|
def get_users(
|
|
@@ -580,28 +521,11 @@ def get_users(
|
|
|
580
521
|
db: Session = Depends(get_db),
|
|
581
522
|
params: Params = Depends(),
|
|
582
523
|
username: Optional[str] = None,
|
|
583
|
-
client: ClientDetail = Security(verify_user_read_scopes),
|
|
584
|
-
authorization: str = Security(oauth2_scheme),
|
|
585
524
|
) -> AbstractPage[FidesUser]:
|
|
586
|
-
"""Returns a paginated list of users
|
|
525
|
+
"""Returns a paginated list of all users"""
|
|
587
526
|
query = FidesUser.query(db)
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
# The verify_user_read_scopes dependency already verified the user has either USER_READ or USER_READ_OWN
|
|
591
|
-
token_data, _ = extract_token_and_load_client(authorization, db)
|
|
592
|
-
if has_permissions(
|
|
593
|
-
token_data=token_data,
|
|
594
|
-
client=client,
|
|
595
|
-
endpoint_scopes=SecurityScopes([USER_READ]),
|
|
596
|
-
):
|
|
597
|
-
# User has USER_READ scope, can see all users
|
|
598
|
-
if username:
|
|
599
|
-
query = query.filter(FidesUser.username.ilike(f"%{escape_like(username)}%"))
|
|
600
|
-
else:
|
|
601
|
-
# User has USER_READ_OWN scope, only show their own data
|
|
602
|
-
query = query.filter(FidesUser.id == client.user_id)
|
|
603
|
-
if username:
|
|
604
|
-
query = query.filter(FidesUser.username.ilike(f"%{escape_like(username)}%"))
|
|
527
|
+
if username:
|
|
528
|
+
query = query.filter(FidesUser.username.ilike(f"%{escape_like(username)}%"))
|
|
605
529
|
|
|
606
530
|
logger.debug("Returning a paginated list of users.")
|
|
607
531
|
|
fides/api/db/base.py
CHANGED
|
@@ -33,7 +33,6 @@ from fides.api.models.identity_salt import IdentitySalt
|
|
|
33
33
|
from fides.api.models.location_regulation_selections import LocationRegulationSelections
|
|
34
34
|
from fides.api.models.manual_task import (
|
|
35
35
|
ManualTask,
|
|
36
|
-
ManualTaskConditionalDependency,
|
|
37
36
|
ManualTaskConfig,
|
|
38
37
|
ManualTaskConfigField,
|
|
39
38
|
ManualTaskInstance,
|
fides/api/graph/execution.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
|
2
2
|
|
|
3
3
|
from fideslang.validation import FidesKey
|
|
4
|
-
from loguru import logger
|
|
5
4
|
|
|
6
5
|
from fides.api.graph.config import (
|
|
7
6
|
Collection,
|
|
@@ -118,8 +117,6 @@ class ExecutionNode(Contextualizable): # pylint: disable=too-many-instance-attr
|
|
|
118
117
|
The values are cast based on field types, if those types are specified.
|
|
119
118
|
"""
|
|
120
119
|
out = {}
|
|
121
|
-
failed_conversions: Dict[str, Dict[str, Any]] = {}
|
|
122
|
-
|
|
123
120
|
for key, values in input_data.items():
|
|
124
121
|
path: FieldPath = FieldPath.parse(key)
|
|
125
122
|
field: Optional[Field] = self.collection.field(path)
|
|
@@ -129,31 +126,4 @@ class ExecutionNode(Contextualizable): # pylint: disable=too-many-instance-attr
|
|
|
129
126
|
filtered = list(filter(lambda x: x is not None, cast_values))
|
|
130
127
|
if filtered:
|
|
131
128
|
out[key] = filtered
|
|
132
|
-
elif values: # Had input values but all failed conversion
|
|
133
|
-
# Track conversion failures for logging
|
|
134
|
-
failed_conversions[key] = {"field": field, "input_values": values}
|
|
135
|
-
|
|
136
|
-
# Log conversion failures if any occurred
|
|
137
|
-
if failed_conversions:
|
|
138
|
-
field_details = []
|
|
139
|
-
for field_name, failure_info in failed_conversions.items():
|
|
140
|
-
field = failure_info["field"]
|
|
141
|
-
values = failure_info["input_values"]
|
|
142
|
-
|
|
143
|
-
expected_type = field.data_type() if field else "unknown"
|
|
144
|
-
actual_types = {type(v).__name__ for v in values if v is not None}
|
|
145
|
-
actual_type_str = (
|
|
146
|
-
", ".join(sorted(actual_types)) if actual_types else "NoneType"
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
field_details.append(
|
|
150
|
-
f"{field_name} (expected: {expected_type}, got: {actual_type_str})"
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
logger.warning(
|
|
154
|
-
"Type conversion failures for {}: {}",
|
|
155
|
-
self.address,
|
|
156
|
-
"; ".join(field_details),
|
|
157
|
-
)
|
|
158
|
-
|
|
159
129
|
return out
|
|
@@ -26,9 +26,6 @@ from fides.api.schemas.base_class import FidesSchema
|
|
|
26
26
|
if TYPE_CHECKING:
|
|
27
27
|
from fides.api.models.attachment import Attachment
|
|
28
28
|
from fides.api.models.fides_user import FidesUser
|
|
29
|
-
from fides.api.models.manual_task.conditional_dependency import (
|
|
30
|
-
ManualTaskConditionalDependency,
|
|
31
|
-
)
|
|
32
29
|
|
|
33
30
|
# ------------------------------------------------------------
|
|
34
31
|
# Enums
|
|
@@ -245,13 +242,6 @@ class ManualTask(Base):
|
|
|
245
242
|
viewonly=True, # No cascade delete - submissions are historical data
|
|
246
243
|
)
|
|
247
244
|
|
|
248
|
-
conditional_dependencies = relationship(
|
|
249
|
-
"ManualTaskConditionalDependency",
|
|
250
|
-
back_populates="task",
|
|
251
|
-
uselist=True,
|
|
252
|
-
cascade="all, delete-orphan",
|
|
253
|
-
)
|
|
254
|
-
|
|
255
245
|
# Properties
|
|
256
246
|
@property
|
|
257
247
|
def assigned_users(self) -> list[str]:
|
fides/api/oauth/roles.py
CHANGED
|
@@ -47,7 +47,6 @@ from fides.common.api.scope_registry import (
|
|
|
47
47
|
SYSTEM_READ,
|
|
48
48
|
USER_PERMISSION_ASSIGN_OWNERS,
|
|
49
49
|
USER_READ,
|
|
50
|
-
USER_READ_OWN,
|
|
51
50
|
WEBHOOK_READ,
|
|
52
51
|
)
|
|
53
52
|
|
|
@@ -127,7 +126,6 @@ viewer_scopes = [ # Intentionally omitted USER_PERMISSION_READ and PRIVACY_REQU
|
|
|
127
126
|
|
|
128
127
|
respondent_scopes = [
|
|
129
128
|
PRIVACY_REQUEST_MANUAL_STEPS_RESPOND, # allows respondents to respond to assigned manual steps
|
|
130
|
-
USER_READ_OWN,
|
|
131
129
|
]
|
|
132
130
|
|
|
133
131
|
external_respondent_scopes = [
|
|
@@ -11,14 +11,6 @@ from fides.api.schemas.messaging.messaging import MessagingServiceType
|
|
|
11
11
|
from fides.config.admin_ui_settings import ErrorNotificationMode
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class SqlDryRunMode(str, Enum):
|
|
15
|
-
"""SQL dry run mode for controlling execution of SQL statements in privacy requests"""
|
|
16
|
-
|
|
17
|
-
none = "none"
|
|
18
|
-
access = "access"
|
|
19
|
-
erasure = "erasure"
|
|
20
|
-
|
|
21
|
-
|
|
22
14
|
class StorageTypeApiAccepted(Enum):
|
|
23
15
|
"""Enum for storage destination types accepted in API updates"""
|
|
24
16
|
|
|
@@ -70,9 +62,7 @@ class ExecutionApplicationConfig(FidesSchema):
|
|
|
70
62
|
subject_identity_verification_required: Optional[bool] = None
|
|
71
63
|
disable_consent_identity_verification: Optional[bool] = None
|
|
72
64
|
require_manual_request_approval: Optional[bool] = None
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
model_config = ConfigDict(use_enum_values=True, extra="forbid")
|
|
65
|
+
model_config = ConfigDict(extra="forbid")
|
|
76
66
|
|
|
77
67
|
|
|
78
68
|
class AdminUIConfig(FidesSchema):
|
|
@@ -82,7 +82,6 @@ class BaseConnector(Generic[DB_CONNECTOR_TYPE], ABC):
|
|
|
82
82
|
privacy_request: PrivacyRequest,
|
|
83
83
|
request_task: RequestTask,
|
|
84
84
|
rows: List[Row],
|
|
85
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
86
85
|
) -> int:
|
|
87
86
|
"""Execute a masking request. Return the number of rows that have been updated
|
|
88
87
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import List, Optional
|
|
2
2
|
|
|
3
3
|
from loguru import logger
|
|
4
4
|
from sqlalchemy import text
|
|
5
|
-
from sqlalchemy.engine import
|
|
5
|
+
from sqlalchemy.engine import ( # type: ignore
|
|
6
|
+
Connection,
|
|
7
|
+
Engine,
|
|
8
|
+
LegacyCursorResult,
|
|
9
|
+
create_engine,
|
|
10
|
+
)
|
|
6
11
|
from sqlalchemy.orm import Session
|
|
7
12
|
from sqlalchemy.sql import Executable # type: ignore
|
|
8
13
|
from sqlalchemy.sql.elements import TextClause
|
|
@@ -12,7 +17,6 @@ from fides.api.graph.execution import ExecutionNode
|
|
|
12
17
|
from fides.api.models.connectionconfig import ConnectionTestStatus
|
|
13
18
|
from fides.api.models.policy import Policy
|
|
14
19
|
from fides.api.models.privacy_request import PrivacyRequest, RequestTask
|
|
15
|
-
from fides.api.schemas.application_config import SqlDryRunMode
|
|
16
20
|
from fides.api.schemas.connection_configuration.connection_secrets_bigquery import (
|
|
17
21
|
BigQuerySchema,
|
|
18
22
|
)
|
|
@@ -95,16 +99,6 @@ class BigQueryConnector(SQLConnector):
|
|
|
95
99
|
logger.info(
|
|
96
100
|
f"Executing {len(partition_clauses)} partition queries for node '{query_config.node.address}' in DSR execution"
|
|
97
101
|
)
|
|
98
|
-
|
|
99
|
-
if self.should_dry_run(SqlDryRunMode.access):
|
|
100
|
-
for partition_clause in partition_clauses:
|
|
101
|
-
existing_bind_params = stmt.compile().params
|
|
102
|
-
partitioned_stmt = text(
|
|
103
|
-
f"{stmt} AND ({text(partition_clause)})"
|
|
104
|
-
).params(existing_bind_params)
|
|
105
|
-
logger.warning(f"SQL DRY RUN - Would execute SQL: {partitioned_stmt}")
|
|
106
|
-
return []
|
|
107
|
-
|
|
108
102
|
rows = []
|
|
109
103
|
for partition_clause in partition_clauses:
|
|
110
104
|
logger.debug(
|
|
@@ -141,39 +135,6 @@ class BigQueryConnector(SQLConnector):
|
|
|
141
135
|
logger.exception(f"Error testing connection to remote BigQuery {str(e)}")
|
|
142
136
|
raise ConnectionException(f"Connection error: {e}")
|
|
143
137
|
|
|
144
|
-
def _execute_statements_with_sql_dry_run(
|
|
145
|
-
self,
|
|
146
|
-
statements: List[Executable],
|
|
147
|
-
sql_dry_run_enabled: bool,
|
|
148
|
-
client: Engine,
|
|
149
|
-
) -> int:
|
|
150
|
-
"""
|
|
151
|
-
Execute SQL statements with sql_dry_run support.
|
|
152
|
-
|
|
153
|
-
Args:
|
|
154
|
-
statements: List of SQL statements to execute
|
|
155
|
-
sql_dry_run_enabled: Whether sql_dry_run mode is enabled
|
|
156
|
-
client: Database engine
|
|
157
|
-
|
|
158
|
-
Returns:
|
|
159
|
-
int: Number of affected rows (0 in sql_dry_run mode)
|
|
160
|
-
"""
|
|
161
|
-
if not statements:
|
|
162
|
-
return 0
|
|
163
|
-
|
|
164
|
-
if sql_dry_run_enabled:
|
|
165
|
-
for stmt in statements:
|
|
166
|
-
logger.warning(f"SQL DRY RUN - Would execute SQL: {stmt}")
|
|
167
|
-
return 0
|
|
168
|
-
|
|
169
|
-
row_count = 0
|
|
170
|
-
with client.connect() as connection:
|
|
171
|
-
for stmt in statements:
|
|
172
|
-
results = connection.execute(stmt)
|
|
173
|
-
logger.debug(f"Affected {results.rowcount} rows")
|
|
174
|
-
row_count += results.rowcount
|
|
175
|
-
return row_count
|
|
176
|
-
|
|
177
138
|
def mask_data(
|
|
178
139
|
self,
|
|
179
140
|
node: ExecutionNode,
|
|
@@ -181,31 +142,22 @@ class BigQueryConnector(SQLConnector):
|
|
|
181
142
|
privacy_request: PrivacyRequest,
|
|
182
143
|
request_task: RequestTask,
|
|
183
144
|
rows: List[Row],
|
|
184
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
185
145
|
) -> int:
|
|
186
146
|
"""Execute a masking request. Returns the number of records updated or deleted"""
|
|
187
|
-
|
|
188
147
|
query_config = self.query_config(node)
|
|
189
148
|
update_or_delete_ct = 0
|
|
190
149
|
client = self.client()
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
update_or_delete_ct += self._execute_statements_with_sql_dry_run(
|
|
196
|
-
delete_stmts, self.should_dry_run(SqlDryRunMode.erasure), client
|
|
197
|
-
)
|
|
198
|
-
else:
|
|
199
|
-
for row in rows:
|
|
200
|
-
update_or_delete_stmts: List[Executable] = query_config.generate_update(
|
|
201
|
-
row, policy, privacy_request, client
|
|
202
|
-
)
|
|
203
|
-
logger.debug(
|
|
204
|
-
f"Generated {len(update_or_delete_stmts)} UPDATE statements"
|
|
205
|
-
)
|
|
206
|
-
update_or_delete_ct += self._execute_statements_with_sql_dry_run(
|
|
207
|
-
update_or_delete_stmts,
|
|
208
|
-
self.should_dry_run(SqlDryRunMode.erasure),
|
|
209
|
-
client,
|
|
150
|
+
for row in rows:
|
|
151
|
+
update_or_delete_stmts: List[Executable] = (
|
|
152
|
+
query_config.generate_masking_stmt(
|
|
153
|
+
node, row, policy, privacy_request, client
|
|
210
154
|
)
|
|
155
|
+
)
|
|
156
|
+
if update_or_delete_stmts:
|
|
157
|
+
with client.connect() as connection:
|
|
158
|
+
for update_or_delete_stmt in update_or_delete_stmts:
|
|
159
|
+
results: LegacyCursorResult = connection.execute(
|
|
160
|
+
update_or_delete_stmt
|
|
161
|
+
)
|
|
162
|
+
update_or_delete_ct = update_or_delete_ct + results.rowcount
|
|
211
163
|
return update_or_delete_ct
|
|
@@ -140,9 +140,8 @@ class DynamoDBConnector(BaseConnector[Any]): # type: ignore
|
|
|
140
140
|
privacy_request: PrivacyRequest,
|
|
141
141
|
request_task: RequestTask,
|
|
142
142
|
rows: List[Row],
|
|
143
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
144
143
|
) -> int:
|
|
145
|
-
"""Execute a masking
|
|
144
|
+
"""Execute a masking requestfor DynamoDB"""
|
|
146
145
|
|
|
147
146
|
query_config = self.query_config(node)
|
|
148
147
|
collection_name = node.address.collection
|
|
@@ -142,7 +142,6 @@ class FidesConnector(BaseConnector[FidesClient]):
|
|
|
142
142
|
privacy_request: PrivacyRequest,
|
|
143
143
|
request_task: RequestTask,
|
|
144
144
|
rows: List[Row],
|
|
145
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
146
145
|
) -> int:
|
|
147
146
|
"""Execute an erasure request on remote fides"""
|
|
148
147
|
identity_data = {
|
|
@@ -90,7 +90,6 @@ class HTTPSConnector(BaseConnector[None]):
|
|
|
90
90
|
privacy_request: PrivacyRequest,
|
|
91
91
|
request_task: RequestTask,
|
|
92
92
|
rows: List[Row],
|
|
93
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
94
93
|
) -> int:
|
|
95
94
|
"""Currently not supported as webhooks are not called at the collection level"""
|
|
96
95
|
raise NotImplementedError(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any, Dict, List
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
2
|
|
|
3
3
|
from fides.api.graph.execution import ExecutionNode
|
|
4
4
|
from fides.api.models.connectionconfig import ConnectionConfig, ConnectionTestStatus
|
|
@@ -53,7 +53,6 @@ class ManualWebhookConnector(BaseConnector[None]):
|
|
|
53
53
|
privacy_request: PrivacyRequest,
|
|
54
54
|
request_task: RequestTask,
|
|
55
55
|
rows: List[Row],
|
|
56
|
-
input_data: Optional[List[List[Row]]] = None,
|
|
57
56
|
) -> None:
|
|
58
57
|
"""
|
|
59
58
|
Not applicable for a manual webhook. Manual webhooks are not called as part of the traversal.
|
|
@@ -126,7 +126,6 @@ class MongoDBConnector(BaseConnector[MongoClient]):
|
|
|
126
126
|
privacy_request: PrivacyRequest,
|
|
127
127
|
request_task: RequestTask,
|
|
128
128
|
rows: List[Row],
|
|
129
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
130
129
|
) -> int:
|
|
131
130
|
"""Execute a masking request"""
|
|
132
131
|
query_config = self.query_config(node)
|
|
@@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional, Union, cast
|
|
|
3
3
|
import pydash
|
|
4
4
|
from fideslang.models import MaskingStrategies
|
|
5
5
|
from loguru import logger
|
|
6
|
-
from sqlalchemy import MetaData, Table,
|
|
6
|
+
from sqlalchemy import MetaData, Table, text
|
|
7
7
|
from sqlalchemy.engine import Engine
|
|
8
8
|
from sqlalchemy.sql import Delete, Update
|
|
9
9
|
from sqlalchemy.sql.elements import ColumnElement, TextClause
|
|
@@ -125,7 +125,6 @@ class BigQueryQueryConfig(QueryStringWithoutTuplesOverrideQueryConfig):
|
|
|
125
125
|
policy: Policy,
|
|
126
126
|
request: PrivacyRequest,
|
|
127
127
|
client: Engine,
|
|
128
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
129
128
|
) -> Union[List[Update], List[Delete]]:
|
|
130
129
|
"""
|
|
131
130
|
Generate a masking statement for BigQuery.
|
|
@@ -138,7 +137,7 @@ class BigQueryQueryConfig(QueryStringWithoutTuplesOverrideQueryConfig):
|
|
|
138
137
|
logger.info(
|
|
139
138
|
f"Masking override detected for collection {node.address.value}: {masking_override.strategy.value}"
|
|
140
139
|
)
|
|
141
|
-
return self.generate_delete(
|
|
140
|
+
return self.generate_delete(row, client)
|
|
142
141
|
return self.generate_update(row, policy, request, client)
|
|
143
142
|
|
|
144
143
|
def generate_update(
|
|
@@ -219,30 +218,27 @@ class BigQueryQueryConfig(QueryStringWithoutTuplesOverrideQueryConfig):
|
|
|
219
218
|
|
|
220
219
|
return [table.update().where(*where_clauses).values(**final_update_map)]
|
|
221
220
|
|
|
222
|
-
def generate_delete(
|
|
223
|
-
|
|
224
|
-
client: Engine,
|
|
225
|
-
input_data: Optional[Dict[str, List[Any]]] = None,
|
|
226
|
-
) -> List[Delete]:
|
|
227
|
-
"""
|
|
228
|
-
Returns a List of SQLAlchemy DELETE statements for BigQuery. Does not actually execute the delete statement.
|
|
221
|
+
def generate_delete(self, row: Row, client: Engine) -> List[Delete]:
|
|
222
|
+
"""Returns a List of SQLAlchemy DELETE statements for BigQuery. Does not actually execute the delete statement.
|
|
229
223
|
|
|
230
224
|
Used when a collection-level masking override is present and the masking strategy is DELETE.
|
|
231
225
|
|
|
232
226
|
A List of multiple DELETE statements are returned for partitioned tables; for a non-partitioned table,
|
|
233
227
|
a single DELETE statement is returned in a List for consistent typing.
|
|
234
|
-
"""
|
|
235
228
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
"No input data provided for node '{}', skipping DELETE statement generation",
|
|
239
|
-
self.node.address,
|
|
240
|
-
)
|
|
241
|
-
return []
|
|
229
|
+
TODO: DRY up this method and `generate_update` a bit
|
|
230
|
+
"""
|
|
242
231
|
|
|
243
|
-
|
|
232
|
+
non_empty_reference_field_keys: Dict[str, Field] = filter_nonempty_values(
|
|
233
|
+
{
|
|
234
|
+
fpath.string_path: fld.cast(row[fpath.string_path])
|
|
235
|
+
for fpath, fld in self.reference_field_paths.items()
|
|
236
|
+
if fpath.string_path in row
|
|
237
|
+
}
|
|
238
|
+
)
|
|
244
239
|
|
|
245
|
-
|
|
240
|
+
valid = len(non_empty_reference_field_keys) > 0
|
|
241
|
+
if not valid:
|
|
246
242
|
logger.warning(
|
|
247
243
|
"There is not enough data to generate a valid DELETE statement for {}",
|
|
248
244
|
self.node.address,
|
|
@@ -250,17 +246,9 @@ class BigQueryQueryConfig(QueryStringWithoutTuplesOverrideQueryConfig):
|
|
|
250
246
|
return []
|
|
251
247
|
|
|
252
248
|
table = Table(self._generate_table_name(), MetaData(bind=client), autoload=True)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
for column_name, values in filtered_data.items():
|
|
257
|
-
if len(values) == 1:
|
|
258
|
-
where_clauses.append(getattr(table.c, column_name) == values[0])
|
|
259
|
-
else:
|
|
260
|
-
where_clauses.append(getattr(table.c, column_name).in_(values))
|
|
261
|
-
|
|
262
|
-
# Combine reference clauses with OR instead of AND
|
|
263
|
-
combined_reference_clause = or_(*where_clauses)
|
|
249
|
+
where_clauses: List[ColumnElement] = [
|
|
250
|
+
getattr(table.c, k) == v for k, v in non_empty_reference_field_keys.items()
|
|
251
|
+
]
|
|
264
252
|
|
|
265
253
|
if self.partitioning:
|
|
266
254
|
partition_clauses = self.get_partition_clauses()
|
|
@@ -271,25 +259,12 @@ class BigQueryQueryConfig(QueryStringWithoutTuplesOverrideQueryConfig):
|
|
|
271
259
|
|
|
272
260
|
for partition_clause in partition_clauses:
|
|
273
261
|
partitioned_queries.append(
|
|
274
|
-
table.delete()
|
|
275
|
-
.where(combined_reference_clause)
|
|
276
|
-
.where(text(partition_clause))
|
|
262
|
+
table.delete().where(*(where_clauses + [text(partition_clause)]))
|
|
277
263
|
)
|
|
278
264
|
|
|
279
265
|
return partitioned_queries
|
|
280
266
|
|
|
281
|
-
return [table.delete().where(
|
|
282
|
-
|
|
283
|
-
def uses_delete_masking_strategy(self) -> bool:
|
|
284
|
-
"""Check if this collection uses DELETE masking strategy.
|
|
285
|
-
|
|
286
|
-
Returns True if masking override is present and strategy is DELETE.
|
|
287
|
-
"""
|
|
288
|
-
masking_override = self.node.collection.masking_strategy_override
|
|
289
|
-
return (
|
|
290
|
-
masking_override is not None
|
|
291
|
-
and masking_override.strategy == MaskingStrategies.DELETE
|
|
292
|
-
)
|
|
267
|
+
return [table.delete().where(*where_clauses)]
|
|
293
268
|
|
|
294
269
|
def format_fields_for_query(
|
|
295
270
|
self,
|