# HG changeset patch # User Goffi # Date 1581368513 -3600 # Node ID d10b2368684ee5e259721bea7dc7b175a77d4993 # Parent b5c058c7692ec389036023179d92b848d3f6b023 bridge: added methods to let frontends store/retrieve/delete private data diff -r b5c058c7692e -r d10b2368684e sat/bridge/bridge_constructor/bridge_template.ini --- 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 diff -r b5c058c7692e -r d10b2368684e sat/bridge/dbus_bridge.py --- 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) diff -r b5c058c7692e -r d10b2368684e sat/core/sat_main.py --- 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", diff -r b5c058c7692e -r d10b2368684e sat/memory/memory.py --- 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): diff -r b5c058c7692e -r d10b2368684e sat_frontends/bridge/dbus_bridge.py --- 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() diff -r b5c058c7692e -r d10b2368684e sat_frontends/bridge/pb.py --- 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)