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

Jira connector #2350

Closed
wants to merge 1 commit into from
Closed
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
50 changes: 50 additions & 0 deletions data/saas/config/jira_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
saas_config:
fides_key: <instance_fides_key>
name: Jira SaaS Config
type: jira
description: A sample schema representing the Jira connector for Fides
version: 0.1.0

connector_params:
- name: domain
default_value: ethycaconnectors.atlassian.net
- name: api_key

client_config:
protocol: https
host: <domain>
authentication:
strategy: api_key
configuration:
headers:
- name: Authorization
value: Basic <api_key>

test_request:
method: GET
path: /rest/api/3/users/search

endpoints:
- name: user
requests:
read:
method: GET
path: /rest/api/3/user/search
query_params:
- name: query
value: <email>
param_values:
- name: email
identity: email
delete:
method: DELETE
path: /rest/api/3/user
query_params:
- name: accountId
value: <account_id>
param_values:
- name: account_id
references:
- dataset: <instance_fides_key>
field: user.accountId
direction: from
60 changes: 60 additions & 0 deletions data/saas/dataset/jira_dataset.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
dataset:
- fides_key: <instance_fides_key>
name: jira
description: A sample dataset representing the Jira connector for Fides
collections:
- name: user
fields:
- name: self
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: accountId
data_categories: [system.operations]
fidesops_meta:
primary_key: True
data_type: string
- name: accountType
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: emailAddress
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: avatarUrls
fidesops_meta:
data_type: object
fields:
- name: 48x48
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: 24x24
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: 16x16
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: 32x32
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: displayName
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: active
data_categories: [system.operations]
fidesops_meta:
data_type: boolean
- name: timeZone
data_categories: [system.operations]
fidesops_meta:
data_type: string
- name: locale
data_categories: [system.operations]
fidesops_meta:
data_type: string
7 changes: 7 additions & 0 deletions data/saas/saas_connector_registry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,10 @@ config = "data/saas/config/recharge_config.yml"
dataset = "data/saas/dataset/recharge_dataset.yml"
icon = "data/saas/icon/default.svg"
human_readable = "Recharge"

[jira]
config = "data/saas/config/jira_config.yml"
dataset = "data/saas/dataset/jira_dataset.yml"
icon = "data/saas/icon/default.svg"
human_readable = "Jira"

6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
170 changes: 170 additions & 0 deletions tests/ops/fixtures/saas/jira_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
from time import sleep
from typing import Any, Dict, Generator

import pydash
import pytest
import requests
from sqlalchemy.orm import Session
from multidimensional_urlencode import urlencode as multidimensional_urlencode


from fides.api.ops.models.connectionconfig import (
AccessLevel,
ConnectionConfig,
ConnectionType,
)
from fides.api.ops.models.datasetconfig import DatasetConfig
from fides.api.ops.util.saas_util import (
load_config_with_replacement,
load_dataset_with_replacement,
)
from fides.lib.cryptography import cryptographic_util
from tests.ops.test_helpers.vault_client import get_secrets
from tests.ops.test_helpers.saas_test_utils import poll_for_existence


secrets = get_secrets("jira")


@pytest.fixture(scope="session")
def jira_secrets(saas_config):
return {
"domain": pydash.get(saas_config, "jira.domain") or secrets["domain"],
"api_key": pydash.get(saas_config, "jira.api_key") or secrets["api_key"]
}


@pytest.fixture(scope="session")
def jira_identity_email(saas_config):
return (
pydash.get(saas_config, "jira.identity_email") or secrets["identity_email"]
)


@pytest.fixture(scope="function")
def jira_erasure_identity_email() -> str:
return f"{cryptographic_util.generate_secure_random_string(13)}@email.com"


@pytest.fixture
def jira_config() -> Dict[str, Any]:
return load_config_with_replacement(
"data/saas/config/jira_config.yml",
"<instance_fides_key>",
"jira_instance",
)


@pytest.fixture
def jira_dataset() -> Dict[str, Any]:
return load_dataset_with_replacement(
"data/saas/dataset/jira_dataset.yml",
"<instance_fides_key>",
"jira_instance",
)[0]


@pytest.fixture(scope="function")
def jira_connection_config(
db: Session, jira_config, jira_secrets
) -> Generator:
fides_key = jira_config["fides_key"]
connection_config = ConnectionConfig.create(
db=db,
data={
"key": fides_key,
"name": fides_key,
"connection_type": ConnectionType.saas,
"access": AccessLevel.write,
"secrets": jira_secrets,
"saas_config": jira_config,
},
)
yield connection_config
connection_config.delete(db)


@pytest.fixture
def jira_dataset_config(
db: Session,
jira_connection_config: ConnectionConfig,
jira_dataset: Dict[str, Any],
) -> Generator:
fides_key = jira_dataset["fides_key"]
jira_connection_config.name = fides_key
jira_connection_config.key = fides_key
jira_connection_config.save(db=db)
dataset = DatasetConfig.create(
db=db,
data={
"connection_config_id": jira_connection_config.id,
"fides_key": fides_key,
"dataset": jira_dataset,
},
)
yield dataset
dataset.delete(db=db)

@pytest.fixture(scope="function")
def jira_create_erasure_data(
jira_connection_config: ConnectionConfig, jira_erasure_identity_email: str
) -> None:

# sleep(60)

jira_secrets = jira_connection_config.secrets
base_url = f"https://{jira_secrets['domain']}"
headers = {
"Authorization": f"Basic {jira_secrets['api_key']}",
}


# user
body = {
"name": "Ethyca Test Erasure",
"emailAddress": jira_erasure_identity_email,
}

users_response = requests.post(url=f"{base_url}/rest/api/3/user", headers=headers, json=body)
user = users_response.json()
sleep(30)

error_message = f"User with email {jira_erasure_identity_email} could not be added to Jira"

user = poll_for_existence(
user_exists,
(jira_erasure_identity_email, jira_secrets),
error_message=error_message,
)

yield user

def user_exists(jira_erasure_identity_email: str, jira_secrets):
"""
Confirm whether contact exists by calling contact search by email api and comparing resulting firstname str.
Returns contact ID if it exists, returns None if it does not.
"""
base_url = f"https://{jira_secrets['domain']}"
body = {"query": [jira_erasure_identity_email]}
headers = {
"Authorization": f"Basic {jira_secrets['api_key']}",
}
user_response = requests.get(
url=f"{base_url}/rest/api/3/user/search",
headers=headers,
params=body,
)

# we expect 200 if contact doesn't exist
if 200 != user_response.status_code:
return None
if len(user_response.json()) == 0:
return None

return user_response.json()






Loading