Cleanup security layer - Add-on default access role (#2954)

* Allow access to network info (add-on)

* fix check

* make it nice

* cleanup

* cleanup

* fix tests

* Add warning

* allow access to addons/store/snapshot infos

* revert
This commit is contained in:
Pascal Vizeli 2021-06-14 10:05:37 +02:00 committed by GitHub
parent 6b58970354
commit cd8fc16bcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 15 additions and 13 deletions

View File

@ -19,7 +19,7 @@ from .host import APIHost
from .info import APIInfo from .info import APIInfo
from .ingress import APIIngress from .ingress import APIIngress
from .jobs import APIJobs from .jobs import APIJobs
from .middleware_security import SecurityMiddleware from .middleware.security import SecurityMiddleware
from .multicast import APIMulticast from .multicast import APIMulticast
from .network import APINetwork from .network import APINetwork
from .observer import APIObserver from .observer import APIObserver
@ -223,7 +223,6 @@ class RestAPI(CoreSysAttributes):
[ [
web.get("/hardware/info", api_hardware.info), web.get("/hardware/info", api_hardware.info),
web.get("/hardware/audio", api_hardware.audio), web.get("/hardware/audio", api_hardware.audio),
web.post("/hardware/trigger", api_hardware.trigger),
] ]
) )

View File

@ -1,6 +1,6 @@
"""Init file for Supervisor hardware RESTful API.""" """Init file for Supervisor hardware RESTful API."""
import logging import logging
from typing import Any, Awaitable, Dict from typing import Any, Dict
from aiohttp import web from aiohttp import web
@ -58,8 +58,3 @@ class APIHardware(CoreSysAttributes):
}, },
} }
} }
@api_process
async def trigger(self, request: web.Request) -> Awaitable[None]:
"""Trigger a udev device reload."""
_LOGGER.debug("Ignoring DEPRECATED hardware trigger function call.")

View File

@ -0,0 +1 @@
"""API middleware for aiohttp."""

View File

@ -5,7 +5,7 @@ import re
from aiohttp.web import Request, RequestHandler, Response, middleware from aiohttp.web import Request, RequestHandler, Response, middleware
from aiohttp.web_exceptions import HTTPForbidden, HTTPUnauthorized from aiohttp.web_exceptions import HTTPForbidden, HTTPUnauthorized
from ..const import ( from ...const import (
REQUEST_FROM, REQUEST_FROM,
ROLE_ADMIN, ROLE_ADMIN,
ROLE_BACKUP, ROLE_BACKUP,
@ -14,8 +14,8 @@ from ..const import (
ROLE_MANAGER, ROLE_MANAGER,
CoreState, CoreState,
) )
from ..coresys import CoreSys, CoreSysAttributes from ...coresys import CoreSys, CoreSysAttributes
from .utils import api_return_error, excract_supervisor_token from ..utils import api_return_error, excract_supervisor_token
_LOGGER: logging.Logger = logging.getLogger(__name__) _LOGGER: logging.Logger = logging.getLogger(__name__)
@ -53,7 +53,6 @@ ADDONS_API_BYPASS = re.compile(
r"|/addons/self/(?!security|update)[^/]+" r"|/addons/self/(?!security|update)[^/]+"
r"|/addons/self/options/config" r"|/addons/self/options/config"
r"|/info" r"|/info"
r"|/hardware/trigger"
r"|/services.*" r"|/services.*"
r"|/discovery.*" r"|/discovery.*"
r"|/auth" r"|/auth"
@ -65,22 +64,24 @@ ADDONS_ROLE_ACCESS = {
ROLE_DEFAULT: re.compile( ROLE_DEFAULT: re.compile(
r"^(?:" r"^(?:"
r"|/.+/info" r"|/.+/info"
r"|/addons"
r")$" r")$"
), ),
ROLE_HOMEASSISTANT: re.compile( ROLE_HOMEASSISTANT: re.compile(
r"^(?:" r"^(?:"
r"|/.+/info"
r"|/core/.+" r"|/core/.+"
r"|/homeassistant/.+" r"|/homeassistant/.+"
r")$" r")$"
), ),
ROLE_BACKUP: re.compile( ROLE_BACKUP: re.compile(
r"^(?:" r"^(?:"
r"|/.+/info"
r"|/snapshots.*" r"|/snapshots.*"
r")$" r")$"
), ),
ROLE_MANAGER: re.compile( ROLE_MANAGER: re.compile(
r"^(?:" r"^(?:"
r"|/.+/info"
r"|/addons(?:/[^/]+/(?!security).+|/reload)?" r"|/addons(?:/[^/]+/(?!security).+|/reload)?"
r"|/audio/.+" r"|/audio/.+"
r"|/auth/cache" r"|/auth/cache"
@ -101,6 +102,7 @@ ADDONS_ROLE_ACCESS = {
r"|/snapshots.*" r"|/snapshots.*"
r"|/store.*" r"|/store.*"
r"|/supervisor/.+" r"|/supervisor/.+"
r"|/security/.+"
r")$" r")$"
), ),
ROLE_ADMIN: re.compile( ROLE_ADMIN: re.compile(
@ -191,6 +193,10 @@ class SecurityMiddleware(CoreSysAttributes):
request_from = addon request_from = addon
else: else:
_LOGGER.warning("%s no role for %s", request.path, addon.slug) _LOGGER.warning("%s no role for %s", request.path, addon.slug)
elif addon:
_LOGGER.warning(
"%s missing API permission for %s", addon.slug, request.path
)
if request_from: if request_from:
request[REQUEST_FROM] = request_from request[REQUEST_FROM] = request_from

View File

@ -0,0 +1 @@
"""Test for API middleware."""