"""Config flow to configure Google Hangouts.""" import functools from hangups import get_auth import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_EMAIL, CONF_PASSWORD from homeassistant.core import callback from .const import ( CONF_2FA, CONF_AUTH_CODE, CONF_REFRESH_TOKEN, DOMAIN as HANGOUTS_DOMAIN, ) from .hangups_utils import ( Google2FAError, GoogleAuthError, HangoutsCredentials, HangoutsRefreshToken, ) @callback def configured_hangouts(hass): """Return the configures Google Hangouts Account.""" entries = hass.config_entries.async_entries(HANGOUTS_DOMAIN) if entries: return entries[0] return None @config_entries.HANDLERS.register(HANGOUTS_DOMAIN) class HangoutsFlowHandler(config_entries.ConfigFlow): """Config flow Google Hangouts.""" VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_PUSH def __init__(self): """Initialize Google Hangouts config flow.""" self._credentials = None self._refresh_token = None async def async_step_user(self, user_input=None): """Handle a flow start.""" errors = {} if configured_hangouts(self.hass) is not None: return self.async_abort(reason="already_configured") if user_input is not None: user_email = user_input[CONF_EMAIL] user_password = user_input[CONF_PASSWORD] user_auth_code = user_input.get(CONF_AUTH_CODE) manual_login = user_auth_code is not None user_pin = None self._credentials = HangoutsCredentials( user_email, user_password, user_pin, user_auth_code ) self._refresh_token = HangoutsRefreshToken(None) try: await self.hass.async_add_executor_job( functools.partial( get_auth, self._credentials, self._refresh_token, manual_login=manual_login, ) ) return await self.async_step_final() except GoogleAuthError as err: if isinstance(err, Google2FAError): return await self.async_step_2fa() msg = str(err) if msg == "Unknown verification code input": errors["base"] = "invalid_2fa_method" else: errors["base"] = "invalid_login" return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required(CONF_EMAIL): str, vol.Required(CONF_PASSWORD): str, vol.Optional(CONF_AUTH_CODE): str, } ), errors=errors, ) async def async_step_2fa(self, user_input=None): """Handle the 2fa step, if needed.""" errors = {} if user_input is not None: self._credentials.set_verification_code(user_input[CONF_2FA]) try: await self.hass.async_add_executor_job( get_auth, self._credentials, self._refresh_token ) return await self.async_step_final() except GoogleAuthError: errors["base"] = "invalid_2fa" return self.async_show_form( step_id=CONF_2FA, data_schema=vol.Schema({vol.Required(CONF_2FA): str}), errors=errors, ) async def async_step_final(self): """Handle the final step, create the config entry.""" return self.async_create_entry( title=self._credentials.get_email(), data={ CONF_EMAIL: self._credentials.get_email(), CONF_REFRESH_TOKEN: self._refresh_token.get(), }, ) async def async_step_import(self, _): """Handle a flow import.""" return await self.async_step_user()