ethyca-fides 2.69.1rc0__py2.py3-none-any.whl → 2.76.0rc2__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.
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/METADATA +9 -6
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/RECORD +488 -361
- fides/_version.py +3 -3
- fides/api/alembic/alembic.ini +5 -1
- fides/api/alembic/migrations/env.py +7 -1
- fides/api/alembic/migrations/versions/0eef0016cf06_adding_oauth2_config_for_.py +69 -0
- fides/api/alembic/migrations/versions/303287c70600_migrate_resource_type_from_enum_to_.py +99 -0
- fides/api/alembic/migrations/versions/30369bb8ae01_add_webmonitorgroupjob_model.py +67 -0
- fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -0
- fides/api/alembic/migrations/versions/4bfbeff34611_add_polling_status.py +68 -0
- fides/api/alembic/migrations/versions/4d8c0fcc5771_adding_default_system_groups.py +78 -0
- fides/api/alembic/migrations/versions/5fa78b1f324d_add_event_audit_table.py +82 -0
- fides/api/alembic/migrations/versions/65a1bc82ae09_adds_experience_config_for_delete_.py +53 -0
- fides/api/alembic/migrations/versions/67d0e389b003_update_consentstatus_enum.py +47 -0
- fides/api/alembic/migrations/versions/795f46f656c0_migrate_field_type_from_enum_to_string.py +61 -0
- fides/api/alembic/migrations/versions/7db29f9cd77b_create_new_sub_request_table.py +95 -0
- fides/api/alembic/migrations/versions/918aefc950c9_create_digest_conditional_dependencies.py +125 -0
- fides/api/alembic/migrations/versions/9caf76161e55_make_user_assigned_data_uses_nullable_.py +64 -0
- fides/api/alembic/migrations/versions/9e0dcbf67b9f_add_digest_config.py +84 -0
- fides/api/alembic/migrations/versions/a55e12c2c2df_add_tagging_instructions_to_data_.py +29 -0
- fides/api/alembic/migrations/versions/a8e0c016afd_add_classification_benchmark_table.py +126 -0
- fides/api/alembic/migrations/versions/b97e92b038d2_add_digest_execution_model.py +117 -0
- fides/api/alembic/migrations/versions/b9bfa12c167b_add_not_applicable_to_asset_consentstatus.py +46 -0
- fides/api/alembic/migrations/versions/c09e76282dd1_add_privacy_request_duplication_cols.py +64 -0
- fides/api/alembic/migrations/versions/cd8649be3a2b_add_classifications_and_user_assigned_.py +74 -0
- fides/api/alembic/migrations/versions/e2cda8d6abc3_add_dismissed_in_activity_view_to_.py +29 -0
- fides/api/alembic/migrations/versions/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
- fides/api/alembic/migrations/versions/f36ce1bde293_add_system_groups.py +132 -0
- fides/api/alembic/migrations/versions/fd7571bef683_adds_new_fields_to_messagingconfig_for_.py +31 -0
- fides/api/alembic/migrations/versions/xx_2025_10_17_1603_5093e92e2a5a_add_consent_data_v3_to_the_database.py +72 -0
- fides/api/alembic/migrations/versions/xx_2025_10_27_1834_67f0f2f4748e_adding_identity_definition_model.py +45 -0
- fides/api/alembic/migrations/versions/xx_2025_10_29_1659_80d28dea3b6b_added_duplicate_group_table.py +79 -0
- fides/api/alembic/migrations/versions/xx_2025_11_05_0200_f1a2b3c4d5e6_create_staged_resource_error_table.py +82 -0
- fides/api/alembic/migrations/versions/xx_2025_11_07_1709_56fe6fad2d89_add_notice_display_order.py +47 -0
- fides/api/alembic/migrations/versions/xx_2025_11_10_1200_a1b2c3d4e5f6_add_test_datastore_to_connectiontype.py +53 -0
- fides/api/alembic/migrations/versions/xx_2025_11_11_1317_7d82c8fc4c34_store_saas_template_datasets.py +68 -0
- fides/api/alembic/migrations/versions/xx_2025_11_12_1430_b2c3d4e5f6a7_add_default_identity_definitions.py +81 -0
- fides/api/alembic/migrations/versions/xx_2025_11_25_1854_3ff6449c099e_add_index_on_providedidentity_privacy_.py +50 -0
- fides/api/api/v1/api.py +2 -0
- fides/api/api/v1/endpoints/admin.py +39 -0
- fides/api/api/v1/endpoints/connection_endpoints.py +191 -47
- fides/api/api/v1/endpoints/connector_template_endpoints.py +167 -0
- fides/api/api/v1/endpoints/generic_overrides.py +90 -15
- fides/api/api/v1/endpoints/messaging_endpoints.py +164 -34
- fides/api/api/v1/endpoints/pre_approval_webhook_endpoints.py +5 -5
- fides/api/api/v1/endpoints/privacy_request_endpoints.py +231 -46
- fides/api/api/v1/endpoints/saas_config_endpoints.py +63 -92
- fides/api/api/v1/endpoints/storage_endpoints.py +5 -1
- fides/api/api/v1/endpoints/system.py +157 -100
- fides/api/api/v1/endpoints/user_endpoints.py +17 -4
- fides/api/app_setup.py +1 -3
- fides/api/common_exceptions.py +8 -0
- fides/api/db/base.py +8 -0
- fides/api/db/crud.py +30 -2
- fides/api/db/database.py +261 -4
- fides/api/db/safe_crud.py +377 -0
- fides/api/db/seed.py +35 -1
- fides/api/email_templates/get_email_template.py +3 -0
- fides/api/email_templates/template_names.py +1 -0
- fides/api/email_templates/templates/external_user_welcome.html +9 -5
- fides/api/email_templates/templates/manual_task_digest.html +316 -0
- fides/api/main.py +2 -0
- fides/api/migrations/post_upgrade_index_creation.py +20 -0
- fides/api/models/asset.py +17 -1
- fides/api/models/attachment.py +1 -0
- fides/api/models/conditional_dependency/__init__.py +0 -0
- fides/api/models/conditional_dependency/conditional_dependency_base.py +311 -0
- fides/api/models/connection_oauth_credentials.py +57 -0
- fides/api/models/connectionconfig.py +11 -1
- fides/api/models/detection_discovery/__init__.py +4 -0
- fides/api/models/detection_discovery/classification_benchmark.py +140 -0
- fides/api/models/detection_discovery/core.py +78 -3
- fides/api/models/detection_discovery/monitor_task.py +3 -1
- fides/api/models/detection_discovery/staged_resource_error.py +25 -0
- fides/api/models/detection_discovery/web_monitor.py +61 -0
- fides/api/models/digest/__init__.py +16 -0
- fides/api/models/digest/conditional_dependencies.py +275 -0
- fides/api/models/digest/digest_config.py +110 -0
- fides/api/models/digest/digest_execution.py +142 -0
- fides/api/models/event_audit.py +85 -0
- fides/api/models/experience_notices.py +6 -1
- fides/api/models/fides_user.py +9 -0
- fides/api/models/identity_definition.py +66 -0
- fides/api/models/location_regulation_selections.py +22 -0
- fides/api/models/manual_task/conditional_dependency.py +29 -87
- fides/api/models/manual_webhook.py +17 -6
- fides/api/models/messaging.py +30 -10
- fides/api/models/messaging_template.py +14 -0
- fides/api/models/policy.py +27 -0
- fides/api/models/privacy_experience.py +41 -0
- fides/api/models/privacy_notice.py +196 -13
- fides/api/models/privacy_preference.py +2 -0
- fides/api/models/privacy_request/duplicate_group.py +84 -0
- fides/api/models/privacy_request/privacy_request.py +154 -8
- fides/api/models/privacy_request/provided_identity.py +22 -1
- fides/api/models/privacy_request/request_task.py +98 -1
- fides/api/models/privacy_request/webhook.py +3 -1
- fides/api/models/saas_template_dataset.py +63 -0
- fides/api/models/sql_models.py +161 -7
- fides/api/models/system_group.py +85 -0
- fides/api/models/taxonomy.py +91 -9
- fides/api/models/v3/__init__.py +0 -0
- fides/api/models/v3/privacy_preferences.py +85 -0
- fides/api/models/worker_task.py +8 -0
- fides/api/oauth/roles.py +4 -0
- fides/api/schemas/application_config.py +32 -1
- fides/api/schemas/connection_configuration/connection_config.py +1 -30
- fides/api/schemas/connection_configuration/connection_oauth_config.py +42 -0
- fides/api/schemas/connection_configuration/connection_secrets_mongodb.py +15 -3
- fides/api/schemas/connection_configuration/connection_secrets_mssql.py +5 -0
- fides/api/schemas/messaging/messaging.py +49 -66
- fides/api/schemas/messaging/messaging_secrets_docs_only.py +1 -1
- fides/api/schemas/messaging/shared_schemas.py +102 -0
- fides/api/schemas/oauth.py +2 -1
- fides/api/schemas/privacy_center_config.py +29 -5
- fides/api/schemas/privacy_request.py +44 -7
- fides/api/schemas/saas/async_polling_configuration.py +81 -0
- fides/api/schemas/saas/connector_template.py +14 -0
- fides/api/schemas/saas/saas_config.py +12 -20
- fides/api/schemas/system.py +8 -0
- fides/api/schemas/taxonomy_extensions.py +8 -0
- fides/api/schemas/user.py +2 -2
- fides/api/service/async_dsr/handlers/__init__.py +0 -0
- fides/api/service/async_dsr/handlers/polling_attachment_handler.py +155 -0
- fides/api/service/async_dsr/handlers/polling_request_handler.py +88 -0
- fides/api/service/async_dsr/handlers/polling_response_handler.py +261 -0
- fides/api/service/async_dsr/handlers/polling_sub_request_handler.py +123 -0
- fides/api/service/async_dsr/strategies/__init__.py +0 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy.py +52 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_callback.py +199 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_factory.py +72 -0
- fides/api/service/async_dsr/strategies/async_dsr_strategy_polling.py +691 -0
- fides/api/service/async_dsr/utils.py +130 -0
- fides/api/service/connectors/base_erasure_email_connector.py +7 -0
- fides/api/service/connectors/bigquery_connector.py +34 -16
- fides/api/service/connectors/fides/fides_client.py +63 -1
- fides/api/service/connectors/http_connector.py +48 -12
- fides/api/service/connectors/microsoft_sql_server_connector.py +6 -1
- fides/api/service/connectors/mongodb_connector.py +74 -9
- fides/api/service/connectors/query_configs/saas_query_config.py +160 -79
- fides/api/service/connectors/saas/connector_registry_service.py +42 -135
- fides/api/service/connectors/saas_connector.py +116 -76
- fides/api/service/connectors/sql_connector.py +14 -4
- fides/api/service/deps.py +25 -2
- fides/api/service/messaging/message_dispatch_service.py +98 -20
- fides/api/service/messaging/messaging_crud_service.py +5 -9
- fides/api/service/privacy_request/attachment_handling.py +9 -2
- fides/api/service/privacy_request/dsr_package/dsr_report_builder.py +17 -9
- fides/api/service/privacy_request/dsr_package/templates/attachments_index.html +41 -30
- fides/api/service/privacy_request/dsr_package/templates/clickme.html +68 -0
- fides/api/service/privacy_request/dsr_package/templates/dataset_index.html +30 -27
- fides/api/service/privacy_request/duplication_detection.py +439 -0
- fides/api/service/privacy_request/email_batch_service.py +2 -1
- fides/api/service/privacy_request/request_runner_service.py +92 -91
- fides/api/service/privacy_request/request_service.py +74 -90
- fides/api/service/saas_request/saas_request_override_factory.py +71 -1
- fides/api/service/storage/streaming/schemas.py +27 -19
- fides/api/service/storage/streaming/smart_open_client.py +2 -2
- fides/api/service/storage/streaming/smart_open_streaming_storage.py +238 -147
- fides/api/service/storage/util.py +20 -106
- fides/api/service/strategy.py +6 -3
- fides/api/task/conditional_dependencies/privacy_request/__init__.py +0 -0
- fides/api/task/conditional_dependencies/privacy_request/convenience_fields.py +155 -0
- fides/api/task/conditional_dependencies/privacy_request/privacy_request_data.py +140 -0
- fides/api/task/conditional_dependencies/privacy_request/schemas.py +212 -0
- fides/api/task/conditional_dependencies/sql_schemas.py +301 -0
- fides/api/task/conditional_dependencies/sql_translator.py +757 -0
- fides/api/task/conditional_dependencies/util.py +111 -0
- fides/api/task/execute_request_tasks.py +34 -13
- fides/api/task/filter_results.py +35 -2
- fides/api/task/graph_runners.py +2 -32
- fides/api/task/graph_task.py +42 -12
- fides/api/task/manual/manual_task_conditional_evaluation.py +33 -28
- fides/api/task/manual/manual_task_graph_task.py +4 -1
- fides/api/task/manual/manual_task_utils.py +68 -26
- fides/api/task/scheduler_utils.py +39 -0
- fides/api/tasks/__init__.py +15 -1
- fides/api/util/cache.py +5 -1
- fides/api/util/connection_util.py +101 -218
- fides/api/util/event_audit_util.py +230 -0
- fides/api/util/filter_utils.py +0 -3
- fides/api/util/fuzzy_search_utils.py +7 -1
- fides/api/util/lock.py +13 -3
- fides/api/util/logger.py +58 -4
- fides/api/util/logger_context_utils.py +3 -1
- fides/api/util/masking_util.py +31 -0
- fides/api/util/memory_watchdog.py +118 -0
- fides/api/util/rate_limit.py +25 -7
- fides/api/util/saas_config_updater.py +76 -0
- fides/api/util/saas_util.py +28 -1
- fides/api/worker/__init__.py +6 -0
- fides/common/api/scope_registry.py +6 -7
- fides/common/api/v1/urn_registry.py +15 -3
- fides/config/__init__.py +11 -2
- fides/config/celery_settings.py +42 -0
- fides/config/config_proxy.py +10 -0
- fides/config/duplicate_detection_settings.py +31 -0
- fides/config/execution_settings.py +6 -6
- fides/config/security_settings.py +4 -1
- fides/config/utils.py +5 -0
- fides/data/language/languages.yml +2 -0
- fides/service/connection/__init__.py +0 -0
- fides/service/connection/connection_service.py +651 -0
- fides/service/dataset/dataset_service.py +39 -0
- fides/service/event_audit_service.py +109 -0
- fides/service/messaging/aws_ses_service.py +2 -4
- fides/service/messaging/messaging_service.py +75 -74
- fides/service/privacy_request/privacy_request_service.py +345 -100
- fides/service/system/__init__.py +0 -0
- fides/service/system/system_service.py +153 -0
- fides/service/taxonomy/handlers/legacy_handler.py +3 -3
- fides/service/taxonomy/taxonomy_service.py +64 -18
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-688fa865621531cc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1115-7fd171dac1eb0e51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1276.deb10ae2643f8463.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1438-8a33b3834d6e43f3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6148-59a59d5c5925344f.js → 1533-84e250d1f26e6d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1821-c1daa160f492aacf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1840-359ee056e4cf6629.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{1975.78e719130cfe3fd6.js → 1975.bef017bc80e2012c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/2040-70972e15960d9afe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2121.321b0fd3932164d4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2397-3434603a97f3f5d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/2921-49ed0ed897832958.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3150-da5406b80d25fe6d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3214-90ce0a366b0f461a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3377-02bf9780fd383d94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3615-5e2d062d684b8fa1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3655-5e1ba5dd68b5ec48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3729-31ff8ba51491bf21.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3872-cff30ca0844fe2b1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/3931-8bedde156fe83564.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/401-582d9970d89deefe.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4093-7e47408c28de5375.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4259.d1507e0db19cbed7.js → 4259.05038c9b78467244.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/431-e01ee730c8ad9ece.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4322-f6aeff6880726c83.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4339-04a715ab07122744.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4496-ccbce2459174e0d6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/454-d5c2c84f1a14e4f1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4589-c1d83c6a8dab4d30.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4809-a8f4a108a42f53ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4903-19c0bc07a956dfa8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4910-d990773601f794c1.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5185-96423702fba70ced.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5258-4e308cca01d59367.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5487-5c3501754bf027ba.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/549-1bdc3e6f3264c020.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5505-43b9c39491b88e08.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5698.2135391a128cc373.js +164 -0
- fides/ui-build/static/admin/_next/static/chunks/5783-016dfcee8e49bf61.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5826-4db99ea4e5077911.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/590-be447cacf12419dd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6084-91badbc6569a0efb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6344-026cb323c1d49926.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6362-ba0e12f2fc4cad94.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6853-882889659769d7b4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6882-bb1b469d7d7f5335.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6954-0dcf22a9aabe39c5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7170-46db82bb5b55e856.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7218-2ace8c82e3e7eb74.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7245-1cdafb35f289861b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7630-7f75ab7b8df42eb3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/7654-2e9a8be02e41769a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/8212-348ddd2b6933db70.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9014-eeae6f581158e645.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5596-bb601cbf40e47a0f.js → 9195-da717d324917b049.js} +3 -3
- fides/ui-build/static/admin/_next/static/chunks/9450-b7b7bb1d755ecf57.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{9676.9fd9552ef744c717.js → 9676.1f395eeb9cc34968.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-1078e46f3ac0b688.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/9911-ece086f2230e34f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{404-471a6b18e712f050.js → 404-800be6996aaa999c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-fcdad91f6f66292b.js → _app-de4b578c904df772.js} +57 -220
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-f12020b82dd4bd1a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-a911b7990371704d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-ad585b79953c2753.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure/{add-vendors-406170eaae4329c6.js → add-vendors-bb263d394ca1c8fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-6907c368d8611c44.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-f80cf2d3966816fd.js → [id]-c32f381af358149b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-6efb3c069d8b47dd.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-1975c529905eea9b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-b378576cba255609.js → [id]-b05331178928ab52.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-2ca1de7b88094ab0.js → new-516834e930bb0d0d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-985717f2565f9d9d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{properties-226efa1dcd41437f.js → properties-2be773e08498e40c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-850afb74f4192e87.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-b63d1e395d879b86.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-5b28f0f674ea87bd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/{[projectUrn]-04cfe2cfba7b7cd8.js → [projectUrn]-676177e2f3c9c2a2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-794906929efb8e1d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-3ccbf7c0d06507b9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-1ea0b24d306b1e67.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore/[monitorId]-d4861a4a218bb65a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/datastore-4498881c26f1458d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure/[monitorId]-66bd265044daf97d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/infrastructure-c9c79fa8576a4f77.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]/[systemId]-60cacc3232c2eead.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website/[monitorId]-437bd64a3016de36.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/website-5b3e0009d442bc3f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-8349248c2da970a6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-6919a1d6cadaa46b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/detection/{[resourceUrn]-8f736b078e9842da.js → [resourceUrn]-1a50d421897d3da1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{detection-eb814e3c22807871.js → detection-49509414a15e8393.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/discovery/{[resourceUrn]-6875b7783fcfda2f.js → [resourceUrn]-1a1bb80b586d0c0f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{discovery-172dbd7740e212ca.js → discovery-49de61df1e8e7fba.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c2719f5cff20c0f8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-dfd71c1e9c458b89.js → [...subfieldNames]-415015aebab60436.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-7cdc42ec5493b83d.js → [collectionName]-5accb09715b5122d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-aebecca1d8ec5f98.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-9551a82ddec9f909.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-72f8fe47beef0f09.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-3a8aa3f633528e88.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-87512616f35ec6da.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-2f1bf4eac7aa55fd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{fides-js-docs-1f4335dca5c09860.js → fides-js-docs-5235760b3e508d7d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-8d67cd2872cb682a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-7a631df29cd0e31a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-ea3bc43cdaf273de.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/new-privacy-requests-5d8632bba1b81cd4.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/[id]-92e01822ecde8fb8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests/new-1256cf6d3f6794e0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/digests-0daac00911d27617.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/[key]-2d976fe5e8ba0a3a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers/new-7766ba497b863740.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/providers-f2880d2ed4734270.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/[id]-669f585c3458faff.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates/add-template-c79e7724e4bc3899.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications/templates-891654e8dc13965c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/notifications-40c8148244c5d347.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-1e86f3e28bd23ed6.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-9b7bd8c38f02c091.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-b18a53a940cf9e19.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-6d028d7450e77578.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-8399083ee2cd8cc2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-0a910125cdb2b3b8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-acc90b6f7fe915cb.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-bbc42026f2685438.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-c08ca6ad21c99799.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-77c2db582f8823bc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{[id]-e784c05d056b2371.js → [id]-74ccea4868408e3d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/properties/{add-property-0a7a2db148a7561a.js → add-property-7d9f09bfe9d44dfc.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{properties-da734840e4f9d04b.js → properties-cd77bc30672bb1fa.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-cc3bd9540132d5ed.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/sandbox/privacy-notices-7ce7d720107ab4b5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-68eaac2d79133679.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-6c4904c157477285.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-ae789892343c24f5.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-13ee1b331ced0846.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/[id]-ee4e43692336a330.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields/new-ca51d794abfcbf25.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-ecd1dc5db8e81409.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-df06f7e2f668c540.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-da0c77bd510c6c51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-950b0c115bf673d8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{locations-2e635dcd11b78224.js → locations-7e36cb4756973a9d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-a0e5ed486d24ccf3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-3cdebafb6870d3ad.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{regulations-7c02e469d8c5bd74.js → regulations-159aad34f1021320.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-dbd1a64090ad0946.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-7d042497a57a3788.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-21f1172e73dfc9f0.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-e553161e6338ee48.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-92f52c43f522a350.js → new-efc4af017723e57a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-64452dfae2c5e614.js → [id]-b152319d67372ee4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-dba8692491f7935e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/webpack-09ca52bc7beb0b43.js +1 -0
- fides/ui-build/static/admin/_next/static/css/012b10627a654d5c.css +1 -0
- fides/ui-build/static/admin/_next/static/css/05d05fc31d09638b.css +1 -0
- fides/ui-build/static/admin/_next/static/css/0fd6e0884cfcc5f3.css +1 -0
- fides/ui-build/static/admin/_next/static/css/14ba79c49597d37a.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{34a7eb08b86ddb57.css → 3d6582469f7d56e0.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/3d66bb57ddcb0978.css +1 -0
- fides/ui-build/static/admin/_next/static/css/4861ca3e088f2d05.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1800714b486e230.css +1 -0
- fides/ui-build/static/admin/_next/static/css/a1e4be9466578ef1.css +1 -0
- fides/ui-build/static/admin/_next/static/css/af32fcac7a177a0e.css +1 -0
- fides/ui-build/static/admin/_next/static/css/cb417f0587918f85.css +1 -0
- fides/ui-build/static/admin/_next/static/css/dd15c278b964de80.css +1 -0
- fides/ui-build/static/admin/_next/static/css/{5f393dea1c0d031c.css → f89607996ad54f4b.css} +1 -1
- fides/ui-build/static/admin/_next/static/css/f9a2a44d3d34c904.css +1 -0
- fides/ui-build/static/admin/_next/static/l2vgGUHB04Fi4oEVlVMrc/_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/datastore/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/datastore.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/infrastructure.html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId]/[systemId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website/[monitorId].html +1 -0
- fides/ui-build/static/admin/data-discovery/action-center/website.html +1 -0
- 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/new-privacy-requests.html +1 -0
- fides/ui-build/static/admin/notifications/digests/[id].html +1 -0
- fides/ui-build/static/admin/notifications/digests/new.html +1 -0
- fides/ui-build/static/admin/notifications/digests.html +1 -0
- fides/ui-build/static/admin/notifications/providers/[key].html +1 -0
- fides/ui-build/static/admin/notifications/providers/new.html +1 -0
- fides/ui-build/static/admin/notifications/providers.html +1 -0
- fides/ui-build/static/admin/notifications/templates/[id].html +1 -0
- fides/ui-build/static/admin/notifications/templates/add-template.html +1 -0
- fides/ui-build/static/admin/notifications/templates.html +1 -0
- fides/ui-build/static/admin/notifications.html +1 -0
- 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/privacy-requests/[id].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/sandbox/privacy-notices.html +1 -0
- 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/[id].html +1 -0
- fides/ui-build/static/admin/settings/custom-fields/new.html +1 -0
- 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/privacy-requests.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/service/async_dsr/async_dsr_service.py +0 -75
- fides/api/service/privacy_request/dsr_package/templates/welcome.html +0 -66
- fides/ui-build/static/admin/_next/static/OmXHlY9MvjoZH9jDkAytl/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1099-79646e64f26d62fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1316-2606e19807c08aa5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1345-5e1c5b66e25c566e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1467-8808ec8836e033f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-0ca16d288fad916d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2150-930ffaf2c4718edc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/255-1bc0cbef7a59cdc6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/2921-52328140bc420d0f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/346-aa3b88efb85f2e28.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3550-d04125c828d591a1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3620-602eb74dc896d556.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3729-c17ac8031a4c4fd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3847-230bf61b053bc706.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-ef5194cdb228beb6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3872-f78dec02f0d959ae.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3923-bb2417b8dcade7a4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/401-4af0a912e249d30f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4164-355644b916ae0094.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/431-86ad2beeb93c95c9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-be8cba73f5d7c326.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4786-61154adf88e448e1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4808-dd4157aa72648068.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4831-fd99c0b3784de128.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4844-46324c3d848b8b6a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5163-e682273cd76a7d07.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5258-b0de22a8521686ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5487-02d00bad7c6830e0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/549-38ea1d91ee2addaa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5619-9b50cec521203989.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6084-c153669d5567e242.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6419-d0c00d661b01f8fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6853-b17673391117c976.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6954-5296188c19d7d0ac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/699-8ca44b0de9fa20f0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7476-45c5088baa8b66af.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/7630-7ed6c6117775dffe.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/787-a8c7eab617e2fceb.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/79-65674011d455af4d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/796-9e1ca1a4030707c5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8002-24af20d679efc04e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/8765-f622a35b40a7ec63.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9046-712156d461165f56.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9187-7438242f0d380bb0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9278-08cc704317fe535e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9729-fcf6ff4e3534e4a8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9826-dbae8dee941a7fac.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9951-a88367a129b724ba.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/manual-ace203dfacacbdc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/multiple-920fb469e0dda1d2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-bd0d82078e67cac3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/configure-7207ab23bdb36ce8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-9dda4de5ec580279.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-0d4844d0b808e6e4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-28b192e2c074b0f3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent-3e8bdefe714254ec.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2c29ff7a01198f30.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/projects-5f2d7b24804f861f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-8eb581024bc0172f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog-30108b00ac769fc3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-e1ba213fb666b3f4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-6d133580045abdda.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center-9a81d42a474e1e48.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-b6ae7adb8ef0b525.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-c7390e046b2e2b7f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]-e12b11ba15bc3fc1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-e32fccc4ca520d2b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset-7c59a6abf6ba6207.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/[id]-927b7e476c4b47d0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/new-cbe100d50df34285.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-cce20440b177050b.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/index-6cd8708106331b8d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-4c3c413a2668df53.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-95402b5001c07ef2.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/[id]-3c6dc2f6e6bae960.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging/add-template-4a6d4023a7791be8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/messaging-76b204c9b98d656f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/ant-components-bc0e2adf6e0d3ac7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/AntForm-86ffcc1ad3fa912e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikAntFormItem-ec04f595465bdf69.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikControlled-41d309754ff0c1de.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/form-experiments/FormikField-cab1f78cec7808f9.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/forms-eb6058221403b156.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/poc/table-migration-48500551fd6a7602.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/[id]-0f25a76dd18c5e20.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/messaging-ad6ad3e5bd72765d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-6032d82f0fc2893d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure-d83e5bd52a638234.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests-baf31c3e4b081046.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/datamap-6903f42a0412bfa6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about/alpha-a82f3df840d5c1b5.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/about-d06fb16487705b9d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-9495e2eb506606c7.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-93a978443bf299db.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-9ecb803099082bf4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domain-records-16fdd91a81074dd1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/domains-4cdd6001e7cb9aee.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/email-templates-1914de830ce5cfc4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/organization-f547f1f33c12faf3.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/privacy-requests-2ecc073f41628f62.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/test-datasets-20b1193ed76c56b0.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]-6e15332935f6b538.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-fbc8761ef4d55516.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-4d7827fc9c46b6b8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management-9cec020f89544426.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/webpack-678e89d68dbcd94f.js +0 -1
- fides/ui-build/static/admin/_next/static/css/073713cd1eddda79.css +0 -1
- fides/ui-build/static/admin/_next/static/css/23cf870196941c9a.css +0 -1
- fides/ui-build/static/admin/_next/static/css/304c6f148886a8d4.css +0 -1
- fides/ui-build/static/admin/_next/static/css/650df9c348000a26.css +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +0 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +0 -1
- fides/ui-build/static/admin/messaging/[id].html +0 -1
- fides/ui-build/static/admin/messaging/add-template.html +0 -1
- fides/ui-build/static/admin/messaging.html +0 -1
- fides/ui-build/static/admin/poc/table-migration.html +0 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +0 -1
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.69.1rc0.dist-info → ethyca_fides-2.76.0rc2.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/data-catalog/[systemId]/{resources-de704de849960f01.js → resources-81d1b50585468fb0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{OmXHlY9MvjoZH9jDkAytl → l2vgGUHB04Fi4oEVlVMrc}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
from datetime import datetime, timedelta, timezone
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from uuid import UUID
|
|
4
|
+
|
|
5
|
+
from loguru import logger
|
|
6
|
+
from sqlalchemy.orm import Session, defer
|
|
7
|
+
|
|
8
|
+
from fides.api.models.privacy_request.duplicate_group import (
|
|
9
|
+
DuplicateGroup,
|
|
10
|
+
generate_rule_version,
|
|
11
|
+
)
|
|
12
|
+
from fides.api.models.privacy_request.privacy_request import PrivacyRequest
|
|
13
|
+
from fides.api.schemas.policy import ActionType
|
|
14
|
+
from fides.api.schemas.privacy_request import PrivacyRequestStatus
|
|
15
|
+
from fides.api.task.conditional_dependencies.schemas import (
|
|
16
|
+
Condition,
|
|
17
|
+
ConditionGroup,
|
|
18
|
+
ConditionLeaf,
|
|
19
|
+
GroupOperator,
|
|
20
|
+
Operator,
|
|
21
|
+
)
|
|
22
|
+
from fides.api.task.conditional_dependencies.sql_translator import (
|
|
23
|
+
SQLConditionTranslator,
|
|
24
|
+
)
|
|
25
|
+
from fides.config.config_proxy import ConfigProxy
|
|
26
|
+
from fides.config.duplicate_detection_settings import DuplicateDetectionSettings
|
|
27
|
+
|
|
28
|
+
ACTIONED_REQUEST_STATUSES = [
|
|
29
|
+
PrivacyRequestStatus.approved,
|
|
30
|
+
PrivacyRequestStatus.in_processing,
|
|
31
|
+
PrivacyRequestStatus.requires_manual_finalization,
|
|
32
|
+
PrivacyRequestStatus.requires_input,
|
|
33
|
+
PrivacyRequestStatus.paused,
|
|
34
|
+
PrivacyRequestStatus.awaiting_email_send,
|
|
35
|
+
PrivacyRequestStatus.error,
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class DuplicateDetectionService:
|
|
40
|
+
def __init__(self, db: Session):
|
|
41
|
+
self.db = db
|
|
42
|
+
self._config = ConfigProxy(db).privacy_request_duplicate_detection
|
|
43
|
+
|
|
44
|
+
def is_enabled(self) -> bool:
|
|
45
|
+
return self._config.enabled
|
|
46
|
+
|
|
47
|
+
def _create_identity_conditions(
|
|
48
|
+
self, current_request: PrivacyRequest
|
|
49
|
+
) -> list[Condition]:
|
|
50
|
+
"""Creates conditions for matching identity fields.
|
|
51
|
+
|
|
52
|
+
For identity field matching using the EAV pattern in ProvidedIdentity, we need to match both field_name
|
|
53
|
+
and hashed_value. This function creates the required nested conditions for each identity field.
|
|
54
|
+
Also adds a condition for the policy_id to ensure that we are only matching requests for the same policy.
|
|
55
|
+
"""
|
|
56
|
+
conditions: list[Condition] = []
|
|
57
|
+
current_identities: dict[str, str] = {
|
|
58
|
+
pi.field_name: pi.hashed_value
|
|
59
|
+
for pi in current_request.provided_identities # type: ignore [attr-defined]
|
|
60
|
+
if pi.field_name in self._config.match_identity_fields
|
|
61
|
+
}
|
|
62
|
+
if len(current_identities) != len(self._config.match_identity_fields):
|
|
63
|
+
missing_fields = [
|
|
64
|
+
field
|
|
65
|
+
for field in self._config.match_identity_fields
|
|
66
|
+
if field not in current_identities.keys()
|
|
67
|
+
]
|
|
68
|
+
logger.debug(
|
|
69
|
+
f"Some identity fields were not found in the current request: {missing_fields}"
|
|
70
|
+
)
|
|
71
|
+
return []
|
|
72
|
+
|
|
73
|
+
for field_name, hashed_value in current_identities.items():
|
|
74
|
+
identity_condition = ConditionGroup(
|
|
75
|
+
logical_operator=GroupOperator.and_,
|
|
76
|
+
conditions=[
|
|
77
|
+
ConditionLeaf(
|
|
78
|
+
field_address="privacyrequest.provided_identities.field_name",
|
|
79
|
+
operator=Operator.eq,
|
|
80
|
+
value=field_name,
|
|
81
|
+
),
|
|
82
|
+
ConditionLeaf(
|
|
83
|
+
field_address="privacyrequest.provided_identities.hashed_value",
|
|
84
|
+
operator=Operator.eq,
|
|
85
|
+
value=hashed_value,
|
|
86
|
+
),
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
conditions.append(identity_condition)
|
|
90
|
+
policy_condition = ConditionLeaf(
|
|
91
|
+
field_address="privacyrequest.policy_id",
|
|
92
|
+
operator=Operator.eq,
|
|
93
|
+
value=current_request.policy_id,
|
|
94
|
+
)
|
|
95
|
+
conditions.append(policy_condition)
|
|
96
|
+
return conditions
|
|
97
|
+
|
|
98
|
+
def _create_time_window_condition(self, time_window_days: int) -> Condition:
|
|
99
|
+
"""Creates a condition for matching requests within a time window."""
|
|
100
|
+
cutoff_date = datetime.now(timezone.utc) - timedelta(days=time_window_days)
|
|
101
|
+
condition = ConditionLeaf(
|
|
102
|
+
field_address="privacyrequest.created_at",
|
|
103
|
+
operator=Operator.gte,
|
|
104
|
+
value=cutoff_date.isoformat(),
|
|
105
|
+
)
|
|
106
|
+
return condition
|
|
107
|
+
|
|
108
|
+
def create_duplicate_detection_conditions(
|
|
109
|
+
self,
|
|
110
|
+
current_request: PrivacyRequest,
|
|
111
|
+
) -> Optional[ConditionGroup]:
|
|
112
|
+
"""
|
|
113
|
+
Create conditions for duplicate detection based on configuration.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
current_request: The current privacy request to find duplicates for
|
|
117
|
+
config: Duplicate detection configuration settings
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
A ConditionGroup with AND operator, or None if no conditions can be created
|
|
121
|
+
"""
|
|
122
|
+
if len(self._config.match_identity_fields) == 0:
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
identity_conditions = self._create_identity_conditions(current_request)
|
|
126
|
+
if not identity_conditions:
|
|
127
|
+
return None # Only proceed if we have identity conditions
|
|
128
|
+
|
|
129
|
+
time_window_condition = self._create_time_window_condition(
|
|
130
|
+
self._config.time_window_days
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Combine all conditions with AND operator
|
|
134
|
+
all_conditions: list[Condition] = [*identity_conditions, time_window_condition]
|
|
135
|
+
return ConditionGroup(
|
|
136
|
+
logical_operator=GroupOperator.and_, conditions=all_conditions
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
def find_duplicate_privacy_requests(
|
|
140
|
+
self,
|
|
141
|
+
current_request: PrivacyRequest,
|
|
142
|
+
) -> list[PrivacyRequest]:
|
|
143
|
+
"""
|
|
144
|
+
Find potential duplicate privacy requests based on duplicate detection configuration.
|
|
145
|
+
|
|
146
|
+
Uses the SQLConditionTranslator to build queries from conditions, which handles
|
|
147
|
+
the ProvidedIdentity relationship using SQLAlchemy's .any() method.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
current_request: The privacy request to check for duplicates
|
|
151
|
+
config: Duplicate detection configuration settings
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
List of PrivacyRequest objects that match the duplicate criteria,
|
|
155
|
+
does not include the current request
|
|
156
|
+
"""
|
|
157
|
+
condition = self.create_duplicate_detection_conditions(current_request)
|
|
158
|
+
|
|
159
|
+
if condition is None:
|
|
160
|
+
return []
|
|
161
|
+
|
|
162
|
+
translator = SQLConditionTranslator(self.db)
|
|
163
|
+
query = translator.generate_query_from_condition(condition)
|
|
164
|
+
|
|
165
|
+
query = query.filter(PrivacyRequest.id != current_request.id).filter(
|
|
166
|
+
PrivacyRequest.deleted_at.is_(None)
|
|
167
|
+
)
|
|
168
|
+
# Apply defer options to prevent loading large columns when checking for duplicates
|
|
169
|
+
# pylint: disable=protected-access
|
|
170
|
+
query = query.options(
|
|
171
|
+
defer(PrivacyRequest._filtered_final_upload),
|
|
172
|
+
defer(PrivacyRequest.access_result_urls),
|
|
173
|
+
)
|
|
174
|
+
return query.all()
|
|
175
|
+
|
|
176
|
+
def generate_dedup_key(self, request: PrivacyRequest) -> str:
|
|
177
|
+
"""
|
|
178
|
+
Generate a dedup key for a request based on the duplicate detection settings.
|
|
179
|
+
"""
|
|
180
|
+
current_identities: dict[str, str] = {
|
|
181
|
+
pi.field_name: pi.hashed_value
|
|
182
|
+
for pi in request.provided_identities # type: ignore [attr-defined]
|
|
183
|
+
if pi.field_name in self._config.match_identity_fields
|
|
184
|
+
}
|
|
185
|
+
if len(current_identities) != len(self._config.match_identity_fields):
|
|
186
|
+
raise ValueError(
|
|
187
|
+
"This request does not contain the required identity fields for duplicate detection."
|
|
188
|
+
)
|
|
189
|
+
return "|".join(
|
|
190
|
+
[
|
|
191
|
+
current_identities[field]
|
|
192
|
+
for field in sorted(self._config.match_identity_fields)
|
|
193
|
+
]
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
def update_duplicate_group_ids(
|
|
197
|
+
self,
|
|
198
|
+
request: PrivacyRequest,
|
|
199
|
+
duplicates: list[PrivacyRequest],
|
|
200
|
+
duplicate_group_id: UUID,
|
|
201
|
+
) -> None:
|
|
202
|
+
"""
|
|
203
|
+
Update the duplicate request group ids for a request and its duplicates.
|
|
204
|
+
Args:
|
|
205
|
+
request: The privacy request to update
|
|
206
|
+
duplicates: The list of duplicate requests to update
|
|
207
|
+
duplicate_group_id: The duplicate request group id to update
|
|
208
|
+
"""
|
|
209
|
+
update_all = [request] + duplicates
|
|
210
|
+
try:
|
|
211
|
+
for privacy_request in update_all:
|
|
212
|
+
privacy_request.duplicate_request_group_id = duplicate_group_id # type: ignore [assignment]
|
|
213
|
+
except Exception as e:
|
|
214
|
+
logger.error(f"Failed to update duplicate request group ids: {e}")
|
|
215
|
+
raise e
|
|
216
|
+
|
|
217
|
+
def mark_as_duplicate(self, request: PrivacyRequest, message: str) -> None:
|
|
218
|
+
"""
|
|
219
|
+
Mark a request as a duplicate.
|
|
220
|
+
"""
|
|
221
|
+
request.update(self.db, data={"status": PrivacyRequestStatus.duplicate})
|
|
222
|
+
logger.debug(message)
|
|
223
|
+
request.add_skipped_execution_log(
|
|
224
|
+
self.db,
|
|
225
|
+
connection_key=None,
|
|
226
|
+
dataset_name="Duplicate Request Detection",
|
|
227
|
+
collection_name=None,
|
|
228
|
+
message=message,
|
|
229
|
+
action_type=(request.policy.get_action_type() if request.policy else None)
|
|
230
|
+
or ActionType.access,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def add_success_execution_log(self, request: PrivacyRequest, message: str) -> None:
|
|
234
|
+
request.add_success_execution_log(
|
|
235
|
+
db=self.db,
|
|
236
|
+
connection_key=None,
|
|
237
|
+
dataset_name="Duplicate Request Detection",
|
|
238
|
+
collection_name=None,
|
|
239
|
+
message=message,
|
|
240
|
+
action_type=(
|
|
241
|
+
request.policy.get_action_type() # type: ignore [arg-type]
|
|
242
|
+
if request.policy
|
|
243
|
+
else ActionType.access
|
|
244
|
+
),
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
def verified_identity_cases(
|
|
248
|
+
self, request: PrivacyRequest, duplicates: list[PrivacyRequest]
|
|
249
|
+
) -> bool:
|
|
250
|
+
"""
|
|
251
|
+
Apply verified identity rules to determine if a request is a duplicate request.
|
|
252
|
+
- If this request does not have a verified identity, it may be a duplicate if another request in the group is verified.
|
|
253
|
+
- If this is the first request to be verified, it is not a duplicate request
|
|
254
|
+
- If other requests identities were verified before this request, it is a duplicate request
|
|
255
|
+
Args:
|
|
256
|
+
request: The privacy request to check
|
|
257
|
+
duplicates: The list of duplicate requests
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
True if the request is a duplicate request, False otherwise
|
|
261
|
+
"""
|
|
262
|
+
verified_in_group = [
|
|
263
|
+
duplicate for duplicate in duplicates if duplicate.identity_verified_at
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
# The request identity is not verified.
|
|
267
|
+
if not request.identity_verified_at:
|
|
268
|
+
if len(verified_in_group) > 0:
|
|
269
|
+
message = f"Request {request.id} is a duplicate: it is duplicating request(s) {[duplicate.id for duplicate in verified_in_group]}."
|
|
270
|
+
self.mark_as_duplicate(request, message)
|
|
271
|
+
return True
|
|
272
|
+
|
|
273
|
+
canonical_request = min(duplicates, key=lambda x: x.created_at) # type: ignore [arg-type, return-value]
|
|
274
|
+
canonical_request_created_at = canonical_request.created_at or datetime.now(
|
|
275
|
+
timezone.utc
|
|
276
|
+
)
|
|
277
|
+
request_created_at = request.created_at or datetime.now(timezone.utc)
|
|
278
|
+
if request_created_at < canonical_request_created_at:
|
|
279
|
+
message = f"Request {request.id} is not a duplicate: it is the first request to be created in the group."
|
|
280
|
+
logger.debug(message)
|
|
281
|
+
self.add_success_execution_log(request, message)
|
|
282
|
+
return False
|
|
283
|
+
|
|
284
|
+
message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
|
|
285
|
+
self.mark_as_duplicate(request, message)
|
|
286
|
+
return True
|
|
287
|
+
|
|
288
|
+
# The request identity is verified.
|
|
289
|
+
if not verified_in_group:
|
|
290
|
+
message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
|
|
291
|
+
logger.debug(message)
|
|
292
|
+
for duplicate in duplicates:
|
|
293
|
+
dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
|
|
294
|
+
self.mark_as_duplicate(duplicate, dup_message)
|
|
295
|
+
self.add_success_execution_log(request, message)
|
|
296
|
+
return False
|
|
297
|
+
|
|
298
|
+
# If this request is the first with a verified identity, it is not a duplicate.
|
|
299
|
+
canonical_request = min(verified_in_group, key=lambda x: x.identity_verified_at) # type: ignore [arg-type, return-value]
|
|
300
|
+
canonical_request_verified_at = (
|
|
301
|
+
canonical_request.identity_verified_at or datetime.now(timezone.utc)
|
|
302
|
+
)
|
|
303
|
+
request_verified_at = request.identity_verified_at or datetime.now(timezone.utc)
|
|
304
|
+
if request_verified_at < canonical_request_verified_at:
|
|
305
|
+
message = f"Request {request.id} is not a duplicate: it is the first request to be verified in the group."
|
|
306
|
+
logger.debug(message)
|
|
307
|
+
self.add_success_execution_log(request, message)
|
|
308
|
+
for duplicate in duplicates:
|
|
309
|
+
dup_message = f"Request {duplicate.id} is a duplicate: it is duplicating request(s) ['{request.id}']."
|
|
310
|
+
self.mark_as_duplicate(duplicate, dup_message)
|
|
311
|
+
return False
|
|
312
|
+
message = f"Request {request.id} is a duplicate: it is duplicating request(s) ['{canonical_request.id}']."
|
|
313
|
+
self.mark_as_duplicate(request, message)
|
|
314
|
+
return True
|
|
315
|
+
|
|
316
|
+
# pylint: disable=too-many-return-statements
|
|
317
|
+
def is_duplicate_request(self, request: PrivacyRequest) -> bool:
|
|
318
|
+
"""
|
|
319
|
+
Determine if a request is a duplicate request and assigns a duplicate request group id.
|
|
320
|
+
|
|
321
|
+
The hierarchy is:
|
|
322
|
+
1. Actioned requests: if this request duplicates an actioned request, it is a duplicate.
|
|
323
|
+
2. Verified identity requests:
|
|
324
|
+
a. if this request has a verified identity:
|
|
325
|
+
- If none of the duplicates have a verified identity, it is not a duplicate.
|
|
326
|
+
- If duplicates have verified identities, but this request is the first with a verified identity, it is not a duplicate.
|
|
327
|
+
b. if this request does not have a verified identity:
|
|
328
|
+
- If no duplicates have a verified identity, and this was the first created request, it is not a duplicate.
|
|
329
|
+
3. First created request: if this is the first created request in the group, it is not a duplicate.
|
|
330
|
+
4. If no canonical requests are found (meaning all requests are marked as duplicates), this request is not a duplicate.
|
|
331
|
+
- Could occur if configuration changes and previous requests were already marked as duplicates.
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
request: The privacy request to check
|
|
335
|
+
config: Duplicate detection configuration settings
|
|
336
|
+
Returns:
|
|
337
|
+
True if the request is a duplicate request, False otherwise
|
|
338
|
+
"""
|
|
339
|
+
if request.policy.get_action_type() == ActionType.consent:
|
|
340
|
+
message = f"Consent request {request.id} is not a duplicate."
|
|
341
|
+
logger.info(message)
|
|
342
|
+
self.add_success_execution_log(request, message)
|
|
343
|
+
return False
|
|
344
|
+
duplicates = self.find_duplicate_privacy_requests(request)
|
|
345
|
+
rule_version = generate_rule_version(
|
|
346
|
+
DuplicateDetectionSettings(
|
|
347
|
+
enabled=self._config.enabled,
|
|
348
|
+
time_window_days=self._config.time_window_days,
|
|
349
|
+
match_identity_fields=self._config.match_identity_fields,
|
|
350
|
+
)
|
|
351
|
+
)
|
|
352
|
+
try:
|
|
353
|
+
dedup_key = self.generate_dedup_key(request)
|
|
354
|
+
except ValueError as e:
|
|
355
|
+
message = f"Request {request.id} is not a duplicate: {e}"
|
|
356
|
+
logger.warning(message)
|
|
357
|
+
self.add_success_execution_log(request, message)
|
|
358
|
+
return False
|
|
359
|
+
|
|
360
|
+
_, duplicate_group = DuplicateGroup.get_or_create(
|
|
361
|
+
db=self.db, data={"rule_version": rule_version, "dedup_key": dedup_key}
|
|
362
|
+
)
|
|
363
|
+
if duplicate_group is None:
|
|
364
|
+
message = f"Failed to create duplicate group for request {request.id} with dedup key {dedup_key}"
|
|
365
|
+
logger.error(message)
|
|
366
|
+
request.add_error_execution_log(
|
|
367
|
+
db=self.db,
|
|
368
|
+
connection_key=None,
|
|
369
|
+
dataset_name="Duplicate Request Detection",
|
|
370
|
+
collection_name=None,
|
|
371
|
+
message=message,
|
|
372
|
+
action_type=(
|
|
373
|
+
request.policy.get_action_type() # type: ignore [arg-type]
|
|
374
|
+
if request.policy
|
|
375
|
+
else ActionType.access
|
|
376
|
+
),
|
|
377
|
+
)
|
|
378
|
+
return False
|
|
379
|
+
|
|
380
|
+
self.update_duplicate_group_ids(request, duplicates, duplicate_group.id) # type: ignore [arg-type]
|
|
381
|
+
|
|
382
|
+
if request.status in ACTIONED_REQUEST_STATUSES:
|
|
383
|
+
message = (
|
|
384
|
+
f"Request {request.id} is not a duplicate: it is an actioned request."
|
|
385
|
+
)
|
|
386
|
+
logger.debug(message)
|
|
387
|
+
self.add_success_execution_log(request, message)
|
|
388
|
+
return False
|
|
389
|
+
|
|
390
|
+
# if this is the only request in the group, it is not a duplicate
|
|
391
|
+
if len(duplicates) == 0:
|
|
392
|
+
message = f"Request {request.id} is not a duplicate."
|
|
393
|
+
logger.debug(message)
|
|
394
|
+
self.add_success_execution_log(request, message)
|
|
395
|
+
return False
|
|
396
|
+
|
|
397
|
+
if request.status == PrivacyRequestStatus.duplicate:
|
|
398
|
+
return True
|
|
399
|
+
|
|
400
|
+
# only compare to non-duplicate/complete requests for the following cases
|
|
401
|
+
canonical_requests = [
|
|
402
|
+
duplicate
|
|
403
|
+
for duplicate in duplicates
|
|
404
|
+
if duplicate.status
|
|
405
|
+
not in [
|
|
406
|
+
PrivacyRequestStatus.duplicate,
|
|
407
|
+
PrivacyRequestStatus.complete,
|
|
408
|
+
PrivacyRequestStatus.denied,
|
|
409
|
+
]
|
|
410
|
+
]
|
|
411
|
+
# If no non-duplicate requests are found, this request is not a duplicate.
|
|
412
|
+
if len(canonical_requests) == 0:
|
|
413
|
+
message = f"Request {request.id} is not a duplicate."
|
|
414
|
+
logger.debug(message)
|
|
415
|
+
self.add_success_execution_log(request, message)
|
|
416
|
+
return False
|
|
417
|
+
|
|
418
|
+
# If any requests in group are actioned, this request is a duplicate.
|
|
419
|
+
actioned_in_group = [
|
|
420
|
+
duplicate
|
|
421
|
+
for duplicate in canonical_requests
|
|
422
|
+
if duplicate.status in ACTIONED_REQUEST_STATUSES
|
|
423
|
+
]
|
|
424
|
+
if len(actioned_in_group) > 0:
|
|
425
|
+
message = f"Request {request.id} is a duplicate: it is duplicating actioned request(s) {[duplicate.id for duplicate in actioned_in_group]}."
|
|
426
|
+
self.mark_as_duplicate(request, message)
|
|
427
|
+
return True
|
|
428
|
+
# Check against verified identity rules.
|
|
429
|
+
return self.verified_identity_cases(request, canonical_requests)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def check_for_duplicates(db: Session, privacy_request: PrivacyRequest) -> None:
|
|
433
|
+
duplicate_detection_service = DuplicateDetectionService(db)
|
|
434
|
+
if duplicate_detection_service.is_enabled():
|
|
435
|
+
logger.info(
|
|
436
|
+
"Duplicate detection is enabled. Checking if privacy request is a duplicate."
|
|
437
|
+
)
|
|
438
|
+
if duplicate_detection_service.is_duplicate_request(privacy_request):
|
|
439
|
+
logger.info("Terminating privacy request: request is a duplicate.")
|
|
@@ -50,8 +50,9 @@ def send_email_batch(self: DatabaseTask) -> EmailExitState:
|
|
|
50
50
|
batch_id = str(uuid.uuid4())
|
|
51
51
|
logger.info("Starting batch email send {}...", batch_id)
|
|
52
52
|
with self.get_new_session() as session:
|
|
53
|
+
# Use query_without_large_columns to prevent OOM errors when processing many privacy requests
|
|
53
54
|
privacy_requests: Query = (
|
|
54
|
-
|
|
55
|
+
PrivacyRequest.query_without_large_columns(session)
|
|
55
56
|
.filter(
|
|
56
57
|
PrivacyRequest.status == PrivacyRequestStatus.awaiting_email_send
|
|
57
58
|
)
|