From ed9fde84fe918fe0705c332a3c2953b828b36574 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 2 Apr 2022 21:19:01 +0000 Subject: [PATCH 01/14] Documentation for initial developer credentials platform --- docs/core/platform/developer_credentials.md | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 docs/core/platform/developer_credentials.md diff --git a/docs/core/platform/developer_credentials.md b/docs/core/platform/developer_credentials.md new file mode 100644 index 00000000..2ce1c35b --- /dev/null +++ b/docs/core/platform/developer_credentials.md @@ -0,0 +1,51 @@ +--- +title: "Developer Credentials" +--- + +Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Clount Account Linking service. Integrations may also allow users to provide their own developer credentials by adding a `developer_credentials.py` and implementing the right functions. + +:::note +Developer Credentials is under active development and integrations should still prefer using +`LocalOAuth2Implementation`. +::: + +## Adding support + +Integrations support developer credentials with a file in the integration folder called `developer_credetnails.py` and implement the following: + +```python +from homeassistant.core import HomeAssistant +from homeassistant.components.developer_credentials.AuthorizationServer +from homeassistant.components.developer_credentials.DeveloperCredential + + +async def async_get_authorization_server( + self, hass: HomeAssistant +) -> AuthorizationServer: + """Return authorization server.""" + + +# Optional: Only implement if needed to provide a credential from configuration.yaml +async def async_get_developer_credential( + self, hass: HomeAssistant +) -> DeveloperCredential: + """Return a developer credential from configuration.yaml.""" +``` + +## AuthorizationServer + +A `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration. + +| Name | Type | | Description | +| ------------- | ---- | -------------------------------------------------------------------------------------------------- | ----------- | +| authorize_url | str | **Required** | The OAuth authorize URL that the user is redirected to during the configuration flow. | +| token_url | str | **Required** | The URL used for obtaining an access token. | + +## DeveloperCredential + +A `DeveloperCredential` represents the a developer credential provided by the user. This is only provided for backward compatibility by integrations that allowed users to specify developer credentials via `configuration.yaml`. + +| Name | Type | | Description | +| ------------- | ---- | ------------------------------------------------------------------------- | ----------- | +| client_id | str | **Required** | The developer credential client ID provided by the user. | +| client_secret | str | **Required** | The developer credential client secret provided by the user. | From c701c3f9cb6f099dc0184fe22882d5b630579687 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 2 Apr 2022 17:22:57 -0700 Subject: [PATCH 02/14] Fix typo --- docs/core/platform/developer_credentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/platform/developer_credentials.md b/docs/core/platform/developer_credentials.md index 2ce1c35b..8a880663 100644 --- a/docs/core/platform/developer_credentials.md +++ b/docs/core/platform/developer_credentials.md @@ -11,7 +11,7 @@ Developer Credentials is under active development and integrations should still ## Adding support -Integrations support developer credentials with a file in the integration folder called `developer_credetnails.py` and implement the following: +Integrations support developer credentials with a file in the integration folder called `developer_credentails.py` and implement the following: ```python from homeassistant.core import HomeAssistant From db05ef6886249c4d3a8fe935ad124edd795a6378 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 2 Apr 2022 22:18:25 -0700 Subject: [PATCH 03/14] Update docs/core/platform/developer_credentials.md Co-authored-by: Paulus Schoutsen --- docs/core/platform/developer_credentials.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/core/platform/developer_credentials.md b/docs/core/platform/developer_credentials.md index 8a880663..de8141c4 100644 --- a/docs/core/platform/developer_credentials.md +++ b/docs/core/platform/developer_credentials.md @@ -25,7 +25,8 @@ async def async_get_authorization_server( """Return authorization server.""" -# Optional: Only implement if needed to provide a credential from configuration.yaml +# Optional and provided only for backwards compatibility if integration used to +# accept YAML credentials. Return YAML client ID and secret. async def async_get_developer_credential( self, hass: HomeAssistant ) -> DeveloperCredential: From 0cc5a85c13f05c25d3e38cdfceaac91a48cfb01a Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 3 Apr 2022 17:19:23 +0000 Subject: [PATCH 04/14] Add static example for AuthorizationServer --- docs/core/platform/developer_credentials.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/core/platform/developer_credentials.md b/docs/core/platform/developer_credentials.md index 8a880663..fa90c1de 100644 --- a/docs/core/platform/developer_credentials.md +++ b/docs/core/platform/developer_credentials.md @@ -23,6 +23,10 @@ async def async_get_authorization_server( self, hass: HomeAssistant ) -> AuthorizationServer: """Return authorization server.""" + return AuthorizationServer( + authorize_url="https://example.com/auth", + token_url="https://example.com/oauth2/v4/token" + ) # Optional: Only implement if needed to provide a credential from configuration.yaml From d7afabef6e52ff4080a8a6bce8abbac1f19b3391 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 3 Apr 2022 17:26:02 +0000 Subject: [PATCH 05/14] Rename developer credentials to client credentials --- ...r_credentials.md => client_credentials.md} | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) rename docs/core/platform/{developer_credentials.md => client_credentials.md} (57%) diff --git a/docs/core/platform/developer_credentials.md b/docs/core/platform/client_credentials.md similarity index 57% rename from docs/core/platform/developer_credentials.md rename to docs/core/platform/client_credentials.md index cfba2c1a..6b995ffb 100644 --- a/docs/core/platform/developer_credentials.md +++ b/docs/core/platform/client_credentials.md @@ -1,22 +1,21 @@ --- -title: "Developer Credentials" +title: "Client Credentials" --- -Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Clount Account Linking service. Integrations may also allow users to provide their own developer credentials by adding a `developer_credentials.py` and implementing the right functions. +Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Cloud Account Linking service. Integrations may also allow users to provide their own OAuth client credentials by adding a `client_credentials.py` and implementing the right functions. :::note -Developer Credentials is under active development and integrations should still prefer using -`LocalOAuth2Implementation`. +Client Credentials is under active development and integrations should still prefer using `LocalOAuth2Implementation`. ::: ## Adding support -Integrations support developer credentials with a file in the integration folder called `developer_credentails.py` and implement the following: +Integrations support client credentials with a file in the integration folder called `client_credentails.py` and implement the following: ```python from homeassistant.core import HomeAssistant -from homeassistant.components.developer_credentials.AuthorizationServer -from homeassistant.components.developer_credentials.DeveloperCredential +from homeassistant.components.client_credentials.AuthorizationServer +from homeassistant.components.client_credentials.ClientCredential async def async_get_authorization_server( @@ -31,10 +30,10 @@ async def async_get_authorization_server( # Optional and provided only for backwards compatibility if integration used to # accept YAML credentials. Return YAML client ID and secret. -async def async_get_developer_credential( +async def async_get_client_credential( self, hass: HomeAssistant -) -> DeveloperCredential: - """Return a developer credential from configuration.yaml.""" +) -> ClientCredential: + """Return a client credential from configuration.yaml.""" ``` ## AuthorizationServer @@ -46,11 +45,11 @@ A `AuthorizationServer` represents the [OAuth2 Authorization server](https://dat | authorize_url | str | **Required** | The OAuth authorize URL that the user is redirected to during the configuration flow. | | token_url | str | **Required** | The URL used for obtaining an access token. | -## DeveloperCredential +## ClientCredential -A `DeveloperCredential` represents the a developer credential provided by the user. This is only provided for backward compatibility by integrations that allowed users to specify developer credentials via `configuration.yaml`. +A `ClientCredential` represents the a client credential provided by the user. | Name | Type | | Description | | ------------- | ---- | ------------------------------------------------------------------------- | ----------- | -| client_id | str | **Required** | The developer credential client ID provided by the user. | -| client_secret | str | **Required** | The developer credential client secret provided by the user. | +| client_id | str | **Required** | The OAuth Client ID provided by the user. | +| client_secret | str | **Required** | The OAuth Client Secret provided by the user. | \ No newline at end of file From b2349f56752343d432760e752839b0f03ece93a8 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 3 Apr 2022 17:32:00 +0000 Subject: [PATCH 06/14] Rename component to application credentials --- ...ent_credentials.md => application_credentials.md} | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename docs/core/platform/{client_credentials.md => application_credentials.md} (80%) diff --git a/docs/core/platform/client_credentials.md b/docs/core/platform/application_credentials.md similarity index 80% rename from docs/core/platform/client_credentials.md rename to docs/core/platform/application_credentials.md index 6b995ffb..f69eef58 100644 --- a/docs/core/platform/client_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -1,21 +1,21 @@ --- -title: "Client Credentials" +title: "Application Credentials" --- -Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Cloud Account Linking service. Integrations may also allow users to provide their own OAuth client credentials by adding a `client_credentials.py` and implementing the right functions. +Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Cloud Account Linking service. Integrations may also allow users to provide their own OAuth client credentials by adding a `application_credentials.py` and implementing the right functions. :::note -Client Credentials is under active development and integrations should still prefer using `LocalOAuth2Implementation`. +Application Credentials is under active development and integrations should still prefer using `LocalOAuth2Implementation`. ::: ## Adding support -Integrations support client credentials with a file in the integration folder called `client_credentails.py` and implement the following: +Integrations support application credentials with a file in the integration folder called `application_credentials.py` and implement the following: ```python from homeassistant.core import HomeAssistant -from homeassistant.components.client_credentials.AuthorizationServer -from homeassistant.components.client_credentials.ClientCredential +from homeassistant.components.application_credentials.AuthorizationServer +from homeassistant.components.application_credentials.ClientCredential async def async_get_authorization_server( From 7acbe01b38e4b37ac92bfafe63e1cc115b03d75c Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Tue, 5 Apr 2022 15:14:20 +0000 Subject: [PATCH 07/14] Update documentation to explain the import API --- docs/core/platform/application_credentials.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index f69eef58..286cb592 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -26,16 +26,10 @@ async def async_get_authorization_server( authorize_url="https://example.com/auth", token_url="https://example.com/oauth2/v4/token" ) - - -# Optional and provided only for backwards compatibility if integration used to -# accept YAML credentials. Return YAML client ID and secret. -async def async_get_client_credential( - self, hass: HomeAssistant -) -> ClientCredential: - """Return a client credential from configuration.yaml.""" ``` +See below for details on backwards compatibility with YAML credentials. + ## AuthorizationServer A `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration. @@ -45,6 +39,12 @@ A `AuthorizationServer` represents the [OAuth2 Authorization server](https://dat | authorize_url | str | **Required** | The OAuth authorize URL that the user is redirected to during the configuration flow. | | token_url | str | **Required** | The URL used for obtaining an access token. | +## Import YAML credentials + +Credentials may be imported by integrations that used to accept YAML credentials using the import API `async_import_client_credential` provided by the application credentials integration. + +The `auth_domain` is the domain for the auth implementation in in the config entry, which is typically the domain specified in an existing `LocalOAuth2Implementation`. + ## ClientCredential A `ClientCredential` represents the a client credential provided by the user. From 11fd12dc0a062a9e6d9a79c1a246204b7fa5b385 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 00:29:01 -0700 Subject: [PATCH 08/14] Update docs/core/platform/application_credentials.md Co-authored-by: Martin Hjelmare --- docs/core/platform/application_credentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index f69eef58..2aed87a8 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -38,7 +38,7 @@ async def async_get_client_credential( ## AuthorizationServer -A `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration. +An `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration. | Name | Type | | Description | | ------------- | ---- | -------------------------------------------------------------------------------------------------- | ----------- | From 483379412813baeda1595840b8f8c18885de244d Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 07:30:36 +0000 Subject: [PATCH 09/14] Add missing import statement and remove unused import --- docs/core/platform/application_credentials.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index a9e78060..a0ad2163 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -14,8 +14,7 @@ Integrations support application credentials with a file in the integration fold ```python from homeassistant.core import HomeAssistant -from homeassistant.components.application_credentials.AuthorizationServer -from homeassistant.components.application_credentials.ClientCredential +from homeassistant.components.application_credentials import AuthorizationServer async def async_get_authorization_server( From 02158c2a7a73a9ca0efef8d362d7583a9b76cf77 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 01:02:28 -0700 Subject: [PATCH 10/14] Update docs/core/platform/application_credentials.md Co-authored-by: Martin Hjelmare --- docs/core/platform/application_credentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index a0ad2163..e18d7ebb 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -42,7 +42,7 @@ An `AuthorizationServer` represents the [OAuth2 Authorization server](https://da Credentials may be imported by integrations that used to accept YAML credentials using the import API `async_import_client_credential` provided by the application credentials integration. -The `auth_domain` is the domain for the auth implementation in in the config entry, which is typically the domain specified in an existing `LocalOAuth2Implementation`. +The `auth_domain` is the domain for the auth implementation in the config entry, which is typically the domain specified in an existing `LocalOAuth2Implementation`. ## ClientCredential From ca080a4d4b6a15dd25ed115a3df145403c71dea6 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 01:02:35 -0700 Subject: [PATCH 11/14] Update docs/core/platform/application_credentials.md Co-authored-by: Martin Hjelmare --- docs/core/platform/application_credentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index e18d7ebb..1893cd6b 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -46,7 +46,7 @@ The `auth_domain` is the domain for the auth implementation in the config entry, ## ClientCredential -A `ClientCredential` represents the a client credential provided by the user. +A `ClientCredential` represents a client credential provided by the user. | Name | Type | | Description | | ------------- | ---- | ------------------------------------------------------------------------- | ----------- | From e35b60aba94d10ff7cb45e612bf072a6f0319180 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 15:40:56 +0000 Subject: [PATCH 12/14] Rewrote documentation structure based on PR feedback --- docs/core/platform/application_credentials.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index 1893cd6b..0cf17c08 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -2,11 +2,13 @@ title: "Application Credentials" --- -Integrations support [Configuration via OAuth2](https://developers.home-assistant.io/docs/config_entries_config_flow_handler#configuration-via-oauth2) and the preferred approach is to use the Home Assistant Cloud Account Linking service. Integrations may also allow users to provide their own OAuth client credentials by adding a `application_credentials.py` and implementing the right functions. +Integrations may support [Configuration via OAuth2](/docs/config_entries_config_flow_handler#configuration-via-oauth2) allowing +users to link their accounts. Integrations may add a `application_credentials.py` file and implement the functions described below. -:::note -Application Credentials is under active development and integrations should still prefer using `LocalOAuth2Implementation`. -::: +OAuth2 requires credentials that are shared between an application and provider. In Home Assistant, integration specific OAuth2 credentials are typically provided using these approaches: + +- *Local OAuth with Application Credentials Component*: Users create their own credentials with the cloud provider, often acting as an application developer, and register the credentials with Home Assistant and integration. This approach is *required* by all integrations that support OAuth2. +- *Cloud Account Linking with Cloud Component*: Nabu Casa registers credentials with the cloud provider, providing a seamless user experience. This approach provides a seamless user experience and is *recommended* ([more info](/docs/config_entries_config_flow_handler#configuration-via-oauth2)). ## Adding support @@ -27,8 +29,6 @@ async def async_get_authorization_server( ) ``` -See below for details on backwards compatibility with YAML credentials. - ## AuthorizationServer An `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration. @@ -42,9 +42,7 @@ An `AuthorizationServer` represents the [OAuth2 Authorization server](https://da Credentials may be imported by integrations that used to accept YAML credentials using the import API `async_import_client_credential` provided by the application credentials integration. -The `auth_domain` is the domain for the auth implementation in the config entry, which is typically the domain specified in an existing `LocalOAuth2Implementation`. - -## ClientCredential +### ClientCredential A `ClientCredential` represents a client credential provided by the user. From 008360b395be045cdbaf569f86e02b6c92fed6d7 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Thu, 7 Apr 2022 15:43:13 +0000 Subject: [PATCH 13/14] Additional wording improvements --- docs/core/platform/application_credentials.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index 0cf17c08..333e9ea1 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -5,7 +5,7 @@ title: "Application Credentials" Integrations may support [Configuration via OAuth2](/docs/config_entries_config_flow_handler#configuration-via-oauth2) allowing users to link their accounts. Integrations may add a `application_credentials.py` file and implement the functions described below. -OAuth2 requires credentials that are shared between an application and provider. In Home Assistant, integration specific OAuth2 credentials are typically provided using these approaches: +OAuth2 requires credentials that are shared between an application and provider. In Home Assistant, integration specific OAuth2 credentials are provided using one or more approaches: - *Local OAuth with Application Credentials Component*: Users create their own credentials with the cloud provider, often acting as an application developer, and register the credentials with Home Assistant and integration. This approach is *required* by all integrations that support OAuth2. - *Cloud Account Linking with Cloud Component*: Nabu Casa registers credentials with the cloud provider, providing a seamless user experience. This approach provides a seamless user experience and is *recommended* ([more info](/docs/config_entries_config_flow_handler#configuration-via-oauth2)). From 8fc9d847b5305fbb07a4e364dfefd57629ea815b Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 16 Apr 2022 11:49:02 -0700 Subject: [PATCH 14/14] Update documentation for developer credentials after PR discussion feedback --- docs/config_entries_config_flow_handler.md | 2 +- docs/core/platform/application_credentials.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index 0ec6d30d..cccfc09c 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -154,7 +154,7 @@ To get started, run `python3 -m script.scaffold config_flow_discovery` and follo Home Assistant has built-in support for integrations that offer account linking using [the OAuth2 authorization framework](https://tools.ietf.org/html/rfc6749). To be able to leverage this, you will need to structure your Python API library in a way that allows Home Assistant to be responsible for refreshing tokens. See our [API library guide](api_lib_index.md) on how to do this. -The built-in OAuth2 support works out of the box with locally configured client ID / secret and with the Home Assistant Cloud Account Linking service. This service allows users to link their account with a centrally managed client ID/secret. If you want your integration to be part of this service, reach out to us at [hello@home-assistant.io](mailto:hello@home-assistant.io). +The built-in OAuth2 support works out of the box with locally configured client ID / secret using the [Application Credentials platform](/docs/core/platform/application_credentials) and with the Home Assistant Cloud Account Linking service. This service allows users to link their account with a centrally managed client ID/secret. If you want your integration to be part of this service, reach out to us at [hello@home-assistant.io](mailto:hello@home-assistant.io). To get started, run `python3 -m script.scaffold config_flow_oauth2` and follow the instructions. This will create all the boilerplate necessary to configure your integration using OAuth2. diff --git a/docs/core/platform/application_credentials.md b/docs/core/platform/application_credentials.md index 333e9ea1..5b7f5b53 100644 --- a/docs/core/platform/application_credentials.md +++ b/docs/core/platform/application_credentials.md @@ -29,7 +29,7 @@ async def async_get_authorization_server( ) ``` -## AuthorizationServer +### AuthorizationServer An `AuthorizationServer` represents the [OAuth2 Authorization server](https://datatracker.ietf.org/doc/html/rfc6749) used for an integration.