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

🎉 Source Zendesk-Support: Implement OAuth2.0 #11162

Merged
merged 4 commits into from
Mar 16, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@
- name: Zendesk Support
sourceDefinitionId: 79c1aa37-dae3-42ae-b333-d1c105477715
dockerRepository: airbyte/source-zendesk-support
dockerImageTag: 0.2.0
dockerImageTag: 0.2.1
documentationUrl: https://docs.airbyte.io/integrations/sources/zendesk-support
icon: zendesk.svg
sourceType: api
Expand Down
107 changes: 80 additions & 27 deletions airbyte-config/init/src/main/resources/seed/source_specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8882,7 +8882,7 @@
path_in_connector_config:
- "credentials"
- "client_secret"
- dockerImage: "airbyte/source-zendesk-support:0.2.0"
- dockerImage: "airbyte/source-zendesk-support:0.2.1"
spec:
documentationUrl: "https://docs.airbyte.io/integrations/sources/zendesk-support"
connectionSpecification:
Expand All @@ -8892,8 +8892,7 @@
required:
- "start_date"
- "subdomain"
- "auth_method"
additionalProperties: false
additionalProperties: true
properties:
start_date:
type: "string"
Expand All @@ -8906,25 +8905,49 @@
pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$"
subdomain:
type: "string"
description: "The subdomain for your Zendesk Support"
auth_method:
title: "Subdomain"
description: "Identifier of your Zendesk Subdomain, like: https://{MY_SUBDOMAIN}.zendesk.com/,\
\ where MY_SUBDOMAIN is the value of your subdomain"
credentials:
title: "Authorization Method"
type: "object"
default: "api_token"
description: "Zendesk service provides 2 auth method: API token and OAuth2.\
\ Now only the first one is available. Another one will be added in the\
\ future."
description: "Zendesk service provides two authentication methods. Choose\
\ between: `OAuth2.0` or `API token`."
oneOf:
- title: "OAuth2.0"
type: "object"
required:
- "access_token"
additionalProperties: true
properties:
credentials:
type: "string"
const: "oauth2.0"
enum:
- "oauth2.0"
default: "oauth2.0"
order: 0
access_token:
type: "string"
title: "Access Token"
description: "The value of the API token generated. See the <a href=\"\
https://docs.airbyte.io/integrations/sources/zendesk-support\">docs</a>\
\ for more information."
airbyte_secret: true
- title: "API Token"
type: "object"
required:
- "email"
- "api_token"
additionalProperties: false
additionalProperties: true
properties:
auth_method:
credentials:
type: "string"
const: "api_token"
enum:
- "api_token"
default: "api_token"
order: 0
email:
title: "Email"
type: "string"
Expand All @@ -8936,25 +8959,55 @@
https://docs.airbyte.io/integrations/sources/zendesk-support\">docs</a>\
\ for more information."
airbyte_secret: true
- title: "OAuth2.0"
type: "object"
required:
- "access_token"
additionalProperties: false
properties:
auth_method:
type: "string"
const: "access_token"
access_token:
title: "Access Token"
type: "string"
description: "The value of the Access token generated. See the <a\
\ href=\"https://docs.airbyte.io/integrations/sources/zendesk-support\"\
>docs</a> for more information."
airbyte_secret: true
supportsNormalization: false
supportsDBT: false
supported_destination_sync_modes: []
advanced_auth:
auth_flow_type: "oauth2.0"
predicate_key:
- "credentials"
- "credentials"
predicate_value: "oauth2.0"
oauth_config_specification:
oauth_user_input_from_connector_config_specification:
type: "object"
additionalProperties: false
properties:
subdomain:
type: "string"
path_in_connector_config:
- "subdomain"
complete_oauth_output_specification:
type: "object"
additionalProperties: false
properties:
access_token:
type: "string"
path_in_connector_config:
- "credentials"
- "access_token"
complete_oauth_server_input_specification:
type: "object"
additionalProperties: false
properties:
client_id:
type: "string"
client_secret:
type: "string"
complete_oauth_server_output_specification:
type: "object"
additionalProperties: false
properties:
client_id:
type: "string"
path_in_connector_config:
- "credentials"
- "client_id"
client_secret:
type: "string"
path_in_connector_config:
- "credentials"
- "client_secret"
- dockerImage: "airbyte/source-zendesk-talk:0.1.3"
spec:
documentationUrl: "https://docs.airbyte.io/integrations/sources/zendesk-talk"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ COPY source_zendesk_support ./source_zendesk_support
ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]

LABEL io.airbyte.version=0.2.0
LABEL io.airbyte.version=0.2.1
LABEL io.airbyte.name=airbyte/source-zendesk-support
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ Customize `acceptance-test-config.yml` file to configure tests. See [Source Acce
If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py.
To run your integration tests with acceptance tests, from the connector root, run
```
python -m pytest integration_tests -p integration_tests.acceptance
docker build . --no-cache -t airbyte/source-zendesk-support:dev \
&& python -m pytest -p source_acceptance_test.plugin
```
To run your integration tests with docker

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tests:
status: "failed"
discovery:
- config_path: "secrets/config.json"
- config_path: "secrets/config_oauth.json"
basic_read:
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog.json"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"auth_method": {
"credentials": {
"credentials": "api_token",
"api_token": "<broken token>",
"email": "broken.email@invalid.config"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,21 @@ class SourceZendeskSupport(AbstractSource):

@classmethod
def get_authenticator(cls, config: Mapping[str, Any]) -> BasicApiTokenAuthenticator:
if config["auth_method"]["auth_method"] == "access_token":
return TokenAuthenticator(token=config["auth_method"]["access_token"])
elif config["auth_method"]["auth_method"] == "api_token":
return BasicApiTokenAuthenticator(config["auth_method"]["email"], config["auth_method"]["api_token"])
raise SourceZendeskException(f"Not implemented authorization method: {config['auth_method']}")

# old authentication flow support
auth_old = config.get("auth_method")
if auth_old:
if auth_old.get("auth_method") == "api_token":
return BasicApiTokenAuthenticator(config["auth_method"]["email"], config["auth_method"]["api_token"])
# new authentication flow
auth = config.get("credentials")
if auth:
if auth.get("credentials") == "oauth2.0":
return TokenAuthenticator(token=config["credentials"]["access_token"])
elif auth.get("credentials") == "api_token":
return BasicApiTokenAuthenticator(config["credentials"]["email"], config["credentials"]["api_token"])
else:
raise SourceZendeskException(f"Not implemented authorization method: {config['credentials']}")

def check_connection(self, logger, config) -> Tuple[bool, any]:
"""Connection check to validate that the user-provided config can be used to connect to the underlying API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Source Zendesk Support Spec",
"type": "object",
"required": ["start_date", "subdomain", "auth_method"],
"additionalProperties": false,
"required": ["start_date", "subdomain"],
"additionalProperties": true,
"properties": {
"start_date": {
"type": "string",
Expand All @@ -16,57 +16,116 @@
},
"subdomain": {
"type": "string",
"description": "The subdomain for your Zendesk Support"
"title": "Subdomain",
"description": "Identifier of your Zendesk Subdomain, like: https://{MY_SUBDOMAIN}.zendesk.com/, where MY_SUBDOMAIN is the value of your subdomain"
},
"auth_method": {
"credentials": {
"title": "Authorization Method",
"type": "object",
"default": "api_token",
"description": "Zendesk service provides 2 auth method: API token and OAuth2. Now only the first one is available. Another one will be added in the future.",
"description": "Zendesk service provides two authentication methods. Choose between: `OAuth2.0` or `API token`.",
"oneOf": [
{
"title": "API Token",
"title": "OAuth2.0",
"type": "object",
"required": ["email", "api_token"],
"additionalProperties": false,
"required": ["access_token"],
"additionalProperties": true,
"properties": {
"auth_method": {
"credentials": {
"type": "string",
"const": "api_token"
"const": "oauth2.0",
"enum": ["oauth2.0"],
"default": "oauth2.0",
"order": 0
},
"email": {
"title": "Email",
"type": "string",
"description": "The user email for your Zendesk account."
},
"api_token": {
"title": "API Token",
"access_token": {
"type": "string",
"title": "Access Token",
"description": "The value of the API token generated. See the <a href=\"https://docs.airbyte.io/integrations/sources/zendesk-support\">docs</a> for more information.",
"airbyte_secret": true
}
}
},
{
"title": "OAuth2.0",
"title": "API Token",
"type": "object",
"required": ["access_token"],
"additionalProperties": false,
"required": ["email", "api_token"],
"additionalProperties": true,
"properties": {
"auth_method": {
"credentials": {
"type": "string",
"const": "access_token"
"const": "api_token",
"enum": ["api_token"],
"default": "api_token",
"order": 0
},
"access_token": {
"title": "Access Token",
"email": {
"title": "Email",
"type": "string",
"description": "The value of the Access token generated. See the <a href=\"https://docs.airbyte.io/integrations/sources/zendesk-support\">docs</a> for more information.",
"description": "The user email for your Zendesk account."
},
"api_token": {
"title": "API Token",
"type": "string",
"description": "The value of the API token generated. See the <a href=\"https://docs.airbyte.io/integrations/sources/zendesk-support\">docs</a> for more information.",
"airbyte_secret": true
}
}
}
]
}
}
},
"advanced_auth": {
"auth_flow_type": "oauth2.0",
"predicate_key": ["credentials", "credentials"],
"predicate_value": "oauth2.0",
"oauth_config_specification": {
"complete_oauth_output_specification": {
"type": "object",
"additionalProperties": false,
"properties": {
"access_token": {
"type": "string",
"path_in_connector_config": ["credentials", "access_token"]
}
}
},
"complete_oauth_server_input_specification": {
"type": "object",
"additionalProperties": false,
"properties": {
"client_id": {
"type": "string"
},
"client_secret": {
"type": "string"
}
}
},
"complete_oauth_server_output_specification": {
"type": "object",
"additionalProperties": false,
"properties": {
"client_id": {
"type": "string",
"path_in_connector_config": ["credentials", "client_id"]
},
"client_secret": {
"type": "string",
"path_in_connector_config": ["credentials", "client_secret"]
}
}
},
"oauth_user_input_from_connector_config_specification": {
"type": "object",
"additionalProperties": false,
"properties": {
"subdomain": {
"type": "string",
"path_in_connector_config": ["subdomain"]
}
}
}
}
}
}
Loading