mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-13 20:26:29 +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(
|
||||
[
|
||||
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.view("/ingress/{token}/{path:.*}", api_ingress.handler),
|
||||
]
|
||||
|
@ -12,6 +12,7 @@ from aiohttp.web_exceptions import (
|
||||
HTTPUnauthorized,
|
||||
)
|
||||
from multidict import CIMultiDict, istr
|
||||
import voluptuous as vol
|
||||
|
||||
from ..addons.addon import Addon
|
||||
from ..const import (
|
||||
@ -27,10 +28,12 @@ from ..const import (
|
||||
REQUEST_FROM,
|
||||
)
|
||||
from ..coresys import CoreSysAttributes
|
||||
from .utils import api_process
|
||||
from .utils import api_process, api_validate
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
VALIDATE_SESSION_DATA = vol.Schema({ATTR_SESSION: str})
|
||||
|
||||
|
||||
class APIIngress(CoreSysAttributes):
|
||||
"""Ingress view to handle add-on webui routing."""
|
||||
@ -78,6 +81,18 @@ class APIIngress(CoreSysAttributes):
|
||||
session = self.sys_ingress.create_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(
|
||||
self, request: web.Request
|
||||
) -> 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
|
||||
|
||||
from supervisor.const import DOCKER_NETWORK, DOCKER_NETWORK_MASK
|
||||
|
Loading…
x
Reference in New Issue
Block a user