Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion homeassistant/components/hassio/addon_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from aiohttp import web

from homeassistant.components import frontend
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http import HomeAssistantView, require_admin
from homeassistant.core import HomeAssistant

from .handler import get_supervisor_client
Expand Down Expand Up @@ -43,6 +43,7 @@ def __init__(self, hass: HomeAssistant) -> None:
self.hass = hass
self.client = get_supervisor_client(hass)

@require_admin
async def post(self, request: web.Request, addon: str) -> web.Response:
"""Handle new add-on panel requests."""
panels = await self.get_panels()
Expand All @@ -56,6 +57,7 @@ async def post(self, request: web.Request, addon: str) -> web.Response:
_register_panel(self.hass, addon, panels[addon])
return web.Response()

@require_admin
async def delete(self, request: web.Request, addon: str) -> web.Response:
"""Handle remove add-on panel requests."""
frontend.async_remove_panel(self.hass, addon)
Expand Down
83 changes: 83 additions & 0 deletions tests/components/hassio/test_addon_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component

from tests.common import MockUser
from tests.typing import ClientSessionGenerator


Expand Down Expand Up @@ -90,6 +91,42 @@ async def test_hassio_addon_panel_api(
)


@pytest.mark.usefixtures("hassio_env")
async def test_hassio_addon_panel_api_non_admin(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
ingress_panels: AsyncMock,
hass_admin_user: MockUser,
) -> None:
"""Test register panel api fails with non admin user."""
ingress_panels.return_value = {
"test1": IngressPanel(enable=True, title="Test", icon="mdi:test", admin=False),
}

with patch(
"homeassistant.components.hassio.addon_panel._register_panel",
) as mock_panel:
await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()

ingress_panels.assert_called_once()
mock_panel.assert_called_once()

mock_panel.reset_mock()
hass_admin_user.groups = []
hass_client = await hass_client()

# Both should return unauthorized regardless of enabled as the endpoint requires
# admin and the user is not admin
resp = await hass_client.post("/api/hassio_push/panel/test2")
assert resp.status == HTTPStatus.UNAUTHORIZED

resp = await hass_client.post("/api/hassio_push/panel/test1")
assert resp.status == HTTPStatus.UNAUTHORIZED

mock_panel.assert_not_called()


@pytest.mark.usefixtures("hassio_env")
async def test_hassio_addon_panel_registration(
hass: HomeAssistant, ingress_panels: AsyncMock
Expand Down Expand Up @@ -118,3 +155,49 @@ async def test_hassio_addon_panel_registration(
require_admin=True,
config={"addon": "test_addon"},
)


@pytest.mark.usefixtures("hassio_env")
async def test_hassio_addon_panel_api_delete(
hass: HomeAssistant, hass_client: ClientSessionGenerator, ingress_panels: AsyncMock
) -> None:
"""Test panel api delete."""
ingress_panels.return_value = {
"test1": IngressPanel(enable=True, title="Test", icon="mdi:test", admin=False),
}
await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()

hass_client = await hass_client()

with patch(
"homeassistant.components.hassio.addon_panel.frontend.async_remove_panel"
) as mock_remove:
resp = await hass_client.delete("/api/hassio_push/panel/test1")
assert resp.status == HTTPStatus.OK
mock_remove.assert_called_once_with(hass, "test1")


@pytest.mark.usefixtures("hassio_env")
async def test_hassio_addon_panel_api_delete_non_admin(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
ingress_panels: AsyncMock,
hass_admin_user: MockUser,
) -> None:
"""Test panel api delete fails with non admin user."""
ingress_panels.return_value = {
"test1": IngressPanel(enable=True, title="Test", icon="mdi:test", admin=False),
}
await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()

hass_admin_user.groups = []
hass_client = await hass_client()

with patch(
"homeassistant.components.hassio.addon_panel.frontend.async_remove_panel"
) as mock_remove:
resp = await hass_client.delete("/api/hassio_push/panel/test1")
assert resp.status == HTTPStatus.UNAUTHORIZED
mock_remove.assert_not_called()