ethyca-fides 2.66.2rc0__py2.py3-none-any.whl → 2.66.3b0__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.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/METADATA +1 -1
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/RECORD +270 -259
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/7e9a2b52f498_adding_masking_secrets.py +60 -0
- fides/api/alembic/migrations/versions/a7065df4dcf1_add_finalized_fields_to_privacy_request.py +65 -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/privacy_request_endpoints.py +44 -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/graph/traversal.py +1 -1
- 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/execution_log.py +1 -0
- fides/api/models/privacy_request/privacy_request.py +31 -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/schemas/policy.py +1 -0
- fides/api/schemas/privacy_request.py +5 -0
- 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 +142 -53
- 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/create_request_tasks.py +1 -1
- fides/api/task/deprecated_graph_task.py +24 -6
- fides/api/task/execute_request_tasks.py +89 -12
- fides/api/task/filter_results.py +1 -1
- fides/api/task/graph_task.py +38 -3
- fides/api/task/manual/manual_task_address.py +46 -0
- fides/api/task/manual/manual_task_graph_task.py +118 -126
- fides/api/task/manual/manual_task_utils.py +52 -105
- 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/common/api/v1/urn_registry.py +1 -1
- fides/config/execution_settings.py +4 -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/chunks/1817-6f35f58cd08b04ae.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{203-5a663f465ba26bb4.js → 203-4e777c324a01dbec.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-ade3e312fac3430b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6780-a00c87739acc004d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{796-329a5f823ec258a5.js → 796-3bdda2a7868464af.js} +1 -1
- 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-f2c3d287bac00395.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]-7d3115059503b904.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]-c73497fc333c324d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-7498d1d5974a78b0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-2d3a2d967767a131.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-6a9068df48bdee05.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/79e296c724c1568c.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{94965f224bc991e9.css → 8bc1833f1fa53ff0.css} +1 -1
- fides/ui-build/static/admin/_next/static/hKDMNIRKgB86FSDpiOjHn/_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/ui-build/static/admin/_next/static/8108ANFxs99VY7KZ_Xev2/_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-e3d40aa17a4bf2e9.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]-5d522637871ac6c8.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/configure/messaging-10ce53ea356f8bad.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-5501bbb129fee9c4.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.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.66.2rc0.dist-info → ethyca_fides-2.66.3b0.dist-info}/top_level.txt +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-1cc2bb07ed142203.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-84b7e380b88b4454.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-b2c4803370634ff8.js → 5309-1172322bf91b5d57.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5574-b13021775a15bfd2.js → 5574-9312f97b637d9ee2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6084-7178ff6ea6822475.js → 6084-5d7598b7bcb548cf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6662-507be5d46e5b719b.js → 6662-efb2cf74641647f2.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-586b84aeb02d5830.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-d206c11823c91088.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{7630-9aac73191ed5ed13.js → 7630-b1c93688013ef013.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{787-fb41002f797eb2df.js → 787-cbe2d0bfb513d90a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{79-7e87aff851423d4a.js → 79-3db1941d274f40c7.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9046-5c4c22c375de25b1.js → 9046-c8233981762585b4.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9226-746771d47dff6266.js → 9226-72ad691ca57b83ef.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9826-111aaee8bd8dbd09.js → 9826-3c578665c6d3b21d.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-0943633a8e422695.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-0e1ca0f4c8e7f4da.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-e17c56eec8d91371.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-8a7f9285da66b965.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-9ddb52ebb7ac4c71.js → action-center-85e140788e251272.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-d2b275d83089820d.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-0f29b47402292070.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{index-1919aab9e5834b51.js → index-12ac3e317fc86f21.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/integrations/{[id]-0a58aee2d1e7fa01.js → [id]-f9c0eac932188593.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-d888a69a3bbe040e.js → configure-e551a860ec727802.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-8f98a4895e74725e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-241f95e372b65d0f.js → about-8155a35a62fdb5ae.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-a989532a12c40dcf.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-d992103cc55901ae.js → custom-fields-45bea76ff7eda3cb.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-41242f805599feda.js → domain-records-51333dbd21cb37c8.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domains-2e885f74c92f669c.js → domains-bde86e5f6c09da5a.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{email-templates-ff112655ad5f41e5.js → email-templates-4f9a5cc8bea7725b.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-55a10e01dffc8039.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-f91f22cf96566ed4.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-648a0ff4920579ce.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-6387fcc8cce872eb.js → taxonomy-0b9d1a24188f65a9.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-63a0c45b150a1037.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{8108ANFxs99VY7KZ_Xev2 → hKDMNIRKgB86FSDpiOjHn}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Any,
|
|
1
|
+
from typing import Any, Optional
|
|
2
2
|
|
|
3
3
|
from loguru import logger
|
|
4
4
|
from sqlalchemy.orm import Session
|
|
@@ -18,9 +18,9 @@ from fides.api.models.privacy_request import PrivacyRequest
|
|
|
18
18
|
from fides.api.schemas.policy import ActionType
|
|
19
19
|
from fides.api.schemas.privacy_request import PrivacyRequestStatus
|
|
20
20
|
from fides.api.task.graph_task import GraphTask, retry
|
|
21
|
+
from fides.api.task.manual.manual_task_address import ManualTaskAddress
|
|
21
22
|
from fides.api.task.manual.manual_task_utils import (
|
|
22
|
-
|
|
23
|
-
get_manual_tasks_for_connection_config,
|
|
23
|
+
get_manual_task_for_connection_config,
|
|
24
24
|
)
|
|
25
25
|
from fides.api.util.collection_util import Row
|
|
26
26
|
|
|
@@ -29,7 +29,7 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
29
29
|
"""GraphTask implementation for ManualTask execution"""
|
|
30
30
|
|
|
31
31
|
@retry(action_type=ActionType.access, default_return=[])
|
|
32
|
-
def access_request(self, *inputs:
|
|
32
|
+
def access_request(self, *inputs: list[Row]) -> list[Row]:
|
|
33
33
|
"""
|
|
34
34
|
Execute manual task logic following the standard GraphTask pattern:
|
|
35
35
|
1. Create ManualTaskInstances if they don't exist
|
|
@@ -46,9 +46,9 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
46
46
|
connection_key = ManualTaskAddress.get_connection_key(collection_address)
|
|
47
47
|
|
|
48
48
|
# Get manual tasks for this connection
|
|
49
|
-
|
|
49
|
+
manual_task = get_manual_task_for_connection_config(db, connection_key)
|
|
50
50
|
|
|
51
|
-
if not
|
|
51
|
+
if not manual_task:
|
|
52
52
|
return []
|
|
53
53
|
|
|
54
54
|
# Check if any manual tasks have ACCESS configs
|
|
@@ -56,7 +56,6 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
56
56
|
|
|
57
57
|
has_access_configs = [
|
|
58
58
|
config
|
|
59
|
-
for manual_task in manual_tasks
|
|
60
59
|
for config in manual_task.configs
|
|
61
60
|
if config.is_current
|
|
62
61
|
and config.config_type == ManualTaskConfigurationType.access_privacy_request
|
|
@@ -77,7 +76,7 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
77
76
|
# Check/create manual task instances for ACCESS configs only
|
|
78
77
|
self._ensure_manual_task_instances(
|
|
79
78
|
db,
|
|
80
|
-
|
|
79
|
+
manual_task,
|
|
81
80
|
self.resources.request,
|
|
82
81
|
ManualTaskConfigurationType.access_privacy_request,
|
|
83
82
|
)
|
|
@@ -85,13 +84,13 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
85
84
|
# Check if all manual task instances have submissions for ACCESS configs only
|
|
86
85
|
submitted_data = self._get_submitted_data(
|
|
87
86
|
db,
|
|
88
|
-
|
|
87
|
+
manual_task,
|
|
89
88
|
self.resources.request,
|
|
90
89
|
ManualTaskConfigurationType.access_privacy_request,
|
|
91
90
|
)
|
|
92
91
|
|
|
93
92
|
if submitted_data is not None:
|
|
94
|
-
result:
|
|
93
|
+
result: list[Row] = [submitted_data] if submitted_data else []
|
|
95
94
|
self.request_task.access_data = result
|
|
96
95
|
|
|
97
96
|
# Mark request task as complete and write execution log
|
|
@@ -111,67 +110,65 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
111
110
|
def _ensure_manual_task_instances(
|
|
112
111
|
self,
|
|
113
112
|
db: Session,
|
|
114
|
-
|
|
113
|
+
manual_task: ManualTask,
|
|
115
114
|
privacy_request: PrivacyRequest,
|
|
116
115
|
allowed_config_type: "ManualTaskConfigurationType",
|
|
117
116
|
) -> None:
|
|
118
117
|
"""Create ManualTaskInstances for configs matching `allowed_config_type` if they don't exist."""
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
# Only check for instances of the same config type
|
|
136
|
-
ManualTaskConfig.config_type == allowed_config_type,
|
|
137
|
-
)
|
|
138
|
-
.first()
|
|
119
|
+
# ------------------------------------------------------------------
|
|
120
|
+
# Check if instances already exist for this task & entity with the SAME config type
|
|
121
|
+
# This prevents duplicates when configurations are versioned after the privacy
|
|
122
|
+
# request has started, while allowing different config types (access vs erasure)
|
|
123
|
+
# to have separate instances.
|
|
124
|
+
# ------------------------------------------------------------------
|
|
125
|
+
existing_task_instance = (
|
|
126
|
+
db.query(ManualTaskInstance)
|
|
127
|
+
.join(ManualTaskInstance.config) # Join to access config information
|
|
128
|
+
.filter(
|
|
129
|
+
ManualTaskInstance.task_id == manual_task.id,
|
|
130
|
+
ManualTaskInstance.entity_id == privacy_request.id,
|
|
131
|
+
ManualTaskInstance.entity_type == ManualTaskEntityType.privacy_request,
|
|
132
|
+
# Only check for instances of the same config type
|
|
133
|
+
ManualTaskConfig.config_type == allowed_config_type,
|
|
139
134
|
)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
135
|
+
.first()
|
|
136
|
+
)
|
|
137
|
+
if existing_task_instance:
|
|
138
|
+
# An instance already exists for this privacy request and config type – no need
|
|
139
|
+
# to create another one tied to a newer config version.
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
# Check each active config for instances (now we know none exist yet for this config type)
|
|
143
|
+
for config in manual_task.configs:
|
|
144
|
+
if not config.is_current or config.config_type != allowed_config_type:
|
|
145
|
+
# Skip configs that are not current or not relevant for this request type
|
|
143
146
|
continue
|
|
144
147
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"config_id": config.id,
|
|
156
|
-
"entity_id": privacy_request.id,
|
|
157
|
-
"entity_type": ManualTaskEntityType.privacy_request.value,
|
|
158
|
-
"status": StatusType.pending.value,
|
|
159
|
-
},
|
|
160
|
-
)
|
|
148
|
+
ManualTaskInstance.create(
|
|
149
|
+
db=db,
|
|
150
|
+
data={
|
|
151
|
+
"task_id": manual_task.id,
|
|
152
|
+
"config_id": config.id,
|
|
153
|
+
"entity_id": privacy_request.id,
|
|
154
|
+
"entity_type": ManualTaskEntityType.privacy_request.value,
|
|
155
|
+
"status": StatusType.pending.value,
|
|
156
|
+
},
|
|
157
|
+
)
|
|
161
158
|
|
|
162
159
|
# pylint: disable=too-many-branches,too-many-nested-blocks
|
|
163
160
|
def _get_submitted_data(
|
|
164
161
|
self,
|
|
165
162
|
db: Session,
|
|
166
|
-
|
|
163
|
+
manual_task: ManualTask,
|
|
167
164
|
privacy_request: PrivacyRequest,
|
|
168
165
|
allowed_config_type: "ManualTaskConfigurationType",
|
|
169
|
-
) -> Optional[
|
|
166
|
+
) -> Optional[dict[str, Any]]:
|
|
170
167
|
"""
|
|
171
168
|
Check if all manual task instances have submissions for ALL fields and return aggregated data
|
|
172
169
|
Returns None if any field submissions are missing (all fields must be completed or skipped)
|
|
173
170
|
"""
|
|
174
|
-
aggregated_data:
|
|
171
|
+
aggregated_data: dict[str, Any] = {}
|
|
175
172
|
|
|
176
173
|
def _format_size(size_bytes: int) -> str:
|
|
177
174
|
units = ["B", "KB", "MB", "GB", "TB"]
|
|
@@ -182,79 +179,74 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
182
179
|
size /= 1024.0
|
|
183
180
|
return f"{size:.1f} PB"
|
|
184
181
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
.
|
|
190
|
-
|
|
191
|
-
ManualTaskInstance.entity_id == privacy_request.id,
|
|
192
|
-
ManualTaskInstance.entity_type
|
|
193
|
-
== ManualTaskEntityType.privacy_request,
|
|
194
|
-
)
|
|
195
|
-
.all()
|
|
182
|
+
candidate_instances: list[ManualTaskInstance] = (
|
|
183
|
+
db.query(ManualTaskInstance)
|
|
184
|
+
.filter(
|
|
185
|
+
ManualTaskInstance.task_id == manual_task.id,
|
|
186
|
+
ManualTaskInstance.entity_id == privacy_request.id,
|
|
187
|
+
ManualTaskInstance.entity_type == ManualTaskEntityType.privacy_request,
|
|
196
188
|
)
|
|
189
|
+
.all()
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
if not candidate_instances:
|
|
193
|
+
return None # No instance yet for this manual task
|
|
194
|
+
|
|
195
|
+
for inst in candidate_instances:
|
|
196
|
+
# Skip instances tied to other request types
|
|
197
|
+
if not inst.config or inst.config.config_type != allowed_config_type:
|
|
198
|
+
continue
|
|
199
|
+
|
|
200
|
+
all_fields = inst.config.field_definitions or []
|
|
201
|
+
|
|
202
|
+
# Every field must have a submission
|
|
203
|
+
if not all(inst.get_submission_for_field(f.id) for f in all_fields):
|
|
204
|
+
return None # At least one instance still incomplete
|
|
205
|
+
|
|
206
|
+
# Ensure status set
|
|
207
|
+
if inst.status != StatusType.completed:
|
|
208
|
+
inst.status = StatusType.completed
|
|
209
|
+
inst.save(db)
|
|
210
|
+
|
|
211
|
+
# Aggregate submission data from this instance
|
|
212
|
+
for submission in inst.submissions:
|
|
213
|
+
if not submission.field or not submission.field.field_key:
|
|
214
|
+
continue
|
|
197
215
|
|
|
198
|
-
|
|
199
|
-
return None # No instance yet for this manual task
|
|
216
|
+
field_key = submission.field.field_key
|
|
200
217
|
|
|
201
|
-
|
|
202
|
-
# Skip instances tied to other request types
|
|
203
|
-
if not inst.config or inst.config.config_type != allowed_config_type:
|
|
218
|
+
if not isinstance(submission.data, dict):
|
|
204
219
|
continue
|
|
205
220
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
attachment.attachment_type
|
|
236
|
-
== AttachmentType.include_with_access_package
|
|
237
|
-
):
|
|
238
|
-
try:
|
|
239
|
-
size, url = attachment.retrieve_attachment()
|
|
240
|
-
attachment_map[attachment.file_name] = {
|
|
241
|
-
"url": str(url) if url else None,
|
|
242
|
-
"size": (
|
|
243
|
-
_format_size(size) if size else "Unknown"
|
|
244
|
-
),
|
|
245
|
-
}
|
|
246
|
-
except (
|
|
247
|
-
Exception
|
|
248
|
-
) as exc: # pylint: disable=broad-exception-caught
|
|
249
|
-
logger.warning(
|
|
250
|
-
"Error retrieving attachment {}: {}",
|
|
251
|
-
attachment.file_name,
|
|
252
|
-
str(exc),
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
aggregated_data[field_key] = attachment_map or None
|
|
256
|
-
else:
|
|
257
|
-
aggregated_data[field_key] = data_dict.get("value")
|
|
221
|
+
data_dict: dict[str, Any] = submission.data
|
|
222
|
+
|
|
223
|
+
field_type = data_dict.get("field_type")
|
|
224
|
+
|
|
225
|
+
if field_type == ManualTaskFieldType.attachment.value:
|
|
226
|
+
attachment_map: dict[str, dict[str, Any]] = {}
|
|
227
|
+
for attachment in submission.attachments or []:
|
|
228
|
+
if (
|
|
229
|
+
attachment.attachment_type
|
|
230
|
+
== AttachmentType.include_with_access_package
|
|
231
|
+
):
|
|
232
|
+
try:
|
|
233
|
+
size, url = attachment.retrieve_attachment()
|
|
234
|
+
attachment_map[attachment.file_name] = {
|
|
235
|
+
"url": str(url) if url else None,
|
|
236
|
+
"size": (_format_size(size) if size else "Unknown"),
|
|
237
|
+
}
|
|
238
|
+
except (
|
|
239
|
+
Exception
|
|
240
|
+
) as exc: # pylint: disable=broad-exception-caught
|
|
241
|
+
logger.warning(
|
|
242
|
+
"Error retrieving attachment {}: {}",
|
|
243
|
+
attachment.file_name,
|
|
244
|
+
str(exc),
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
aggregated_data[field_key] = attachment_map or None
|
|
248
|
+
else:
|
|
249
|
+
aggregated_data[field_key] = data_dict.get("value")
|
|
258
250
|
|
|
259
251
|
return aggregated_data if aggregated_data else None
|
|
260
252
|
|
|
@@ -266,8 +258,9 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
266
258
|
@retry(action_type=ActionType.erasure, default_return=0)
|
|
267
259
|
def erasure_request(
|
|
268
260
|
self,
|
|
269
|
-
retrieved_data:
|
|
261
|
+
retrieved_data: list[Row],
|
|
270
262
|
*erasure_prereqs: int, # noqa: D401, pylint: disable=unused-argument
|
|
263
|
+
inputs: Optional[list[list[Row]]] = None,
|
|
271
264
|
) -> int:
|
|
272
265
|
"""Execute manual-task-driven erasure logic.
|
|
273
266
|
|
|
@@ -285,8 +278,8 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
285
278
|
connection_key = ManualTaskAddress.get_connection_key(collection_address)
|
|
286
279
|
|
|
287
280
|
# Fetch relevant manual tasks for this connection
|
|
288
|
-
|
|
289
|
-
if not
|
|
281
|
+
manual_task = get_manual_task_for_connection_config(db, connection_key)
|
|
282
|
+
if not manual_task:
|
|
290
283
|
# No manual tasks defined – nothing to erase
|
|
291
284
|
self.log_end(ActionType.erasure)
|
|
292
285
|
return 0
|
|
@@ -294,7 +287,6 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
294
287
|
# Check if any manual tasks have ERASURE configs
|
|
295
288
|
has_erasure_configs = [
|
|
296
289
|
config
|
|
297
|
-
for manual_task in manual_tasks
|
|
298
290
|
for config in manual_task.configs
|
|
299
291
|
if config.is_current
|
|
300
292
|
and config.config_type
|
|
@@ -309,7 +301,7 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
309
301
|
# Create ManualTaskInstances for ERASURE configs only
|
|
310
302
|
self._ensure_manual_task_instances(
|
|
311
303
|
db,
|
|
312
|
-
|
|
304
|
+
manual_task,
|
|
313
305
|
self.resources.request,
|
|
314
306
|
ManualTaskConfigurationType.erasure_privacy_request,
|
|
315
307
|
)
|
|
@@ -317,7 +309,7 @@ class ManualTaskGraphTask(GraphTask):
|
|
|
317
309
|
# Check for full submissions – reuse helper used by access flow, filtering ERASURE configs
|
|
318
310
|
submissions_complete = self._get_submitted_data(
|
|
319
311
|
db,
|
|
320
|
-
|
|
312
|
+
manual_task,
|
|
321
313
|
self.resources.request,
|
|
322
314
|
ManualTaskConfigurationType.erasure_privacy_request,
|
|
323
315
|
)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, List
|
|
2
|
-
|
|
3
1
|
from sqlalchemy.orm import Session
|
|
4
2
|
|
|
5
3
|
from fides.api.graph.config import (
|
|
@@ -10,6 +8,7 @@ from fides.api.graph.config import (
|
|
|
10
8
|
ScalarField,
|
|
11
9
|
)
|
|
12
10
|
from fides.api.graph.graph import Node
|
|
11
|
+
from fides.api.graph.traversal import TraversalNode
|
|
13
12
|
from fides.api.models.connectionconfig import ConnectionConfig
|
|
14
13
|
|
|
15
14
|
# Import application models
|
|
@@ -22,51 +21,10 @@ from fides.api.models.manual_task import (
|
|
|
22
21
|
)
|
|
23
22
|
from fides.api.models.privacy_request import PrivacyRequest
|
|
24
23
|
from fides.api.schemas.policy import ActionType
|
|
24
|
+
from fides.api.task.manual.manual_task_address import ManualTaskAddress
|
|
25
25
|
|
|
26
|
-
# TYPE_CHECKING import placed after all runtime imports to avoid lint issues
|
|
27
|
-
if TYPE_CHECKING: # pragma: no cover
|
|
28
|
-
from fides.api.graph.traversal import TraversalNode # noqa: F401
|
|
29
|
-
from fides.api.models.policy import Policy # noqa: F401
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class ManualTaskAddress:
|
|
33
|
-
"""Utility class for creating and parsing manual task addresses"""
|
|
34
|
-
|
|
35
|
-
MANUAL_DATA_COLLECTION = "manual_data"
|
|
36
|
-
|
|
37
|
-
@staticmethod
|
|
38
|
-
def create(connection_config_key: str) -> CollectionAddress:
|
|
39
|
-
"""Create a CollectionAddress for manual data: {connection_key}:manual_data"""
|
|
40
|
-
return CollectionAddress(
|
|
41
|
-
dataset=connection_config_key,
|
|
42
|
-
collection=ManualTaskAddress.MANUAL_DATA_COLLECTION,
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
@staticmethod
|
|
46
|
-
def is_manual_task_address(address: CollectionAddress) -> bool:
|
|
47
|
-
"""Check if address represents manual task data"""
|
|
48
|
-
if isinstance(address, str):
|
|
49
|
-
# Handle string format "connection_key:collection_name"
|
|
50
|
-
return address.endswith(f":{ManualTaskAddress.MANUAL_DATA_COLLECTION}")
|
|
51
|
-
|
|
52
|
-
# Handle CollectionAddress object
|
|
53
|
-
return address.collection == ManualTaskAddress.MANUAL_DATA_COLLECTION
|
|
54
|
-
|
|
55
|
-
@staticmethod
|
|
56
|
-
def get_connection_key(address: CollectionAddress) -> str:
|
|
57
|
-
"""Extract connection config key from manual task address"""
|
|
58
|
-
if not ManualTaskAddress.is_manual_task_address(address):
|
|
59
|
-
raise ValueError(f"Not a manual task address: {address}")
|
|
60
|
-
|
|
61
|
-
if isinstance(address, str):
|
|
62
|
-
# Handle string format "connection_key:collection_name"
|
|
63
|
-
return address.split(":")[0]
|
|
64
|
-
|
|
65
|
-
# Handle CollectionAddress object
|
|
66
|
-
return address.dataset
|
|
67
26
|
|
|
68
|
-
|
|
69
|
-
def get_connection_configs_with_manual_tasks(db: Session) -> List[ConnectionConfig]:
|
|
27
|
+
def get_connection_configs_with_manual_tasks(db: Session) -> list[ConnectionConfig]:
|
|
70
28
|
"""
|
|
71
29
|
Get all connection configs that have manual tasks.
|
|
72
30
|
"""
|
|
@@ -79,7 +37,7 @@ def get_connection_configs_with_manual_tasks(db: Session) -> List[ConnectionConf
|
|
|
79
37
|
)
|
|
80
38
|
|
|
81
39
|
|
|
82
|
-
def get_manual_task_addresses(db: Session) ->
|
|
40
|
+
def get_manual_task_addresses(db: Session) -> list[CollectionAddress]:
|
|
83
41
|
"""
|
|
84
42
|
Get manual task addresses for all connection configs that have manual tasks.
|
|
85
43
|
|
|
@@ -98,26 +56,20 @@ def get_manual_task_addresses(db: Session) -> List[CollectionAddress]:
|
|
|
98
56
|
return manual_task_addresses
|
|
99
57
|
|
|
100
58
|
|
|
101
|
-
def
|
|
59
|
+
def get_manual_task_for_connection_config(
|
|
102
60
|
db: Session, connection_config_key: str
|
|
103
|
-
) ->
|
|
104
|
-
"""Get
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
.filter(ConnectionConfig.key == connection_config_key)
|
|
108
|
-
.first()
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
if not connection_config:
|
|
112
|
-
return []
|
|
113
|
-
|
|
61
|
+
) -> ManualTask:
|
|
62
|
+
"""Get the ManualTask for a specific connection config,
|
|
63
|
+
the manual task/connection config relationship is 1:1.
|
|
64
|
+
"""
|
|
114
65
|
return (
|
|
115
66
|
db.query(ManualTask)
|
|
67
|
+
.join(ConnectionConfig, ManualTask.parent_entity_id == ConnectionConfig.id)
|
|
116
68
|
.filter(
|
|
117
|
-
|
|
69
|
+
ConnectionConfig.key == connection_config_key,
|
|
118
70
|
ManualTask.parent_entity_type == "connection_config",
|
|
119
71
|
)
|
|
120
|
-
.
|
|
72
|
+
.one_or_none()
|
|
121
73
|
)
|
|
122
74
|
|
|
123
75
|
|
|
@@ -130,24 +82,23 @@ def create_manual_data_traversal_node(
|
|
|
130
82
|
connection_key = address.dataset
|
|
131
83
|
|
|
132
84
|
# Get manual tasks for this connection to determine fields
|
|
133
|
-
|
|
85
|
+
manual_task = get_manual_task_for_connection_config(db, connection_key)
|
|
134
86
|
|
|
135
87
|
# Create fields based on ManualTaskConfigFields
|
|
136
|
-
fields:
|
|
137
|
-
for
|
|
138
|
-
for
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
fields.append(scalar_field)
|
|
88
|
+
fields: list[Field] = []
|
|
89
|
+
for config in manual_task.configs:
|
|
90
|
+
for field in config.field_definitions:
|
|
91
|
+
# Create a scalar field for each manual task field
|
|
92
|
+
# Extract data categories from field metadata if available
|
|
93
|
+
field_metadata = field.field_metadata or {}
|
|
94
|
+
data_categories = field_metadata.get("data_categories", [])
|
|
95
|
+
|
|
96
|
+
scalar_field = ScalarField(
|
|
97
|
+
name=field.field_key,
|
|
98
|
+
data_categories=data_categories,
|
|
99
|
+
# Manual task fields don't have complex relationships
|
|
100
|
+
)
|
|
101
|
+
fields.append(scalar_field)
|
|
151
102
|
|
|
152
103
|
# Create a synthetic Collection
|
|
153
104
|
collection = Collection(
|
|
@@ -165,9 +116,6 @@ def create_manual_data_traversal_node(
|
|
|
165
116
|
after=set(),
|
|
166
117
|
)
|
|
167
118
|
|
|
168
|
-
# Create Node and TraversalNode (import locally to avoid cyclic import)
|
|
169
|
-
from fides.api.graph.traversal import TraversalNode # local import
|
|
170
|
-
|
|
171
119
|
node = Node(dataset, collection)
|
|
172
120
|
traversal_node = TraversalNode(node)
|
|
173
121
|
|
|
@@ -176,7 +124,7 @@ def create_manual_data_traversal_node(
|
|
|
176
124
|
|
|
177
125
|
def create_manual_task_instances_for_privacy_request(
|
|
178
126
|
db: Session, privacy_request: PrivacyRequest
|
|
179
|
-
) ->
|
|
127
|
+
) -> list[ManualTaskInstance]:
|
|
180
128
|
"""Create ManualTaskInstance entries for all active manual tasks relevant to a privacy request."""
|
|
181
129
|
instances = []
|
|
182
130
|
|
|
@@ -272,7 +220,7 @@ def create_manual_task_instances_for_privacy_request(
|
|
|
272
220
|
|
|
273
221
|
def get_manual_task_instances_for_privacy_request(
|
|
274
222
|
db: Session, privacy_request: PrivacyRequest
|
|
275
|
-
) ->
|
|
223
|
+
) -> list[ManualTaskInstance]:
|
|
276
224
|
"""Get all manual task instances for a privacy request."""
|
|
277
225
|
return (
|
|
278
226
|
db.query(ManualTaskInstance)
|
|
@@ -286,7 +234,7 @@ def get_manual_task_instances_for_privacy_request(
|
|
|
286
234
|
|
|
287
235
|
def create_manual_task_artificial_graphs(
|
|
288
236
|
db: Session,
|
|
289
|
-
) ->
|
|
237
|
+
) -> list:
|
|
290
238
|
"""
|
|
291
239
|
Create artificial GraphDataset objects for manual tasks that can be included
|
|
292
240
|
in the main dataset graph during the dataset configuration phase.
|
|
@@ -313,34 +261,33 @@ def create_manual_task_artificial_graphs(
|
|
|
313
261
|
connection_key = address.dataset
|
|
314
262
|
|
|
315
263
|
# Get manual tasks for this connection to determine fields
|
|
316
|
-
|
|
264
|
+
manual_task = get_manual_task_for_connection_config(db, connection_key)
|
|
317
265
|
|
|
318
266
|
# Create fields based only on ManualTaskConfigFields
|
|
319
|
-
fields:
|
|
267
|
+
fields: list = []
|
|
320
268
|
|
|
321
269
|
# Manual task collections act as root nodes - they don't need identity dependencies
|
|
322
270
|
# since they provide manually-entered data rather than consuming identity data.
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
fields.append(scalar_field)
|
|
271
|
+
current_configs = [
|
|
272
|
+
config for config in manual_task.configs if config.is_current
|
|
273
|
+
]
|
|
274
|
+
for config in current_configs:
|
|
275
|
+
if config.config_type not in [
|
|
276
|
+
ManualTaskConfigurationType.access_privacy_request,
|
|
277
|
+
ManualTaskConfigurationType.erasure_privacy_request,
|
|
278
|
+
]:
|
|
279
|
+
continue
|
|
280
|
+
|
|
281
|
+
for field in config.field_definitions:
|
|
282
|
+
# Create a scalar field for each manual task field
|
|
283
|
+
field_metadata = field.field_metadata or {}
|
|
284
|
+
data_categories = field_metadata.get("data_categories", [])
|
|
285
|
+
|
|
286
|
+
scalar_field = ScalarField(
|
|
287
|
+
name=field.field_key,
|
|
288
|
+
data_categories=data_categories,
|
|
289
|
+
)
|
|
290
|
+
fields.append(scalar_field)
|
|
344
291
|
|
|
345
292
|
if fields: # Only create graph if there are fields
|
|
346
293
|
# Create a synthetic Collection
|
fides/api/util/cache.py
CHANGED
|
@@ -387,3 +387,8 @@ def get_queue_counts() -> Dict[str, int]:
|
|
|
387
387
|
logger.critical(exception)
|
|
388
388
|
queue_counts = {}
|
|
389
389
|
return queue_counts
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def get_all_masking_secret_keys(privacy_request_id: str) -> List[str]:
|
|
393
|
+
cache: FidesopsRedis = get_cache()
|
|
394
|
+
return cache.keys(f"id-{privacy_request_id}-masking-secret-*")
|