diff libervia/web/pages/_bridge/page_meta.py @ 1518:eb00d593801d

refactoring: rename `libervia` to `libervia.web` + update imports following backend changes
author Goffi <goffi@goffi.org>
date Fri, 02 Jun 2023 16:49:28 +0200
parents libervia/pages/_bridge/page_meta.py@106bae41f5c8
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libervia/web/pages/_bridge/page_meta.py	Fri Jun 02 16:49:28 2023 +0200
@@ -0,0 +1,75 @@
+#!/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)