From 6557b22a529695f345e444e71ea40b67e91e1dfe Mon Sep 17 00:00:00 2001 From: Paul Shawn <32349595+topsworld@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:19:24 +0800 Subject: [PATCH] fix: fix multi ha instance login (#560) * fix: fix multi ha instance login * fix: fix option flow oauth --- custom_components/xiaomi_home/config_flow.py | 25 ++++++++++++------- .../xiaomi_home/miot/miot_client.py | 1 + .../xiaomi_home/miot/miot_cloud.py | 8 +++++- .../xiaomi_home/translations/de.json | 1 + .../xiaomi_home/translations/en.json | 1 + .../xiaomi_home/translations/es.json | 1 + .../xiaomi_home/translations/fr.json | 1 + .../xiaomi_home/translations/ja.json | 1 + .../xiaomi_home/translations/nl.json | 1 + .../xiaomi_home/translations/pt-BR.json | 1 + .../xiaomi_home/translations/pt.json | 1 + .../xiaomi_home/translations/ru.json | 1 + .../xiaomi_home/translations/zh-Hans.json | 1 + .../xiaomi_home/translations/zh-Hant.json | 1 + 14 files changed, 35 insertions(+), 10 deletions(-) diff --git a/custom_components/xiaomi_home/config_flow.py b/custom_components/xiaomi_home/config_flow.py index 667e5fe7..8e488493 100644 --- a/custom_components/xiaomi_home/config_flow.py +++ b/custom_components/xiaomi_home/config_flow.py @@ -68,6 +68,7 @@ ) from homeassistant.core import callback from homeassistant.data_entry_flow import AbortFlow +from homeassistant.helpers.instance_id import async_get import homeassistant.helpers.config_validation as cv from .miot.const import ( @@ -247,6 +248,13 @@ async def async_step_auth_config( if user_input: self._cloud_server = user_input.get( 'cloud_server', self._cloud_server) + # Gen instance uuid + ha_uuid = await async_get(self.hass) + if not ha_uuid: + raise AbortFlow(reason='ha_uuid_get_failed') + self._uuid = hashlib.sha256( + f'{ha_uuid}.{self._virtual_did}.{self._cloud_server}'.encode( + 'utf-8')).hexdigest()[:32] self._integration_language = user_input.get( 'integration_language', DEFAULT_INTEGRATION_LANGUAGE) self._miot_i18n = MIoTI18n( @@ -415,9 +423,11 @@ async def async_step_oauth( miot_oauth = MIoTOauthClient( client_id=OAUTH2_CLIENT_ID, redirect_url=self._oauth_redirect_url_full, - cloud_server=self._cloud_server - ) - state = str(secrets.randbits(64)) + cloud_server=self._cloud_server, + uuid=self._uuid, + loop=self._main_loop) + state = hashlib.sha1( + f'd=ha.{self._uuid}'.encode('utf-8')).hexdigest() self.hass.data[DOMAIN][self._virtual_did]['oauth_state'] = state self._cc_oauth_auth_url = miot_oauth.gen_auth_url( redirect_url=self._oauth_redirect_url_full, state=state) @@ -498,11 +508,6 @@ async def __check_oauth_async(self) -> None: client_id=OAUTH2_CLIENT_ID, access_token=auth_info['access_token']) self._auth_info = auth_info - # Gen uuid - self._uuid = hashlib.sha256( - f'{self._virtual_did}.{auth_info["access_token"]}'.encode( - 'utf-8') - ).hexdigest()[:32] try: self._nick_name = ( await self._miot_http.get_user_info_async() or {} @@ -1145,7 +1150,9 @@ async def async_step_auth_config(self, user_input=None): async def async_step_oauth(self, user_input=None): try: if self._cc_task_oauth is None: - state = str(secrets.randbits(64)) + state = hashlib.sha1( + f'd=ha.{self._entry_data["uuid"]}'.encode('utf-8') + ).hexdigest() self.hass.data[DOMAIN][self._virtual_did]['oauth_state'] = state self._miot_oauth.set_redirect_url( redirect_url=self._oauth_redirect_url_full) diff --git a/custom_components/xiaomi_home/miot/miot_client.py b/custom_components/xiaomi_home/miot/miot_client.py index b762ce30..b618ea59 100644 --- a/custom_components/xiaomi_home/miot/miot_client.py +++ b/custom_components/xiaomi_home/miot/miot_client.py @@ -257,6 +257,7 @@ async def init_async(self) -> None: client_id=OAUTH2_CLIENT_ID, redirect_url=self._entry_data['oauth_redirect_url'], cloud_server=self._cloud_server, + uuid=self._entry_data["uuid"], loop=self._main_loop) # MIoT http client instance self._http = MIoTHttpClient( diff --git a/custom_components/xiaomi_home/miot/miot_cloud.py b/custom_components/xiaomi_home/miot/miot_cloud.py index 7ed3875e..4c076fee 100644 --- a/custom_components/xiaomi_home/miot/miot_cloud.py +++ b/custom_components/xiaomi_home/miot/miot_cloud.py @@ -75,10 +75,11 @@ class MIoTOauthClient: _oauth_host: str _client_id: int _redirect_url: str + _device_id: str def __init__( self, client_id: str, redirect_url: str, cloud_server: str, - loop: Optional[asyncio.AbstractEventLoop] = None + uuid: str, loop: Optional[asyncio.AbstractEventLoop] = None ) -> None: self._main_loop = loop or asyncio.get_running_loop() if client_id is None or client_id.strip() == '': @@ -87,6 +88,8 @@ def __init__( raise MIoTOauthError('invalid redirect_url') if not cloud_server: raise MIoTOauthError('invalid cloud_server') + if not uuid: + raise MIoTOauthError('invalid uuid') self._client_id = int(client_id) self._redirect_url = redirect_url @@ -94,6 +97,7 @@ def __init__( self._oauth_host = DEFAULT_OAUTH2_API_HOST else: self._oauth_host = f'{cloud_server}.{DEFAULT_OAUTH2_API_HOST}' + self._device_id = f'ha.{uuid}' self._session = aiohttp.ClientSession(loop=self._main_loop) async def deinit_async(self) -> None: @@ -132,6 +136,7 @@ def gen_auth_url( 'redirect_uri': redirect_url or self._redirect_url, 'client_id': self._client_id, 'response_type': 'code', + 'device_id': self._device_id } if state: params['state'] = state @@ -191,6 +196,7 @@ async def get_access_token_async(self, code: str) -> dict: 'client_id': self._client_id, 'redirect_uri': self._redirect_url, 'code': code, + 'device_id': self._device_id }) async def refresh_access_token_async(self, refresh_token: str) -> dict: diff --git a/custom_components/xiaomi_home/translations/de.json b/custom_components/xiaomi_home/translations/de.json index 68a03732..25dfd023 100644 --- a/custom_components/xiaomi_home/translations/de.json +++ b/custom_components/xiaomi_home/translations/de.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Xiaomi MQTT Broker-Adresse ist nicht erreichbar, bitte überprüfen Sie die Netzwerkkonfiguration." }, "abort": { + "ha_uuid_get_failed": "Fehler beim Abrufen der Home Assistant-UUID.", "network_connect_error": "Konfiguration fehlgeschlagen. Netzwerkverbindung fehlgeschlagen. Überprüfen Sie die Netzwerkkonfiguration des Geräts.", "already_configured": "Dieser Benutzer hat die Konfiguration bereits abgeschlossen. Gehen Sie zur Integrationsseite und klicken Sie auf die Schaltfläche \"Konfiguration\", um die Konfiguration zu ändern.", "invalid_auth_info": "Authentifizierungsinformationen sind abgelaufen. Gehen Sie zur Integrationsseite und klicken Sie auf die Schaltfläche \"Konfiguration\", um die Authentifizierung erneut durchzuführen.", diff --git a/custom_components/xiaomi_home/translations/en.json b/custom_components/xiaomi_home/translations/en.json index 22447305..0ee151c1 100644 --- a/custom_components/xiaomi_home/translations/en.json +++ b/custom_components/xiaomi_home/translations/en.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Unable to reach Xiaomi MQTT Broker address, please check network configuration." }, "abort": { + "ha_uuid_get_failed": "Failed to get Home Assistant UUID.", "network_connect_error": "Configuration failed. The network connection is abnormal. Please check the equipment network configuration.", "already_configured": "Configuration for this user is already completed. Please go to the integration page and click the CONFIGURE button for modifications.", "invalid_auth_info": "Authentication information has expired. Please go to the integration page and click the CONFIGURE button to re-authenticate.", diff --git a/custom_components/xiaomi_home/translations/es.json b/custom_components/xiaomi_home/translations/es.json index 29425675..e7b0c757 100644 --- a/custom_components/xiaomi_home/translations/es.json +++ b/custom_components/xiaomi_home/translations/es.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "No se puede acceder a la dirección del Broker MQTT de Xiaomi, por favor verifique la configuración de la red." }, "abort": { + "ha_uuid_get_failed": "Error al obtener el UUID de Home Assistant.", "network_connect_error": "La configuración ha fallado. Existe un problema con la conexión de red, verifique la configuración de red del dispositivo.", "already_configured": "Esta cuenta ya ha finalizado la configuración. Ingrese a la página de integración y haga clic en el botón \"Configurar\" para modificar la configuración.", "invalid_auth_info": "La información de autorización ha caducado. Ingrese a la página de integración y haga clic en el botón \"Configurar\" para volver a autenticarse.", diff --git a/custom_components/xiaomi_home/translations/fr.json b/custom_components/xiaomi_home/translations/fr.json index fa1b84da..63b9c443 100644 --- a/custom_components/xiaomi_home/translations/fr.json +++ b/custom_components/xiaomi_home/translations/fr.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Impossible d'atteindre l'adresse du Broker MQTT de Xiaomi, veuillez vérifier la configuration réseau." }, "abort": { + "ha_uuid_get_failed": "Échec de l'obtention de l'UUID de Home Assistant.", "network_connect_error": "La configuration a échoué. Erreur de connexion réseau. Veuillez vérifier la configuration du réseau de l'appareil.", "already_configured": "Cet utilisateur a déjà terminé la configuration. Veuillez accéder à la page d'intégration et cliquer sur le bouton \"Configurer\" pour modifier la configuration.", "invalid_auth_info": "Les informations d'authentification ont expiré. Veuillez accéder à la page d'intégration et cliquer sur le bouton \"Configurer\" pour vous authentifier à nouveau.", diff --git a/custom_components/xiaomi_home/translations/ja.json b/custom_components/xiaomi_home/translations/ja.json index d63201bc..2b07b06f 100644 --- a/custom_components/xiaomi_home/translations/ja.json +++ b/custom_components/xiaomi_home/translations/ja.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Xiaomi MQTT ブローカーアドレスにアクセスできません。ネットワーク設定を確認してください。" }, "abort": { + "ha_uuid_get_failed": "Home Assistant インスタンスIDを取得できませんでした。", "network_connect_error": "設定に失敗しました。ネットワーク接続に異常があります。デバイスのネットワーク設定を確認してください。", "already_configured": "このユーザーはすでに設定が完了しています。統合ページにアクセスして、「設定」ボタンをクリックして設定を変更してください。", "invalid_auth_info": "認証情報が期限切れになりました。統合ページにアクセスして、「設定」ボタンをクリックして再度認証してください。", diff --git a/custom_components/xiaomi_home/translations/nl.json b/custom_components/xiaomi_home/translations/nl.json index 6c4c4363..6e289369 100644 --- a/custom_components/xiaomi_home/translations/nl.json +++ b/custom_components/xiaomi_home/translations/nl.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Kan Xiaomi MQTT Broker-adres niet bereiken, controleer de netwerkconfiguratie." }, "abort": { + "ha_uuid_get_failed": "Mislukt bij het ophalen van Home Assistant UUID.", "network_connect_error": "Configuratie mislukt. De netwerkverbinding is abnormaal. Controleer de netwerkinstellingen van de apparatuur.", "already_configured": "Configuratie voor deze gebruiker is al voltooid. Ga naar de integratiepagina en klik op de CONFIGUREER-knop om wijzigingen aan te brengen.", "invalid_auth_info": "Authenticatie-informatie is verlopen. Ga naar de integratiepagina en klik op de CONFIGUREER-knop om opnieuw te authentiseren.", diff --git a/custom_components/xiaomi_home/translations/pt-BR.json b/custom_components/xiaomi_home/translations/pt-BR.json index 0c453b51..3adcd0d1 100644 --- a/custom_components/xiaomi_home/translations/pt-BR.json +++ b/custom_components/xiaomi_home/translations/pt-BR.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede." }, "abort": { + "ha_uuid_get_failed": "Falha ao obter o UUID do Home Assistant.", "network_connect_error": "Configuração falhou. A conexão de rede está anormal. Verifique a configuração de rede do equipamento.", "already_configured": "A configuração para este usuário já foi concluída. Vá para a página de integrações e clique no botão CONFIGURAR para modificações.", "invalid_auth_info": "As informações de autenticação expiraram. Vá para a página de integrações e clique em CONFIGURAR para reautenticar.", diff --git a/custom_components/xiaomi_home/translations/pt.json b/custom_components/xiaomi_home/translations/pt.json index 787ddcd4..ce58cd55 100644 --- a/custom_components/xiaomi_home/translations/pt.json +++ b/custom_components/xiaomi_home/translations/pt.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Não é possível acessar o endereço do Broker MQTT da Xiaomi, verifique a configuração da rede." }, "abort": { + "ha_uuid_get_failed": "Não foi possível obter o UUID do Home Assistant.", "network_connect_error": "A configuração falhou. A ligação de rede é anormal. Verifique a configuração de rede do equipamento.", "already_configured": "A configuração para este utilizador já foi concluída. Vá à página de integrações e clique em CONFIGURAR para efetuar alterações.", "invalid_auth_info": "A informação de autenticação expirou. Vá à página de integrações e clique em CONFIGURAR para reautenticar.", diff --git a/custom_components/xiaomi_home/translations/ru.json b/custom_components/xiaomi_home/translations/ru.json index 7e060558..a4928697 100644 --- a/custom_components/xiaomi_home/translations/ru.json +++ b/custom_components/xiaomi_home/translations/ru.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "Не удается подключиться к адресу MQTT брокера Xiaomi, проверьте настройки сети." }, "abort": { + "ha_uuid_get_failed": "Не удалось получить UUID Home Assistant.", "network_connect_error": "Ошибка настройки. Сетевое подключение недоступно. Проверьте настройки сети устройства.", "already_configured": "Этот пользователь уже настроен. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы изменить настройки.", "invalid_auth_info": "Информация об авторизации истекла. Перейдите на страницу интеграции и нажмите кнопку «Настроить», чтобы переавторизоваться.", diff --git a/custom_components/xiaomi_home/translations/zh-Hans.json b/custom_components/xiaomi_home/translations/zh-Hans.json index 1b6a1387..39859da9 100644 --- a/custom_components/xiaomi_home/translations/zh-Hans.json +++ b/custom_components/xiaomi_home/translations/zh-Hans.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "无法访问小米 MQTT Broker 地址,请检查网络配置。" }, "abort": { + "ha_uuid_get_failed": "获取 Home Assistant UUID 失败。", "network_connect_error": "配置失败。网络连接异常,请检查设备网络配置。", "already_configured": "该用户已配置完成。请进入集成页面,点击“配置”按钮修改配置。", "invalid_auth_info": "认证信息已过期。请进入集成页面,点击“配置”按钮重新认证。", diff --git a/custom_components/xiaomi_home/translations/zh-Hant.json b/custom_components/xiaomi_home/translations/zh-Hant.json index 7fcfb67a..59580aea 100644 --- a/custom_components/xiaomi_home/translations/zh-Hant.json +++ b/custom_components/xiaomi_home/translations/zh-Hant.json @@ -90,6 +90,7 @@ "unreachable_mqtt_broker": "無法訪問小米 MQTT Broker 地址,請檢查網絡配置。" }, "abort": { + "ha_uuid_get_failed": "獲取 Home Assistant UUID 失敗。", "network_connect_error": "配置失敗。網絡連接異常,請檢查設備網絡配置。", "already_configured": "該用戶已配置完成。請進入集成頁面,點擊“配置”按鈕修改配置。", "invalid_auth_info": "認證信息已過期。請進入集成頁面,點擊“配置”按鈕重新認證。",