Opower MFA fixes (#99317)

opower mfa fixes
This commit is contained in:
tronikos 2023-08-30 21:36:07 -07:00 committed by GitHub
parent 99a65fb45b
commit 343e8f0ecc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 22 deletions

View File

@ -5,7 +5,13 @@ from collections.abc import Mapping
import logging
from typing import Any
from opower import CannotConnect, InvalidAuth, Opower, get_supported_utility_names
from opower import (
CannotConnect,
InvalidAuth,
Opower,
get_supported_utility_names,
select_utility,
)
import voluptuous as vol
from homeassistant import config_entries
@ -20,9 +26,7 @@ _LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_UTILITY): vol.In(
get_supported_utility_names(supports_mfa=True)
),
vol.Required(CONF_UTILITY): vol.In(get_supported_utility_names()),
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
}
@ -38,7 +42,7 @@ async def _validate_login(
login_data[CONF_UTILITY],
login_data[CONF_USERNAME],
login_data[CONF_PASSWORD],
login_data.get(CONF_TOTP_SECRET, None),
login_data.get(CONF_TOTP_SECRET),
)
errors: dict[str, str] = {}
try:
@ -50,12 +54,6 @@ async def _validate_login(
return errors
@callback
def _supports_mfa(utility: str) -> bool:
"""Return whether the utility supports MFA."""
return utility not in get_supported_utility_names(supports_mfa=False)
class OpowerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Opower."""
@ -78,7 +76,7 @@ class OpowerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
CONF_USERNAME: user_input[CONF_USERNAME],
}
)
if _supports_mfa(user_input[CONF_UTILITY]):
if select_utility(user_input[CONF_UTILITY]).accepts_mfa():
self.utility_info = user_input
return await self.async_step_mfa()
@ -154,7 +152,7 @@ class OpowerConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
vol.Required(CONF_USERNAME): self.reauth_entry.data[CONF_USERNAME],
vol.Required(CONF_PASSWORD): str,
}
if _supports_mfa(self.reauth_entry.data[CONF_UTILITY]):
if select_utility(self.reauth_entry.data[CONF_UTILITY]).accepts_mfa():
schema[vol.Optional(CONF_TOTP_SECRET)] = str
return self.async_show_form(
step_id="reauth_confirm",

View File

@ -55,7 +55,7 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, Forecast]]):
entry_data[CONF_UTILITY],
entry_data[CONF_USERNAME],
entry_data[CONF_PASSWORD],
entry_data.get(CONF_TOTP_SECRET, None),
entry_data.get(CONF_TOTP_SECRET),
)
async def _async_update_data(

View File

@ -7,5 +7,5 @@
"documentation": "https://www.home-assistant.io/integrations/opower",
"iot_class": "cloud_polling",
"loggers": ["opower"],
"requirements": ["opower==0.0.32"]
"requirements": ["opower==0.0.33"]
}

View File

@ -5,8 +5,13 @@
"data": {
"utility": "Utility name",
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]",
"totp_secret": "TOTP Secret (only for some utilities, see documentation)"
"password": "[%key:common::config_flow::data::password%]"
}
},
"mfa": {
"description": "The TOTP secret below is not one of the 6 digit time-based numeric codes. It is a string of around 16 characters containing the shared secret that enables your authenticator app to generate the correct time-based code at the appropriate time. See the documentation.",
"data": {
"totp_secret": "TOTP Secret"
}
},
"reauth_confirm": {
@ -14,7 +19,7 @@
"data": {
"username": "[%key:common::config_flow::data::username%]",
"password": "[%key:common::config_flow::data::password%]",
"totp_secret": "TOTP Secret (only for some utilities, see documentation)"
"totp_secret": "TOTP Secret"
}
}
},

View File

@ -1374,7 +1374,7 @@ openwrt-luci-rpc==1.1.16
openwrt-ubus-rpc==0.0.2
# homeassistant.components.opower
opower==0.0.32
opower==0.0.33
# homeassistant.components.oralb
oralb-ble==0.17.6

View File

@ -1040,7 +1040,7 @@ openerz-api==0.2.0
openhomedevice==2.2.0
# homeassistant.components.opower
opower==0.0.32
opower==0.0.33
# homeassistant.components.oralb
oralb-ble==0.17.6

View File

@ -300,7 +300,7 @@ async def test_form_valid_reauth(
assert result["reason"] == "reauth_successful"
await hass.async_block_till_done()
assert hass.config_entries.async_entries(DOMAIN)[0].data == {
assert mock_config_entry.data == {
"utility": "Pacific Gas and Electric Company (PG&E)",
"username": "test-username",
"password": "test-password2",
@ -350,7 +350,7 @@ async def test_form_valid_reauth_with_mfa(
assert result["reason"] == "reauth_successful"
await hass.async_block_till_done()
assert hass.config_entries.async_entries(DOMAIN)[0].data == {
assert mock_config_entry.data == {
"utility": "Consolidated Edison (ConEd)",
"username": "test-username",
"password": "test-password2",