First clean renaming for smooth migration (#1476)
* First clean renaming for smooth migration * Update security * fix lint * Update hassio/const.py Co-Authored-By: Franck Nijhof <git@frenck.dev> Co-authored-by: Franck Nijhof <frenck@frenck.nl>
This commit is contained in:
parent
3a834d1a73
commit
25d324c73a
|
@ -89,6 +89,11 @@ class RestAPI(CoreSysAttributes):
|
|||
|
||||
self.webapp.add_routes(
|
||||
[
|
||||
web.get("/os/info", api_hassos.info),
|
||||
web.post("/os/update", api_hassos.update),
|
||||
web.post("/os/update/cli", api_hassos.update_cli),
|
||||
web.post("/os/config/sync", api_hassos.config_sync),
|
||||
# Remove with old Hass.io fallback
|
||||
web.get("/hassos/info", api_hassos.info),
|
||||
web.post("/hassos/update", api_hassos.update),
|
||||
web.post("/hassos/update/cli", api_hassos.update_cli),
|
||||
|
@ -150,6 +155,17 @@ class RestAPI(CoreSysAttributes):
|
|||
|
||||
self.webapp.add_routes(
|
||||
[
|
||||
web.get("/core/info", api_hass.info),
|
||||
web.get("/core/logs", api_hass.logs),
|
||||
web.get("/core/stats", api_hass.stats),
|
||||
web.post("/core/options", api_hass.options),
|
||||
web.post("/core/update", api_hass.update),
|
||||
web.post("/core/restart", api_hass.restart),
|
||||
web.post("/core/stop", api_hass.stop),
|
||||
web.post("/core/start", api_hass.start),
|
||||
web.post("/core/check", api_hass.check),
|
||||
web.post("/core/rebuild", api_hass.rebuild),
|
||||
# Remove with old Hass.io fallback
|
||||
web.get("/homeassistant/info", api_hass.info),
|
||||
web.get("/homeassistant/logs", api_hass.logs),
|
||||
web.get("/homeassistant/stats", api_hass.stats),
|
||||
|
@ -170,6 +186,13 @@ class RestAPI(CoreSysAttributes):
|
|||
|
||||
self.webapp.add_routes(
|
||||
[
|
||||
web.get("/core/api/websocket", api_proxy.websocket),
|
||||
web.get("/core/websocket", api_proxy.websocket),
|
||||
web.get("/core/api/stream", api_proxy.stream),
|
||||
web.post("/core/api/{path:.+}", api_proxy.api),
|
||||
web.get("/core/api/{path:.+}", api_proxy.api),
|
||||
web.get("/core/api/", api_proxy.api),
|
||||
# Remove with old Hass.io fallback
|
||||
web.get("/homeassistant/api/websocket", api_proxy.websocket),
|
||||
web.get("/homeassistant/websocket", api_proxy.websocket),
|
||||
web.get("/homeassistant/api/stream", api_proxy.stream),
|
||||
|
|
|
@ -23,6 +23,7 @@ from ..const import (
|
|||
ATTR_ENABLE,
|
||||
COOKIE_INGRESS,
|
||||
HEADER_TOKEN,
|
||||
HEADER_TOKEN_OLD,
|
||||
REQUEST_FROM,
|
||||
)
|
||||
from ..coresys import CoreSysAttributes
|
||||
|
@ -212,6 +213,7 @@ def _init_header(
|
|||
hdrs.SEC_WEBSOCKET_VERSION,
|
||||
hdrs.SEC_WEBSOCKET_KEY,
|
||||
istr(HEADER_TOKEN),
|
||||
istr(HEADER_TOKEN_OLD),
|
||||
):
|
||||
continue
|
||||
headers[name] = value
|
||||
|
|
|
@ -9,7 +9,6 @@ from aiohttp.web_exceptions import HTTPBadGateway, HTTPUnauthorized
|
|||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
from aiohttp.hdrs import CONTENT_TYPE, AUTHORIZATION
|
||||
|
||||
from ..const import HEADER_HA_ACCESS
|
||||
from ..coresys import CoreSysAttributes
|
||||
from ..exceptions import HomeAssistantAuthError, HomeAssistantAPIError, APIError
|
||||
|
||||
|
@ -17,6 +16,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
FORWARD_HEADERS = ("X-Speech-Content",)
|
||||
HEADER_HA_ACCESS = "X-Ha-Access"
|
||||
|
||||
|
||||
class APIProxy(CoreSysAttributes):
|
||||
|
|
|
@ -3,16 +3,16 @@ import logging
|
|||
import re
|
||||
|
||||
from aiohttp.web import middleware
|
||||
from aiohttp.web_exceptions import HTTPUnauthorized, HTTPForbidden
|
||||
from aiohttp.web_exceptions import HTTPForbidden, HTTPUnauthorized
|
||||
|
||||
from .utils import excract_supervisor_token
|
||||
from ..const import (
|
||||
HEADER_TOKEN,
|
||||
REQUEST_FROM,
|
||||
ROLE_ADMIN,
|
||||
ROLE_BACKUP,
|
||||
ROLE_DEFAULT,
|
||||
ROLE_HOMEASSISTANT,
|
||||
ROLE_MANAGER,
|
||||
ROLE_BACKUP,
|
||||
)
|
||||
from ..coresys import CoreSysAttributes
|
||||
|
||||
|
@ -24,6 +24,7 @@ _LOGGER: logging.Logger = logging.getLogger(__name__)
|
|||
BLACKLIST = re.compile(
|
||||
r"^(?:"
|
||||
r"|/homeassistant/api/hassio/.*"
|
||||
r"|/core/api/hassio/.*"
|
||||
r")$"
|
||||
)
|
||||
|
||||
|
@ -32,6 +33,8 @@ NO_SECURITY_CHECK = re.compile(
|
|||
r"^(?:"
|
||||
r"|/homeassistant/api/.*"
|
||||
r"|/homeassistant/websocket"
|
||||
r"|/core/api/.*"
|
||||
r"|/core/websocket"
|
||||
r"|/supervisor/ping"
|
||||
r")$"
|
||||
)
|
||||
|
@ -59,6 +62,7 @@ ADDONS_ROLE_ACCESS = {
|
|||
),
|
||||
ROLE_HOMEASSISTANT: re.compile(
|
||||
r"^(?:"
|
||||
r"|/core/.+"
|
||||
r"|/homeassistant/.+"
|
||||
r")$"
|
||||
),
|
||||
|
@ -70,9 +74,11 @@ ADDONS_ROLE_ACCESS = {
|
|||
ROLE_MANAGER: re.compile(
|
||||
r"^(?:"
|
||||
r"|/dns/.*"
|
||||
r"|/core/.+"
|
||||
r"|/homeassistant/.+"
|
||||
r"|/host/.+"
|
||||
r"|/hardware/.+"
|
||||
r"|/os/.+"
|
||||
r"|/hassos/.+"
|
||||
r"|/supervisor/.+"
|
||||
r"|/addons(?:/[^/]+/(?!security).+|/reload)?"
|
||||
|
@ -98,7 +104,7 @@ class SecurityMiddleware(CoreSysAttributes):
|
|||
async def token_validation(self, request, handler):
|
||||
"""Check security access of this layer."""
|
||||
request_from = None
|
||||
hassio_token = request.headers.get(HEADER_TOKEN)
|
||||
supervisor_token = excract_supervisor_token(request)
|
||||
|
||||
# Blacklist
|
||||
if BLACKLIST.match(request.path):
|
||||
|
@ -111,24 +117,24 @@ class SecurityMiddleware(CoreSysAttributes):
|
|||
return await handler(request)
|
||||
|
||||
# Not token
|
||||
if not hassio_token:
|
||||
if not supervisor_token:
|
||||
_LOGGER.warning("No API token provided for %s", request.path)
|
||||
raise HTTPUnauthorized()
|
||||
|
||||
# Home-Assistant
|
||||
if hassio_token == self.sys_homeassistant.hassio_token:
|
||||
if supervisor_token == self.sys_homeassistant.hassio_token:
|
||||
_LOGGER.debug("%s access from Home Assistant", request.path)
|
||||
request_from = self.sys_homeassistant
|
||||
|
||||
# Host
|
||||
if hassio_token == self.sys_machine_id:
|
||||
if supervisor_token == self.sys_machine_id:
|
||||
_LOGGER.debug("%s access from Host", request.path)
|
||||
request_from = self.sys_host
|
||||
|
||||
# Add-on
|
||||
addon = None
|
||||
if hassio_token and not request_from:
|
||||
addon = self.sys_addons.from_token(hassio_token)
|
||||
if supervisor_token and not request_from:
|
||||
addon = self.sys_addons.from_token(supervisor_token)
|
||||
|
||||
# Check Add-on API access
|
||||
if addon and ADDONS_API_BYPASS.match(request.path):
|
||||
|
|
|
@ -4,11 +4,14 @@ import logging
|
|||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from aiohttp import web
|
||||
from aiohttp.hdrs import AUTHORIZATION
|
||||
import voluptuous as vol
|
||||
from voluptuous.humanize import humanize_error
|
||||
|
||||
from ..const import (
|
||||
CONTENT_TYPE_BINARY,
|
||||
HEADER_TOKEN,
|
||||
HEADER_TOKEN_OLD,
|
||||
JSON_DATA,
|
||||
JSON_MESSAGE,
|
||||
JSON_RESULT,
|
||||
|
@ -20,6 +23,22 @@ from ..exceptions import APIError, APIForbidden, HassioError
|
|||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def excract_supervisor_token(request: web.Request) -> Optional[str]:
|
||||
"""Extract Supervisor token from request."""
|
||||
supervisor_token = request.headers.get(AUTHORIZATION)
|
||||
if supervisor_token:
|
||||
return supervisor_token.split(" ")[-1]
|
||||
|
||||
# Header token handling
|
||||
supervisor_token = request.headers.get(HEADER_TOKEN)
|
||||
|
||||
# Remove with old Hass.io fallback
|
||||
if not supervisor_token:
|
||||
supervisor_token = request.headers.get(HEADER_TOKEN_OLD)
|
||||
|
||||
return supervisor_token
|
||||
|
||||
|
||||
def json_loads(data: Any) -> Dict[str, Any]:
|
||||
"""Extract json from string with support for '' and None."""
|
||||
if not data:
|
||||
|
|
|
@ -58,11 +58,13 @@ CONTENT_TYPE_JSON = "application/json"
|
|||
CONTENT_TYPE_TEXT = "text/plain"
|
||||
CONTENT_TYPE_TAR = "application/tar"
|
||||
CONTENT_TYPE_URL = "application/x-www-form-urlencoded"
|
||||
HEADER_HA_ACCESS = "X-Ha-Access"
|
||||
HEADER_TOKEN = "X-Hassio-Key"
|
||||
COOKIE_INGRESS = "ingress_session"
|
||||
|
||||
ENV_TOKEN = "HASSIO_TOKEN"
|
||||
HEADER_TOKEN = "X-Supervisor-Token"
|
||||
HEADER_TOKEN_OLD = "X-Hassio-Key"
|
||||
|
||||
ENV_TOKEN_OLD = "HASSIO_TOKEN"
|
||||
ENV_TOKEN = "SUPERVISOR_TOKEN"
|
||||
ENV_TIME = "TZ"
|
||||
|
||||
REQUEST_FROM = "HASSIO_FROM"
|
||||
|
|
|
@ -6,7 +6,7 @@ from ipaddress import IPv4Address, ip_address
|
|||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Union, Awaitable
|
||||
from typing import TYPE_CHECKING, Awaitable, Dict, List, Optional, Union
|
||||
|
||||
import docker
|
||||
import requests
|
||||
|
@ -15,6 +15,7 @@ from ..addons.build import AddonBuild
|
|||
from ..const import (
|
||||
ENV_TIME,
|
||||
ENV_TOKEN,
|
||||
ENV_TOKEN_OLD,
|
||||
MAP_ADDONS,
|
||||
MAP_BACKUP,
|
||||
MAP_CONFIG,
|
||||
|
@ -118,6 +119,7 @@ class DockerAddon(DockerInterface):
|
|||
**addon_env,
|
||||
ENV_TIME: self.sys_timezone,
|
||||
ENV_TOKEN: self.addon.hassio_token,
|
||||
ENV_TOKEN_OLD: self.addon.hassio_token,
|
||||
}
|
||||
|
||||
@property
|
||||
|
@ -189,7 +191,10 @@ class DockerAddon(DockerInterface):
|
|||
@property
|
||||
def network_mapping(self) -> Dict[str, str]:
|
||||
"""Return hosts mapping."""
|
||||
return {"hassio": self.sys_docker.network.supervisor}
|
||||
return {
|
||||
"supervisor": self.sys_docker.network.supervisor,
|
||||
"hassio": self.sys_docker.network.supervisor,
|
||||
}
|
||||
|
||||
@property
|
||||
def network_mode(self) -> Optional[str]:
|
||||
|
|
|
@ -6,7 +6,7 @@ from typing import Awaitable, Optional
|
|||
|
||||
import docker
|
||||
|
||||
from ..const import ENV_TIME, ENV_TOKEN, LABEL_MACHINE
|
||||
from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_OLD, LABEL_MACHINE
|
||||
from ..exceptions import DockerAPIError
|
||||
from .interface import CommandReturn, DockerInterface
|
||||
|
||||
|
@ -69,8 +69,10 @@ class DockerHomeAssistant(DockerInterface):
|
|||
network_mode="host",
|
||||
environment={
|
||||
"HASSIO": self.sys_docker.network.supervisor,
|
||||
"SUPERVISOR": self.sys_docker.network.supervisor,
|
||||
ENV_TIME: self.sys_timezone,
|
||||
ENV_TOKEN: self.sys_homeassistant.hassio_token,
|
||||
ENV_TOKEN_OLD: self.sys_homeassistant.hassio_token,
|
||||
},
|
||||
volumes={
|
||||
str(self.sys_config.path_extern_homeassistant): {
|
||||
|
|
Loading…
Reference in New Issue