From d69a7e7be925a31b10d81d35bd4a1d106ae83bbd Mon Sep 17 00:00:00 2001 From: Dave T <17680170+davet2001@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:57:52 +0100 Subject: [PATCH] Hide credentials from generated titles in generic camera (#70204) --- homeassistant/components/generic/config_flow.py | 5 ++--- tests/components/generic/test_config_flow.py | 13 +++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/generic/config_flow.py b/homeassistant/components/generic/config_flow.py index 6b303fab077..3d15069bca8 100644 --- a/homeassistant/components/generic/config_flow.py +++ b/homeassistant/components/generic/config_flow.py @@ -8,13 +8,13 @@ import io import logging from types import MappingProxyType from typing import Any -from urllib.parse import urlparse, urlunparse import PIL from async_timeout import timeout import av from httpx import HTTPStatusError, RequestError, TimeoutException import voluptuous as vol +import yarl from homeassistant.components.stream.const import SOURCE_TIMEOUT from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow @@ -172,8 +172,7 @@ def slug_url(url) -> str | None: """Convert a camera url into a string suitable for a camera name.""" if not url: return None - url_no_scheme = urlparse(url)._replace(scheme="") - return slugify(urlunparse(url_no_scheme).strip("/")) + return slugify(yarl.URL(url).host) async def async_test_stream(hass, info) -> dict[str, str]: diff --git a/tests/components/generic/test_config_flow.py b/tests/components/generic/test_config_flow.py index 007e7fc8ebd..3caa1aa7adf 100644 --- a/tests/components/generic/test_config_flow.py +++ b/tests/components/generic/test_config_flow.py @@ -62,7 +62,7 @@ async def test_form(hass, fakeimg_png, mock_av_open, user_flow): TESTDATA, ) assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "127_0_0_1_testurl_1" + assert result2["title"] == "127_0_0_1" assert result2["options"] == { CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_STREAM_SOURCE: "http://127.0.0.1/testurl/2", @@ -96,7 +96,7 @@ async def test_form_only_stillimage(hass, fakeimg_png, user_flow): data, ) assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "127_0_0_1_testurl_1" + assert result2["title"] == "127_0_0_1" assert result2["options"] == { CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, @@ -176,7 +176,7 @@ async def test_form_rtsp_mode(hass, fakeimg_png, mock_av_open, user_flow): ) assert "errors" not in result2, f"errors={result2['errors']}" assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "127_0_0_1_testurl_1" + assert result2["title"] == "127_0_0_1" assert result2["options"] == { CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, @@ -202,6 +202,7 @@ async def test_form_only_stream(hass, mock_av_open, fakeimgbytes_jpg): ) data = TESTDATA.copy() data.pop(CONF_STILL_IMAGE_URL) + data[CONF_STREAM_SOURCE] = "rtsp://user:pass@127.0.0.1/testurl/2" with mock_av_open as mock_setup: result3 = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -209,10 +210,10 @@ async def test_form_only_stream(hass, mock_av_open, fakeimgbytes_jpg): ) assert result3["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - assert result3["title"] == "127_0_0_1_testurl_2" + assert result3["title"] == "127_0_0_1" assert result3["options"] == { CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, - CONF_STREAM_SOURCE: "http://127.0.0.1/testurl/2", + CONF_STREAM_SOURCE: "rtsp://user:pass@127.0.0.1/testurl/2", CONF_USERNAME: "fred_flintstone", CONF_PASSWORD: "bambam", CONF_LIMIT_REFETCH_TO_URL_CHANGE: False, @@ -227,7 +228,7 @@ async def test_form_only_stream(hass, mock_av_open, fakeimgbytes_jpg): "homeassistant.components.generic.camera.GenericCamera.async_camera_image", return_value=fakeimgbytes_jpg, ): - image_obj = await async_get_image(hass, "camera.127_0_0_1_testurl_2") + image_obj = await async_get_image(hass, "camera.127_0_0_1") assert image_obj.content == fakeimgbytes_jpg assert len(mock_setup.mock_calls) == 1