changeset 3163:d10b2368684e

bridge: added methods to let frontends store/retrieve/delete private data
author Goffi <goffi@goffi.org>
date Mon, 10 Feb 2020 22:01:53 +0100
parents b5c058c7692e
children 9dc170635bee
files sat/bridge/bridge_constructor/bridge_template.ini sat/bridge/dbus_bridge.py sat/core/sat_main.py sat/memory/memory.py sat_frontends/bridge/dbus_bridge.py sat_frontends/bridge/pb.py
diffstat 6 files changed, 168 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/sat/bridge/bridge_constructor/bridge_template.ini	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat/bridge/bridge_constructor/bridge_template.ini	Mon Feb 10 22:01:53 2020 +0100
@@ -573,6 +573,41 @@
 doc_param_2=attribute: Name of the attribute
 doc_param_3=%(doc_profile_key)s
 
+[privateDataGet]
+async=
+type=method
+category=core
+sig_in=sss
+sig_out=s
+doc=Retrieve private data
+doc_param_0=namespace: unique namespace to use
+doc_param_1=key: key of the data to set
+doc_param_2=%(doc_profile_key)s
+doc_return=serialised data
+
+[privateDataSet]
+async=
+type=method
+category=core
+sig_in=ssss
+sig_out=
+doc=Store private data
+doc_param_0=namespace: unique namespace to use
+doc_param_1=key: key of the data to set
+doc_param_2=data: serialised data
+doc_param_3=%(doc_profile_key)s
+
+[privateDataDelete]
+async=
+type=method
+category=core
+sig_in=sss
+sig_out=
+doc=Delete private data
+doc_param_0=namespace: unique namespace to use
+doc_param_1=key: key of the data to delete
+doc_param_3=%(doc_profile_key)s
+
 [asyncGetParamA]
 async=
 type=method
--- a/sat/bridge/dbus_bridge.py	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat/bridge/dbus_bridge.py	Mon Feb 10 22:01:53 2020 +0100
@@ -477,6 +477,24 @@
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
                          in_signature='sss', out_signature='',
                          async_callbacks=('callback', 'errback'))
+    def privateDataDelete(self, namespace, key, arg_2, callback=None, errback=None):
+        return self._callback("privateDataDelete", str(namespace), str(key), str(arg_2), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sss', out_signature='s',
+                         async_callbacks=('callback', 'errback'))
+    def privateDataGet(self, namespace, key, profile_key, callback=None, errback=None):
+        return self._callback("privateDataGet", str(namespace), str(key), str(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='ssss', out_signature='',
+                         async_callbacks=('callback', 'errback'))
+    def privateDataSet(self, namespace, key, data, profile_key, callback=None, errback=None):
+        return self._callback("privateDataSet", str(namespace), str(key), str(data), str(profile_key), callback=callback, errback=errback)
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='sss', out_signature='',
+                         async_callbacks=('callback', 'errback'))
     def profileCreate(self, profile, password='', component='', callback=None, errback=None):
         return self._callback("profileCreate", str(profile), str(password), str(component), callback=callback, errback=errback)
 
--- a/sat/core/sat_main.py	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat/core/sat_main.py	Mon Feb 10 22:01:53 2020 +0100
@@ -136,6 +136,9 @@
         self.bridge.register_method("getConfig", self._getConfig)
         self.bridge.register_method("setParam", self.setParam)
         self.bridge.register_method("getParamA", self.memory.getStringParamA)
+        self.bridge.register_method("privateDataGet", self.memory._privateDataGet)
+        self.bridge.register_method("privateDataSet", self.memory._privateDataSet)
+        self.bridge.register_method("privateDataDelete", self.memory._privateDataDelete)
         self.bridge.register_method("asyncGetParamA", self.memory.asyncGetStringParamA)
         self.bridge.register_method(
             "asyncGetParamsValuesFromCategory",
--- a/sat/memory/memory.py	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat/memory/memory.py	Mon Feb 10 22:01:53 2020 +0100
@@ -39,6 +39,7 @@
 from sat.memory.crypto import BlockCipher
 from sat.memory.crypto import PasswordHasher
 from sat.tools import config as tools_config
+from sat.tools.common import data_format
 import shortuuid
 import mimetypes
 import time
@@ -1153,6 +1154,27 @@
     def setDefault(self, name, category, callback, errback=None):
         return self.params.setDefault(name, category, callback, errback)
 
+    ## Private Data ##
+
+    def _privateDataSet(self, namespace, key, data_s, profile_key):
+        client = self.host.getClient(profile_key)
+        # we accept any type
+        data = data_format.deserialise(data_s, type_check=None)
+        return self.storage.setPrivateValue(
+            namespace, key, data, binary=True, profile=client.profile)
+
+    def _privateDataGet(self, namespace, key, profile_key):
+        client = self.host.getClient(profile_key)
+        d = self.storage.getPrivates(
+            namespace, [key], binary=True, profile=client.profile)
+        d.addCallback(lambda data_dict: data_format.serialise(data_dict.get(key)))
+        return d
+
+    def _privateDataDelete(self, namespace, key, profile_key):
+        client = self.host.getClient(profile_key)
+        return self.storage.delPrivateValue(
+            namespace, key, binary=True, profile=client.profile)
+
     ## Files ##
 
     def checkFilePermission(self, file_data, peer_jid, perms_to_check):
--- a/sat_frontends/bridge/dbus_bridge.py	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat_frontends/bridge/dbus_bridge.py	Mon Feb 10 22:01:53 2020 +0100
@@ -641,6 +641,33 @@
             kwargs['error_handler'] = error_handler
         return self.db_core_iface.paramsRegisterApp(xml, security_limit, app, **kwargs)
 
+    def privateDataDelete(self, namespace, key, arg_2, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.privateDataDelete(namespace, key, arg_2, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
+    def privateDataGet(self, namespace, key, profile_key, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return str(self.db_core_iface.privateDataGet(namespace, key, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler))
+
+    def privateDataSet(self, namespace, key, data, profile_key, callback=None, errback=None):
+        if callback is None:
+            error_handler = None
+        else:
+            if errback is None:
+                errback = log.error
+            error_handler = lambda err:errback(dbus_to_bridge_exception(err))
+        return self.db_core_iface.privateDataSet(namespace, key, data, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+
     def profileCreate(self, profile, password='', component='', callback=None, errback=None):
         if callback is None:
             error_handler = None
@@ -1226,6 +1253,30 @@
         self.db_core_iface.paramsRegisterApp(xml, security_limit, app, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
         return fut
 
+    def privateDataDelete(self, namespace, key, arg_2):
+        loop = asyncio.get_running_loop()
+        fut = loop.create_future()
+        reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
+        error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err))
+        self.db_core_iface.privateDataDelete(namespace, key, arg_2, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
+        return fut
+
+    def privateDataGet(self, namespace, key, profile_key):
+        loop = asyncio.get_running_loop()
+        fut = loop.create_future()
+        reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
+        error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err))
+        self.db_core_iface.privateDataGet(namespace, key, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
+        return fut
+
+    def privateDataSet(self, namespace, key, data, profile_key):
+        loop = asyncio.get_running_loop()
+        fut = loop.create_future()
+        reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
+        error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err))
+        self.db_core_iface.privateDataSet(namespace, key, data, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
+        return fut
+
     def profileCreate(self, profile, password='', component=''):
         loop = asyncio.get_running_loop()
         fut = loop.create_future()
--- a/sat_frontends/bridge/pb.py	Sun Feb 09 23:56:42 2020 +0100
+++ b/sat_frontends/bridge/pb.py	Mon Feb 10 22:01:53 2020 +0100
@@ -487,6 +487,30 @@
             errback = self._generic_errback
         d.addErrback(errback)
 
+    def privateDataDelete(self, namespace, key, arg_2, callback=None, errback=None):
+        d = self.root.callRemote("privateDataDelete", namespace, key, arg_2)
+        if callback is not None:
+            d.addCallback(lambda __: callback())
+        if errback is None:
+            errback = self._generic_errback
+        d.addErrback(errback)
+
+    def privateDataGet(self, namespace, key, profile_key, callback=None, errback=None):
+        d = self.root.callRemote("privateDataGet", namespace, key, profile_key)
+        if callback is not None:
+            d.addCallback(callback)
+        if errback is None:
+            errback = self._generic_errback
+        d.addErrback(errback)
+
+    def privateDataSet(self, namespace, key, data, profile_key, callback=None, errback=None):
+        d = self.root.callRemote("privateDataSet", namespace, key, data, profile_key)
+        if callback is not None:
+            d.addCallback(lambda __: callback())
+        if errback is None:
+            errback = self._generic_errback
+        d.addErrback(errback)
+
     def profileCreate(self, profile, password='', component='', callback=None, errback=None):
         d = self.root.callRemote("profileCreate", profile, password, component)
         if callback is not None:
@@ -859,6 +883,21 @@
         d.addErrback(self._errback)
         return d.asFuture(asyncio.get_event_loop())
 
+    def privateDataDelete(self, namespace, key, arg_2):
+        d = self.root.callRemote("privateDataDelete", namespace, key, arg_2)
+        d.addErrback(self._errback)
+        return d.asFuture(asyncio.get_event_loop())
+
+    def privateDataGet(self, namespace, key, profile_key):
+        d = self.root.callRemote("privateDataGet", namespace, key, profile_key)
+        d.addErrback(self._errback)
+        return d.asFuture(asyncio.get_event_loop())
+
+    def privateDataSet(self, namespace, key, data, profile_key):
+        d = self.root.callRemote("privateDataSet", namespace, key, data, profile_key)
+        d.addErrback(self._errback)
+        return d.asFuture(asyncio.get_event_loop())
+
     def profileCreate(self, profile, password='', component=''):
         d = self.root.callRemote("profileCreate", profile, password, component)
         d.addErrback(self._errback)