Add validate session API (#2223)

This commit is contained in:
Paulus Schoutsen 2020-11-06 11:52:11 +01:00 committed by GitHub
parent 517e6cb437
commit ffaeb2b96d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 2 deletions

View File

@ -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),
]

View File

@ -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
View 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

View File

@ -1,4 +1,4 @@
"""Test NetwrokInterface API."""
"""Test NetworkInterface API."""
import pytest
from supervisor.const import DOCKER_NETWORK, DOCKER_NETWORK_MASK