mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-14 12:46:32 +00:00
Add validate session API (#2223)
This commit is contained in:
parent
517e6cb437
commit
ffaeb2b96d
@ -342,6 +342,7 @@ class RestAPI(CoreSysAttributes):
|
|||||||
self.webapp.add_routes(
|
self.webapp.add_routes(
|
||||||
[
|
[
|
||||||
web.post("/ingress/session", api_ingress.create_session),
|
web.post("/ingress/session", api_ingress.create_session),
|
||||||
|
web.post("/ingress/validate_session", api_ingress.validate_session),
|
||||||
web.get("/ingress/panels", api_ingress.panels),
|
web.get("/ingress/panels", api_ingress.panels),
|
||||||
web.view("/ingress/{token}/{path:.*}", api_ingress.handler),
|
web.view("/ingress/{token}/{path:.*}", api_ingress.handler),
|
||||||
]
|
]
|
||||||
|
@ -12,6 +12,7 @@ from aiohttp.web_exceptions import (
|
|||||||
HTTPUnauthorized,
|
HTTPUnauthorized,
|
||||||
)
|
)
|
||||||
from multidict import CIMultiDict, istr
|
from multidict import CIMultiDict, istr
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
from ..addons.addon import Addon
|
from ..addons.addon import Addon
|
||||||
from ..const import (
|
from ..const import (
|
||||||
@ -27,10 +28,12 @@ from ..const import (
|
|||||||
REQUEST_FROM,
|
REQUEST_FROM,
|
||||||
)
|
)
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from .utils import api_process
|
from .utils import api_process, api_validate
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
VALIDATE_SESSION_DATA = vol.Schema({ATTR_SESSION: str})
|
||||||
|
|
||||||
|
|
||||||
class APIIngress(CoreSysAttributes):
|
class APIIngress(CoreSysAttributes):
|
||||||
"""Ingress view to handle add-on webui routing."""
|
"""Ingress view to handle add-on webui routing."""
|
||||||
@ -78,6 +81,18 @@ class APIIngress(CoreSysAttributes):
|
|||||||
session = self.sys_ingress.create_session()
|
session = self.sys_ingress.create_session()
|
||||||
return {ATTR_SESSION: session}
|
return {ATTR_SESSION: session}
|
||||||
|
|
||||||
|
@api_process
|
||||||
|
async def validate_session(self, request: web.Request) -> Dict[str, Any]:
|
||||||
|
"""Validate session and extending how long it's valid for."""
|
||||||
|
self._check_ha_access(request)
|
||||||
|
|
||||||
|
data = await api_validate(VALIDATE_SESSION_DATA, request)
|
||||||
|
|
||||||
|
# Check Ingress Session
|
||||||
|
if not self.sys_ingress.validate_session(data[ATTR_SESSION]):
|
||||||
|
_LOGGER.warning("No valid ingress session %s", data[ATTR_SESSION])
|
||||||
|
raise HTTPUnauthorized()
|
||||||
|
|
||||||
async def handler(
|
async def handler(
|
||||||
self, request: web.Request
|
self, request: web.Request
|
||||||
) -> Union[web.Response, web.StreamResponse, web.WebSocketResponse]:
|
) -> Union[web.Response, web.StreamResponse, web.WebSocketResponse]:
|
||||||
|
43
tests/api/test_ingress.py
Normal file
43
tests/api/test_ingress.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
"""Test ingress API."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def stub_auth():
|
||||||
|
"""Bypass auth check."""
|
||||||
|
with patch("supervisor.api.ingress.APIIngress._check_ha_access") as mock_auth:
|
||||||
|
yield mock_auth
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_validate_session(stub_auth, api_client, coresys):
|
||||||
|
"""Test validating ingress session."""
|
||||||
|
coresys.core.sys_homeassistant.supervisor_token = "ABCD"
|
||||||
|
resp = await api_client.post(
|
||||||
|
"/ingress/validate_session",
|
||||||
|
json={"session": "non-existing"},
|
||||||
|
)
|
||||||
|
assert resp.status == 401
|
||||||
|
assert len(stub_auth.mock_calls) == 1
|
||||||
|
|
||||||
|
resp = await api_client.post("/ingress/session")
|
||||||
|
result = await resp.json()
|
||||||
|
assert len(stub_auth.mock_calls) == 2
|
||||||
|
|
||||||
|
assert "session" in result["data"]
|
||||||
|
session = result["data"]["session"]
|
||||||
|
assert session in coresys.ingress.sessions
|
||||||
|
|
||||||
|
valid_time = coresys.ingress.sessions[session]
|
||||||
|
|
||||||
|
resp = await api_client.post(
|
||||||
|
"/ingress/validate_session",
|
||||||
|
json={"session": session},
|
||||||
|
)
|
||||||
|
assert resp.status == 200
|
||||||
|
assert len(stub_auth.mock_calls) == 3
|
||||||
|
assert await resp.json() == {"result": "ok", "data": {}}
|
||||||
|
|
||||||
|
assert coresys.ingress.sessions[session] > valid_time
|
@ -1,4 +1,4 @@
|
|||||||
"""Test NetwrokInterface API."""
|
"""Test NetworkInterface API."""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from supervisor.const import DOCKER_NETWORK, DOCKER_NETWORK_MASK
|
from supervisor.const import DOCKER_NETWORK, DOCKER_NETWORK_MASK
|
||||||
|
Loading…
x
Reference in New Issue
Block a user