bridge: added methods to let frontends store/retrieve/delete private data

This commit is contained in:
Goffi 2020-02-10 22:01:53 +01:00
commit d684685e24
6 changed files with 168 additions and 0 deletions

View file

@ -573,6 +573,41 @@ doc_param_1=category: as for [setParam]
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

View file

@ -474,6 +474,24 @@ class DbusObject(dbus.service.Object):
def paramsRegisterApp(self, xml, security_limit=-1, app=''):
return self._callback("paramsRegisterApp", str(xml), security_limit, str(app))
@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'))

View file

@ -136,6 +136,9 @@ class SAT(service.Service):
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",

View file

@ -39,6 +39,7 @@ from sat.memory.disco import Discovery
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 @@ class Memory(object):
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):

View file

@ -641,6 +641,33 @@ class Bridge:
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 @@ class AIOBridge(Bridge):
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()

View file

@ -487,6 +487,30 @@ class Bridge(object):
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 @@ class AIOBridge(Bridge):
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)