mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-23 17:16:33 +00:00
Observer access handling (#2043)
* Change access handling * add security check
This commit is contained in:
parent
da83edf231
commit
409b53109b
@ -39,6 +39,13 @@ NO_SECURITY_CHECK = re.compile(
|
|||||||
r")$"
|
r")$"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Observer allow API calls
|
||||||
|
OBSERVER_CHECK = re.compile(
|
||||||
|
r"^(?:"
|
||||||
|
r"|/[^/]+/info"
|
||||||
|
r")$"
|
||||||
|
)
|
||||||
|
|
||||||
# Can called by every add-on
|
# Can called by every add-on
|
||||||
ADDONS_API_BYPASS = re.compile(
|
ADDONS_API_BYPASS = re.compile(
|
||||||
r"^(?:"
|
r"^(?:"
|
||||||
@ -95,7 +102,7 @@ ADDONS_ROLE_ACCESS = {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
# fmt: off
|
# fmt: on
|
||||||
|
|
||||||
|
|
||||||
class SecurityMiddleware(CoreSysAttributes):
|
class SecurityMiddleware(CoreSysAttributes):
|
||||||
@ -136,6 +143,14 @@ class SecurityMiddleware(CoreSysAttributes):
|
|||||||
_LOGGER.debug("%s access from Host", request.path)
|
_LOGGER.debug("%s access from Host", request.path)
|
||||||
request_from = self.sys_host
|
request_from = self.sys_host
|
||||||
|
|
||||||
|
# Observer
|
||||||
|
if supervisor_token == self.sys_plugins.observer.supervisor_token:
|
||||||
|
if not OBSERVER_CHECK.match(request.url):
|
||||||
|
_LOGGER.warning("%s invalid Observer access", request.path)
|
||||||
|
raise HTTPForbidden()
|
||||||
|
_LOGGER.debug("%s access from Observer", request.path)
|
||||||
|
request_from = self.sys_plugins.observer
|
||||||
|
|
||||||
# Add-on
|
# Add-on
|
||||||
addon = None
|
addon = None
|
||||||
if supervisor_token and not request_from:
|
if supervisor_token and not request_from:
|
||||||
|
@ -70,8 +70,7 @@ HEADER_TOKEN_OLD = "X-Hassio-Key"
|
|||||||
|
|
||||||
ENV_TIME = "TZ"
|
ENV_TIME = "TZ"
|
||||||
ENV_TOKEN = "SUPERVISOR_TOKEN"
|
ENV_TOKEN = "SUPERVISOR_TOKEN"
|
||||||
ENV_TOKEN_OLD = "HASSIO_TOKEN"
|
ENV_TOKEN_HASSIO = "HASSIO_TOKEN"
|
||||||
ENV_OBSERVER = "OBSERVER_TOKEN"
|
|
||||||
|
|
||||||
ENV_HOMEASSISTANT_REPOSITORY = "HOMEASSISTANT_REPOSITORY"
|
ENV_HOMEASSISTANT_REPOSITORY = "HOMEASSISTANT_REPOSITORY"
|
||||||
ENV_SUPERVISOR_DEV = "SUPERVISOR_DEV"
|
ENV_SUPERVISOR_DEV = "SUPERVISOR_DEV"
|
||||||
|
@ -15,7 +15,7 @@ from ..addons.build import AddonBuild
|
|||||||
from ..const import (
|
from ..const import (
|
||||||
ENV_TIME,
|
ENV_TIME,
|
||||||
ENV_TOKEN,
|
ENV_TOKEN,
|
||||||
ENV_TOKEN_OLD,
|
ENV_TOKEN_HASSIO,
|
||||||
MAP_ADDONS,
|
MAP_ADDONS,
|
||||||
MAP_BACKUP,
|
MAP_BACKUP,
|
||||||
MAP_CONFIG,
|
MAP_CONFIG,
|
||||||
@ -119,7 +119,7 @@ class DockerAddon(DockerInterface):
|
|||||||
**addon_env,
|
**addon_env,
|
||||||
ENV_TIME: self.sys_config.timezone,
|
ENV_TIME: self.sys_config.timezone,
|
||||||
ENV_TOKEN: self.addon.supervisor_token,
|
ENV_TOKEN: self.addon.supervisor_token,
|
||||||
ENV_TOKEN_OLD: self.addon.supervisor_token,
|
ENV_TOKEN_HASSIO: self.addon.supervisor_token,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""HA Cli docker object."""
|
"""HA Cli docker object."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from ..const import ENV_OBSERVER, ENV_TIME, ENV_TOKEN
|
from ..const import ENV_TIME, ENV_TOKEN
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from .interface import DockerInterface
|
from .interface import DockerInterface
|
||||||
|
|
||||||
@ -52,7 +52,6 @@ class DockerCli(DockerInterface, CoreSysAttributes):
|
|||||||
environment={
|
environment={
|
||||||
ENV_TIME: self.sys_config.timezone,
|
ENV_TIME: self.sys_config.timezone,
|
||||||
ENV_TOKEN: self.sys_plugins.cli.supervisor_token,
|
ENV_TOKEN: self.sys_plugins.cli.supervisor_token,
|
||||||
ENV_OBSERVER: self.sys_plugins.observer.access_token,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -6,14 +6,7 @@ from typing import Awaitable, Dict, Optional
|
|||||||
import docker
|
import docker
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from ..const import (
|
from ..const import ENV_TIME, ENV_TOKEN, ENV_TOKEN_HASSIO, LABEL_MACHINE, MACHINE_ID
|
||||||
ENV_OBSERVER,
|
|
||||||
ENV_TIME,
|
|
||||||
ENV_TOKEN,
|
|
||||||
ENV_TOKEN_OLD,
|
|
||||||
LABEL_MACHINE,
|
|
||||||
MACHINE_ID,
|
|
||||||
)
|
|
||||||
from ..exceptions import DockerAPIError
|
from ..exceptions import DockerAPIError
|
||||||
from .interface import CommandReturn, DockerInterface
|
from .interface import CommandReturn, DockerInterface
|
||||||
|
|
||||||
@ -131,8 +124,7 @@ class DockerHomeAssistant(DockerInterface):
|
|||||||
"SUPERVISOR": self.sys_docker.network.supervisor,
|
"SUPERVISOR": self.sys_docker.network.supervisor,
|
||||||
ENV_TIME: self.sys_config.timezone,
|
ENV_TIME: self.sys_config.timezone,
|
||||||
ENV_TOKEN: self.sys_homeassistant.supervisor_token,
|
ENV_TOKEN: self.sys_homeassistant.supervisor_token,
|
||||||
ENV_TOKEN_OLD: self.sys_homeassistant.supervisor_token,
|
ENV_TOKEN_HASSIO: self.sys_homeassistant.supervisor_token,
|
||||||
ENV_OBSERVER: self.sys_plugins.observer.access_token,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Observer docker object."""
|
"""Observer docker object."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from ..const import ENV_OBSERVER, ENV_TIME
|
from ..const import ENV_TIME, ENV_TOKEN
|
||||||
from ..coresys import CoreSysAttributes
|
from ..coresys import CoreSysAttributes
|
||||||
from .interface import DockerInterface
|
from .interface import DockerInterface
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ class DockerObserver(DockerInterface, CoreSysAttributes):
|
|||||||
extra_hosts={"supervisor": self.sys_docker.network.supervisor},
|
extra_hosts={"supervisor": self.sys_docker.network.supervisor},
|
||||||
environment={
|
environment={
|
||||||
ENV_TIME: self.sys_config.timezone,
|
ENV_TIME: self.sys_config.timezone,
|
||||||
ENV_OBSERVER: self.sys_plugins.observer.access_token,
|
ENV_TOKEN: self.sys_plugins.observer.supervisor_token,
|
||||||
},
|
},
|
||||||
volumes={"/run/docker.sock": {"bind": "/run/docker.sock", "mode": "ro"}},
|
volumes={"/run/docker.sock": {"bind": "/run/docker.sock", "mode": "ro"}},
|
||||||
ports={"80/tcp": 4357},
|
ports={"80/tcp": 4357},
|
||||||
|
@ -21,7 +21,7 @@ class PluginManager(CoreSysAttributes):
|
|||||||
required_cli: LegacyVersion = pkg_parse("26")
|
required_cli: LegacyVersion = pkg_parse("26")
|
||||||
required_dns: LegacyVersion = pkg_parse("9")
|
required_dns: LegacyVersion = pkg_parse("9")
|
||||||
required_audio: LegacyVersion = pkg_parse("17")
|
required_audio: LegacyVersion = pkg_parse("17")
|
||||||
required_observer: LegacyVersion = pkg_parse("1")
|
required_observer: LegacyVersion = pkg_parse("2")
|
||||||
required_multicast: LegacyVersion = pkg_parse("3")
|
required_multicast: LegacyVersion = pkg_parse("3")
|
||||||
|
|
||||||
def __init__(self, coresys: CoreSys):
|
def __init__(self, coresys: CoreSys):
|
||||||
|
@ -62,7 +62,7 @@ class Observer(CoreSysAttributes, JsonConfig):
|
|||||||
return self.version != self.latest_version
|
return self.version != self.latest_version
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def access_token(self) -> str:
|
def supervisor_token(self) -> str:
|
||||||
"""Return an access token for the Observer API."""
|
"""Return an access token for the Observer API."""
|
||||||
return self._data.get(ATTR_ACCESS_TOKEN)
|
return self._data.get(ATTR_ACCESS_TOKEN)
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ class Observer(CoreSysAttributes, JsonConfig):
|
|||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
"""Run observer."""
|
"""Run observer."""
|
||||||
# Create new API token
|
# Create new API token
|
||||||
if not self.access_token:
|
if not self.supervisor_token:
|
||||||
self._data[ATTR_ACCESS_TOKEN] = secrets.token_hex(56)
|
self._data[ATTR_ACCESS_TOKEN] = secrets.token_hex(56)
|
||||||
self.save_data()
|
self.save_data()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user