async def test_get_external_url(hass): """Test get_external_url.""" hass.config.api = Mock(base_url="http://192.168.1.100:8123") assert network.async_get_external_url(hass) is None hass.config.api = Mock(base_url="http://example.duckdns.org:8123") assert network.async_get_external_url( hass) == "http://example.duckdns.org:8123" hass.config.components.add("cloud") assert network.async_get_external_url( hass) == "http://example.duckdns.org:8123" with patch.object( hass.components.cloud, "async_remote_ui_url", side_effect=cloud.CloudNotAvailable, ): assert network.async_get_external_url( hass) == "http://example.duckdns.org:8123" with patch.object( hass.components.cloud, "async_remote_ui_url", return_value="https://example.nabu.casa", ): assert network.async_get_external_url( hass) == "https://example.nabu.casa"
def _check_requirements(self): """Check the hass URL for HTTPS scheme.""" if "stream" not in self.hass.config.components: _LOGGER.debug( "%s requires stream component for AlexaCameraStreamController", self.entity_id, ) return False url = urlparse(network.async_get_external_url(self.hass)) if url.scheme != "https": _LOGGER.debug("%s requires HTTPS for AlexaCameraStreamController", self.entity_id) return False return True
def _check_requirements(self): """Check the hass URL for HTTPS scheme and port 443.""" if "stream" not in self.hass.config.components: _LOGGER.error( "%s requires stream component for AlexaCameraStreamController", self.entity_id, ) return False url = urlparse(network.async_get_external_url(self.hass)) if url.scheme != "https" or (url.port is not None and url.port != 443): _LOGGER.error( "%s requires HTTPS support on port 443 for AlexaCameraStreamController", self.entity_id, ) return False return True
async def _configure_almond_for_ha( hass: HomeAssistant, entry: config_entries.ConfigEntry, api: WebAlmondAPI ): """Configure Almond to connect to HA.""" if entry.data["type"] == TYPE_OAUTH2: # If we're connecting over OAuth2, we will only set up connection # with Home Assistant if we're remotely accessible. hass_url = network.async_get_external_url(hass) else: hass_url = hass.config.api.base_url # If hass_url is None, we're not going to configure Almond to connect to HA. if hass_url is None: return _LOGGER.debug("Configuring Almond to connect to Home Assistant at %s", hass_url) store = storage.Store(hass, STORAGE_VERSION, STORAGE_KEY) data = await store.async_load() if data is None: data = {} user = None if "almond_user" in data: user = await hass.auth.async_get_user(data["almond_user"]) if user is None: user = await hass.auth.async_create_system_user("Almond", [GROUP_ID_ADMIN]) data["almond_user"] = user.id await store.async_save(data) refresh_token = await hass.auth.async_create_refresh_token( user, # Almond will be fine as long as we restart once every 5 years access_token_expiration=timedelta(days=365 * 5), ) # Create long lived access token access_token = hass.auth.async_create_access_token(refresh_token) # Store token in Almond try: with async_timeout.timeout(30): await api.async_create_device( { "kind": "io.home-assistant", "hassUrl": hass_url, "accessToken": access_token, "refreshToken": "", # 5 years from now in ms. "accessTokenExpires": (time.time() + 60 * 60 * 24 * 365 * 5) * 1000, } ) except (asyncio.TimeoutError, ClientError) as err: if isinstance(err, asyncio.TimeoutError): msg = "Request timeout" else: msg = err _LOGGER.warning("Unable to configure Almond: %s", msg) await hass.auth.async_remove_refresh_token(refresh_token) raise ConfigEntryNotReady # Clear all other refresh tokens for token in list(user.refresh_tokens.values()): if token.id != refresh_token.id: await hass.auth.async_remove_refresh_token(token)