From 177f323343a63975fcab6c89a32d733471033b04 Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Sun, 16 Feb 2025 23:35:12 +0100 Subject: [PATCH 1/7] make oauth2 declarative --- .../integration_tests/invalid_config.json | 10 +- .../integration_tests/sample_config.json | 8 +- .../sample_config_oauth2-confidential.json | 9 - .../connectors/source-xero/manifest.yaml | 189 +++++++++++------- .../connectors/source-xero/metadata.yaml | 7 +- docs/integrations/sources/xero-migrations.md | 12 ++ docs/integrations/sources/xero.md | 1 + 7 files changed, 138 insertions(+), 98 deletions(-) delete mode 100644 airbyte-integrations/connectors/source-xero/integration_tests/sample_config_oauth2-confidential.json diff --git a/airbyte-integrations/connectors/source-xero/integration_tests/invalid_config.json b/airbyte-integrations/connectors/source-xero/integration_tests/invalid_config.json index f9d24da10af17..13e34f94e6ff8 100644 --- a/airbyte-integrations/connectors/source-xero/integration_tests/invalid_config.json +++ b/airbyte-integrations/connectors/source-xero/integration_tests/invalid_config.json @@ -1,8 +1,6 @@ { - "credentials": { - "auth_type": "oauth2_access_token", - "access_token": "Invalid-token" - }, - "start_date": "2099-08-05T00:43:59.244Z", - "tenant_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "start_date": "2021-01-01T00:00:00Z", + "tenant_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } diff --git a/airbyte-integrations/connectors/source-xero/integration_tests/sample_config.json b/airbyte-integrations/connectors/source-xero/integration_tests/sample_config.json index 97a700ad88fd9..13e34f94e6ff8 100644 --- a/airbyte-integrations/connectors/source-xero/integration_tests/sample_config.json +++ b/airbyte-integrations/connectors/source-xero/integration_tests/sample_config.json @@ -1,8 +1,6 @@ { - "credentials": { - "auth_type": "oauth2_access_token", - "access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, "start_date": "2021-01-01T00:00:00Z", - "tenant_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "tenant_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" } diff --git a/airbyte-integrations/connectors/source-xero/integration_tests/sample_config_oauth2-confidential.json b/airbyte-integrations/connectors/source-xero/integration_tests/sample_config_oauth2-confidential.json deleted file mode 100644 index 4ecf68db22faf..0000000000000 --- a/airbyte-integrations/connectors/source-xero/integration_tests/sample_config_oauth2-confidential.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "credentials": { - "auth_type": "oauth2_confidential_application", - "client_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "client_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, - "start_date": "2023-08-05T00:43:59.244Z", - "tenant_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -} diff --git a/airbyte-integrations/connectors/source-xero/manifest.yaml b/airbyte-integrations/connectors/source-xero/manifest.yaml index 5413aacda7c93..0f9db584545b6 100644 --- a/airbyte-integrations/connectors/source-xero/manifest.yaml +++ b/airbyte-integrations/connectors/source-xero/manifest.yaml @@ -1612,35 +1612,31 @@ definitions: type: HttpRequester url_base: https://api.xero.com/api.xro/2.0/ authenticator: - type: SelectiveAuthenticator - authenticators: - oauth2_access_token: - type: BearerAuthenticator - api_token: "{{ config['credentials']['access_token'] }}" - oauth2_confidential_application: - type: OAuthAuthenticator - scopes: - - offline_access - - accounting.transactions.read - - accounting.reports.read - - accounting.budgets.read - - accounting.reports.tenninetynine.read - - accounting.journals.read - - accounting.settings.read - - accounting.contacts.read - - accounting.attachments.read - - assets.read files.read projects.read - - openid - client_id: "{{ config['credentials']['client_id'] }}" - grant_type: client_credentials - client_secret: "{{ config['credentials']['client_secret'] }}" - expires_in_name: expires_in - access_token_name: access_token - refresh_request_body: {} - token_refresh_endpoint: https://identity.xero.com/connect/token - authenticator_selection_path: - - credentials - - auth_type + type: OAuthAuthenticator + # scopes: + # - offline_access + # - accounting.transactions.read + # - accounting.reports.read + # - accounting.budgets.read + # - accounting.reports.tenninetynine.read + # - accounting.journals.read + # - accounting.settings.read + # - accounting.contacts.read + # - accounting.attachments.read + # - assets.read files.read projects.read + # - openid + client_id: "{{ config['client_id'] }}" + client_secret: "{{ config['client_secret'] }}" + access_token_value: "{{ config['client_access_token'] }}" + grant_type: refresh_token + # expires_in_name: expires_in + refresh_request_body: {} + token_refresh_endpoint: https://identity.xero.com/connect/token + refresh_token: "{{ config['client_refresh_token'] }}" + refresh_token_updater: + refresh_token_name: refresh_token + refresh_token_config_path: + - client_refresh_token streams: - $ref: "#/definitions/streams/bank_transactions" @@ -1673,7 +1669,10 @@ spec: required: - tenant_id - start_date - - credentials + - client_id + - client_secret + - client_access_token + - client_refresh_token properties: tenant_id: type: string @@ -1692,55 +1691,91 @@ spec: pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$ examples: - "2022-03-01T00:00:00Z" - credentials: - type: object - oneOf: - - type: object - title: OAuth Custom Connection - required: - - auth_type - - client_id - - client_secret - properties: - auth_type: - type: string - const: oauth2_confidential_application - order: 0 - title: Authentication Method - client_id: - type: string - description: Your Xero application's Client ID. - title: Client ID - examples: - - Client_ID - client_secret: - type: string - description: Your Xero application's Client Secret. - title: Client Secret - examples: - - Client_Secret - airbyte_secret: true - - type: object - title: Bearer Access Token - required: - - access_token - - auth_type - properties: - auth_type: - type: string - const: oauth2_access_token - order: 0 - title: Authentication Method - examples: - - access_token - access_token: - type: string - description: The access token used to call the Xero API. - title: Access Token - airbyte_secret: true + client_id: + type: string + description: Your Xero application's Client ID. + title: Client ID + examples: + - Client_ID order: 2 - title: Authentication Method + client_secret: + type: string + description: Your Xero application's Client Secret. + title: Client Secret + examples: + - Client_Secret + airbyte_secret: true + order: 3 + client_access_token: + type: string + title: Access token + airbyte_secret: true + order: 4 + client_refresh_token: + type: string + title: Refresh token + airbyte_secret: true + order: 5 additionalProperties: true + advanced_auth: + auth_flow_type: oauth2.0 + oauth_config_specification: + oauth_connector_input_specification: + consent_url: https://login.xero.com/identity/connect/authorize?response_type=code&client_id={{ client_id_value }}&scope={{ scope_value }}&redirect_uri={{ redirect_uri_value }} + scope: offline_access accounting.transactions.read accounting.reports.read accounting.budgets.read accounting.reports.tenninetynine.read accounting.journals.read accounting.settings.read accounting.contacts.read accounting.attachments.read assets.read files.read projects.read openid + access_token_url: https://identity.xero.com/connect/token + access_token_headers: + Authorization: "{{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" + access_token_params: + grant_type: authorization_code + code: "{{ auth_code_value }}" + redirect_uri: "{{ redirect_uri_value }}" + complete_oauth_output_specification: + required: + - access_token + - refresh_token + - token_expiry_date + properties: + access_token: + type: string + path_in_connector_config: + - client_access_token + path_in_oauth_response: + - access_token + refresh_token: + type: string + path_in_connector_config: + - refresh_token + path_in_oauth_response: + - refresh_token + token_expiry_date: + type: string + path_in_connector_config: + - token_expiry_date + path_in_oauth_response: + - expires_in + complete_oauth_server_input_specification: + required: + - client_id + - client_secret + properties: + client_id: + type: string + client_secret: + type: string + complete_oauth_server_output_specification: + required: + - client_id + - client_secret + properties: + client_id: + type: string + path_in_connector_config: + - client_id + client_secret: + type: string + path_in_connector_config: + - client_secret metadata: autoImportSchema: diff --git a/airbyte-integrations/connectors/source-xero/metadata.yaml b/airbyte-integrations/connectors/source-xero/metadata.yaml index 9899a474473c2..d71f5c38d4ca7 100644 --- a/airbyte-integrations/connectors/source-xero/metadata.yaml +++ b/airbyte-integrations/connectors/source-xero/metadata.yaml @@ -13,6 +13,11 @@ data: packageName: airbyte-source-xero releases: breakingChanges: + 3.0.0: + upgradeDeadline: "2025-03-01" + message: + The authorization method was changed to support only OAuth2 strategy. Due to changes in authorization, users can now bring their own OAuth2 apps, and use it on cloud. For more information, see our migration documentation for source Xero. + Important - The authentication scheme now uses only the OAuth2 strategy from this version. 2.0.0: upgradeDeadline: "2024-06-30" message: @@ -31,7 +36,7 @@ data: connectorSubtype: api connectorType: source definitionId: 6fd1e833-dd6e-45ec-a727-ab917c5be892 - dockerImageTag: 2.1.1 + dockerImageTag: 3.0.0 dockerRepository: airbyte/source-xero githubIssueLabel: source-xero icon: xero.svg diff --git a/docs/integrations/sources/xero-migrations.md b/docs/integrations/sources/xero-migrations.md index 0307d28e40e68..b37c1a1e6bd3f 100644 --- a/docs/integrations/sources/xero-migrations.md +++ b/docs/integrations/sources/xero-migrations.md @@ -1,5 +1,17 @@ # Xero Migration Guide +## Upgrading to 3.0.0 + +Xero connector now only accepts OAuth2 authentication method. + +To get started, [create an OAuth2 app](https://developer.xero.com/app/manage) and make sure you select the “Auth Code” grant type. Your app is assigned a unique Client ID and you can then generate a Client Secret. The Client Secret is private and should not be shared. + +Then authorize your source with the required information. +1. Go to set up `The Source` page. +2. Enter your Xero application's Client ID and Client Secret. +3. Click `Reset saved source` button. + + ## Upgrading to 2.0.0 You can now choose your preferred xero authentication method. You can choose between `client_credentials` and `bearer_token` authentication methods. diff --git a/docs/integrations/sources/xero.md b/docs/integrations/sources/xero.md index c037b97ba4bb0..d5390e3d06fce 100644 --- a/docs/integrations/sources/xero.md +++ b/docs/integrations/sources/xero.md @@ -120,6 +120,7 @@ The connector is restricted by Xero [API rate limits](https://developer.xero.com | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------| +| 3.0.0 | 2025-02-16 | [x](https://github.com/airbytehq/airbyte/pull/x) | Make OAuth2 authenticator declarative | | 2.1.1 | 2025-02-08 | [43841](https://github.com/airbytehq/airbyte/pull/43841) | Update dependencies | | 2.1.0 | 2024-10-23 | [47264](https://github.com/airbytehq/airbyte/pull/47264) | Migrate to Manifest-only | | 2.0.1 | 2025-01-10 | [51034](https://github.com/airbytehq/airbyte/pull/51034) | Fix for time part being removed from all datetimes fields | From 64574500604514f793f7598b3d41878a1bb63832 Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Sun, 16 Feb 2025 23:39:42 +0100 Subject: [PATCH 2/7] activate connector on cloud --- airbyte-integrations/connectors/source-xero/metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-integrations/connectors/source-xero/metadata.yaml b/airbyte-integrations/connectors/source-xero/metadata.yaml index d71f5c38d4ca7..edf3abd21e29d 100644 --- a/airbyte-integrations/connectors/source-xero/metadata.yaml +++ b/airbyte-integrations/connectors/source-xero/metadata.yaml @@ -6,7 +6,7 @@ data: oss: enabled: true cloud: - enabled: false + enabled: true remoteRegistries: pypi: enabled: false From 53b1b5609ca0296e0324a63180a9fccf48f45755 Mon Sep 17 00:00:00 2001 From: Tope Folorunso <66448986+topefolorunso@users.noreply.github.com> Date: Sun, 16 Feb 2025 23:49:19 +0100 Subject: [PATCH 3/7] Update xero.md --- docs/integrations/sources/xero.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integrations/sources/xero.md b/docs/integrations/sources/xero.md index d5390e3d06fce..2ac32c4fd57c5 100644 --- a/docs/integrations/sources/xero.md +++ b/docs/integrations/sources/xero.md @@ -120,7 +120,7 @@ The connector is restricted by Xero [API rate limits](https://developer.xero.com | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------| -| 3.0.0 | 2025-02-16 | [x](https://github.com/airbytehq/airbyte/pull/x) | Make OAuth2 authenticator declarative | +| 3.0.0 | 2025-02-16 | [54127](https://github.com/airbytehq/airbyte/pull/54127) | Make OAuth2 authenticator declarative | | 2.1.1 | 2025-02-08 | [43841](https://github.com/airbytehq/airbyte/pull/43841) | Update dependencies | | 2.1.0 | 2024-10-23 | [47264](https://github.com/airbytehq/airbyte/pull/47264) | Migrate to Manifest-only | | 2.0.1 | 2025-01-10 | [51034](https://github.com/airbytehq/airbyte/pull/51034) | Fix for time part being removed from all datetimes fields | From 6d17e9669e202f5a0d08a98aa47d4273afdddb0c Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Tue, 18 Feb 2025 17:29:01 +0100 Subject: [PATCH 4/7] fix auth flow --- .../connectors/source-xero/manifest.yaml | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/airbyte-integrations/connectors/source-xero/manifest.yaml b/airbyte-integrations/connectors/source-xero/manifest.yaml index 0f9db584545b6..09e3b8fa7faa0 100644 --- a/airbyte-integrations/connectors/source-xero/manifest.yaml +++ b/airbyte-integrations/connectors/source-xero/manifest.yaml @@ -1613,30 +1613,25 @@ definitions: url_base: https://api.xero.com/api.xro/2.0/ authenticator: type: OAuthAuthenticator - # scopes: - # - offline_access - # - accounting.transactions.read - # - accounting.reports.read - # - accounting.budgets.read - # - accounting.reports.tenninetynine.read - # - accounting.journals.read - # - accounting.settings.read - # - accounting.contacts.read - # - accounting.attachments.read - # - assets.read files.read projects.read - # - openid client_id: "{{ config['client_id'] }}" client_secret: "{{ config['client_secret'] }}" access_token_value: "{{ config['client_access_token'] }}" grant_type: refresh_token - # expires_in_name: expires_in + expires_in_name: expires_in refresh_request_body: {} token_refresh_endpoint: https://identity.xero.com/connect/token refresh_token: "{{ config['client_refresh_token'] }}" + token_expiry_date: "{{ config['token_expiry_date'] }}" + refresh_request_headers: + Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" refresh_token_updater: refresh_token_name: refresh_token refresh_token_config_path: - client_refresh_token + access_token_config_path: + - client_access_token + token_expiry_date_config_path: + - token_expiry_date streams: - $ref: "#/definitions/streams/bank_transactions" @@ -1671,8 +1666,6 @@ spec: - start_date - client_id - client_secret - - client_access_token - - client_refresh_token properties: tenant_id: type: string @@ -1716,16 +1709,20 @@ spec: title: Refresh token airbyte_secret: true order: 5 + token_expiry_date: + type: string + description: The amount of seconds until the access token expires. + format: date-time additionalProperties: true advanced_auth: auth_flow_type: oauth2.0 oauth_config_specification: oauth_connector_input_specification: - consent_url: https://login.xero.com/identity/connect/authorize?response_type=code&client_id={{ client_id_value }}&scope={{ scope_value }}&redirect_uri={{ redirect_uri_value }} + consent_url: https://login.xero.com/identity/connect/authorize?response_type=code&{{client_id_param}}&{{scope_param}}&{{redirect_uri_param}} scope: offline_access accounting.transactions.read accounting.reports.read accounting.budgets.read accounting.reports.tenninetynine.read accounting.journals.read accounting.settings.read accounting.contacts.read accounting.attachments.read assets.read files.read projects.read openid access_token_url: https://identity.xero.com/connect/token access_token_headers: - Authorization: "{{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" + Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" access_token_params: grant_type: authorization_code code: "{{ auth_code_value }}" From 0efbefaab28790d655ff6cafef818027c63bb113 Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Wed, 19 Feb 2025 11:43:48 +0100 Subject: [PATCH 5/7] fix --- airbyte-integrations/connectors/source-xero/manifest.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-xero/manifest.yaml b/airbyte-integrations/connectors/source-xero/manifest.yaml index 09e3b8fa7faa0..4cfeb6c9e3445 100644 --- a/airbyte-integrations/connectors/source-xero/manifest.yaml +++ b/airbyte-integrations/connectors/source-xero/manifest.yaml @@ -1623,7 +1623,7 @@ definitions: refresh_token: "{{ config['client_refresh_token'] }}" token_expiry_date: "{{ config['token_expiry_date'] }}" refresh_request_headers: - Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" + Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | base64encode }}" refresh_token_updater: refresh_token_name: refresh_token refresh_token_config_path: @@ -1722,11 +1722,13 @@ spec: scope: offline_access accounting.transactions.read accounting.reports.read accounting.budgets.read accounting.reports.tenninetynine.read accounting.journals.read accounting.settings.read accounting.contacts.read accounting.attachments.read assets.read files.read projects.read openid access_token_url: https://identity.xero.com/connect/token access_token_headers: - Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" + Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | base64encode }}" access_token_params: grant_type: authorization_code code: "{{ auth_code_value }}" redirect_uri: "{{ redirect_uri_value }}" + extract_output: + - access_token complete_oauth_output_specification: required: - access_token From d16569468bdce1b7c052e7513acc950b522ba697 Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Wed, 19 Feb 2025 18:44:45 +0100 Subject: [PATCH 6/7] fix --- airbyte-integrations/connectors/source-xero/manifest.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-xero/manifest.yaml b/airbyte-integrations/connectors/source-xero/manifest.yaml index 4cfeb6c9e3445..6064744da44f3 100644 --- a/airbyte-integrations/connectors/source-xero/manifest.yaml +++ b/airbyte-integrations/connectors/source-xero/manifest.yaml @@ -1623,7 +1623,7 @@ definitions: refresh_token: "{{ config['client_refresh_token'] }}" token_expiry_date: "{{ config['token_expiry_date'] }}" refresh_request_headers: - Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | base64encode }}" + Authorization: "Basic {{ (config['client_id'] ~ ':' ~ config['client_secret']) | base64encode }}" refresh_token_updater: refresh_token_name: refresh_token refresh_token_config_path: @@ -1722,7 +1722,7 @@ spec: scope: offline_access accounting.transactions.read accounting.reports.read accounting.budgets.read accounting.reports.tenninetynine.read accounting.journals.read accounting.settings.read accounting.contacts.read accounting.attachments.read assets.read files.read projects.read openid access_token_url: https://identity.xero.com/connect/token access_token_headers: - Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | base64encode }}" + Authorization: "Basic {{ (client_id_value ~ ':' ~ client_secret_value) | b64encode }}" access_token_params: grant_type: authorization_code code: "{{ auth_code_value }}" From e253ba7d573fcad6b7299985d009630ebb14de33 Mon Sep 17 00:00:00 2001 From: Tope Folorunso Date: Wed, 19 Feb 2025 20:53:52 +0100 Subject: [PATCH 7/7] fix auth flow --- .../connectors/source-xero/manifest.yaml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/airbyte-integrations/connectors/source-xero/manifest.yaml b/airbyte-integrations/connectors/source-xero/manifest.yaml index 6064744da44f3..4943bff7ff181 100644 --- a/airbyte-integrations/connectors/source-xero/manifest.yaml +++ b/airbyte-integrations/connectors/source-xero/manifest.yaml @@ -1615,7 +1615,6 @@ definitions: type: OAuthAuthenticator client_id: "{{ config['client_id'] }}" client_secret: "{{ config['client_secret'] }}" - access_token_value: "{{ config['client_access_token'] }}" grant_type: refresh_token expires_in_name: expires_in refresh_request_body: {} @@ -1728,10 +1727,10 @@ spec: code: "{{ auth_code_value }}" redirect_uri: "{{ redirect_uri_value }}" extract_output: - - access_token + - refresh_token + - token_expiry_date complete_oauth_output_specification: required: - - access_token - refresh_token - token_expiry_date properties: @@ -1739,20 +1738,14 @@ spec: type: string path_in_connector_config: - client_access_token - path_in_oauth_response: - - access_token refresh_token: type: string path_in_connector_config: - refresh_token - path_in_oauth_response: - - refresh_token token_expiry_date: type: string path_in_connector_config: - token_expiry_date - path_in_oauth_response: - - expires_in complete_oauth_server_input_specification: required: - client_id