view libervia/web/pages/_bridge/page_meta.py @ 1524:311febeae2d5

build: new "dev" env with debugging packages
author Goffi <goffi@goffi.org>
date Thu, 08 Jun 2023 21:07:52 +0200
parents eb00d593801d
children
line wrap: on
line source

#!/usr/bin/env python3

import json
from libervia.backend.core.i18n import _
from libervia.backend.core.log import getLogger
from libervia.frontends.bridge.bridge_frontend import BridgeException
from libervia.web.server.constants import Const as C


log = getLogger(__name__)
"""access to restricted bridge"""

name = "bridge"
on_data_post = "continue"

# bridge method allowed when no profile is connected
NO_SESSION_ALLOWED = ("contacts_get", "identities_base_get", "identities_get")


def parse_url(self, request):
    self.get_path_args(request, ["method_name"], min_args=1)


async def render(self, request):
    if request.method != b'POST':
        log.warning(f"Bad method used with _bridge endpoint: {request.method.decode()}")
        return self.page_error(request, C.HTTP_BAD_REQUEST)
    data = self.get_r_data(request)
    profile = self.get_profile(request)
    self.check_csrf(request)
    method_name = data["method_name"]
    if profile is None:
        if method_name in NO_SESSION_ALLOWED:
            # this method is allowed, we use the service profile
            profile = C.SERVICE_PROFILE
        else:
            log.warning("_bridge endpoint accessed without authorisation")
            return self.page_error(request, C.HTTP_UNAUTHORIZED)
    method_data = json.load(request.content)
    try:
        bridge_method = getattr(self.host.restricted_bridge, method_name)
    except AttributeError:
        log.warning(_(
            "{profile!r} is trying to access a bridge method not implemented in "
            "RestrictedBridge: {method_name}").format(
                profile=profile, method_name=method_name))
        return self.page_error(request, C.HTTP_BAD_REQUEST)

    try:
        args, kwargs = method_data['args'], method_data['kwargs']
    except KeyError:
        log.warning(_(
            "{profile!r} has sent a badly formatted method call: {method_data}"
        ).format(profile=profile, method_data=method_data))
        return self.page_error(request, C.HTTP_BAD_REQUEST)

    if "profile" in kwargs or "profile_key" in kwargs:
        log.warning(_(
            '"profile" key should not be in method kwargs, hack attempt? '
            "profile={profile}, method_data={method_data}"
        ).format(profile=profile, method_data=method_data))
        return self.page_error(request, C.HTTP_BAD_REQUEST)

    try:
        ret = await bridge_method(*args, **kwargs, profile=profile)
    except BridgeException as e:
        request.setResponseCode(C.HTTP_PROXY_ERROR)
        ret = {
            "fullname": e.fullname,
            "message": e.message,
            "condition": e.condition,
            "module": e.module,
            "classname": e.classname,
        }
    return json.dumps(ret)