Raise an exception when trying to save camera snapshots to a not allowed path (#91869)

This commit is contained in:
J. Nick Koston 2023-04-22 18:15:56 -05:00 committed by GitHub
parent 9ccc0059d2
commit e4744199ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 3 deletions

View file

@ -56,6 +56,7 @@ from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.network import get_url
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass
@ -912,15 +913,16 @@ async def async_handle_snapshot_service(
) -> None:
"""Handle snapshot services calls."""
hass = camera.hass
filename = service_call.data[ATTR_FILENAME]
filename: Template = service_call.data[ATTR_FILENAME]
filename.hass = hass
snapshot_file = filename.async_render(variables={ATTR_ENTITY_ID: camera})
# check if we allow to access to that file
if not hass.config.is_allowed_path(snapshot_file):
_LOGGER.error("Can't write %s, no access to path!", snapshot_file)
return
raise HomeAssistantError(
f"Cannot write `{snapshot_file}`, no access to path; `allowlist_external_dirs` may need to be adjusted in `configuration.yaml`"
)
image = await camera.async_camera_image()

View file

@ -245,6 +245,26 @@ async def test_snapshot_service(hass: HomeAssistant, mock_camera) -> None:
assert mock_write.mock_calls[0][1][0] == b"Test"
async def test_snapshot_service_not_allowed_path(
hass: HomeAssistant, mock_camera
) -> None:
"""Test snapshot service with a not allowed path."""
mopen = mock_open()
with patch("homeassistant.components.camera.open", mopen, create=True), patch(
"homeassistant.components.camera.os.makedirs",
), pytest.raises(HomeAssistantError, match="/test/snapshot.jpg"):
await hass.services.async_call(
camera.DOMAIN,
camera.SERVICE_SNAPSHOT,
{
ATTR_ENTITY_ID: "camera.demo_camera",
camera.ATTR_FILENAME: "/test/snapshot.jpg",
},
blocking=True,
)
async def test_websocket_stream_no_source(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, mock_camera, mock_stream
) -> None: