Skip to content

Commit

Permalink
CON-9 Talkable Connector (#4589)
Browse files Browse the repository at this point in the history
Co-authored-by: Adrian Galvan <adrian@ethyca.com>
  • Loading branch information
RobertKeyser and galvana authored Feb 6, 2024
1 parent 43e3385 commit 0135810
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The types of changes are:
### Added

- Add enum and registry of supported languages [#4592](https://github.com/ethyca/fides/pull/4592)
- Access and erasure support for Talkable [#4589](https://github.com/ethyca/fides/pull/4589)

### Fixed

Expand Down
60 changes: 60 additions & 0 deletions data/saas/config/talkable_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
saas_config:
fides_key: <instance_fides_key>
name: Talkable
type: talkable
description: A sample schema representing the talkable connector for Fides
version: 0.1.0

connector_params:
- name: domain
default_value: www.talkable.com
- name: site_slug
label: Site slug
description: Your Talkable site ID
- name: api_key
label: API key
sensitive: True

client_config:
protocol: https
host: <domain>
authentication:
strategy: bearer
configuration:
token: <api_key>

test_request:
method: GET
path: /api/v2/campaigns
query_params:
- name: site_slug
value: <site_slug>
param_values:
- name: site_slug
connector_param: site_slug

endpoints:
- name: person
requests:
read:
method: GET
path: /api/v2/people/<email>/personal_data
query_params:
- name: site_slug
value: <site_slug>
data_path: result.person
param_values:
- name: email
identity: email
- name: site_slug
connector_param: site_slug
update:
method: POST
path: /api/v2/people/<email>/anonymize
body: |
{"site_slug":"<site_slug>"}
param_values:
- name: email
identity: email
- name: site_slug
connector_param: site_slug
63 changes: 63 additions & 0 deletions data/saas/dataset/talkable_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
dataset:
- fides_key: <instance_fides_key>
name: Talkable Dataset
description: A sample dataset representing the talkable connector for Fides
collections:
- name: person
fields:
- name: created_at
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: customer_id
data_categories: [user.unique_id]
fidesops_meta:
primary_key: True
- name: email
data_categories: [user.contact.email]
fidesops_meta:
data_type: string
- name: first_name
data_categories: [user.name.first]
fidesops_meta:
data_type: string
- name: last_name
data_categories: [user.name.last]
fidesops_meta:
data_type: string
- name: username
data_categories: [user.account.username]
fidesops_meta:
data_type: string
- name: origins
fidesops_meta:
data_type: "object[]"
fields:
- name: type
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: created_at
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: ip_address
data_categories: [user.device.ip_address]
fidesops_meta:
data_type: string
- name: order_number
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: subtotal
data_categories: [system.operations]
fidesops_meta:
data_type: integer
- name: shipping_address
data_categories: [user.contact.address]
fidesops_meta:
data_type: string
- name: shipping_zip
data_categories: [user.contact.address.postal_code]
fidesops_meta:
data_type: string
31 changes: 31 additions & 0 deletions data/saas/icon/talkable.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions tests/fixtures/saas/talkable_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from typing import Any, Dict, Generator

import pydash
import pytest
import requests

from tests.ops.integration_tests.saas.connector_runner import (
ConnectorRunner,
generate_random_email,
)
from tests.ops.test_helpers.vault_client import get_secrets

secrets = get_secrets("talkable")


@pytest.fixture(scope="session")
def talkable_secrets(saas_config) -> Dict[str, Any]:
return {
"domain": pydash.get(saas_config, "talkable.domain") or secrets["domain"],
"site_slug": pydash.get(saas_config, "talkable.site_slug")
or secrets["site_slug"],
"api_key": pydash.get(saas_config, "talkable.api_key") or secrets["api_key"],
}


@pytest.fixture(scope="session")
def talkable_identity_email(saas_config) -> str:
return (
pydash.get(saas_config, "talkable.identity_email") or secrets["identity_email"]
)


@pytest.fixture(scope="function")
def talkable_erasure_identity_email() -> str:
return generate_random_email()


@pytest.fixture(scope="function")
def talkable_erasure_data(
talkable_erasure_identity_email: str,
talkable_secrets,
) -> Generator:
# create the data needed for erasure tests here
base_url = f"https://{talkable_secrets['domain']}"
headers = {
"Authorization": f"Bearer {talkable_secrets['api_key']}",
}

# person
body = {
"site_slug": talkable_secrets["site_slug"],
"data": {
"first_name": "Ethyca",
"last_name": "RTF",
"email": talkable_erasure_identity_email,
"phone_number": "+19515551234",
"username": "ethycatrtf",
"gated_param_subscribed": False,
"unsubscribed": False,
},
}

people_response = requests.put(
url=f"{base_url}/api/v2/people/{talkable_erasure_identity_email}",
headers=headers,
json=body,
)
person = people_response.json()["result"]["person"]

yield person


@pytest.fixture
def talkable_runner(
db,
cache,
talkable_secrets,
) -> ConnectorRunner:
return ConnectorRunner(
db,
cache,
"talkable",
talkable_secrets,
)
44 changes: 44 additions & 0 deletions tests/ops/integration_tests/saas/test_talkable_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest

from fides.api.models.policy import Policy
from tests.ops.integration_tests.saas.connector_runner import ConnectorRunner


@pytest.mark.integration_saas
class TestTalkableConnector:
def test_connection(self, talkable_runner: ConnectorRunner):
talkable_runner.test_connection()

async def test_access_request(
self, talkable_runner: ConnectorRunner, policy, talkable_identity_email: str
):
access_results = await talkable_runner.access_request(
access_policy=policy, identities={"email": talkable_identity_email}
)

# verify we only returned data for our identity email
assert (
access_results["talkable_instance:person"][0]["email"]
== talkable_identity_email
)

async def test_non_strict_erasure_request(
self,
talkable_runner: ConnectorRunner,
policy: Policy,
erasure_policy_string_rewrite: Policy,
talkable_erasure_identity_email: str,
talkable_erasure_data,
):
(
access_results,
erasure_results,
) = await talkable_runner.non_strict_erasure_request(
access_policy=policy,
erasure_policy=erasure_policy_string_rewrite,
identities={"email": talkable_erasure_identity_email},
)

assert erasure_results == {
"talkable_instance:person": 1,
}

0 comments on commit 0135810

Please sign in to comment.