ethyca-fides 2.66.1rc0__py2.py3-none-any.whl → 2.66.2b0__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.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/METADATA +1 -1
- {ethyca_fides-2.66.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/RECORD +257 -248
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/7e9a2b52f498_adding_masking_secrets.py +60 -0
- fides/api/alembic/migrations/versions/d0031087eacb_create_manualtaskconditionaldependency_.py +106 -0
- fides/api/api/v1/endpoints/dataset_config_endpoints.py +13 -5
- fides/api/api/v1/endpoints/drp_endpoints.py +7 -1
- fides/api/api/v1/endpoints/user_endpoints.py +83 -7
- fides/api/app_setup.py +3 -2
- fides/api/common_exceptions.py +4 -0
- fides/api/db/base.py +1 -0
- fides/api/db/database.py +1 -1
- fides/api/graph/execution.py +30 -0
- fides/api/models/manual_task/__init__.py +2 -0
- fides/api/models/manual_task/conditional_dependency.py +144 -0
- fides/api/models/{manual_task.py → manual_task/manual_task.py} +10 -0
- fides/api/models/masking_secret.py +72 -0
- fides/api/models/policy.py +23 -0
- fides/api/models/privacy_request/privacy_request.py +25 -13
- fides/api/oauth/roles.py +2 -0
- fides/api/schemas/application_config.py +11 -1
- fides/api/schemas/masking/masking_secrets.py +1 -1
- fides/api/service/connectors/base_connector.py +1 -0
- fides/api/service/connectors/bigquery_connector.py +67 -19
- fides/api/service/connectors/dynamodb_connector.py +2 -1
- fides/api/service/connectors/fides_connector.py +1 -0
- fides/api/service/connectors/http_connector.py +1 -0
- fides/api/service/connectors/manual_task_connector.py +1 -0
- fides/api/service/connectors/manual_webhook_connector.py +2 -1
- fides/api/service/connectors/mongodb_connector.py +1 -0
- fides/api/service/connectors/okta_connector.py +1 -0
- fides/api/service/connectors/query_configs/bigquery_query_config.py +91 -32
- fides/api/service/connectors/rds_mysql_connector.py +1 -0
- fides/api/service/connectors/rds_postgres_connector.py +1 -0
- fides/api/service/connectors/s3_connector.py +1 -0
- fides/api/service/connectors/saas_connector.py +1 -0
- fides/api/service/connectors/scylla_connector.py +1 -0
- fides/api/service/connectors/sql_connector.py +36 -4
- fides/api/service/connectors/website_connector.py +1 -0
- fides/api/service/privacy_request/request_runner_service.py +26 -0
- fides/api/service/privacy_request/request_service.py +1 -22
- fides/api/task/conditional_dependencies/__init__.py +0 -0
- fides/api/task/conditional_dependencies/evaluator.py +109 -0
- fides/api/task/conditional_dependencies/schemas.py +54 -0
- fides/api/task/deprecated_graph_task.py +24 -6
- fides/api/task/execute_request_tasks.py +88 -11
- fides/api/task/graph_task.py +38 -3
- fides/api/task/manual/manual_task_graph_task.py +1 -0
- fides/api/util/cache.py +5 -0
- fides/api/util/encryption/secrets_util.py +48 -18
- fides/common/api/scope_registry.py +3 -0
- fides/config/utils.py +1 -0
- fides/service/privacy_request/privacy_request_service.py +6 -1
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/QGhYEMWDATmdofDzIl0_2/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1817-6f35f58cd08b04ae.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/431-ade3e312fac3430b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6780-4b687168dd8daa84.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8237-55049f8f5fd5e058.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-39ccb07327c2c5d5.js → _app-65e47e67bee20654.js} +56 -56
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-71579a199158952e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-7e63ac744c45f6da.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{integrations-e2d5d7e2a5265e68.js → integrations-f10a7dcf7541c865.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/{table-migration-69ad86b7a8a9a115.js → table-migration-05616e2ae20ff4f8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-f18b2b83c4592f03.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-1daa805a3099c6d4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-fe58cebba358119d.js +1 -0
- fides/ui-build/static/admin/_next/static/css/{5bfb2473e5701527.css → 23cf870196941c9a.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/b81194f2c3930152.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-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/ui-build/static/admin/_next/static/IeU4qLtEtRJo0FsaIFIr8/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-e601e737e3cc7a0e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-34f0b91c26f8d9ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6780-5bd185892f6af46e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2265ecb899d45fbc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-8ab33a1e0272df1f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-32600543eb7b584f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-cbe4c8f9096b6543.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/[id]-ff5738706da07801.js +0 -1
- fides/ui-build/static/admin/_next/static/css/2cadb5f62dcd7c2b.css +0 -1
- {ethyca_fides-2.66.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.66.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.66.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.66.1rc0.dist-info → ethyca_fides-2.66.2b0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{IeU4qLtEtRJo0FsaIFIr8 → QGhYEMWDATmdofDzIl0_2}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{203-5a663f465ba26bb4.js → 203-d9fe5384a6e94799.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{2921-455e6357b74d2f76.js → 2921-86f1547ac40a5cdf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3450-0ba194991d0cca88.js → 3450-f7bb8d46fbe4e78d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3855-e172870d3e21b0dd.js → 3855-e2fa6db53d32c3de.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3872-46cebf7ec1b31a2b.js → 3872-08c855f3edb230c4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{3923-6cc911dafccc5f63.js → 3923-13a6b4da2d51bf8f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{401-1b529d5800aa1f3a.js → 401-3cc1fee61494e3bd.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{409-a257e14acebcd73b.js → 409-45a125437261580c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4121-2bc09fc4ddbfe5cb.js → 4121-f50675521dfee6eb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4230-60100f7ef3ddcde1.js → 4230-840c287045c88b34.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4608-bbb7bf511a05c3c2.js → 4608-a8e3100e2806dbff.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5309-d73339f062763fed.js → 5309-67bdf9001531e972.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5574-b13021775a15bfd2.js → 5574-a7d8a753d273b11a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6084-7178ff6ea6822475.js → 6084-a872a8bc704c980f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6662-507be5d46e5b719b.js → 6662-4a7805f74af51f1d.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6853-2ad3e08fe6f9f5f2.js → 6853-4f8bf6558f8c6a46.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6882-6af16fef26c21e06.js → 6882-85c6277d9531a83a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6954-bb875d9ac89f6030.js → 6954-34e062e4bffc7e71.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7476-281ee9a8286556f3.js → 7476-cfe41e915f0c4f40.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-9aac73191ed5ed13.js → 7630-7a8039aa37893129.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{787-fb41002f797eb2df.js → 787-d05b25c73f49b6af.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{79-7e87aff851423d4a.js → 79-1952e8aab93b7209.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{796-329a5f823ec258a5.js → 796-d2876f4d09a6d81f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9046-ce9567c9074563e2.js → 9046-54877976a0529de2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9226-746771d47dff6266.js → 9226-7a799c930b73f217.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-111aaee8bd8dbd09.js → 9826-b7d5467e3a3225c8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9951-9b753ad7c3f51bdf.js → 9951-595d0f1588215081.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{404-aece2c920ea14514.js → 404-2d803dab6a00f353.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-98777246bec9dc2a.js → manual-acb59f8b5e97512a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{multiple-dc75dc6e37e52f05.js → multiple-8ff7f37913ad736a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-a71c0aff4e0e6535.js → add-systems-f28841affa791975.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-24d226b5a8de5c74.js → add-vendors-d00c9034cdeb0236.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-6a8ef51138ac926a.js → configure-50d21e23b607688b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-1edf582ba3cd3bbb.js → [id]-fc3a011154a2e1de.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-experience-685771e5f7196d87.js → privacy-experience-09d4408014bcfe1c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-6ccedc70dc447089.js → [id]-d67542783ef5ddac.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-944bca1cc57985b5.js → new-3f20e8a316bb3d5b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{privacy-notices-84f4bd14ce8673bc.js → privacy-notices-23e9dcd4590312d2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-6f86ab63a08a6528.js → properties-057cad65e7414a44.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-afdbd4665657cfa1.js → reporting-8f891957c8944137.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{consent-73d3cbf68f7c3a31.js → consent-509691da6b06f834.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/{[resourceUrn]-11d52f1570759c4d.js → [resourceUrn]-99c9092d65c94807.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-6ba9e160dae64695.js → [projectUrn]-80a6cc8e8573514a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{projects-32eac8bbd217615a.js → projects-774fecea22ba8852.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/{[resourceUrn]-b83afa5565d0c84e.js → [resourceUrn]-f6bd6aff389cb9fe.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-7648bbd4f6711e4d.js → resources-6c3714ee97a718c1.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-6f630d42ac9fb6b4.js → data-catalog-2f43cfefc869b85f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9ddb52ebb7ac4c71.js → action-center-409694b8441bd8fb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{activity-9aa744d56cdacb0d.js → activity-5af9381f02b2aff6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-393e20924c83373e.js → [resourceUrn]-31e6c54794a9883e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-8733807dad4bc96e.js → detection-2822a423a7ad0550.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-14bd7500362ff224.js → [resourceUrn]-6421ce247549c5d6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-9e7dfd5a6acc2e8f.js → discovery-3eac407ac5181a3c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datamap-7674b97d655c193b.js → datamap-e707dc714452498e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-c0d2bfd465df20e0.js → [...subfieldNames]-1c98bd0959d9570a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-28280a8a39a6e37c.js → [collectionName]-e548cabda7da32c9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{[datasetId]-006b695e5af5ef24.js → [datasetId]-a8e8b5f4ee7af86c.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-82fb246d87e58ebd.js → new-513c862c3a707735.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-20165c31ab1bc7cf.js → dataset-747b7a13289f1cd7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-b4a6bcc87d126840.js → [id]-3d22525b3c327b2e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f95d7b0bbfc58f5a.js → new-d2cad97495e86adb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{datastore-connection-c391c6fad56eec48.js → datastore-connection-6865aa958f3da342.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-1919aab9e5834b51.js → index-f127ebaac4689d10.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-eacabe4a80cb8813.js → [id]-8d83a5518c00fcfc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{[id]-53fecfb9dd6a1e0c.js → [id]-5627d0d0668077f9.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/messaging/{add-template-76b01cec5fde10a9.js → add-template-feca66ad5c5fe54a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{messaging-5094ffea13f32ed9.js → messaging-c1bd3e7adbe8d2d3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{ant-components-5c08e8447c45ce44.js → ant-components-64a322d01aae5ca7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{AntForm-06ad5f34585480aa.js → AntForm-8bca16a7726e7eb2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikAntFormItem-6f071c2bc9446cb0.js → FormikAntFormItem-b0f246fc3b67ebf7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikControlled-efcc38c58991ac9e.js → FormikControlled-1a0852b090bfc392.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/{FormikField-430ba5c979abfb7c.js → FormikField-11f3de1b45e36583.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/poc/{forms-5c561880bf131afb.js → forms-1b73a1c2b6c6285f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-10ce53ea356f8bad.js → messaging-f9be923340cd99cf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-5501bbb129fee9c4.js → storage-eb1ccc8a5dbf0fe5.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{configure-d888a69a3bbe040e.js → configure-295bfe6880b209f2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-d3d8e3d7583ec635.js → [id]-dd99183f93763ae4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-1af10ed303815d46.js → add-property-0bdbc1fcbf553b8f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{properties-cebc0dc186be499a.js → properties-e959378bb32b6b73.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-e130c0197362e8f3.js → datamap-2a98bd257edd8f47.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/{alpha-5e1322de868d615e.js → alpha-8152e5828469cf91.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-241f95e372b65d0f.js → about-9839e544924ac1f2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/{[purpose_id]-fc201657f4a782c7.js → [purpose_id]-668d74c041d74650.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{consent-c2d39cba8396ef3a.js → consent-f7a0f8367129cd70.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-d992103cc55901ae.js → custom-fields-10df8d6fdc8bc149.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-41242f805599feda.js → domain-records-4056a3323cdc7042.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e885f74c92f669c.js → domains-5a3691559262e874.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-ff112655ad5f41e5.js → email-templates-e1d3c3d0ab878812.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-023e1895552817de.js → locations-6946e78a5d43e654.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-ac403c0886b20e20.js → organization-26df33de21fb11b3.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-86062a18e081a52a.js → regulations-102efd9199e87124.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-7a3396ac819c7904.js → test-datasets-170c9c55f65ffb0f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-8314a819837f5b2a.js → [id]-d4a57ea18935dd70.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{systems-21f423a7c417aa9d.js → systems-2112c006765c66b6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-6387fcc8cce872eb.js → taxonomy-a53e89319582ce58.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-a2524414e968f862.js → new-bc4eb541906781e6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-173ac3a1ed2b05a6.js → user-management-45bfa04e45a7d13f.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{webpack-ff0cd6bff75588da.js → webpack-ff4c22c9f0840531.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-25T16:16:16-0700",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.66.
|
|
14
|
+
"full-revisionid": "3805a2cc72d6f998672d84b64fd0f2c78a64f81d",
|
|
15
|
+
"version": "2.66.2b0"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""adding masking secrets
|
|
2
|
+
|
|
3
|
+
Revision ID: 7e9a2b52f498
|
|
4
|
+
Revises: d0031087eacb
|
|
5
|
+
Create Date: 2024-12-23 23:29:53.557951
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
import sqlalchemy_utils
|
|
11
|
+
from alembic import op
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "7e9a2b52f498"
|
|
15
|
+
down_revision = "d0031087eacb"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
op.create_table(
|
|
22
|
+
"masking_secret",
|
|
23
|
+
sa.Column("id", sa.String(length=255), nullable=False),
|
|
24
|
+
sa.Column(
|
|
25
|
+
"created_at",
|
|
26
|
+
sa.DateTime(timezone=True),
|
|
27
|
+
server_default=sa.text("now()"),
|
|
28
|
+
nullable=True,
|
|
29
|
+
),
|
|
30
|
+
sa.Column(
|
|
31
|
+
"updated_at",
|
|
32
|
+
sa.DateTime(timezone=True),
|
|
33
|
+
server_default=sa.text("now()"),
|
|
34
|
+
nullable=True,
|
|
35
|
+
),
|
|
36
|
+
sa.Column("privacy_request_id", sa.String(), nullable=False),
|
|
37
|
+
sa.Column(
|
|
38
|
+
"secret",
|
|
39
|
+
sqlalchemy_utils.types.encrypted.encrypted_type.StringEncryptedType(),
|
|
40
|
+
nullable=False,
|
|
41
|
+
),
|
|
42
|
+
sa.Column("masking_strategy", sa.String(), nullable=False),
|
|
43
|
+
sa.Column(
|
|
44
|
+
"secret_type",
|
|
45
|
+
sa.String(),
|
|
46
|
+
nullable=False,
|
|
47
|
+
),
|
|
48
|
+
sa.ForeignKeyConstraint(
|
|
49
|
+
["privacy_request_id"], ["privacyrequest.id"], ondelete="CASCADE"
|
|
50
|
+
),
|
|
51
|
+
sa.PrimaryKeyConstraint("id"),
|
|
52
|
+
)
|
|
53
|
+
op.create_index(
|
|
54
|
+
op.f("ix_masking_secret_id"), "masking_secret", ["id"], unique=False
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def downgrade():
|
|
59
|
+
op.drop_index(op.f("ix_masking_secret_id"), table_name="masking_secret")
|
|
60
|
+
op.drop_table("masking_secret")
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""create ManualTaskConditionalDependency table
|
|
2
|
+
|
|
3
|
+
Revision ID: d0031087eacb
|
|
4
|
+
Revises: 9e3dab26f75f
|
|
5
|
+
Create Date: 2025-07-17 21:28:20.937945
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from sqlalchemy.dialects import postgresql
|
|
12
|
+
|
|
13
|
+
# revision identifiers, used by Alembic.
|
|
14
|
+
revision = "d0031087eacb"
|
|
15
|
+
down_revision = "9e3dab26f75f"
|
|
16
|
+
branch_labels = None
|
|
17
|
+
depends_on = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def upgrade():
|
|
21
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
22
|
+
|
|
23
|
+
op.create_table(
|
|
24
|
+
"manual_task_conditional_dependency",
|
|
25
|
+
sa.Column(
|
|
26
|
+
"created_at",
|
|
27
|
+
sa.DateTime(timezone=True),
|
|
28
|
+
server_default=sa.text("now()"),
|
|
29
|
+
nullable=True,
|
|
30
|
+
),
|
|
31
|
+
sa.Column(
|
|
32
|
+
"updated_at",
|
|
33
|
+
sa.DateTime(timezone=True),
|
|
34
|
+
server_default=sa.text("now()"),
|
|
35
|
+
nullable=True,
|
|
36
|
+
),
|
|
37
|
+
sa.Column("id", sa.String(length=255), nullable=False),
|
|
38
|
+
sa.Column("manual_task_id", sa.String(), nullable=False),
|
|
39
|
+
sa.Column("parent_id", sa.String(), nullable=True),
|
|
40
|
+
sa.Column(
|
|
41
|
+
"condition_type",
|
|
42
|
+
sa.String(), # Use String instead of Enum to avoid auto-creation
|
|
43
|
+
nullable=False,
|
|
44
|
+
),
|
|
45
|
+
sa.Column("field_address", sa.String(), nullable=True),
|
|
46
|
+
sa.Column("operator", sa.String(), nullable=True),
|
|
47
|
+
sa.Column("value", postgresql.JSONB(astext_type=sa.Text()), nullable=True),
|
|
48
|
+
sa.Column("logical_operator", sa.String(), nullable=True),
|
|
49
|
+
sa.Column("sort_order", sa.Integer(), nullable=False),
|
|
50
|
+
sa.ForeignKeyConstraint(
|
|
51
|
+
["manual_task_id"], ["manual_task.id"], ondelete="CASCADE"
|
|
52
|
+
),
|
|
53
|
+
sa.ForeignKeyConstraint(
|
|
54
|
+
["parent_id"], ["manual_task_conditional_dependency.id"], ondelete="CASCADE"
|
|
55
|
+
),
|
|
56
|
+
sa.PrimaryKeyConstraint("id"),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
op.create_index(
|
|
60
|
+
"ix_manual_task_conditional_dependency_condition_type",
|
|
61
|
+
"manual_task_conditional_dependency",
|
|
62
|
+
["condition_type"],
|
|
63
|
+
unique=False,
|
|
64
|
+
)
|
|
65
|
+
op.create_index(
|
|
66
|
+
"ix_manual_task_conditional_dependency_manual_task_id",
|
|
67
|
+
"manual_task_conditional_dependency",
|
|
68
|
+
["manual_task_id"],
|
|
69
|
+
unique=False,
|
|
70
|
+
)
|
|
71
|
+
op.create_index(
|
|
72
|
+
"ix_manual_task_conditional_dependency_parent_id",
|
|
73
|
+
"manual_task_conditional_dependency",
|
|
74
|
+
["parent_id"],
|
|
75
|
+
unique=False,
|
|
76
|
+
)
|
|
77
|
+
op.create_index(
|
|
78
|
+
"ix_manual_task_conditional_dependency_sort_order",
|
|
79
|
+
"manual_task_conditional_dependency",
|
|
80
|
+
["sort_order"],
|
|
81
|
+
unique=False,
|
|
82
|
+
)
|
|
83
|
+
# ### end Alembic commands ###
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def downgrade():
|
|
87
|
+
# ### commands auto generated by Alembic - please adjust! ###
|
|
88
|
+
op.drop_index(
|
|
89
|
+
"ix_manual_task_conditional_dependency_sort_order",
|
|
90
|
+
table_name="manual_task_conditional_dependency",
|
|
91
|
+
)
|
|
92
|
+
op.drop_index(
|
|
93
|
+
"ix_manual_task_conditional_dependency_parent_id",
|
|
94
|
+
table_name="manual_task_conditional_dependency",
|
|
95
|
+
)
|
|
96
|
+
op.drop_index(
|
|
97
|
+
"ix_manual_task_conditional_dependency_manual_task_id",
|
|
98
|
+
table_name="manual_task_conditional_dependency",
|
|
99
|
+
)
|
|
100
|
+
op.drop_index(
|
|
101
|
+
"ix_manual_task_conditional_dependency_condition_type",
|
|
102
|
+
table_name="manual_task_conditional_dependency",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
op.drop_table("manual_task_conditional_dependency")
|
|
106
|
+
# ### end Alembic commands ###
|
|
@@ -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, Request
|
|
4
|
+
from fastapi import Depends, HTTPException, Query, 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,10 +68,18 @@ 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
|
|
71
72
|
|
|
72
73
|
router = APIRouter(tags=["Dataset Configs"], prefix=V1_URL_PREFIX)
|
|
73
74
|
|
|
74
75
|
|
|
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
|
+
|
|
75
83
|
# Helper method to inject the parent ConnectionConfig into these child routes
|
|
76
84
|
def _get_connection_config(
|
|
77
85
|
connection_key: FidesKey, db: Session = Depends(deps.get_db)
|
|
@@ -131,7 +139,7 @@ def validate_dataset(
|
|
|
131
139
|
response_model=BulkPutDataset,
|
|
132
140
|
)
|
|
133
141
|
def put_dataset_configs(
|
|
134
|
-
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=
|
|
142
|
+
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=MAX_DATASET_CONFIGS_FOR_INTEGRATION_FORM)], # type: ignore
|
|
135
143
|
db: Session = Depends(deps.get_db),
|
|
136
144
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
137
145
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
@@ -181,7 +189,7 @@ def put_dataset_configs(
|
|
|
181
189
|
response_model=BulkPutDataset,
|
|
182
190
|
)
|
|
183
191
|
def patch_dataset_configs(
|
|
184
|
-
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=
|
|
192
|
+
dataset_pairs: Annotated[List[DatasetConfigCtlDataset], Field(max_length=MAX_DATASET_CONFIGS_FOR_INTEGRATION_FORM)], # type: ignore
|
|
185
193
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
186
194
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
187
195
|
) -> BulkPutDataset:
|
|
@@ -217,7 +225,7 @@ def patch_dataset_configs(
|
|
|
217
225
|
response_model=BulkPutDataset,
|
|
218
226
|
)
|
|
219
227
|
def patch_datasets(
|
|
220
|
-
datasets: Annotated[List[FideslangDataset], Field(max_length=
|
|
228
|
+
datasets: Annotated[List[FideslangDataset], Field(max_length=1000)], # type: ignore
|
|
221
229
|
dataset_config_service: DatasetConfigService = Depends(get_dataset_config_service),
|
|
222
230
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
223
231
|
) -> BulkPutDataset:
|
|
@@ -367,7 +375,7 @@ def get_dataset(
|
|
|
367
375
|
)
|
|
368
376
|
def get_dataset_configs(
|
|
369
377
|
db: Session = Depends(deps.get_db),
|
|
370
|
-
params:
|
|
378
|
+
params: DatasetConfigParams = Depends(),
|
|
371
379
|
connection_config: ConnectionConfig = Depends(_get_connection_config),
|
|
372
380
|
) -> AbstractPage[DatasetConfig]:
|
|
373
381
|
"""Returns all Dataset Configs attached to current Connection Config."""
|
|
@@ -125,7 +125,13 @@ async def create_drp_privacy_request(
|
|
|
125
125
|
"Decrypting identity for DRP privacy request {}", privacy_request.id
|
|
126
126
|
)
|
|
127
127
|
|
|
128
|
-
cache_data(privacy_request,
|
|
128
|
+
cache_data(privacy_request, mapped_identity, None, data)
|
|
129
|
+
|
|
130
|
+
if masking_secrets := policy.generate_masking_secrets():
|
|
131
|
+
logger.info(
|
|
132
|
+
"Caching masking secrets for privacy request {}", privacy_request.id
|
|
133
|
+
)
|
|
134
|
+
privacy_request.persist_masking_secrets(masking_secrets)
|
|
129
135
|
|
|
130
136
|
queue_privacy_request(privacy_request.id)
|
|
131
137
|
|
|
@@ -6,6 +6,7 @@ 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
|
|
9
10
|
from fastapi_pagination import Page, Params
|
|
10
11
|
from fastapi_pagination.bases import AbstractPage
|
|
11
12
|
from fastapi_pagination.ext.sqlalchemy import paginate
|
|
@@ -39,7 +40,9 @@ from fides.api.oauth.roles import APPROVER, VIEWER
|
|
|
39
40
|
from fides.api.oauth.utils import (
|
|
40
41
|
create_temporary_user_for_login_flow,
|
|
41
42
|
extract_payload,
|
|
43
|
+
extract_token_and_load_client,
|
|
42
44
|
get_current_user,
|
|
45
|
+
has_permissions,
|
|
43
46
|
oauth2_scheme,
|
|
44
47
|
verify_oauth_client,
|
|
45
48
|
)
|
|
@@ -65,6 +68,7 @@ from fides.common.api.scope_registry import (
|
|
|
65
68
|
USER_DELETE,
|
|
66
69
|
USER_PASSWORD_RESET,
|
|
67
70
|
USER_READ,
|
|
71
|
+
USER_READ_OWN,
|
|
68
72
|
USER_UPDATE,
|
|
69
73
|
)
|
|
70
74
|
from fides.common.api.v1 import urn_registry as urls
|
|
@@ -107,6 +111,37 @@ def _validate_current_user(user_id: str, user_from_token: FidesUser) -> None:
|
|
|
107
111
|
)
|
|
108
112
|
|
|
109
113
|
|
|
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
|
+
|
|
110
145
|
@router.put(
|
|
111
146
|
urls.USER_DETAIL,
|
|
112
147
|
dependencies=[Security(verify_oauth_client)],
|
|
@@ -498,14 +533,38 @@ def delete_user(
|
|
|
498
533
|
|
|
499
534
|
@router.get(
|
|
500
535
|
urls.USER_DETAIL,
|
|
501
|
-
dependencies=[Security(
|
|
536
|
+
dependencies=[Security(verify_user_read_scopes)],
|
|
502
537
|
response_model=UserResponse,
|
|
503
538
|
)
|
|
504
|
-
def get_user(
|
|
505
|
-
|
|
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."""
|
|
506
547
|
user: Optional[FidesUser] = FidesUser.get_by_key_or_id(db, data={"id": user_id})
|
|
507
548
|
if user is None:
|
|
508
549
|
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
|
+
)
|
|
509
568
|
|
|
510
569
|
logger.debug("Returning user with id: '{}'.", user_id)
|
|
511
570
|
return user
|
|
@@ -513,7 +572,7 @@ def get_user(*, db: Session = Depends(get_db), user_id: str) -> FidesUser:
|
|
|
513
572
|
|
|
514
573
|
@router.get(
|
|
515
574
|
urls.USERS,
|
|
516
|
-
dependencies=[Security(
|
|
575
|
+
dependencies=[Security(verify_user_read_scopes)],
|
|
517
576
|
response_model=Page[UserResponse],
|
|
518
577
|
)
|
|
519
578
|
def get_users(
|
|
@@ -521,11 +580,28 @@ def get_users(
|
|
|
521
580
|
db: Session = Depends(get_db),
|
|
522
581
|
params: Params = Depends(),
|
|
523
582
|
username: Optional[str] = None,
|
|
583
|
+
client: ClientDetail = Security(verify_user_read_scopes),
|
|
584
|
+
authorization: str = Security(oauth2_scheme),
|
|
524
585
|
) -> AbstractPage[FidesUser]:
|
|
525
|
-
"""Returns a paginated list of
|
|
586
|
+
"""Returns a paginated list of users. Users with USER_READ_OWN scope only see their own data."""
|
|
526
587
|
query = FidesUser.query(db)
|
|
527
|
-
|
|
528
|
-
|
|
588
|
+
|
|
589
|
+
# Check if user has USER_READ_OWN scope and filter accordingly
|
|
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)}%"))
|
|
529
605
|
|
|
530
606
|
logger.debug("Returning a paginated list of users.")
|
|
531
607
|
|
fides/api/app_setup.py
CHANGED
|
@@ -171,8 +171,9 @@ async def run_database_startup(app: FastAPI) -> None:
|
|
|
171
171
|
if CONFIG.database.automigrate:
|
|
172
172
|
try:
|
|
173
173
|
configure_db(CONFIG.database.sync_database_uri)
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
if not CONFIG.test_mode:
|
|
175
|
+
with get_autoclose_db_session() as session:
|
|
176
|
+
seed_db(session)
|
|
176
177
|
if CONFIG.database.load_samples:
|
|
177
178
|
async with get_async_autoclose_db_session() as async_session:
|
|
178
179
|
await seed.load_samples(async_session)
|
fides/api/common_exceptions.py
CHANGED
|
@@ -283,6 +283,10 @@ class MalisciousUrlException(Exception):
|
|
|
283
283
|
"""Fides has detected a potentially maliscious URL."""
|
|
284
284
|
|
|
285
285
|
|
|
286
|
+
class MaskingSecretsExpired(BaseException):
|
|
287
|
+
"""The cached masking secrets have expired for the given privacy request."""
|
|
288
|
+
|
|
289
|
+
|
|
286
290
|
class AuthenticationError(HTTPException):
|
|
287
291
|
"""To be raised when attempting to fetch an access token using
|
|
288
292
|
invalid credentials.
|
fides/api/db/base.py
CHANGED
|
@@ -33,6 +33,7 @@ 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,
|
|
36
37
|
ManualTaskConfig,
|
|
37
38
|
ManualTaskConfigField,
|
|
38
39
|
ManualTaskInstance,
|
fides/api/db/database.py
CHANGED
fides/api/graph/execution.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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
|
|
4
5
|
|
|
5
6
|
from fides.api.graph.config import (
|
|
6
7
|
Collection,
|
|
@@ -117,6 +118,8 @@ class ExecutionNode(Contextualizable): # pylint: disable=too-many-instance-attr
|
|
|
117
118
|
The values are cast based on field types, if those types are specified.
|
|
118
119
|
"""
|
|
119
120
|
out = {}
|
|
121
|
+
failed_conversions: Dict[str, Dict[str, Any]] = {}
|
|
122
|
+
|
|
120
123
|
for key, values in input_data.items():
|
|
121
124
|
path: FieldPath = FieldPath.parse(key)
|
|
122
125
|
field: Optional[Field] = self.collection.field(path)
|
|
@@ -126,4 +129,31 @@ class ExecutionNode(Contextualizable): # pylint: disable=too-many-instance-attr
|
|
|
126
129
|
filtered = list(filter(lambda x: x is not None, cast_values))
|
|
127
130
|
if filtered:
|
|
128
131
|
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
|
+
|
|
129
159
|
return out
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
3
|
+
|
|
4
|
+
from sqlalchemy import Column, ForeignKey, Index, Integer, String
|
|
5
|
+
from sqlalchemy.dialects.postgresql import JSONB
|
|
6
|
+
from sqlalchemy.ext.declarative import declared_attr
|
|
7
|
+
from sqlalchemy.orm import Session, relationship
|
|
8
|
+
|
|
9
|
+
from fides.api.db.base_class import Base, FidesBase
|
|
10
|
+
from fides.api.db.util import EnumColumn
|
|
11
|
+
from fides.api.task.conditional_dependencies.schemas import (
|
|
12
|
+
ConditionGroup,
|
|
13
|
+
ConditionLeaf,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from fides.api.models.manual_task.manual_task import ManualTask
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ManualTaskConditionalDependencyType(str, Enum):
|
|
21
|
+
"""Enum for manual task conditional dependency types.
|
|
22
|
+
|
|
23
|
+
This enum defines the two types of nodes in a conditional dependency tree:
|
|
24
|
+
|
|
25
|
+
- leaf: A terminal node that represents a single condition (e.g., "user.age >= 18")
|
|
26
|
+
- group: A non-terminal node that groups multiple conditions with logical operators (AND/OR)
|
|
27
|
+
|
|
28
|
+
Examples:
|
|
29
|
+
leaf: Used for simple field comparisons like:
|
|
30
|
+
- "user.name exists"
|
|
31
|
+
- "user.age >= 18"
|
|
32
|
+
- "billing.subscription.status == 'active'"
|
|
33
|
+
|
|
34
|
+
group: Used to combine multiple conditions with logical operators:
|
|
35
|
+
- AND group: "user.age >= 18 AND user.active == true"
|
|
36
|
+
- OR group: "user.role == 'admin' OR user.verified == true"
|
|
37
|
+
- Nested groups: "(user.age >= 18 AND (user.role == 'admin' OR user.verified == true))"
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
leaf = "leaf"
|
|
41
|
+
group = "group"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ManualTaskConditionalDependency(Base):
|
|
45
|
+
"""Model for storing conditional dependencies."""
|
|
46
|
+
|
|
47
|
+
@declared_attr
|
|
48
|
+
def __tablename__(cls) -> str:
|
|
49
|
+
"""Overriding base class method to set the table name."""
|
|
50
|
+
return "manual_task_conditional_dependency"
|
|
51
|
+
|
|
52
|
+
# We need to redefine it here so that self-referential relationships
|
|
53
|
+
# can properly reference the `id` column instead of the built-in Python function.
|
|
54
|
+
id = Column(String(255), primary_key=True, default=FidesBase.generate_uuid)
|
|
55
|
+
|
|
56
|
+
# Foreign key relationships
|
|
57
|
+
manual_task_id = Column(
|
|
58
|
+
String, ForeignKey("manual_task.id", ondelete="CASCADE"), nullable=False
|
|
59
|
+
)
|
|
60
|
+
parent_id = Column(
|
|
61
|
+
String,
|
|
62
|
+
ForeignKey("manual_task_conditional_dependency.id", ondelete="CASCADE"),
|
|
63
|
+
nullable=True,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Condition metadata
|
|
67
|
+
condition_type = Column(
|
|
68
|
+
EnumColumn(ManualTaskConditionalDependencyType), nullable=False
|
|
69
|
+
) # leaf or group
|
|
70
|
+
field_address = Column(String, nullable=True) # For leaf conditions
|
|
71
|
+
operator = Column(String, nullable=True) # For leaf conditions
|
|
72
|
+
value = Column(JSONB, nullable=True) # For leaf conditions
|
|
73
|
+
logical_operator = Column(String, nullable=True) # 'and' or 'or' for groups
|
|
74
|
+
|
|
75
|
+
# Ordering
|
|
76
|
+
sort_order = Column(Integer, nullable=False, default=0)
|
|
77
|
+
|
|
78
|
+
__table_args__ = (
|
|
79
|
+
Index("ix_manual_task_conditional_dependency_manual_task_id", "manual_task_id"),
|
|
80
|
+
Index("ix_manual_task_conditional_dependency_parent_id", "parent_id"),
|
|
81
|
+
Index("ix_manual_task_conditional_dependency_condition_type", "condition_type"),
|
|
82
|
+
Index("ix_manual_task_conditional_dependency_sort_order", "sort_order"),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Relationships
|
|
86
|
+
task = relationship("ManualTask", back_populates="conditional_dependencies")
|
|
87
|
+
parent = relationship(
|
|
88
|
+
"ManualTaskConditionalDependency",
|
|
89
|
+
remote_side=[id],
|
|
90
|
+
back_populates="children",
|
|
91
|
+
foreign_keys=[parent_id],
|
|
92
|
+
)
|
|
93
|
+
children = relationship(
|
|
94
|
+
"ManualTaskConditionalDependency",
|
|
95
|
+
back_populates="parent",
|
|
96
|
+
cascade="all, delete-orphan",
|
|
97
|
+
foreign_keys=[parent_id],
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def to_condition_leaf(self) -> ConditionLeaf:
|
|
101
|
+
"""Convert to ConditionLeaf if this is a leaf condition"""
|
|
102
|
+
if self.condition_type != "leaf":
|
|
103
|
+
raise ValueError("Cannot convert group condition to leaf")
|
|
104
|
+
|
|
105
|
+
return ConditionLeaf(
|
|
106
|
+
field_address=self.field_address, operator=self.operator, value=self.value
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def to_condition_group(self) -> ConditionGroup:
|
|
110
|
+
"""Convert to ConditionGroup if this is a group condition"""
|
|
111
|
+
if self.condition_type != "group":
|
|
112
|
+
raise ValueError("Cannot convert leaf condition to group")
|
|
113
|
+
|
|
114
|
+
# Recursively build children
|
|
115
|
+
child_conditions = []
|
|
116
|
+
children_list = [child for child in self.children] # type: ignore[attr-defined]
|
|
117
|
+
for child in sorted(children_list, key=lambda x: x.sort_order):
|
|
118
|
+
if child.condition_type == "leaf":
|
|
119
|
+
child_conditions.append(child.to_condition_leaf())
|
|
120
|
+
else:
|
|
121
|
+
child_conditions.append(child.to_condition_group())
|
|
122
|
+
|
|
123
|
+
return ConditionGroup(
|
|
124
|
+
logical_operator=self.logical_operator, conditions=child_conditions
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
@classmethod
|
|
128
|
+
def get_root_condition(
|
|
129
|
+
cls, db: Session, manual_task_id: str
|
|
130
|
+
) -> Optional[Union[ConditionLeaf, ConditionGroup]]:
|
|
131
|
+
"""Get the root condition for a config"""
|
|
132
|
+
root = (
|
|
133
|
+
db.query(cls)
|
|
134
|
+
.filter(cls.manual_task_id == manual_task_id, cls.parent_id.is_(None))
|
|
135
|
+
.first()
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if not root:
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
if root.condition_type == "leaf":
|
|
142
|
+
return root.to_condition_leaf()
|
|
143
|
+
|
|
144
|
+
return root.to_condition_group()
|
|
@@ -26,6 +26,9 @@ 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
|
+
)
|
|
29
32
|
|
|
30
33
|
# ------------------------------------------------------------
|
|
31
34
|
# Enums
|
|
@@ -242,6 +245,13 @@ class ManualTask(Base):
|
|
|
242
245
|
viewonly=True, # No cascade delete - submissions are historical data
|
|
243
246
|
)
|
|
244
247
|
|
|
248
|
+
conditional_dependencies = relationship(
|
|
249
|
+
"ManualTaskConditionalDependency",
|
|
250
|
+
back_populates="task",
|
|
251
|
+
uselist=True,
|
|
252
|
+
cascade="all, delete-orphan",
|
|
253
|
+
)
|
|
254
|
+
|
|
245
255
|
# Properties
|
|
246
256
|
@property
|
|
247
257
|
def assigned_users(self) -> list[str]:
|