Hide credentials from generated titles in generic camera (#70204)

pull/69048/head
Dave T 2022-04-18 15:57:52 +01:00 committed by GitHub
parent f9450d32ea
commit d69a7e7be9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 9 deletions

View File

@ -8,13 +8,13 @@ import io
import logging import logging
from types import MappingProxyType from types import MappingProxyType
from typing import Any from typing import Any
from urllib.parse import urlparse, urlunparse
import PIL import PIL
from async_timeout import timeout from async_timeout import timeout
import av import av
from httpx import HTTPStatusError, RequestError, TimeoutException from httpx import HTTPStatusError, RequestError, TimeoutException
import voluptuous as vol import voluptuous as vol
import yarl
from homeassistant.components.stream.const import SOURCE_TIMEOUT from homeassistant.components.stream.const import SOURCE_TIMEOUT
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow 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.""" """Convert a camera url into a string suitable for a camera name."""
if not url: if not url:
return None return None
url_no_scheme = urlparse(url)._replace(scheme="") return slugify(yarl.URL(url).host)
return slugify(urlunparse(url_no_scheme).strip("/"))
async def async_test_stream(hass, info) -> dict[str, str]: async def async_test_stream(hass, info) -> dict[str, str]:

View File

@ -62,7 +62,7 @@ async def test_form(hass, fakeimg_png, mock_av_open, user_flow):
TESTDATA, TESTDATA,
) )
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY 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"] == { assert result2["options"] == {
CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1",
CONF_STREAM_SOURCE: "http://127.0.0.1/testurl/2", 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, data,
) )
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY 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"] == { assert result2["options"] == {
CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1",
CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, 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 "errors" not in result2, f"errors={result2['errors']}"
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY 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"] == { assert result2["options"] == {
CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1", CONF_STILL_IMAGE_URL: "http://127.0.0.1/testurl/1",
CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, 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 = TESTDATA.copy()
data.pop(CONF_STILL_IMAGE_URL) 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: with mock_av_open as mock_setup:
result3 = await hass.config_entries.flow.async_configure( result3 = await hass.config_entries.flow.async_configure(
result["flow_id"], 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["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"] == { assert result3["options"] == {
CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, 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_USERNAME: "fred_flintstone",
CONF_PASSWORD: "bambam", CONF_PASSWORD: "bambam",
CONF_LIMIT_REFETCH_TO_URL_CHANGE: False, 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", "homeassistant.components.generic.camera.GenericCamera.async_camera_image",
return_value=fakeimgbytes_jpg, 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 image_obj.content == fakeimgbytes_jpg
assert len(mock_setup.mock_calls) == 1 assert len(mock_setup.mock_calls) == 1