ethyca-fides 2.71.0rc4__py2.py3-none-any.whl → 2.71.1b1__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.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/METADATA +2 -2
- {ethyca_fides-2.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/RECORD +158 -154
- fides/_version.py +3 -3
- fides/api/alembic/migrations/versions/3efe14d4469a_adds_new_experience_configs_for_vendor_.py +79 -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/f108fa05c579_adds_optional_duration_field_to_assets.py +28 -0
- fides/api/api/v1/endpoints/generic_overrides.py +9 -3
- fides/api/db/base.py +1 -1
- fides/api/models/asset.py +14 -1
- fides/api/models/conditional_dependency/conditional_dependency_base.py +253 -24
- fides/api/models/detection_discovery/core.py +57 -3
- fides/api/models/digest/__init__.py +5 -1
- fides/api/models/digest/conditional_dependencies.py +267 -1
- fides/api/models/digest/digest_config.py +34 -9
- fides/api/models/fides_user.py +9 -0
- fides/api/models/manual_task/conditional_dependency.py +16 -18
- fides/api/models/privacy_experience.py +10 -0
- fides/api/models/privacy_notice.py +139 -20
- fides/api/task/manual/manual_task_conditional_evaluation.py +1 -1
- fides/service/dataset/dataset_service.py +39 -0
- fides/service/privacy_request/privacy_request_service.py +103 -48
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/_IxwgneyQjdSaZFEF3Tqu/_buildManifest.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/155-b4337d0826d5addc.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/1817-1ad037b7d6d2f6d2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3585-efd5d41f08e180c4.js → 3585-f728d32fda6f1ac1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-ed226b8a8050bd40.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/409-5c3d31163028339f.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4558-8305aee48def1dcd.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4608-0c6ef78e30a51f84.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{4718-6585c97c26647e65.js → 4718-3a412bdb90add82f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/502-0d9f4ac29ef34a1c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/5279-12c9cbdc67ad7b14.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/6277-182efc294d413f64.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{7045-f15044a4d4525946.js → 7045-14e955890f1147e4.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/7079-50571e9f3269d74d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-a77584f9ad3334af.js → _app-c1c2f757b1f3da12.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-75e99306393938e8.js → manual-4ec03eed67572861.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-19214babd1f219e3.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{[id]-fd41ffaff543e05a.js → [id]-e1e2fd704ac2d71d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-e74cb5ea87f15b40.js → new-a5e738a234dadc7e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-9c23fbe813c997d0.js → [id]-5fc78b78a51c239c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{new-0e5e38bbcfe59fd2.js → new-b79bcb93b5f4c734.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-c1a3caf3c286bf5d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-5b57f9132426fe52.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-a28cc0e23bbe4fc8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-7d22222608ec3aac.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-d514cd4ec62e3b03.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-153eb88ab4e7dc6d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-331544e9b85c4ac2.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-479890582973deaf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-4d658222ec800511.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-2fcd95c41e578d57.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{privacy-requests-8cbdfd08e0fa88fb.js → privacy-requests-97221067330c0c27.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-547c6ef0ad52b85d.js → [id]-4d470bbf199a2f9c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-6c91bdea40875227.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-3059aba38adefa56.js +1 -0
- fides/ui-build/static/admin/_next/static/css/{64fac6fb884435c2.css → 295d729ea1b11885.css} +1 -1
- 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-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/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/[id].html +1 -1
- fides/ui-build/static/admin/settings/custom-fields/new.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/messaging-providers/[key].html +1 -1
- fides/ui-build/static/admin/settings/messaging-providers/new.html +1 -1
- fides/ui-build/static/admin/settings/messaging-providers.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/ui-build/static/admin/_next/static/chunks/155-047c3806cc41295e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-ca6473f31a67a804.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3700-08e0703b1ef770da.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3855-12ee1dfbbe47fd28.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/409-c1256ecda1b15db6.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4558-de5ced790b3380dc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4608-a9941d0c236ebca1.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/502-d3ecae97b67befbd.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6084-d0943ee628bf4388.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/6416-0ccadfefcdad00cc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems-58920afe2b67f952.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/reporting-ae4909cad9b67822.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-2e1e2b7808d3b21f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-2635ef588bf06145.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datamap-15616bea02397ef4.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/new-ea198c4a7869f402.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-01e025f878ba806c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations-14120a529d7dac27.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/storage-648d775d0fce49dc.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-e5d781b28f8e29c8.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/custom-fields-5edfec10a945ca43.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems-0f1d833282f09684.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/taxonomy-a8cfa7de4948b374.js +0 -1
- fides/ui-build/static/admin/_next/static/kdnucJIsIefS6ViqY-8w3/_buildManifest.js +0 -1
- {ethyca_fides-2.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/licenses/LICENSE +0 -0
- {ethyca_fides-2.71.0rc4.dist-info → ethyca_fides-2.71.1b1.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/{kdnucJIsIefS6ViqY-8w3 → _IxwgneyQjdSaZFEF3Tqu}/_ssgManifest.js +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{6882-10296485ec326e6b.js → 6882-dbe0a25dcf1a8ee0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{9046-2a332fe338535c84.js → 9046-b6616ba7b59d947e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-56fd0f3e465e52b6.js → data-catalog-b7326c51d88cc2cc.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/[collectionName]/{[...subfieldNames]-d4031e438c363fff.js → [...subfieldNames]-0abd30eada811b5b.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/dataset/[datasetId]/{[collectionName]-9463af37079762d0.js → [collectionName]-007965429368d9a3.js} +0 -0
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import itertools
|
|
3
4
|
import re
|
|
4
5
|
from enum import Enum
|
|
6
|
+
from functools import cached_property
|
|
5
7
|
from typing import Any, Dict, List, Optional, Set, Type
|
|
6
8
|
|
|
7
9
|
from fideslang.validation import FidesKey, validate_fides_key
|
|
8
10
|
from sqlalchemy import Boolean, Column
|
|
9
11
|
from sqlalchemy import Enum as EnumColumn
|
|
10
|
-
from sqlalchemy import Float, ForeignKey, String, UniqueConstraint, or_, text
|
|
12
|
+
from sqlalchemy import Float, ForeignKey, String, UniqueConstraint, false, or_, text
|
|
11
13
|
from sqlalchemy.dialects.postgresql import ARRAY, JSONB
|
|
12
14
|
from sqlalchemy.ext.mutable import MutableList
|
|
13
|
-
from sqlalchemy.orm import RelationshipProperty, Session, relationship
|
|
15
|
+
from sqlalchemy.orm import RelationshipProperty, Session, relationship, selectinload
|
|
14
16
|
from sqlalchemy.orm.dynamic import AppenderQuery
|
|
17
|
+
from sqlalchemy.sql.elements import ColumnElement
|
|
15
18
|
from sqlalchemy.util import hybridproperty
|
|
16
19
|
|
|
17
20
|
from fides.api.db.base_class import Base, FidesBase
|
|
@@ -189,21 +192,17 @@ class PrivacyNotice(PrivacyNoticeBase, Base):
|
|
|
189
192
|
|
|
190
193
|
raise Exception("Invalid notice consent mechanism.")
|
|
191
194
|
|
|
192
|
-
@
|
|
193
|
-
def
|
|
195
|
+
@staticmethod
|
|
196
|
+
def _get_cookie_filter_for_data_uses(data_uses: List[str]) -> ColumnElement:
|
|
194
197
|
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
that is either an exact match or a hierarchical descendant of a one of the
|
|
198
|
-
data uses in the privacy notice.
|
|
198
|
+
Returns the SQLAlchemy filter clause to find cookies for the given data uses.
|
|
199
|
+
This is a helper method to keep the query logic consistent and safe.
|
|
199
200
|
"""
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if not self.data_uses:
|
|
203
|
-
return []
|
|
201
|
+
if not data_uses:
|
|
202
|
+
return false()
|
|
204
203
|
|
|
205
204
|
# Use array overlap operator (&&) for exact matches - GIN index friendly
|
|
206
|
-
exact_matches_condition = Asset.data_uses.op("&&")(
|
|
205
|
+
exact_matches_condition = Asset.data_uses.op("&&")(data_uses)
|
|
207
206
|
|
|
208
207
|
# For hierarchical children, we still need to check individual elements with LIKE
|
|
209
208
|
# They have to match the data_use and the period separator, so we know it's a hierarchical descendant
|
|
@@ -211,20 +210,132 @@ class PrivacyNotice(PrivacyNoticeBase, Base):
|
|
|
211
210
|
text(
|
|
212
211
|
f"EXISTS(SELECT 1 FROM unnest(data_uses) AS data_use WHERE data_use LIKE :pattern_{i})"
|
|
213
212
|
).bindparams(**{f"pattern_{i}": f"{data_use}.%"})
|
|
214
|
-
for i, data_use in enumerate(
|
|
213
|
+
for i, data_use in enumerate(data_uses)
|
|
215
214
|
]
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
return or_(exact_matches_condition, *hierarchical_conditions)
|
|
217
|
+
|
|
218
|
+
@classmethod
|
|
219
|
+
def _query_cookie_assets_for_data_uses(
|
|
220
|
+
cls,
|
|
221
|
+
db: Session,
|
|
222
|
+
data_uses: Set[str],
|
|
223
|
+
exclude_cookies_from_systems: Optional[Set[str]] = None,
|
|
224
|
+
) -> List[Asset]:
|
|
225
|
+
"""
|
|
226
|
+
Query cookie Assets for the given set of data uses using the shared filter logic.
|
|
227
|
+
Applies optional exclusion by `System.fides_key` and eagerly loads the `system` relationship.
|
|
228
|
+
"""
|
|
229
|
+
if not data_uses:
|
|
230
|
+
return []
|
|
220
231
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
232
|
+
cookie_filter = cls._get_cookie_filter_for_data_uses(list(data_uses))
|
|
233
|
+
query = (
|
|
234
|
+
db.query(Asset)
|
|
235
|
+
.options(selectinload("system"))
|
|
236
|
+
.filter(
|
|
237
|
+
Asset.asset_type == "Cookie",
|
|
238
|
+
cookie_filter,
|
|
239
|
+
)
|
|
224
240
|
)
|
|
241
|
+
if exclude_cookies_from_systems:
|
|
242
|
+
query = query.outerjoin(System).filter(
|
|
243
|
+
or_(
|
|
244
|
+
Asset.system_id.is_(None),
|
|
245
|
+
System.fides_key.not_in(exclude_cookies_from_systems),
|
|
246
|
+
)
|
|
247
|
+
)
|
|
225
248
|
|
|
226
249
|
return query.all()
|
|
227
250
|
|
|
251
|
+
@staticmethod
|
|
252
|
+
def _group_cookies_by_data_use(cookies: List[Asset]) -> Dict[str, List[Asset]]:
|
|
253
|
+
"""Build a mapping of data_use -> list of cookie Assets."""
|
|
254
|
+
cookies_by_data_use: Dict[str, List[Asset]] = {}
|
|
255
|
+
for cookie in cookies:
|
|
256
|
+
for data_use in cookie.data_uses or []:
|
|
257
|
+
cookies_by_data_use.setdefault(data_use, []).append(cookie)
|
|
258
|
+
return cookies_by_data_use
|
|
259
|
+
|
|
260
|
+
@staticmethod
|
|
261
|
+
def _select_cookies_for_notice_data_uses(
|
|
262
|
+
notice_data_uses: List[str],
|
|
263
|
+
cookies_by_data_use: Dict[str, List[Asset]],
|
|
264
|
+
) -> List[Asset]:
|
|
265
|
+
"""
|
|
266
|
+
Return cookies that match the notice data uses either exactly or as hierarchical descendants.
|
|
267
|
+
Deduplicate by object identity; ordering is not guaranteed.
|
|
268
|
+
"""
|
|
269
|
+
unique_cookies_by_id: Dict[int, Asset] = {}
|
|
270
|
+
|
|
271
|
+
for notice_data_use in notice_data_uses or []:
|
|
272
|
+
# Exact matches
|
|
273
|
+
for cookie in cookies_by_data_use.get(notice_data_use, []):
|
|
274
|
+
unique_cookies_by_id[id(cookie)] = cookie
|
|
275
|
+
|
|
276
|
+
# Hierarchical descendants: e.g., "analytics" matches "analytics.reporting"
|
|
277
|
+
prefix = f"{notice_data_use}."
|
|
278
|
+
for du_key, cookie_list in cookies_by_data_use.items():
|
|
279
|
+
if du_key.startswith(prefix):
|
|
280
|
+
for cookie in cookie_list:
|
|
281
|
+
unique_cookies_by_id[id(cookie)] = cookie
|
|
282
|
+
|
|
283
|
+
return list(unique_cookies_by_id.values())
|
|
284
|
+
|
|
285
|
+
@cached_property
|
|
286
|
+
def cookies(self) -> List[Asset]:
|
|
287
|
+
"""
|
|
288
|
+
Return relevant assets of type 'cookie' (via the data use)
|
|
289
|
+
|
|
290
|
+
Cookies are matched to the privacy notice if they have at least one data use
|
|
291
|
+
that is either an exact match or a hierarchical descendant of a one of the
|
|
292
|
+
data uses in the privacy notice.
|
|
293
|
+
|
|
294
|
+
This is a cached_property, so the database query is only executed
|
|
295
|
+
once per instance, and the result is cached for subsequent accesses.
|
|
296
|
+
"""
|
|
297
|
+
db = Session.object_session(self)
|
|
298
|
+
cookie_filter = self._get_cookie_filter_for_data_uses(self.data_uses)
|
|
299
|
+
|
|
300
|
+
return (
|
|
301
|
+
db.query(Asset)
|
|
302
|
+
.filter(
|
|
303
|
+
Asset.asset_type == "Cookie",
|
|
304
|
+
cookie_filter,
|
|
305
|
+
)
|
|
306
|
+
.all()
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
@classmethod
|
|
310
|
+
def load_cookie_data_for_notices(
|
|
311
|
+
cls,
|
|
312
|
+
db: Session,
|
|
313
|
+
notices: List["PrivacyNotice"],
|
|
314
|
+
exclude_cookies_from_systems: Optional[Set[str]] = None,
|
|
315
|
+
) -> None:
|
|
316
|
+
"""
|
|
317
|
+
An efficient method to bulk-load cookie data for a list of PrivacyNotice objects.
|
|
318
|
+
This prevents the "N+1" query problem by pre-populating the `cookies`
|
|
319
|
+
cached_property for each notice.
|
|
320
|
+
"""
|
|
321
|
+
if not notices:
|
|
322
|
+
return
|
|
323
|
+
|
|
324
|
+
all_data_uses = set(itertools.chain.from_iterable(n.data_uses for n in notices))
|
|
325
|
+
all_relevant_cookies = cls._query_cookie_assets_for_data_uses(
|
|
326
|
+
db, all_data_uses, exclude_cookies_from_systems
|
|
327
|
+
)
|
|
328
|
+
cookies_by_data_use = cls._group_cookies_by_data_use(all_relevant_cookies)
|
|
329
|
+
|
|
330
|
+
for notice in notices:
|
|
331
|
+
matching_cookies = cls._select_cookies_for_notice_data_uses(
|
|
332
|
+
notice.data_uses, cookies_by_data_use
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
# Pre-populate the cache of the 'cookies' cached_property.
|
|
336
|
+
# This directly sets the attribute that the decorator would otherwise compute.
|
|
337
|
+
setattr(notice, "cookies", matching_cookies)
|
|
338
|
+
|
|
228
339
|
@property
|
|
229
340
|
def calculated_systems_applicable(self) -> bool:
|
|
230
341
|
"""Convenience property to return if any systems overlap with this notice's data uses
|
|
@@ -419,6 +530,10 @@ class PrivacyNotice(PrivacyNoticeBase, Base):
|
|
|
419
530
|
# to prevent the dry update from being added to Session.new
|
|
420
531
|
updated_attributes.pop("translations", [])
|
|
421
532
|
updated_attributes.pop("children", [])
|
|
533
|
+
# The source PrivacyNotice may have cached/computed attributes (e.g., @cached_property)
|
|
534
|
+
# stored on the instance dict. These should not be included in historical payloads.
|
|
535
|
+
# For example, 'cookies' is cached on the PrivacyNotice instance when accessed.
|
|
536
|
+
updated_attributes.pop("cookies", None)
|
|
422
537
|
|
|
423
538
|
# create a new object with the updated attribute data to keep this
|
|
424
539
|
# ORM object (i.e., `self`) pristine
|
|
@@ -565,6 +680,10 @@ def create_historical_record_for_notice_and_translation(
|
|
|
565
680
|
history_data: dict = create_historical_data_from_record(privacy_notice)
|
|
566
681
|
history_data.pop("translations", None)
|
|
567
682
|
history_data.pop("parent_id", None)
|
|
683
|
+
# The source PrivacyNotice may have cached/computed attributes (e.g., @cached_property)
|
|
684
|
+
# stored on the instance dict. These should not be included in historical payloads.
|
|
685
|
+
# For example, 'cookies' is cached on the PrivacyNotice instance when accessed.
|
|
686
|
+
history_data.pop("cookies", None)
|
|
568
687
|
|
|
569
688
|
updated_translation_data: dict = create_historical_data_from_record(
|
|
570
689
|
notice_translation
|
|
@@ -181,7 +181,7 @@ def evaluate_conditional_dependencies(
|
|
|
181
181
|
"""
|
|
182
182
|
# Get the root condition for this manual task
|
|
183
183
|
root_condition = ManualTaskConditionalDependency.get_root_condition(
|
|
184
|
-
db, manual_task.id
|
|
184
|
+
db, manual_task_id=manual_task.id
|
|
185
185
|
)
|
|
186
186
|
|
|
187
187
|
if not root_condition:
|
|
@@ -6,6 +6,7 @@ from loguru import logger
|
|
|
6
6
|
from sqlalchemy import select
|
|
7
7
|
from sqlalchemy.orm import Session
|
|
8
8
|
|
|
9
|
+
from fides.api.models.datasetconfig import DatasetConfig # type: ignore[attr-defined]
|
|
9
10
|
from fides.api.schemas.dataset import ValidateDatasetResponse
|
|
10
11
|
from fides.service.dataset.dataset_validator import DatasetValidator
|
|
11
12
|
|
|
@@ -26,6 +27,10 @@ class DatasetNotFoundException(DatasetError):
|
|
|
26
27
|
"""Raised when a dataset is not found"""
|
|
27
28
|
|
|
28
29
|
|
|
30
|
+
class LinkedDatasetException(DatasetError):
|
|
31
|
+
"""Raised when attempting to delete a dataset that's associated to a DatasetConfig"""
|
|
32
|
+
|
|
33
|
+
|
|
29
34
|
class DatasetService:
|
|
30
35
|
def __init__(self, db: Session):
|
|
31
36
|
self.db = db
|
|
@@ -68,6 +73,40 @@ class DatasetService:
|
|
|
68
73
|
def delete_dataset(self, fides_key: str) -> CtlDataset:
|
|
69
74
|
"""Delete a dataset by fides key"""
|
|
70
75
|
dataset = self.get_dataset(fides_key)
|
|
76
|
+
|
|
77
|
+
# Check if dataset is associated with any DatasetConfigs
|
|
78
|
+
associated_configs = (
|
|
79
|
+
self.db.query(DatasetConfig)
|
|
80
|
+
.filter(DatasetConfig.ctl_dataset_id == dataset.id)
|
|
81
|
+
.all()
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if associated_configs:
|
|
85
|
+
# Create detailed error message
|
|
86
|
+
integration_details = []
|
|
87
|
+
for config in associated_configs:
|
|
88
|
+
connection_name = (
|
|
89
|
+
config.connection_config.name or config.connection_config.key
|
|
90
|
+
)
|
|
91
|
+
detail = f"'{connection_name}' ({config.connection_config.connection_type.value})" # type: ignore[attr-defined]
|
|
92
|
+
|
|
93
|
+
# Add system information if available
|
|
94
|
+
if config.connection_config.system_id:
|
|
95
|
+
system = config.connection_config.system
|
|
96
|
+
if system:
|
|
97
|
+
system_name = system.name or system.fides_key
|
|
98
|
+
detail += f" in system '{system_name}'"
|
|
99
|
+
|
|
100
|
+
integration_details.append(detail)
|
|
101
|
+
|
|
102
|
+
message = (
|
|
103
|
+
f"Cannot delete dataset '{fides_key}' because it is associated with "
|
|
104
|
+
f"the following integration(s): {', '.join(integration_details)}. "
|
|
105
|
+
f"Remove the dataset from these integrations before deleting."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
raise LinkedDatasetException(message)
|
|
109
|
+
|
|
71
110
|
dataset.delete(self.db)
|
|
72
111
|
return dataset
|
|
73
112
|
|
|
@@ -90,65 +90,120 @@ class PrivacyRequestService:
|
|
|
90
90
|
if privacy_request_data.location:
|
|
91
91
|
return
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
config_dict = self._resolve_privacy_center_config_dict(
|
|
94
|
+
privacy_request_data.property_id
|
|
95
|
+
)
|
|
96
|
+
if not config_dict:
|
|
97
|
+
return
|
|
97
98
|
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
privacy_center_config = self._parse_privacy_center_config(config_dict)
|
|
100
|
+
if not privacy_center_config:
|
|
100
101
|
return
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
action = self._get_matching_action(
|
|
104
|
+
privacy_center_config, privacy_request_data.policy_key
|
|
105
|
+
)
|
|
106
|
+
if not action or not action.custom_privacy_request_fields:
|
|
107
|
+
return
|
|
108
|
+
|
|
109
|
+
missing_required = self._is_required_location_missing(
|
|
110
|
+
action, privacy_request_data
|
|
111
|
+
)
|
|
112
|
+
if missing_required:
|
|
113
|
+
# Find the first location field name to reference in the error for clarity
|
|
114
|
+
first_location_field = next(
|
|
115
|
+
(
|
|
116
|
+
name
|
|
117
|
+
for name, cfg in action.custom_privacy_request_fields.items()
|
|
118
|
+
if isinstance(cfg, LocationCustomPrivacyRequestField)
|
|
119
|
+
and getattr(cfg, "required", False)
|
|
120
|
+
),
|
|
121
|
+
"location",
|
|
106
122
|
)
|
|
107
|
-
|
|
123
|
+
raise PrivacyRequestError(
|
|
124
|
+
f"Location is required for field '{first_location_field}' but was not provided",
|
|
125
|
+
privacy_request_data.model_dump(mode="json"),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def _resolve_privacy_center_config_dict(
|
|
129
|
+
self, property_id: Optional[str]
|
|
130
|
+
) -> Optional[Dict[str, Any]]:
|
|
131
|
+
"""Return the applicable Privacy Center config as a dict using precedence.
|
|
132
|
+
|
|
133
|
+
Precedence:
|
|
134
|
+
1) The request's property config (if provided)
|
|
135
|
+
2) The default property's config (if available)
|
|
136
|
+
3) The single-row Privacy Center config table (legacy/global)
|
|
137
|
+
"""
|
|
138
|
+
# 1) Request's property config
|
|
139
|
+
if property_id:
|
|
140
|
+
prop = Property.get_by(self.db, field="id", value=property_id)
|
|
141
|
+
if prop and getattr(prop, "privacy_center_config", None):
|
|
142
|
+
return prop.privacy_center_config # type: ignore[return-value]
|
|
143
|
+
|
|
144
|
+
# 2) Default property config
|
|
145
|
+
default_prop = Property.get_by(self.db, field="is_default", value=True)
|
|
146
|
+
if default_prop and getattr(default_prop, "privacy_center_config", None):
|
|
147
|
+
return default_prop.privacy_center_config # type: ignore[return-value]
|
|
148
|
+
|
|
149
|
+
# 3) Single-row global config
|
|
150
|
+
privacy_center_config_record = PrivacyCenterConfigModel.filter(
|
|
151
|
+
db=self.db, conditions=PrivacyCenterConfigModel.single_row # type: ignore[arg-type]
|
|
152
|
+
).first()
|
|
153
|
+
if privacy_center_config_record:
|
|
154
|
+
return privacy_center_config_record.config # type: ignore[return-value]
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
def _parse_privacy_center_config(
|
|
158
|
+
self, config_dict: Dict[str, Any]
|
|
159
|
+
) -> Optional[PrivacyCenterConfigSchema]:
|
|
160
|
+
"""Parse a config dict into a schema instance, logging and skipping on error."""
|
|
161
|
+
try:
|
|
162
|
+
return PrivacyCenterConfigSchema.model_validate(config_dict)
|
|
163
|
+
except Exception as exc: # pylint: disable=broad-except
|
|
108
164
|
logger.warning(
|
|
109
165
|
f"Could not parse Privacy Center config for location validation: {exc}"
|
|
110
166
|
)
|
|
111
|
-
return
|
|
167
|
+
return None
|
|
112
168
|
|
|
113
|
-
|
|
114
|
-
|
|
169
|
+
@staticmethod
|
|
170
|
+
def _get_matching_action(
|
|
171
|
+
privacy_center_config: PrivacyCenterConfigSchema, policy_key: str
|
|
172
|
+
) -> Optional[Any]:
|
|
173
|
+
"""Return the action entry matching the given policy key, if any."""
|
|
115
174
|
for action in privacy_center_config.actions:
|
|
116
|
-
if action.policy_key ==
|
|
117
|
-
|
|
118
|
-
|
|
175
|
+
if action.policy_key == policy_key:
|
|
176
|
+
return action
|
|
177
|
+
return None
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def _is_required_location_missing(
|
|
181
|
+
action: Any, privacy_request_data: PrivacyRequestCreate
|
|
182
|
+
) -> bool:
|
|
183
|
+
"""Check if any required location fields exist without values in the request."""
|
|
184
|
+
if not getattr(action, "custom_privacy_request_fields", None):
|
|
185
|
+
return False
|
|
186
|
+
|
|
187
|
+
custom_fields = action.custom_privacy_request_fields
|
|
188
|
+
for field_name, field_config in custom_fields.items():
|
|
189
|
+
if not isinstance(field_config, LocationCustomPrivacyRequestField):
|
|
190
|
+
continue
|
|
191
|
+
if not getattr(field_config, "required", False):
|
|
192
|
+
continue
|
|
119
193
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
194
|
+
# Check if this location field has a value in the request custom fields
|
|
195
|
+
field_has_value = False
|
|
196
|
+
if privacy_request_data.custom_privacy_request_fields:
|
|
197
|
+
field_data = privacy_request_data.custom_privacy_request_fields.get(
|
|
198
|
+
field_name
|
|
199
|
+
)
|
|
200
|
+
if field_data and getattr(field_data, "value", None):
|
|
201
|
+
field_has_value = True
|
|
202
|
+
|
|
203
|
+
if not field_has_value:
|
|
204
|
+
return True
|
|
123
205
|
|
|
124
|
-
|
|
125
|
-
for (
|
|
126
|
-
field_name,
|
|
127
|
-
field_config,
|
|
128
|
-
) in matching_action.custom_privacy_request_fields.items():
|
|
129
|
-
if isinstance(field_config, LocationCustomPrivacyRequestField):
|
|
130
|
-
# This is a location field - check if it's required
|
|
131
|
-
if field_config.required:
|
|
132
|
-
# Check if this field has a value in the request
|
|
133
|
-
field_has_value = False
|
|
134
|
-
if privacy_request_data.custom_privacy_request_fields:
|
|
135
|
-
field_data = (
|
|
136
|
-
privacy_request_data.custom_privacy_request_fields.get(
|
|
137
|
-
field_name
|
|
138
|
-
)
|
|
139
|
-
)
|
|
140
|
-
if (
|
|
141
|
-
field_data
|
|
142
|
-
and hasattr(field_data, "value")
|
|
143
|
-
and field_data.value
|
|
144
|
-
):
|
|
145
|
-
field_has_value = True
|
|
146
|
-
|
|
147
|
-
if not field_has_value:
|
|
148
|
-
raise PrivacyRequestError(
|
|
149
|
-
f"Location is required for field '{field_name}' but was not provided",
|
|
150
|
-
privacy_request_data.model_dump(mode="json"),
|
|
151
|
-
)
|
|
206
|
+
return False
|
|
152
207
|
|
|
153
208
|
# pylint: disable=too-many-branches
|
|
154
209
|
def create_privacy_request(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link data-next-font="" rel="preconnect" href="/" crossorigin="anonymous"/><link rel="preload" href="/_next/static/css/295d729ea1b11885.css" as="style"/><link rel="stylesheet" href="/_next/static/css/295d729ea1b11885.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-2766492c5dbceb0a.js" defer=""></script><script src="/_next/static/chunks/framework-c92fc3344e6fd165.js" defer=""></script><script src="/_next/static/chunks/main-090643377c8254e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-c1c2f757b1f3da12.js" defer=""></script><script src="/_next/static/chunks/pages/404-2eb8aed4939f1142.js" defer=""></script><script src="/_next/static/_IxwgneyQjdSaZFEF3Tqu/_buildManifest.js" defer=""></script><script src="/_next/static/_IxwgneyQjdSaZFEF3Tqu/_ssgManifest.js" defer=""></script><style>.data-ant-cssinjs-cache-path{content:"";}</style></head><body><div id="__next"><div style="height:100%;display:flex"></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/404","query":{},"buildId":"_IxwgneyQjdSaZFEF3Tqu","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
self.__BUILD_MANIFEST=function(s,e,t,a,c,n,i,d,o,r,p,g,u,f,m,j,k,b,h,y,l,v,I,F,x,_,w,U,q,N,A,S,B,C,z,D,E,L,M,T,P,G,H,J,K,O,Q,R,V,W,X,Y,Z,$,ss,se,st,sa){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":[q,"static/chunks/pages/index-b74d1e8608ae5b5d.js"],"/404":["static/chunks/pages/404-2eb8aed4939f1142.js"],"/_error":["static/chunks/pages/_error-bede3a8288930dcf.js"],"/add-systems":[s,q,"static/chunks/pages/add-systems-19214babd1f219e3.js"],"/add-systems/manual":[e,s,t,a,n,f,c,i,r,m,l,N,A,"static/chunks/pages/add-systems/manual-4ec03eed67572861.js"],"/add-systems/multiple":[r,j,S,"static/chunks/pages/add-systems/multiple-2ca59996860a33c5.js"],"/consent":["static/chunks/pages/consent-d2bf72508c3cad55.js"],"/consent/configure":[r,j,"static/chunks/pages/consent/configure-fb5017ff5fa54fcc.js"],"/consent/configure/add-vendors":[r,j,S,"static/chunks/pages/consent/configure/add-vendors-7a258b7ecd6da4b8.js"],"/consent/privacy-experience":[f,B,"static/chunks/pages/consent/privacy-experience-92182be6603c2842.js"],"/consent/privacy-experience/new":[e,d,k,p,b,C,"static/chunks/pages/consent/privacy-experience/new-a5e738a234dadc7e.js"],"/consent/privacy-experience/[id]":[e,d,k,p,b,C,"static/chunks/pages/consent/privacy-experience/[id]-e1e2fd704ac2d71d.js"],"/consent/privacy-notices":[B,"static/chunks/pages/consent/privacy-notices-ab54b19609bff325.js"],"/consent/privacy-notices/new":[e,d,k,p,b,z,"static/chunks/pages/consent/privacy-notices/new-b79bcb93b5f4c734.js"],"/consent/privacy-notices/[id]":[e,d,k,p,b,z,"static/chunks/pages/consent/privacy-notices/[id]-5fc78b78a51c239c.js"],"/consent/properties":[h,D,"static/chunks/pages/consent/properties-069f4e3ee96ebf77.js"],"/consent/reporting":[s,"static/chunks/2150-930ffaf2c4718edc.js","static/chunks/pages/consent/reporting-c1a3caf3c286bf5d.js"],"/data-catalog":[e,t,a,c,"static/css/95ac327e5d70148d.css","static/chunks/pages/data-catalog-b7326c51d88cc2cc.js"],"/data-catalog/[systemId]/projects":[e,t,a,c,v,o,"static/chunks/pages/data-catalog/[systemId]/projects-99573a1ee3ef8f4c.js"],"/data-catalog/[systemId]/projects/[projectUrn]":[E,"static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]-4a1af12d2d7cd660.js"],"/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]":[e,s,t,a,c,v,L,o,"static/chunks/pages/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]-2fa4b3a58f75f81d.js"],"/data-catalog/[systemId]/resources":[E,"static/chunks/pages/data-catalog/[systemId]/resources-6e429b7511028d60.js"],"/data-catalog/[systemId]/resources/[resourceUrn]":[e,s,t,a,c,v,L,o,"static/chunks/pages/data-catalog/[systemId]/resources/[resourceUrn]-5b31e3d7727b917a.js"],"/data-discovery/action-center":[I,"static/chunks/pages/data-discovery/action-center-040813022f0890c9.js"],"/data-discovery/action-center/[monitorId]":[e,s,t,a,i,I,M,F,"static/chunks/pages/data-discovery/action-center/[monitorId]-0d512528b498d75c.js"],"/data-discovery/action-center/[monitorId]/[systemId]":[e,s,t,a,i,r,l,I,M,"static/css/23cf870196941c9a.css","static/chunks/pages/data-discovery/action-center/[monitorId]/[systemId]-5b57f9132426fe52.js"],"/data-discovery/activity":[s,u,"static/chunks/pages/data-discovery/activity-a28cc0e23bbe4fc8.js"],"/data-discovery/detection":[s,i,u,T,"static/chunks/pages/data-discovery/detection-11b07cf2d91b17ef.js"],"/data-discovery/detection/[resourceUrn]":[s,i,u,T,"static/chunks/pages/data-discovery/detection/[resourceUrn]-844a8de0d1b506e2.js"],"/data-discovery/discovery":[e,s,t,a,c,i,u,P,o,"static/chunks/pages/data-discovery/discovery-ed4723e1b67d890e.js"],"/data-discovery/discovery/[resourceUrn]":[e,s,t,a,c,i,u,P,o,"static/chunks/pages/data-discovery/discovery/[resourceUrn]-5525cf287d4ab493.js"],"/datamap":[s,a,"static/chunks/255-1bc0cbef7a59cdc6.js",m,G,"static/chunks/pages/datamap-7d22222608ec3aac.js"],"/dataset":[g,y,"static/chunks/pages/dataset-0e3a6ac4797ffbbb.js"],"/dataset/new":[s,g,y,"static/chunks/pages/dataset/new-d514cd4ec62e3b03.js"],"/dataset/[datasetId]":["static/chunks/9729-fcf6ff4e3534e4a8.js",x,"static/chunks/pages/dataset/[datasetId]-60a4a9eb4aab4c11.js"],"/dataset/[datasetId]/[collectionName]":[e,t,a,n,c,x,o,"static/chunks/pages/dataset/[datasetId]/[collectionName]-007965429368d9a3.js"],"/dataset/[datasetId]/[collectionName]/[...subfieldNames]":[e,t,a,n,c,x,o,"static/chunks/pages/dataset/[datasetId]/[collectionName]/[...subfieldNames]-0abd30eada811b5b.js"],"/datastore-connection":["static/css/5f393dea1c0d031c.css","static/chunks/pages/datastore-connection-223c2d1ded51bfb1.js"],"/datastore-connection/new":[e,s,n,g,f,H,y,J,"static/chunks/pages/datastore-connection/new-b6838162200141b3.js"],"/datastore-connection/[id]":[e,s,n,g,H,y,J,"static/chunks/pages/datastore-connection/[id]-816e02b6cbe4a684.js"],"/fides-js-docs":["static/chunks/2fbcc6de-a6c61724c327e9fa.js","static/chunks/e3251fe7-5777b5d778e6fffa.js",e,t,a,n,g,"static/chunks/5619-9b50cec521203989.js",K,"static/css/0b4b1b65cc874774.css","static/chunks/5596-29a7c8322530b7cf.js","static/chunks/pages/fides-js-docs-1f4335dca5c09860.js"],"/integrations":[e,s,t,a,n,d,O,Q,o,"static/chunks/pages/integrations-331544e9b85c4ac2.js"],"/integrations/[id]":[e,s,t,a,n,d,O,i,p,Q,o,"static/chunks/pages/integrations/[id]-153eb88ab4e7dc6d.js"],"/login":["static/chunks/pages/login-0cb0eb44bf2dd24c.js"],"/login/[provider]":["static/chunks/pages/login/[provider]-c58beef131c3a82d.js"],"/messaging":[e,t,"static/chunks/346-aa3b88efb85f2e28.js","static/chunks/pages/messaging-b5f7d6afdecd013d.js"],"/messaging/add-template":[R,"static/chunks/pages/messaging/add-template-e3f93462a08251bf.js"],"/messaging/[id]":[R,"static/chunks/pages/messaging/[id]-e8d2140787045acd.js"],"/poc/ant-components":["static/chunks/pages/poc/ant-components-248ad9f65a872442.js"],"/poc/form-experiments/AntForm":["static/chunks/pages/poc/form-experiments/AntForm-aedb66a62042b10a.js"],"/poc/form-experiments/FormikAntFormItem":["static/chunks/pages/poc/form-experiments/FormikAntFormItem-018df38b7cd77fdb.js"],"/poc/form-experiments/FormikControlled":["static/chunks/pages/poc/form-experiments/FormikControlled-6ca9099d03aab817.js"],"/poc/form-experiments/FormikField":["static/chunks/pages/poc/form-experiments/FormikField-0f2c90786ea005a4.js"],"/poc/form-experiments/FormikSpreadField":[V,"static/chunks/pages/poc/form-experiments/FormikSpreadField-af097d661f6abcf4.js"],"/poc/forms":[V,"static/chunks/pages/poc/forms-200b51a725f8b2d1.js"],"/poc/table-migration":[r,j,"static/chunks/pages/poc/table-migration-29fb7b39f8962650.js"],"/privacy-requests":[e,s,"static/chunks/3550-83cb70e80cbe41ba.js",W,"static/chunks/pages/privacy-requests-7af00f72cf694077.js"],"/privacy-requests/configure":["static/chunks/pages/privacy-requests/configure-8f577df28ebca869.js"],"/privacy-requests/configure/storage":[s,"static/chunks/pages/privacy-requests/configure/storage-479890582973deaf.js"],"/privacy-requests/[id]":[s,W,"static/css/073713cd1eddda79.css","static/chunks/pages/privacy-requests/[id]-7dac2302f573f5ee.js"],"/properties":[h,D,"static/chunks/pages/properties-08472b2a6bf1d392.js"],"/properties/add-property":[h,X,"static/chunks/pages/properties/add-property-8964c2300206bc89.js"],"/properties/[id]":[h,X,"static/chunks/pages/properties/[id]-57a75c7e9659271a.js"],"/reporting/datamap":[e,s,t,a,K,m,_,G,"static/chunks/pages/reporting/datamap-f7753e9effae3816.js"],"/settings/about":[Y,"static/chunks/pages/settings/about-6c4904c157477285.js"],"/settings/about/alpha":[Y,"static/chunks/pages/settings/about/alpha-68eaac2d79133679.js"],"/settings/consent":[p,"static/chunks/pages/settings/consent-4d658222ec800511.js"],"/settings/consent/[configuration_id]/[purpose_id]":["static/chunks/pages/settings/consent/[configuration_id]/[purpose_id]-f3e6e74e0efb005c.js"],"/settings/custom-fields":[s,"static/chunks/pages/settings/custom-fields-2fcd95c41e578d57.js"],"/settings/custom-fields/new":[e,Z,$,"static/chunks/pages/settings/custom-fields/new-469ad83c8cfa1290.js"],"/settings/custom-fields/[id]":[e,Z,$,"static/chunks/pages/settings/custom-fields/[id]-bd1042a0e9be6aff.js"],"/settings/domain-records":["static/chunks/pages/settings/domain-records-744f669431b84f71.js"],"/settings/domains":["static/chunks/pages/settings/domains-a3275554ffe8e640.js"],"/settings/email-templates":["static/chunks/pages/settings/email-templates-604790638c656fbd.js"],"/settings/locations":[ss,F,"static/chunks/pages/settings/locations-be2a885150adc133.js"],"/settings/messaging-providers":[s,w,"static/chunks/pages/settings/messaging-providers-8d92be437793c96f.js"],"/settings/messaging-providers/new":[e,s,t,d,se,w,st,"static/chunks/pages/settings/messaging-providers/new-8bf1821722b082e9.js"],"/settings/messaging-providers/[key]":[e,s,t,d,se,w,st,"static/chunks/pages/settings/messaging-providers/[key]-77239269acc2d31a.js"],"/settings/organization":["static/chunks/pages/settings/organization-3c86162afe9759df.js"],"/settings/privacy-requests":[s,"static/chunks/pages/settings/privacy-requests-97221067330c0c27.js"],"/settings/regulations":[ss,F,"static/chunks/pages/settings/regulations-4fe3b90747d885e5.js"],"/systems":[e,s,t,a,"static/chunks/1896-49010da5c2705fc5.js",_,"static/chunks/pages/systems-6c91bdea40875227.js"],"/systems/configure/[id]":[e,s,t,a,n,f,c,i,r,m,l,N,A,"static/chunks/pages/systems/configure/[id]-4d470bbf199a2f9c.js"],"/systems/configure/[id]/test-datasets":[g,"static/chunks/pages/systems/configure/[id]/test-datasets-2deb6becece69d46.js"],"/taxonomy":["static/chunks/678d4732-50255cc09048e643.js",e,s,t,a,d,"static/chunks/6148-59a59d5c5925344f.js",_,"static/css/34a7eb08b86ddb57.css","static/chunks/pages/taxonomy-3059aba38adefa56.js"],"/user-management":[U,"static/chunks/pages/user-management-562624e5461083ec.js"],"/user-management/new":[U,sa,"static/chunks/pages/user-management/new-629c88e90699369b.js"],"/user-management/profile/[id]":[U,sa,"static/chunks/pages/user-management/profile/[id]-98f737e735eaa0f0.js"],sortedPages:["/","/404","/_app","/_error","/add-systems","/add-systems/manual","/add-systems/multiple","/consent","/consent/configure","/consent/configure/add-vendors","/consent/privacy-experience","/consent/privacy-experience/new","/consent/privacy-experience/[id]","/consent/privacy-notices","/consent/privacy-notices/new","/consent/privacy-notices/[id]","/consent/properties","/consent/reporting","/data-catalog","/data-catalog/[systemId]/projects","/data-catalog/[systemId]/projects/[projectUrn]","/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn]","/data-catalog/[systemId]/resources","/data-catalog/[systemId]/resources/[resourceUrn]","/data-discovery/action-center","/data-discovery/action-center/[monitorId]","/data-discovery/action-center/[monitorId]/[systemId]","/data-discovery/activity","/data-discovery/detection","/data-discovery/detection/[resourceUrn]","/data-discovery/discovery","/data-discovery/discovery/[resourceUrn]","/datamap","/dataset","/dataset/new","/dataset/[datasetId]","/dataset/[datasetId]/[collectionName]","/dataset/[datasetId]/[collectionName]/[...subfieldNames]","/datastore-connection","/datastore-connection/new","/datastore-connection/[id]","/fides-js-docs","/integrations","/integrations/[id]","/login","/login/[provider]","/messaging","/messaging/add-template","/messaging/[id]","/poc/ant-components","/poc/form-experiments/AntForm","/poc/form-experiments/FormikAntFormItem","/poc/form-experiments/FormikControlled","/poc/form-experiments/FormikField","/poc/form-experiments/FormikSpreadField","/poc/forms","/poc/table-migration","/privacy-requests","/privacy-requests/configure","/privacy-requests/configure/storage","/privacy-requests/[id]","/properties","/properties/add-property","/properties/[id]","/reporting/datamap","/settings/about","/settings/about/alpha","/settings/consent","/settings/consent/[configuration_id]/[purpose_id]","/settings/custom-fields","/settings/custom-fields/new","/settings/custom-fields/[id]","/settings/domain-records","/settings/domains","/settings/email-templates","/settings/locations","/settings/messaging-providers","/settings/messaging-providers/new","/settings/messaging-providers/[key]","/settings/organization","/settings/privacy-requests","/settings/regulations","/systems","/systems/configure/[id]","/systems/configure/[id]/test-datasets","/taxonomy","/user-management","/user-management/new","/user-management/profile/[id]"]}}("static/chunks/431-78bf05f35d7eec4f.js","static/chunks/8765-f622a35b40a7ec63.js","static/chunks/9278-08cc704317fe535e.js","static/chunks/5163-e682273cd76a7d07.js","static/chunks/409-5c3d31163028339f.js","static/chunks/699-8ca44b0de9fa20f0.js","static/chunks/7045-14e955890f1147e4.js","static/chunks/3662-f6a1ddca5ee42076.js","static/css/d2d4e9a6923e6730.css","static/chunks/401-ffe4e8436e1eceb9.js","static/chunks/5279-12c9cbdc67ad7b14.js","static/chunks/6527-0eed08abe252a918.js","static/chunks/8002-ed832921ad190832.js","static/chunks/5277-e8a036319456127f.js","static/chunks/7218-e2983b96b95e33b4.js","static/chunks/3923-98bea73b618292aa.js","static/chunks/6419-9b3a86af57c86791.js","static/chunks/6277-182efc294d413f64.js","static/chunks/2040-fdecc41a18e40bdc.js","static/chunks/5574-c31ea831371610d5.js","static/chunks/3585-f728d32fda6f1ac1.js","static/chunks/6882-dbe0a25dcf1a8ee0.js","static/chunks/7725-f2a7be705b75dcc3.js","static/css/10994e916bc9a00a.css","static/chunks/9226-4a7027057f55ca2a.js","static/chunks/4718-3a412bdb90add82f.js","static/chunks/502-0d9f4ac29ef34a1c.js","static/chunks/7476-d055aa931da47ac0.js","static/css/972dc7eef106ee7c.css","static/chunks/7079-50571e9f3269d74d.js","static/css/304c6f148886a8d4.css","static/chunks/796-02086581996a0548.js","static/chunks/6853-7004a8c420b1ca02.js","static/chunks/1817-1ad037b7d6d2f6d2.js","static/chunks/6954-4b24e1731c1cc3b3.js","static/chunks/5783-d119cb132abd8a91.js","static/chunks/3872-04d3afbfa41a7782.js","static/chunks/3855-ed226b8a8050bd40.js","static/chunks/7929-0fd0d4948bc8d70e.js","static/chunks/5309-3b6cf0cc9d0c6a83.js","static/chunks/9046-b6616ba7b59d947e.js","static/chunks/504-88caa30c03374e9b.js","static/chunks/1467-8808ec8836e033f9.js","static/chunks/4608-0c6ef78e30a51f84.js","static/chunks/9187-7438242f0d380bb0.js","static/chunks/1316-2606e19807c08aa5.js","static/chunks/155-b4337d0826d5addc.js","static/chunks/7630-d0d3a0fe3f95e971.js","static/chunks/2921-66f65496c3a09316.js","static/chunks/4558-8305aee48def1dcd.js","static/chunks/5185-51eaa78e3ed6bfb7.js","static/chunks/1115-90baef2a89f361ad.js","static/chunks/2962-e92d525bf570a9a3.js","static/chunks/5643-10a36584c399526c.js","static/chunks/9826-ccedc28e978ca9e1.js","static/chunks/9037-453224ba3ee65b13.js","static/chunks/7158-04745cc8d684b2e7.js","static/chunks/3696-90c8b336bbc46782.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|