Skip to content

Commit

Permalink
SmartThings continue correct config flow after external auth (home-as…
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewsayre authored and balloob committed Apr 30, 2020
1 parent 6d9aafd commit 3bf1cf4
Show file tree
Hide file tree
Showing 5 changed files with 605 additions and 374 deletions.
10 changes: 10 additions & 0 deletions homeassistant/components/smartthings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
TOKEN_REFRESH_INTERVAL,
)
from .smartapp import (
format_unique_id,
setup_smartapp,
setup_smartapp_endpoint,
smartapp_sync_subscriptions,
Expand Down Expand Up @@ -76,6 +77,15 @@ async def async_migrate_entry(hass: HomeAssistantType, entry: ConfigEntry):

async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
"""Initialize config entry which represents an installed SmartApp."""
# For backwards compat
if entry.unique_id is None:
hass.config_entries.async_update_entry(
entry,
unique_id=format_unique_id(
entry.data[CONF_APP_ID], entry.data[CONF_LOCATION_ID]
),
)

if not validate_webhook_requirements(hass):
_LOGGER.warning(
"The 'base_url' of the 'http' integration must be configured and start with 'https://'"
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/smartthings/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import voluptuous as vol

from homeassistant import config_entries
from homeassistant.const import CONF_ACCESS_TOKEN, HTTP_FORBIDDEN
from homeassistant.const import CONF_ACCESS_TOKEN, HTTP_FORBIDDEN, HTTP_UNAUTHORIZED
from homeassistant.helpers.aiohttp_client import async_get_clientsession

# pylint: disable=unused-import
Expand All @@ -26,6 +26,7 @@
from .smartapp import (
create_app,
find_app,
format_unique_id,
get_webhook_url,
setup_smartapp,
setup_smartapp_endpoint,
Expand Down Expand Up @@ -138,7 +139,7 @@ async def async_step_pat(self, user_input=None):
)
return self._show_step_pat(errors)
except ClientResponseError as ex:
if ex.status == 401:
if ex.status == HTTP_UNAUTHORIZED:
errors[CONF_ACCESS_TOKEN] = "token_unauthorized"
_LOGGER.debug(
"Unauthorized error received setting up SmartApp", exc_info=True
Expand Down Expand Up @@ -183,6 +184,7 @@ async def async_step_select_location(self, user_input=None):
)

self.location_id = user_input[CONF_LOCATION_ID]
await self.async_set_unique_id(format_unique_id(self.app_id, self.location_id))
return await self.async_step_authorize()

async def async_step_authorize(self, user_input=None):
Expand Down
59 changes: 27 additions & 32 deletions homeassistant/components/smartthings/smartapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
CONF_CLOUDHOOK_URL,
CONF_INSTALLED_APP_ID,
CONF_INSTANCE_ID,
CONF_LOCATION_ID,
CONF_REFRESH_TOKEN,
DATA_BROKERS,
DATA_MANAGER,
Expand All @@ -53,6 +52,11 @@
_LOGGER = logging.getLogger(__name__)


def format_unique_id(app_id: str, location_id: str) -> str:
"""Format the unique id for a config entry."""
return f"{app_id}_{location_id}"


async def find_app(hass: HomeAssistantType, api):
"""Find an existing SmartApp for this installation of hass."""
apps = await api.apps()
Expand Down Expand Up @@ -366,32 +370,44 @@ async def delete_subscription(sub: SubscriptionEntity):
_LOGGER.debug("Subscriptions for app '%s' are up-to-date", installed_app_id)


async def smartapp_install(hass: HomeAssistantType, req, resp, app):
"""Handle a SmartApp installation and continue the config flow."""
async def _continue_flow(
hass: HomeAssistantType,
app_id: str,
location_id: str,
installed_app_id: str,
refresh_token: str,
):
"""Continue a config flow if one is in progress for the specific installed app."""
unique_id = format_unique_id(app_id, location_id)
flow = next(
(
flow
for flow in hass.config_entries.flow.async_progress()
if flow["handler"] == DOMAIN
if flow["handler"] == DOMAIN and flow["context"]["unique_id"] == unique_id
),
None,
)
if flow is not None:
await hass.config_entries.flow.async_configure(
flow["flow_id"],
{
CONF_INSTALLED_APP_ID: req.installed_app_id,
CONF_LOCATION_ID: req.location_id,
CONF_REFRESH_TOKEN: req.refresh_token,
CONF_INSTALLED_APP_ID: installed_app_id,
CONF_REFRESH_TOKEN: refresh_token,
},
)
_LOGGER.debug(
"Continued config flow '%s' for SmartApp '%s' under parent app '%s'",
flow["flow_id"],
req.installed_app_id,
app.app_id,
installed_app_id,
app_id,
)


async def smartapp_install(hass: HomeAssistantType, req, resp, app):
"""Handle a SmartApp installation and continue the config flow."""
await _continue_flow(
hass, app.app_id, req.location_id, req.installed_app_id, req.refresh_token
)
_LOGGER.debug(
"Installed SmartApp '%s' under parent app '%s'",
req.installed_app_id,
Expand Down Expand Up @@ -420,30 +436,9 @@ async def smartapp_update(hass: HomeAssistantType, req, resp, app):
app.app_id,
)

flow = next(
(
flow
for flow in hass.config_entries.flow.async_progress()
if flow["handler"] == DOMAIN
),
None,
await _continue_flow(
hass, app.app_id, req.location_id, req.installed_app_id, req.refresh_token
)
if flow is not None:
await hass.config_entries.flow.async_configure(
flow["flow_id"],
{
CONF_INSTALLED_APP_ID: req.installed_app_id,
CONF_LOCATION_ID: req.location_id,
CONF_REFRESH_TOKEN: req.refresh_token,
},
)
_LOGGER.debug(
"Continued config flow '%s' for SmartApp '%s' under parent app '%s'",
flow["flow_id"],
req.installed_app_id,
app.app_id,
)

_LOGGER.debug(
"Updated SmartApp '%s' under parent app '%s'", req.installed_app_id, app.app_id
)
Expand Down
Loading

0 comments on commit 3bf1cf4

Please sign in to comment.