changeset 744:03ccd68a6dab

server side: actionNew now use a dedicated signal handler, which block it if security limit is exceeded
author Goffi <goffi@goffi.org>
date Sun, 22 Nov 2015 21:28:06 +0100
parents 916075bd0356
children ad733b670cc3
files src/server/server.py
diffstat 1 files changed, 38 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/server/server.py	Sat Nov 21 17:03:46 2015 +0100
+++ b/src/server/server.py	Sun Nov 22 21:28:06 2015 +0100
@@ -984,7 +984,8 @@
         Resource.__init__(self)
         self.register = None
         self.sat_host = sat_host
-        self.signalDeferred = {}
+        self.signalDeferred = {} # dict of deferred (key: profile, value: Deferred)
+                                 # which manages the long polling HTTP request with signals
         self.queue = {}
 
     def plugRegister(self, register):
@@ -1024,15 +1025,42 @@
             profile = args[-1]
             if not profile in self.sat_host.prof_connected:
                 return
-            if profile in self.signalDeferred:
-                self.signalDeferred[profile].callback((function_name, args[:-1]))
-                del self.signalDeferred[profile]
+            signal_data = (function_name, args[:-1])
+            try:
+                signal_callback = self.signalDeferred[profile].callback
+            except KeyError:
+                self.queue.setdefault(profile,[]).append(signal_data)
             else:
-                if profile not in self.queue:
-                    self.queue[profile] = []
-                self.queue[profile].append((function_name, args[:-1]))
+                signal_callback(signal_data)
+                del self.signalDeferred[profile]
         return genericCb
 
+    def actionNewHandler(self, action_data, action_id, security_limit, profile):
+        """actionNew handler
+
+        XXX: We need need a dedicated handler has actionNew use a security_limit which must be managed
+        @param action_data(dict): see bridge documentation
+        @param action_id(unicode): identitifer of the action
+        @param security_limit(int): %(doc_security_limit)s
+        @param profile(unicode): %(doc_profile)s
+        """
+        if not profile in self.sat_host.prof_connected:
+            return
+         # FIXME: manage security limit in a dedicated method
+         #        raise an exception if it's not OK
+         #        and read value in sat.conf
+        if security_limit >= C.SECURITY_LIMIT:
+            log.debug(u"Ignoring action  {action_id}, blocked by security limit".format(action_id=action_id))
+            return
+        signal_data = ("actionNew", (action_data, action_id, security_limit))
+        try:
+            signal_callback = self.signalDeferred[profile].callback
+        except KeyError:
+            self.queue.setdefault(profile,[]).append(signal_data)
+        else:
+            signal_callback(signal_data)
+            del self.signalDeferred[profile]
+
     def connected(self, profile, jid_s):
         """Connection is done.
 
@@ -1165,8 +1193,6 @@
         return ("setAvatar", filepath, profile)
 
 
-
-
 class Libervia(service.Service):
 
 
@@ -1210,9 +1236,11 @@
             self.bridge.register("disconnected", self.signal_handler.disconnected)
             self.bridge.register("actionResult", self.action_handler.actionResultCb)
             #core
-            for signal_name in ['presenceUpdate', 'actionNew', 'newMessage', 'subscribe', 'contactDeleted',
+            for signal_name in ['presenceUpdate', 'newMessage', 'subscribe', 'contactDeleted',
                                 'newContact', 'entityDataUpdated', 'askConfirmation', 'newAlert', 'paramUpdate']:
                 self.bridge.register(signal_name, self.signal_handler.getGenericCb(signal_name))
+            # XXX: actionNew is handled separately because the handler must manage security_limit
+            self.bridge.register('actionNew', self.signal_handler.actionNewHandler)
             #plugins
             for signal_name in ['psEvent', 'roomJoined', 'roomUserJoined', 'roomUserLeft', 'tarotGameStarted', 'tarotGameNew', 'tarotGameChooseContrat',
                                 'tarotGameShowCards', 'tarotGameInvalidCards', 'tarotGameCardsPlayed', 'tarotGameYourTurn', 'tarotGameScore', 'tarotGamePlayers',