changeset 634:ca2cae6b2c6d

core: security attribute added to the parameters - getParams, getParamsUI and getParamsForCategory have a security_limit parameter to filter - parameters with security = 0 can be retrieved/modified from Libervia
author souliane <souliane@mailoo.org>
date Thu, 05 Sep 2013 20:28:44 +0200 (2013-09-05)
parents 6a29a4d574bd
children eff8772fd472
files frontends/src/bridge/DBus.py frontends/src/primitivus/primitivus frontends/src/wix/main_window.py frontends/src/wix/param.py src/bridge/DBus.py src/bridge/bridge.py src/bridge/bridge_constructor/bridge_template.ini src/memory/memory.py
diffstat 8 files changed, 123 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/frontends/src/bridge/DBus.py	Thu Sep 05 20:28:44 2013 +0200
@@ -154,17 +154,17 @@
     def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"):
         return unicode(self.db_core_iface.getParamA(name, category, attribute, profile_key))
 
-    def getParams(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        return unicode(self.db_core_iface.getParams(profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
+    def getParams(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return unicode(self.db_core_iface.getParams(security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
 
     def getParamsCategories(self, ):
         return self.db_core_iface.getParamsCategories()
 
-    def getParamsForCategory(self, category, profile_key="@DEFAULT@", callback=None, errback=None):
-        return unicode(self.db_core_iface.getParamsForCategory(category, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
+    def getParamsForCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return unicode(self.db_core_iface.getParamsForCategory(category, security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
 
-    def getParamsUI(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        return unicode(self.db_core_iface.getParamsUI(profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
+    def getParamsUI(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return unicode(self.db_core_iface.getParamsUI(security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])))
 
     def getPresenceStatus(self, profile_key="@DEFAULT@"):
         return self.db_core_iface.getPresenceStatus(profile_key)
--- a/frontends/src/primitivus/primitivus	Sun Sep 08 18:05:19 2013 +0200
+++ b/frontends/src/primitivus/primitivus	Thu Sep 05 20:28:44 2013 +0200
@@ -507,7 +507,8 @@
             self.addWindow(XMLUI(self,xml_data=params))
         def failure(error):
             self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get parameters"), ok_cb=self.removePopUp))
-        self.bridge.getParamsUI(self.profile, callback=success, errback=failure)
+        security_limit = -1
+        self.bridge.getParamsUI(security_limit, self.profile, callback=success, errback=failure)
 
 
     def onExitRequest(self, menu):
--- a/frontends/src/wix/main_window.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/frontends/src/wix/main_window.py	Thu Sep 05 20:28:44 2013 +0200
@@ -363,7 +363,8 @@
 
     def onParam(self, e):
         debug(_("Param request"))
-        #xmlui = self.bridge.getParamsUI(self.profile)
+        #security_limit = -1
+        #xmlui = self.bridge.getParamsUI(security_limit, profile_key=self.profile)
         #XMLUI(self, xml_data = xmlui)
         param=Param(self)
 
--- a/frontends/src/wix/param.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/frontends/src/wix/param.py	Thu Sep 05 20:28:44 2013 +0200
@@ -102,7 +102,11 @@
             self.notebook.AddPage(panel, category)
             cat_dom.unlink()
 
-        self.host.bridge.getParamsForCategory(category, profile_key = self.host.profile, callback = gotParams, errback = errorGettingParams)
+        self.host.bridge.getParamsForCategory(category,
+                                              security_limit=-1,
+                                              profile_key=self.host.profile,
+                                              callback=gotParams,
+                                              errback=errorGettingParams)
 
     def onTextChanged(self, event):
         """Called when a string paramater is modified"""
--- a/src/bridge/DBus.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/src/bridge/DBus.py	Thu Sep 05 20:28:44 2013 +0200
@@ -301,10 +301,10 @@
         return self._callback("getParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key))
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='s',
+                         in_signature='is', out_signature='s',
                          async_callbacks=('callback', 'errback'))
-    def getParams(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("getParams", unicode(profile_key), callback=callback, errback=errback)
+    def getParams(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("getParams", security_limit, unicode(profile_key), callback=callback, errback=errback)
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
                          in_signature='', out_signature='as',
@@ -313,16 +313,16 @@
         return self._callback("getParamsCategories", )
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='ss', out_signature='s',
+                         in_signature='sis', out_signature='s',
                          async_callbacks=('callback', 'errback'))
-    def getParamsForCategory(self, category, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("getParamsForCategory", unicode(category), unicode(profile_key), callback=callback, errback=errback)
+    def getParamsForCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("getParamsForCategory", unicode(category), security_limit, unicode(profile_key), callback=callback, errback=errback)
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='s', out_signature='s',
+                         in_signature='is', out_signature='s',
                          async_callbacks=('callback', 'errback'))
-    def getParamsUI(self, profile_key="@DEFAULT@", callback=None, errback=None):
-        return self._callback("getParamsUI", unicode(profile_key), callback=callback, errback=errback)
+    def getParamsUI(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None):
+        return self._callback("getParamsUI", security_limit, unicode(profile_key), callback=callback, errback=errback)
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
                          in_signature='s', out_signature='a{sa{s(sia{ss})}}',
--- a/src/bridge/bridge.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/src/bridge/bridge.py	Thu Sep 05 20:28:44 2013 +0200
@@ -59,7 +59,7 @@
     def getParam(self, name, namespace):
         raise NotImplementedError
 
-    def getParams(self, namespace):
+    def getParams(self, security_limit, namespace):
         raise NotImplementedError
 
     def getHistory(self, from_jid, to_jid, size):
--- a/src/bridge/bridge_constructor/bridge_template.ini	Sun Sep 08 18:05:19 2013 +0200
+++ b/src/bridge/bridge_constructor/bridge_template.ini	Thu Sep 05 20:28:44 2013 +0200
@@ -436,32 +436,38 @@
 async=
 type=method
 category=core
-sig_in=s
+sig_in=is
 sig_out=s
-param_0_default="@DEFAULT@"
+param_0_default=-1
+param_1_default="@DEFAULT@"
 doc=Return a SàT XMLUI for parameters
-doc_param_0=%(doc_profile_key)s
+doc_param_0=security_limit: -1 means no security then the higher the most secure
+doc_param_1=%(doc_profile_key)s
 
 [getParams]
 async=
 type=method
 category=core
-sig_in=s
+sig_in=is
 sig_out=s
-param_0_default="@DEFAULT@"
+param_0_default=-1
+param_1_default="@DEFAULT@"
 doc=Return XML of parameters
-doc_param_0=%(doc_profile_key)s
+doc_param_0=security_limit: -1 means no security then the higher the most secure
+doc_param_1=%(doc_profile_key)s
 
 [getParamsForCategory]
 async=
 type=method
 category=core
-sig_in=ss
+sig_in=sis
 sig_out=s
-param_1_default="@DEFAULT@"
+param_1_default=-1
+param_2_default="@DEFAULT@"
 doc=Return a xml of all params in a category
 doc_param_0=category: Category to get
-doc_param_1=%(doc_profile_key)s
+doc_param_1=security_limit: -1 means no security then the higher the most secure
+doc_param_2=%(doc_profile_key)s
 
 [getParamsCategories]
 type=method
--- a/src/memory/memory.py	Sun Sep 08 18:05:19 2013 +0200
+++ b/src/memory/memory.py	Thu Sep 05 20:28:44 2013 +0200
@@ -372,47 +372,90 @@
             return None
         return cache[(category, name)]
 
-    def __constructProfileXml(self, profile):
+    def __constructProfileXml(self, security_limit, profile):
         """Construct xml for asked profile, filling values when needed
         /!\ as noticed in doc, don't forget to unlink the minidom.Document
+        @security_limit: -1 to return all the params. Otherwise sole the
+        params which have a security level defined *and* lower or equal to
+        the specified value are returned.
         @param profile: profile name (not key !)
         @return: a deferred that fire a minidom.Document of the profile xml (cf warning above)
         """
 
         def constructProfile(ignore, profile_cache):
+
+            def filterParam(node):
+                """Filter with security level.
+                @return: True is this param must be filtered"""
+                if security_limit < 0:
+                    return False
+                if not node.hasAttribute('security'):
+                    debug("filtered param: %s (no security set)"
+                          % node.getAttribute("name"))
+                    return True
+                if int(node.getAttribute('security')) > security_limit:
+                    debug("filtered param: %s (security level > %i)"
+                          % (node.getAttribute("name"), security_limit))
+                    return True
+                return False
+
+            # init the result document
             prof_xml = minidom.parseString('<params/>')
             cache = {}
 
             for type_node in self.dom.documentElement.childNodes:
-                if type_node.nodeName == 'general' or type_node.nodeName == 'individual':  # we use all params, general and individual
-                    for cat_node in type_node.childNodes:
-                        if cat_node.nodeName == 'category':
-                            category = cat_node.getAttribute('name')
-                            if category not in cache:
-                                cache[category] = dest_cat = cat_node.cloneNode(True)  # we make a copy for the new xml
-                                new_node = True
-                            else:
-                                dest_cat = cache[category]
-                                new_node = False  # It's not a new node, we will merge information
-                            params = cat_node.getElementsByTagName("param")
-                            dest_params = {}
-                            for node in dest_cat.childNodes:
-                                if node.nodeName != "param":
-                                    continue
-                                dest_params[node.getAttribute('name')] = node
+                if type_node.nodeName != 'general' and type_node.nodeName != 'individual':
+                    continue
+                # we use all params, general and individual
+                for cat_node in type_node.childNodes:
+                    if cat_node.nodeName != 'category':
+                        continue
+                    category = cat_node.getAttribute('name')
+                    dest_params = {}  # result (merged) params for category
+                    if category not in cache:
+                        # we make a copy for the new xml
+                        cache[category] = dest_cat = cat_node.cloneNode(True)
+                        for node in dest_cat.childNodes:
+                            if node.nodeName != "param":
+                                continue
+                            if filterParam(node):
+                                dest_cat.removeChild(node)
+                                continue
+                            dest_params[node.getAttribute('name')] = node
+                        new_node = True
+                    else:
+                        # It's not a new node, we use the previously cloned one
+                        dest_cat = cache[category]
+                        new_node = False
+                    params = cat_node.getElementsByTagName("param")
 
-                            for param_node in params:
-                                name = param_node.getAttribute('name')
+                    for param_node in params:
+                        # we have to merge new params (we are parsing individual parameters, we have to add them
+                        # to the previously parsed general ones)
+                        name = param_node.getAttribute('name')
+                        if filterParam(param_node):
+                            continue
+                        if name not in dest_params:
+                            # this is reached when a previous category exists
+                            dest_params[name] = param_node.cloneNode(True)
+                            dest_cat.appendChild(dest_params[name])
 
-                                if name not in dest_params:
-                                    dest_params[name] = param_node.cloneNode(True)
-                                    dest_cat.appendChild(dest_params[name])
+                        profile_value = self.__getParam(profile, category,
+                                                        name, type_node.nodeName,
+                                                        cache=profile_cache)
+                        if profile_value is not None:
+                            # there is a value for this profile, we must change the default
+                            dest_params[name].setAttribute('value', profile_value)
+                    if new_node:
+                        prof_xml.documentElement.appendChild(dest_cat)
 
-                                profile_value = self.__getParam(profile, category, name, type_node.nodeName, cache=profile_cache)
-                                if profile_value is not None:  # there is a value for this profile, we must change the default
-                                    dest_params[name].setAttribute('value', profile_value)
-                            if new_node:
-                                prof_xml.documentElement.appendChild(dest_cat)
+            to_remove = []
+            for cat_node in prof_xml.documentElement.childNodes:
+                # we remove empty categories
+                if cat_node.getElementsByTagName("param").length == 0:
+                    to_remove.append(cat_node)
+            for node in to_remove:
+                prof_xml.documentElement.removeChild(node)
             return prof_xml
 
         if profile in self.params:
@@ -425,16 +468,16 @@
 
         return d.addCallback(constructProfile, profile_cache)
 
-    def getParamsUI(self, profile_key):
+    def getParamsUI(self, security_limit, profile_key):
         """Return a SàT XMLUI for parameters, with given profile"""
         profile = self.getProfileName(profile_key)
         if not profile:
             error(_("Asking params for inexistant profile"))
             return ""
-        d = self.getParams(profile)
+        d = self.getParams(security_limit, profile)
         return d.addCallback(lambda param_xml: paramsXml2xmlUI(param_xml))
 
-    def getParams(self, profile_key):
+    def getParams(self, security_limit, profile_key):
         """Construct xml for asked profile
         Take params xml as skeleton"""
         profile = self.getProfileName(profile_key)
@@ -445,11 +488,11 @@
         def returnXML(prof_xml):
             return_xml = prof_xml.toxml()
             prof_xml.unlink()
-            return return_xml
+            return '\n'.join([line for line in return_xml.split('\n')])
 
-        return self.__constructProfileXml(profile).addCallback(returnXML)
+        return self.__constructProfileXml(security_limit, profile).addCallback(returnXML)
 
-    def getParamsForCategory(self, category, profile_key):
+    def getParamsForCategory(self, category, security_limit, profile_key):
         """Return node's xml for selected category"""
         #TODO: manage category of general type (without existant profile)
         profile = self.getProfileName(profile_key)
@@ -467,7 +510,7 @@
             prof_xml.unlink()
             return "<category />"
 
-        d = self.__constructProfileXml(profile)
+        d = self.__constructProfileXml(security_limit, profile)
         return d.addCallback(returnCategoryXml)
 
     def __getParamNode(self, name, category, _type="@ALL@"):  # FIXME: is _type useful ?
@@ -851,14 +894,14 @@
     def asyncGetStringParamA(self, name, category, attr="value", profile_key='@DEFAULT@'):
         return self.params.asyncGetStringParamA(name, category, attr, profile_key)
 
-    def getParamsUI(self, profile_key):
-        return self.params.getParamsUI(profile_key)
+    def getParamsUI(self, security_limit, profile_key):
+        return self.params.getParamsUI(security_limit, profile_key)
 
-    def getParams(self, profile_key):
-        return self.params.getParams(profile_key)
+    def getParams(self, security_limit, profile_key):
+        return self.params.getParams(security_limit, profile_key)
 
-    def getParamsForCategory(self, category, profile_key):
-        return self.params.getParamsForCategory(category, profile_key)
+    def getParamsForCategory(self, category, security_limit, profile_key):
+        return self.params.getParamsForCategory(category, security_limit, profile_key)
 
     def getParamsCategories(self):
         return self.params.getParamsCategories()