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

Heap - Erasure #3599

Merged
merged 7 commits into from
Jul 19, 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 @@ -43,6 +43,7 @@ The types of changes are:

- Record when consent is served [#3777](https://github.com/ethyca/fides/pull/3777)
- Add an `active` property to taxonomy elements [#3784](https://github.com/ethyca/fides/pull/3784)
- Erasure support for Heap [#3599](https://github.com/ethyca/fides/pull/3599)

### Fixed
- Privacy notice UI's list of possible regions now matches the backend's list [#3787](https://github.com/ethyca/fides/pull/3787)
Expand Down
51 changes: 51 additions & 0 deletions data/saas/config/heap_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
saas_config:
fides_key: <instance_fides_key>
name: Heap
type: heap
description: A sample schema representing the Heap connector for Fides
version: 0.1.0

connector_params:
- name: domain
default_value: heapanalytics.com
- name: app_id
label: App ID
- name: api_key
label: API Key

client_config:
protocol: https
host: <domain>
authentication:
strategy: heap
configuration:
username: <app_id>
password: <api_key>

test_request:
method: POST
path: /api/public/v0/auth_token
client_config:
protocol: https
host: <domain>
authentication:
strategy: basic
configuration:
username: <app_id>
password: <api_key>

endpoints:
- name: user
requests:
delete:
method: POST
path: /api/public/v0/user_deletion
body: |
{
"users": [{
"identity": "<email>"
}]
}
param_values:
- name: email
identity: email
7 changes: 7 additions & 0 deletions data/saas/dataset/heap_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dataset:
- fides_key: <instance_fides_key>
name: heap
description: A sample dataset representing the Heap connector for Fides
collections:
- name: user
fields: []
6 changes: 6 additions & 0 deletions data/saas/icon/heap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from typing import Dict, Optional, cast

from requests import PreparedRequest, post

from fides.api.common_exceptions import FidesopsException
from fides.api.models.connectionconfig import ConnectionConfig
from fides.api.schemas.saas.strategy_configuration import StrategyConfiguration
from fides.api.service.authentication.authentication_strategy import (
AuthenticationStrategy,
)
from fides.api.util.saas_util import assign_placeholders


class HeapAuthenticationConfiguration(StrategyConfiguration):
"""
Parameters to authorize a Heap connection
"""

username: str
password: str


class HeapAuthenticationStrategy(AuthenticationStrategy):
"""
Generates a token from the provided key and secret.
Stores the expiration time to know when to refresh the token.
"""

name = "heap"
configuration_model = HeapAuthenticationConfiguration

def __init__(self, configuration: HeapAuthenticationConfiguration):
self.username = configuration.username
self.password = configuration.password

def add_authentication(
self, request: PreparedRequest, connection_config: ConnectionConfig
) -> PreparedRequest:
"""
Retrieves a token using the provided username and password
"""

secrets = cast(Dict, connection_config.secrets)
domain: Optional[str] = secrets.get("domain")
username: Optional[str] = assign_placeholders(self.username, secrets)
password: Optional[int] = assign_placeholders(self.password, secrets)

response = post(
url=f"https://{domain}/api/public/v0/auth_token",
auth=(username, password),
)

if response.ok:
json_response = response.json()
token = json_response.get("access_token")
else:
raise FidesopsException(f"Unable to get token {response.json()}")

request.headers["Authorization"] = f"Bearer {token}"
return request
35 changes: 35 additions & 0 deletions tests/fixtures/saas/heap_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import Any, Dict

import pydash
import pytest

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("heap")


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


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


@pytest.fixture
def heap_runner(
db,
cache,
heap_secrets,
) -> ConnectorRunner:
return ConnectorRunner(db, cache, "heap", heap_secrets)
30 changes: 30 additions & 0 deletions tests/ops/integration_tests/saas/test_heap_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest

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


@pytest.mark.integration_saas
class TestHeapConnector:
def test_connection(self, heap_runner: ConnectorRunner):
heap_runner.test_connection()

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

assert erasure_results == {
"heap_instance:user": 1,
}