diff libervia/web/server/restricted_bridge.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/server/restricted_bridge.py@a3ca1bab6eb1
children 49ad8dd210d0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libervia/web/server/restricted_bridge.py	Fri Jun 02 16:49:28 2023 +0200
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+
+# Libervia: a SàT frontend
+# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+from libervia.backend.tools.common import data_format
+from libervia.backend.core import exceptions
+from libervia.web.server.constants import Const as C
+
+
+class RestrictedBridge:
+    """bridge with limited access, which can be used in browser
+
+    Only a few method are implemented, with potentially dangerous argument controlled.
+    Security limit is used
+    """
+
+    def __init__(self, host):
+        self.host = host
+        self.security_limit = C.SECURITY_LIMIT
+
+    def no_service_profile(self, profile):
+        """Raise an error if service profile is used"""
+        if profile == C.SERVICE_PROFILE:
+            raise exceptions.PermissionError(
+                "This action is not allowed for service profile"
+            )
+
+    async def action_launch(
+        self, callback_id: str, data_s: str, profile: str
+    ) -> str:
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "action_launch", callback_id, data_s, profile
+        )
+
+    async def call_start(self, entity: str, call_data_s: str, profile: str) -> None:
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "call_start", entity, call_data_s, profile
+        )
+
+    async def call_end(self, session_id: str, call_data: str, profile: str) -> None:
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "call_end", session_id, call_data, profile
+        )
+
+    async def contacts_get(self, profile):
+        return await self.host.bridge_call("contacts_get", profile)
+
+    async def external_disco_get(self, entity, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "external_disco_get", entity, profile)
+
+    async def ice_candidates_add(self, session_id, media_ice_data_s, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "ice_candidates_add", session_id, media_ice_data_s, profile
+        )
+
+    async def identity_get(self, entity, metadata_filter, use_cache, profile):
+        return await self.host.bridge_call(
+            "identity_get", entity, metadata_filter, use_cache, profile)
+
+    async def identities_get(self, entities, metadata_filter, profile):
+        return await self.host.bridge_call(
+            "identities_get", entities, metadata_filter, profile)
+
+    async def identities_base_get(self, profile):
+        return await self.host.bridge_call(
+            "identities_base_get", profile)
+
+    async def ps_node_delete(self, service_s, node, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "ps_node_delete", service_s, node, profile)
+
+    async def ps_node_affiliations_set(self, service_s, node, affiliations, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "ps_node_affiliations_set", service_s, node, affiliations, profile)
+
+    async def ps_item_retract(self, service_s, node, item_id, notify, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "ps_item_retract", service_s, node, item_id, notify, profile)
+
+    async def mb_preview(self, service_s, node, data, profile):
+        return await self.host.bridge_call(
+            "mb_preview", service_s, node, data, profile)
+
+    async def list_set(self, service_s, node, values, schema, item_id, extra, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "list_set", service_s, node, values, "", item_id, "", profile)
+
+
+    async def file_http_upload_get_slot(
+        self, filename, size, content_type, upload_jid, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "file_http_upload_get_slot", filename, size, content_type,
+            upload_jid, profile)
+
+    async def file_sharing_delete(
+        self, service_jid, path, namespace, profile):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "file_sharing_delete", service_jid, path, namespace, profile)
+
+    async def interests_file_sharing_register(
+        self, service, repos_type, namespace, path, name, extra_s, profile
+    ):
+        self.no_service_profile(profile)
+        if extra_s:
+            # we only allow "thumb_url" here
+            extra = data_format.deserialise(extra_s)
+            if "thumb_url" in extra:
+                extra_s = data_format.serialise({"thumb_url": extra["thumb_url"]})
+            else:
+                extra_s = ""
+
+        return await self.host.bridge_call(
+            "interests_file_sharing_register", service, repos_type, namespace, path, name,
+            extra_s, profile
+        )
+
+    async def interest_retract(
+        self, service_jid, item_id, profile
+    ):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "interest_retract", service_jid, item_id, profile)
+
+    async def ps_invite(
+        self, invitee_jid_s, service_s, node, item_id, name, extra_s, profile
+    ):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "ps_invite", invitee_jid_s, service_s, node, item_id, name, extra_s, profile
+        )
+
+    async def fis_invite(
+        self, invitee_jid_s, service_s, repos_type, namespace, path, name, extra_s,
+        profile
+    ):
+        self.no_service_profile(profile)
+        if extra_s:
+            # we only allow "thumb_url" here
+            extra = data_format.deserialise(extra_s)
+            if "thumb_url" in extra:
+                extra_s = data_format.serialise({"thumb_url": extra["thumb_url"]})
+            else:
+                extra_s = ""
+
+        return await self.host.bridge_call(
+            "fis_invite", invitee_jid_s, service_s, repos_type, namespace, path, name,
+            extra_s, profile
+        )
+
+    async def fis_affiliations_set(
+        self, service_s, namespace, path, affiliations, profile
+    ):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "fis_affiliations_set", service_s, namespace, path, affiliations, profile
+        )
+
+    async def invitation_simple_create(
+        self, invitee_email, invitee_name, url_template, extra_s, profile
+    ):
+        self.no_service_profile(profile)
+        return await self.host.bridge_call(
+            "invitation_simple_create", invitee_email, invitee_name, url_template, extra_s,
+            profile
+        )