def open(self): if not self.check_cookie(): self.log.warning("access to websocket from %s blocked due to invalid cookie" % self.request.remote_ip) return # Store user information info = extract_cookie("ClacksRPC", self.__secret, self.request.headers['Cookie']) self.__user = info['REMOTE_USER'] self.log.debug("new websocket connection established by %s" % self.request.remote_ip) # Add event processor amqp = PluginRegistry.getInstance('AMQPHandler') self.__consumer = EventConsumer(self.env, amqp.getConnection(), xquery=""" declare namespace f='http://www.gonicus.de/Events'; let $e := ./f:Event return $e/f:Notification or $e/f:ObjectChanged """, callback=self.__eventProcessor) self.send_message("notification", {"title": N_("Server information"), "body": N_("Websockets enabled"), "icon": "dialog-information"})
class WSHandler(tornado.websocket.WebSocketHandler): def __init__(self, *args, **kwargs): self.log = logging.getLogger(__name__) self.env = Environment.getInstance() self.__secret = self.env.config.get('http.cookie-secret', default="TecloigJink4") self.__consumer = None super(WSHandler, self).__init__(*args, **kwargs) def check_cookie(self): if "Cookie" in self.request.headers: info = extract_cookie("ClacksRPC", self.__secret, self.request.headers['Cookie']) # The cookie seems to be valid - check the session id if info: jsrpc = PluginRegistry.getInstance("JSONRPCService") return jsrpc.check_session(info['REMOTE_SESSION'], info['REMOTE_USER']) return False return False def send_message(self, message_type, message): self.write_message(dumps([message_type, message])) def open(self): if not self.check_cookie(): self.log.warning("access to websocket from %s blocked due to invalid cookie" % self.request.remote_ip) return # Store user information info = extract_cookie("ClacksRPC", self.__secret, self.request.headers['Cookie']) self.__user = info['REMOTE_USER'] self.log.debug("new websocket connection established by %s" % self.request.remote_ip) # Add event processor amqp = PluginRegistry.getInstance('AMQPHandler') self.__consumer = EventConsumer(self.env, amqp.getConnection(), xquery=""" declare namespace f='http://www.gonicus.de/Events'; let $e := ./f:Event return $e/f:Notification or $e/f:ObjectChanged """, callback=self.__eventProcessor) self.send_message("notification", {"title": N_("Server information"), "body": N_("Websockets enabled"), "icon": "dialog-information"}) def on_message(self, message): if not self.check_cookie(): self.log.warning("access to websocket from %s blocked due to invalid cookie" % self.request.remote_ip) return self.log.debug("message received on websocket from %s: %s" % (self.request.remote_ip, message)) def on_close(self): # Close eventually existing consumer if self.__consumer: self.__consumer.close() self.__consumer = None self.log.debug("closing websocket connection to %s" % self.request.remote_ip) def __eventProcessor(self, data): eventType = stripNs(data.xpath('/g:Event/*', namespaces={'g': "http://www.gonicus.de/Events"})[0].tag) func = getattr(self, "_handle" + eventType) func(data) def _handleObjectChanged(self, data): data = data.ObjectChanged self.send_message("objectChange", { "uuid": data.UUID.text, "dn": data.DN.text, "lastChanged": data.ModificationTime.text, "changeType": data.ChangeType.text, }) def _handleNotification(self, data): data = data.Notification if data.Target != self.__user: return title = N_("System notification") icon = "dialog-information" timeout = 10000 if hasattr(data, 'Title'): title = data.Title.text if hasattr(data, 'Icon'): icon = data.Icon.text if hasattr(data, 'Timeout'): timeout = int(data.Timeout.text) self.send_message("notification", { "title": title, "body": data.Body.text, "icon": icon, "timeout": timeout})