From 92f1943811ffa63bfb6c6120217a1b3782cf7c7d Mon Sep 17 00:00:00 2001 From: Xiaonan Shen Date: Sun, 7 Mar 2021 11:40:00 +0800 Subject: [PATCH] [Modify] Support login throgh email otp --- custom_components/dyson_cloud/config_flow.py | 57 ++++++++++++------- custom_components/dyson_cloud/manifest.json | 2 +- .../dyson_cloud/translations/en.json | 10 +++- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/custom_components/dyson_cloud/config_flow.py b/custom_components/dyson_cloud/config_flow.py index 4cbcd43..d14b452 100644 --- a/custom_components/dyson_cloud/config_flow.py +++ b/custom_components/dyson_cloud/config_flow.py @@ -32,9 +32,9 @@ class DysonCloudConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): def __init__(self): """Initialize the config flow.""" self._region = None - self._account = None self._mobile = None - self._mobile_verify = None + self._email = None + self._verify = None async def async_step_user(self, info: Optional[dict]): if info is not None: @@ -68,35 +68,53 @@ async def async_step_email(self, info: Optional[dict]=None): account = DysonAccount() try: - auth_info = await self.hass.async_add_executor_job( - account.login_email_password, - email, - info[CONF_PASSWORD], - self._region, + self._verify = await self.hass.async_add_executor_job( + account.login_email_otp, email, self._region ) except DysonNetworkError: errors["base"] = "cannot_connect" - except (DysonInvalidAccountStatus, DysonLoginFailure): + except DysonInvalidAccountStatus: + errors["base"] = "email_not_registered" + else: + self._email = email + return await self.async_step_email_otp() + + info = info or {} + return self.async_show_form( + step_id="email", + data_schema=vol.Schema({ + vol.Required(CONF_EMAIL, default=info.get(CONF_EMAIL, "")): str, + }), + errors=errors, + ) + + async def async_step_email_otp(self, info: Optional[dict]=None): + errors = {} + if info is not None: + try: + auth_info = await self.hass.async_add_executor_job( + self._verify, info[CONF_OTP], info[CONF_PASSWORD] + ) + except DysonLoginFailure: errors["base"] = "invalid_auth" else: return self.async_create_entry( - title=f"{email} ({self._region})", + title=f"{self._email} ({self._region})", data={ CONF_REGION: self._region, CONF_AUTH: auth_info, } ) - info = info or {} return self.async_show_form( - step_id="email", + step_id="email_otp", data_schema=vol.Schema({ - vol.Required(CONF_EMAIL, default=info.get(CONF_EMAIL, "")): str, - vol.Required(CONF_PASSWORD, default=info.get(CONF_PASSWORD, "")): str, + vol.Required(CONF_PASSWORD): str, + vol.Required(CONF_OTP): str, }), errors=errors, ) - + async def async_step_mobile(self, info: Optional[dict]=None): errors = {} @@ -106,14 +124,14 @@ async def async_step_mobile(self, info: Optional[dict]=None): if not mobile.startswith("+"): mobile = f"+86{mobile}" try: - self._mobile_verify = await self.hass.async_add_executor_job( + self._verify = await self.hass.async_add_executor_job( account.login_mobile_otp, mobile ) except DysonOTPTooFrequently: errors["base"] = "otp_too_frequent" else: self._mobile = mobile - return await self.async_step_otp() + return await self.async_step_mobile_otp() info = info or {} return self.async_show_form( @@ -124,12 +142,12 @@ async def async_step_mobile(self, info: Optional[dict]=None): errors=errors, ) - async def async_step_otp(self, info: Optional[dict]=None): + async def async_step_mobile_otp(self, info: Optional[dict]=None): errors = {} if info is not None: try: auth_info = await self.hass.async_add_executor_job( - self._mobile_verify, info[CONF_OTP] + self._verify, info[CONF_OTP] ) except DysonLoginFailure: errors["base"] = "invalid_otp" @@ -142,9 +160,8 @@ async def async_step_otp(self, info: Optional[dict]=None): } ) - return self.async_show_form( - step_id="otp", + step_id="mobile_otp", data_schema=vol.Schema({ vol.Required(CONF_OTP): str, }), diff --git a/custom_components/dyson_cloud/manifest.json b/custom_components/dyson_cloud/manifest.json index 85f4d1f..b2f076b 100644 --- a/custom_components/dyson_cloud/manifest.json +++ b/custom_components/dyson_cloud/manifest.json @@ -6,5 +6,5 @@ "issue_tracker": "https://github.com/shenxn/ha-dyson/issues", "dependencies": [], "codeowners": ["@shenxn"], - "requirements": ["libdyson==0.5.1"] + "requirements": ["libdyson==0.6.0"] } \ No newline at end of file diff --git a/custom_components/dyson_cloud/translations/en.json b/custom_components/dyson_cloud/translations/en.json index 189b16d..c512f4c 100644 --- a/custom_components/dyson_cloud/translations/en.json +++ b/custom_components/dyson_cloud/translations/en.json @@ -8,7 +8,12 @@ }, "email": { "data": { - "email": "Email", + "email": "Email" + } + }, + "email_otp": { + "data": { + "otp": "Verification code", "password": "Password" } }, @@ -17,7 +22,7 @@ "mobile": "Phone number" } }, - "otp": { + "mobile_otp": { "data": { "otp": "Verification code" } @@ -25,6 +30,7 @@ }, "error": { "cannot_connect": "Failed to connect", + "email_not_registered": "Email not registered", "invalid_auth": "Invalid authentication", "invalid_otp": "Invalid verification code", "otp_too_frequent": "You're requesting verification code too frequently"