Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict TCF Privacy Experience Config if TCF Disabled #4348

Merged
merged 3 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ The types of changes are:
- Forcing hidden sections to use display none [#4299](https://github.com/ethyca/fides/pull/4299)
- Handles Hubspot requiring and email to be formatted as email when processing an erasure [#4322](https://github.com/ethyca/fides/pull/4322)
- Minor CSS improvements for the consent/TCF banners and modals [#4334](https://github.com/ethyca/fides/pull/4334)
- Restrict TCF Privacy Experience Config if TCF is disabled [#4348](https://github.com/ethyca/fides/pull/4348)

### Changed
- Derive cookie storage info, privacy policy and legitimate interest disclosure URLs, and data retention data from the data map instead of directly from gvl.json [#4286](https://github.com/ethyca/fides/pull/4286)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const COMPONENT_MAP = new Map([
["overlay", "Overlay"],
["privacy_center", "Privacy center"],
["tcf_overlay", "TCF overlay"],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't break the cypress tests with this did I? I think I see those same failures on main?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup no worries—we know about the failures on main and are working on it separately! thanks for updating this 👍

]);

export const BANNER_ENABLED_MAP = new Map([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from fides.common.api import scope_registry
from fides.common.api.scope_registry import PRIVACY_EXPERIENCE_UPDATE
from fides.common.api.v1 import urn_registry as urls
from fides.config import CONFIG

router = APIRouter(tags=["Privacy Experience Config"], prefix=urls.V1_URL_PREFIX)

Expand Down Expand Up @@ -86,6 +87,11 @@ def experience_config_list(
should_unescape = request.headers.get(UNESCAPE_SAFESTR_HEADER)
privacy_experience_config_query: Query = db.query(PrivacyExperienceConfig)

if not CONFIG.consent.tcf_enabled:
privacy_experience_config_query = privacy_experience_config_query.filter(
PrivacyExperienceConfig.component != ComponentType.tcf_overlay
)

Comment on lines +90 to +94
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the primary change of this PR!

if component:
privacy_experience_config_query = privacy_experience_config_query.filter(
PrivacyExperienceConfig.component == component
Expand Down
236 changes: 207 additions & 29 deletions tests/ops/api/v1/endpoints/test_privacy_experience_config_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,154 @@ def test_get_experience_config_list(
assert response.status_code == 200
resp = response.json()
assert (
resp["total"] == 5
) # Three default configs loaded on startup plus two here
resp["total"] == 4
) # Two default configs loaded on startup plus two here. TCF Experience is excluded.
assert resp["page"] == 1
assert resp["size"] == 50
data = resp["items"]
assert len(data) == 5
assert len(data) == 4

first_config = data[0]
assert first_config["id"] == experience_config_overlay.id
assert first_config["component"] == "overlay"
assert first_config["banner_enabled"] == "enabled_where_required"
assert first_config["disabled"] is False
assert first_config["regions"] == ["us_ca"]
assert first_config["version"] == 1.0
assert first_config["created_at"] is not None
assert first_config["updated_at"] is not None
assert (
first_config["experience_config_history_id"]
== experience_config_overlay.experience_config_history_id
)

second_config = data[1]
assert second_config["id"] == experience_config_privacy_center.id
assert (
second_config["description"] == "user's description <script />"
) # Unescaped due to header
assert second_config["component"] == "privacy_center"
assert second_config["banner_enabled"] is None
assert second_config["disabled"] is True
assert second_config["regions"] == ["us_co"]
assert second_config["created_at"] is not None
assert second_config["updated_at"] is not None
assert second_config["version"] == 1.0
assert (
second_config["experience_config_history_id"]
== experience_config_privacy_center.experience_config_history_id
)

third_config = data[3]
assert third_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert third_config["is_default"] is True
assert third_config["component"] == "privacy_center"
assert third_config["regions"] == []
assert third_config["version"] == 1.0
assert third_config["created_at"] is not None
assert third_config["updated_at"] is not None

fourth_config = data[4]
assert fourth_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert fourth_config["is_default"] is True
assert fourth_config["disabled"] is False
assert fourth_config["regions"] == []
assert fourth_config["component"] == "overlay"

@pytest.mark.usefixtures(
"privacy_experience_privacy_center", "privacy_experience_overlay"
)
def test_get_experience_config_list(
self,
api_client: TestClient,
url,
generate_auth_header,
experience_config_privacy_center,
experience_config_overlay,
) -> None:
unescape_header = {"Unescape-Safestr": "true"}
auth_header = generate_auth_header(scopes=[scopes.PRIVACY_EXPERIENCE_READ])
response = api_client.get(url, headers={**auth_header, **unescape_header})
assert response.status_code == 200
resp = response.json()
assert (
resp["total"] == 4
) # Two default configs loaded on startup plus two here. TCF Experience is excluded.
assert resp["page"] == 1
assert resp["size"] == 50
data = resp["items"]
assert len(data) == 4

first_config = data[0]
assert first_config["id"] == experience_config_overlay.id
assert first_config["component"] == "overlay"
assert first_config["banner_enabled"] == "enabled_where_required"
assert first_config["disabled"] is False
assert first_config["regions"] == ["us_ca"]
assert first_config["version"] == 1.0
assert first_config["created_at"] is not None
assert first_config["updated_at"] is not None
assert (
first_config["experience_config_history_id"]
== experience_config_overlay.experience_config_history_id
)

second_config = data[1]
assert second_config["id"] == experience_config_privacy_center.id
assert (
second_config["description"] == "user's description <script />"
) # Unescaped due to header
assert second_config["component"] == "privacy_center"
assert second_config["banner_enabled"] is None
assert second_config["disabled"] is True
assert second_config["regions"] == ["us_co"]
assert second_config["created_at"] is not None
assert second_config["updated_at"] is not None
assert second_config["version"] == 1.0
assert (
second_config["experience_config_history_id"]
== experience_config_privacy_center.experience_config_history_id
)

third_config = data[3]
assert third_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert third_config["is_default"] is True
assert third_config["component"] == "privacy_center"
assert third_config["regions"] == []
assert third_config["version"] == 1.0
assert third_config["created_at"] is not None
assert third_config["updated_at"] is not None

fourth_config = data[4]
assert fourth_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert fourth_config["is_default"] is True
assert fourth_config["disabled"] is False
assert fourth_config["regions"] == []
assert fourth_config["component"] == "overlay"

@pytest.mark.usefixtures(
"privacy_experience_privacy_center", "privacy_experience_overlay"
)
def test_get_experience_config_list(
self,
api_client: TestClient,
url,
generate_auth_header,
experience_config_privacy_center,
experience_config_overlay,
) -> None:
unescape_header = {"Unescape-Safestr": "true"}
auth_header = generate_auth_header(scopes=[scopes.PRIVACY_EXPERIENCE_READ])
response = api_client.get(url, headers={**auth_header, **unescape_header})
assert response.status_code == 200
resp = response.json()
assert (
resp["total"] == 4
) # Two default configs loaded on startup plus two here. TCF Experience is excluded.
assert resp["page"] == 1
assert resp["size"] == 50
data = resp["items"]
assert len(data) == 4

first_config = data[0]
assert first_config["id"] == experience_config_overlay.id
Expand Down Expand Up @@ -116,29 +258,74 @@ def test_get_experience_config_list(
)

third_config = data[2]
assert third_config["id"] == "a4974670-abad-471f-9084-2cb-tcf-over"
assert third_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert third_config["is_default"] is True
assert third_config["component"] == "tcf_overlay"
assert third_config["component"] == "privacy_center"
assert third_config["regions"] == []
assert third_config["version"] == 1.0
assert third_config["created_at"] is not None
assert third_config["updated_at"] is not None

fourth_config = data[3]
assert fourth_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert fourth_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert fourth_config["is_default"] is True
assert fourth_config["component"] == "privacy_center"
assert fourth_config["disabled"] is False
assert fourth_config["regions"] == []
assert fourth_config["version"] == 1.0
assert fourth_config["created_at"] is not None
assert fourth_config["updated_at"] is not None
assert fourth_config["component"] == "overlay"

response = api_client.get(
url + "?component=tcf_overlay", headers={**auth_header, **unescape_header}
)
# Even if the TCF Overlay is requested it doesn't show up
assert response.status_code == 200
assert response.json()["items"] == []
assert response.json()["total"] == 0

@pytest.mark.usefixtures("enable_tcf")
def test_get_tcf_experience_config(
self,
api_client: TestClient,
url,
generate_auth_header,
) -> None:
"""TCF Experience Config is returned if TCF is enabled"""
unescape_header = {"Unescape-Safestr": "true"}
auth_header = generate_auth_header(scopes=[scopes.PRIVACY_EXPERIENCE_READ])
response = api_client.get(url, headers={**auth_header, **unescape_header})
assert response.status_code == 200
resp = response.json()
assert (
resp["total"] == 3
) # All three default configs loaded on startup including TCF Experience
assert resp["page"] == 1
assert resp["size"] == 50
data = resp["items"]
assert len(data) == 3

first_config = data[0]
assert first_config["id"] == "a4974670-abad-471f-9084-2cb-tcf-over"
assert first_config["is_default"] is True
assert first_config["component"] == "tcf_overlay"
assert first_config["regions"] == []
assert first_config["version"] == 1.0
assert first_config["created_at"] is not None
assert first_config["updated_at"] is not None

fifth_config = data[4]
assert fifth_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert fifth_config["is_default"] is True
assert fifth_config["disabled"] is False
assert fifth_config["regions"] == []
assert fifth_config["component"] == "overlay"
second_config = data[1]
assert second_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert second_config["is_default"] is True
assert second_config["component"] == "privacy_center"
assert second_config["regions"] == []
assert second_config["version"] == 1.0
assert second_config["created_at"] is not None
assert second_config["updated_at"] is not None

third_config = data[2]
assert third_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert third_config["is_default"] is True
assert third_config["disabled"] is False
assert third_config["regions"] == []
assert third_config["component"] == "overlay"

@pytest.mark.usefixtures(
"privacy_experience_privacy_center",
Expand Down Expand Up @@ -182,11 +369,11 @@ def test_get_experience_config_show_disabled_false_filter(
)
assert response.status_code == 200
resp = response.json()
assert resp["total"] == 4
assert resp["total"] == 3
assert resp["page"] == 1
assert resp["size"] == 50
data = resp["items"]
assert len(data) == 4
assert len(data) == 3

config = data[0]
assert config["id"] == experience_config_overlay.id
Expand All @@ -201,16 +388,7 @@ def test_get_experience_config_show_disabled_false_filter(
== experience_config_overlay.experience_config_history_id
)

second_config = data[1]
assert second_config["id"] == "a4974670-abad-471f-9084-2cb-tcf-over"
assert second_config["is_default"] is True
assert second_config["component"] == "tcf_overlay"
assert second_config["disabled"] is False
assert second_config["version"] == 1.0
assert second_config["created_at"] is not None
assert second_config["updated_at"] is not None

third_config = data[2]
third_config = data[1]
assert third_config["id"] == "pri-097a-d00d-40b6-a08f-f8e50def-pri"
assert third_config["is_default"] is True
assert third_config["component"] == "privacy_center"
Expand All @@ -219,7 +397,7 @@ def test_get_experience_config_show_disabled_false_filter(
assert third_config["created_at"] is not None
assert third_config["updated_at"] is not None

fourth_config = data[3]
fourth_config = data[2]
assert fourth_config["id"] == "pri-7ae3-f06b-4096-970f-0bbbdef-over"
assert fourth_config["is_default"] is True
assert fourth_config["disabled"] is False
Expand Down
Loading