implement support of unix socket for server

This feature can be used for unauthorized access to apis - e.g. for
reporting service if it is run on the same machine. Since now it becomes
recommended way for the interprocess communication, thus some options
(e.g. creating user with as-service flag) are no longer available now
This commit is contained in:
2022-11-29 01:18:01 +02:00
parent 4811dec759
commit 0161617e36
24 changed files with 247 additions and 134 deletions

View File

@ -19,6 +19,7 @@
#
import aiohttp_security # type: ignore
import base64
import socket
import types
from aiohttp import web
@ -101,7 +102,11 @@ def auth_handler(allow_read_only: bool) -> MiddlewareType:
"""
@middleware
async def handle(request: Request, handler: HandlerType) -> StreamResponse:
if (permission_method := getattr(handler, "get_permission", None)) is not None:
if (unix_socket := request.get_extra_info("socket")) is not None and unix_socket.family == socket.AF_UNIX:
# special case for unix sockets. We need to extract socket which is used for the request
# and check its address family
permission = UserAccess.Unauthorized
elif (permission_method := getattr(handler, "get_permission", None)) is not None:
permission = await permission_method(request)
elif isinstance(handler, types.MethodType): # additional wrapper for static resources
handler_instance = getattr(handler, "__self__", None)

View File

@ -78,8 +78,9 @@ def run_server(application: web.Application) -> None:
configuration: Configuration = application["configuration"]
host = configuration.get("web", "host")
port = configuration.getint("web", "port")
unix_socket = configuration.get("web", "unix_socket", fallback=None)
web.run_app(application, host=host, port=port, handle_signals=False,
web.run_app(application, host=host, port=port, path=unix_socket, handle_signals=False,
access_log=logging.getLogger("http"), access_log_class=FilteredAccessLogger)