Пример #1
0
 def on_close(self):
     global clientsList
     if not clientsList:
         log.warning("Clients list not found")
         return
     clientsList.remove(self.client)
     log.debug("WebSocket closed for client %s" % self.client)
Пример #2
0
 def post(self):
     # arguments = { k.lower(): self.get_argument(k) for k in self.request.arguments }
     first_name = self.get_argument("name", "")
     last_name = self.get_argument("lastname", "")
     email = self.get_argument("email", "")
     subject = self.get_argument("subject", "")
     message = self.get_argument("question", "")
     topic = self.get_argument("topic", "")
     topics = topic.replace(',', '\n')
     log.debug(
         f'''{first_name}, {last_name}, {email}, {topics}, {message}''')
     try:
         token = DB.add_new_request({
             'email': email,
             'last_name': last_name,
             'first_name': first_name,
             'subject': subject,
             'message': message,
             'topics': topics,
         })
     except Exception as e:
         log.error(f'''Error adding form record: {e}''')
         self.write(
             'There was an error submitting your form. Please try again.')
         self.set_status(500)
         self.flush()
         self.finish()
         return
     try:
         if token:
             send_confirmation_email(
                 base_url=BASE_URL,
                 token=token,
                 email=email,
                 last_name=last_name,
                 first_name=first_name,
                 subject=subject,
                 message=message,
                 topics=topics,
             )
             self.set_status(200)
             self.flush()
             self.finish()
             return
         else:
             self.write(
                 'There was an error submitting your form. Please try again.'
             )
             self.set_status(500)
             self.flush()
             self.finish()
             return
     except Exception as e:
         log.error(f'''Error sending confirmation email to "{email}"''')
         self.write(
             'There was an error submitting your form. Please try again.')
         self.set_status(500)
         self.flush()
         self.finish()
         return
Пример #3
0
 def on_message(self, message):
     data = json.loads(message)
     for command, args in data.iteritems():
         if command in self.command:
             log.debug("Command executed: %s(%s)" % (command, args))
             self.command[command](args)
         else:
             log.error("Command % s not found" % command)
Пример #4
0
    def control_message(self, event):
        """
        Respond to control message from main application thread

        Currently unused.

        :param event: anything.
        """
        log.debug("control message: %s", event)
Пример #5
0
    async def open(self, *args, **kwargs):
        q = self.request.query_arguments
        if self.application.listener_key and ('key' not in q or q['key'][0].decode() != self.application.listener_key):
            return self.send_error(403)
        log.debug("Opened socket. %s", json.dumps(q))
        # self.application.db_changed.connect(self.send_event)

        queue.sender = self
        await self.sendout()
Пример #6
0
 def open(self, *args):
     global clientsList
     self.client = User()
     clientsList.add(self.client)
     self.stream.set_nodelay(True)
     self.write_message(json.dumps({
         "detail": {
             "uuid": self.client.uuid
         }
     }))
     self.timeline_th = None
     log.debug("WebSocket opened client %s" % self.client)
Пример #7
0
    def send_ping(self, *args, **kwargs):
        """
        Sends ping message

        Runs periodically.
        """
        log.debug("Sending ping")
        message = PING_MESSAGE
        try:
            self.udp.send(message)
        except Exception:
            log.exception("Failed to send ping")
            self.stop()
Пример #8
0
 def __init__(self, address='', port=8080, loglevel=logging.WARNING, mounting_point='',
              listener_key=None, notifier_key=None):
     self.listener_key = listener_key
     self.notifier_key = notifier_key
     # tornado.log.enable_pretty_logging(logger=logging.getLogger('tornado'))
     log.setLevel(loglevel)
     log.debug('Initializing server')
     tornado.web.Application.__init__(self, [
         (mounting_point + r'/send', SendHandler),
         (mounting_point + r'/listen', NotificationSocket),
     ], websocket_ping_interval=10)
     self.stopped = Event()
     self.address = address
     self.port = port
Пример #9
0
 def stop(self):
     """
     Stop ping agent and close pipe for communication with callee
     """
     log.debug("Stopping Agent thread.")
     self.agent.stop()
     log.debug("Waiting for Agent thread to join us.")
     self.agent_thread.join()
     log.debug("Closing main thread part of the pipe")
     self.pipe.close()
     log.debug("Closing agent thread part of the pipe")
     self._agent_pipe.close()
     log.debug("Terminating context")
     self.ctx.term()
Пример #10
0
 def _close(self):
     log.debug("Stopping periodic ping.")
     self.periodic_ping.stop()
     log.debug("Removing beacon handler.")
     self.loop.remove_handler(self.udp.handle.fileno())
     log.debug("Closing UDP client.")
     self.loop.add_callback(self.udp.close)
     log.debug("Stopping loop from agent")
     self.loop.add_callback(self.loop.stop)
Пример #11
0
    def reap_peers(self):
        """
        Removes peers whose activity wasn't seen for a long time

        Called periodically. Sends messages through pipe to main application
        thread.
        """
        now = time.time()
        for peer in list(self.peers.values()):
            if peer.expires_at < now:
                log.debug("reaping %s", peer.hw_address, peer.expires_at, now)
                self.peers.pop(peer.hw_address)
                msg_parts = [b"LEFT", peer.hw_address]
                try:
                    self._send_to_pipe_multipart(msg_parts)
                except Exception:
                    return
Пример #12
0
    def _send_to_pipe_multipart(self, msg_parts):
        """
        Handle errors while sending message to pipe as ERROR message sent to pipe

        Caller should catch use these messages to stop interface thread and thus
        agent as well.

        :param iterable msg_parts: A sequence of objects to send as a multipart message.
        :raises TypeError: after error is caught and ERROR message sent to pipe
        """
        log.debug("Going to send %r.", msg_parts)
        try:
            self.pipe.send_multipart(msg_parts)
        except TypeError as err:
            log.error("Failed to send multipart message to pipe: %s", err)
            self.pipe.send_multipart(
                [b"ERROR", b"Failed to send a message to main thread."]
            )
            self.stop()
            raise
Пример #13
0
    def post(self):
        try:
            req_data = json.loads(self.request.body)
        except ValueError:
            log.debug('Unable to load request JSON.')
            raise tornado.web.HTTPError(400, 'Unable to load request JSON.')

        try:
            jsonschema.validate(req_data, postvalidate.schema)
        except jsonschema.ValidationError:
            log.debug('Post JSON validation failed.')
            raise tornado.web.HTTPError(400, 'Post JSON validation failed.')

        hash_id = dbi.store_grid_entry(req_data)

        if req_data['secret']:
            url = 'http://ipythonblocks.org/secret/{}'
        else:
            url = 'http://ipythonblocks.org/{}'

        url = url.format(hash_id)

        self.write({'url': url})
Пример #14
0
    def start(self):
        """
        Main entry of the thread

        Hooks necessary handlers to send pings, process incoming data and
        mark peers offline if they doesn't respond for long time.
        """
        log.debug("Starting Agent")
        self.loop = tornado.ioloop.IOLoop.current()
        self.loop.add_handler(self.udp.handle.fileno(), self.handle_beacon,
                              self.loop.READ)
        stream = ZMQStream(self.pipe, self.loop)
        stream.on_recv(self.control_message)
        pc = PeriodicCallback(self.send_ping, PING_INTERVAL * 1000)
        pc.start()
        pc = PeriodicCallback(self.reap_peers, PING_INTERVAL * 1000)
        pc.start()
        log.debug("Starting Loop")
        self.loop.start()
        log.debug("Loop ended")
Пример #15
0
    def get(self, path):
        log = logging.getLogger(__name__)
        cookie_user_id = None

        try:
            cookie_user_id = int(
                self.get_secure_cookie(COOKIE_NAME,
                                       max_age_days=COOKIE_DURATION_DAYS))
        except ValueError:
            pass
        except TypeError:
            pass

        self.clear()
        if cookie_user_id is None:
            self.set_status(403)
            return

        path = zyn_util.util.normalized_remote_path('/' + path)
        _, filename = zyn_util.util.split_remote_path(path)
        session = user_sessions.find_session(cookie_user_id)
        socket_id = None
        open_rsp = None

        log.debug('Raw file requested, path="{}", cookie="{}"'.format(
            path,
            cookie_user_id,
        ))

        try:
            socket_id = session.add_websocket(None)
            connection = session.sockets(socket_id).connection
            rsp = connection.open_file_read(path=path)
            if rsp.is_error():
                self.set_status(400)
                raise RuntimeError(
                    zyn_util.errors.error_to_string(rsp.error_code()))

            open_rsp = rsp.as_open_rsp()
            if open_rsp.type_of_file == zyn_util.connection.FILE_TYPE_RANDOM_ACCESS:
                rsp, data = connection.read_file(open_rsp.node_id, 0,
                                                 open_rsp.size)
                if rsp.is_error():
                    self.set_status(500)
                    raise RuntimeError(
                        zyn_util.errors.error_to_string(rsp.error_code()))
                self.write(data)
            elif open_rsp.type_of_file == zyn_util.connection.FILE_TYPE_BLOB:
                if open_rsp.size > open_rsp.block_size:
                    # For large files, server should sent the content is blocks
                    self.set_status(500)
                    raise RuntimeError('Large file download not implemented')

                rsp, data = connection.read_file(open_rsp.node_id, 0,
                                                 open_rsp.size)
                if rsp.is_error():
                    self.set_status(500)
                    raise RuntimeError(
                        zyn_util.errors.error_to_string(rsp.error_code()))
                self.write(data)
            else:
                self.set_status(500)
                raise RuntimeError()

            self.set_header('Content-Disposition',
                            'attachment; filename=' + filename)

        except RuntimeError as e:
            self.write(str(e))

        finally:
            if open_rsp is not None:
                connection.close_file(open_rsp.node_id)
            if socket_id is not None:
                session.remove_websocket(socket_id)
Пример #16
0
 def action(server, sniffer):
     log.debug("Configure sniffer %s on %s" % (sniffer.__class__.__name__, server.name))
     if data['enable']:
         sniffer.capture_start()
     else:
         sniffer.capture_stop()
Пример #17
0
    def handle_beacon(self, fd, event):
        """
        Reads response from nodes

        Creates :class:`Peer` objects and tracks them in `self.peers`. Finally
        sends messages through pipe to main application thread.

        :param fd: not used
        :param event: not used
        """
        log.debug("Waiting for a beacon.")
        try:
            data, host = self._next_packet()
        except ReceiveTimeout:
            msg_parts = [b"RECEIVE_TIMEOUT"]
            try:
                self._send_to_pipe_multipart(msg_parts)
            except Exception:
                return
            return
        if data == PING_MESSAGE:
            log.debug("Ignoring ping message received from network from %s.", host)
            return
        log.debug("Received a beacon from %s.", host)
        ip_address, device_id = decode_discovery_response(data)
        # if host != ip_address:
        # print("Host {} != ip_address {}".format(host, ip_address))
        log.debug("Getting hardware address of %s.", ip_address)
        hw_address = self.get_mac_address(ip_address)
        if hw_address is None:
            log.error("Unable to get HW adress of %s.", ip_address)
            msg_parts = [b"ERROR", device_id, ip_address]
            try:
                self._send_to_pipe_multipart(msg_parts)
            except Exception:
                return
            return
        # print("Host {} has MAC address {}".format(ip_address, hw_address))
        if hw_address in self.peers:
            log.debug("Peer %s seen before.", hw_address)
            return self.process_seen_peer(hw_address, device_id, ip_address)
        else:
            log.debug("Never seen %s before.", hw_address)
            return self.process_new_peer(hw_address, device_id, ip_address)
Пример #18
0
def xdiscover(find_id=None, destination_host=None, timeout=None):
    """Generator discover all devices or device of specific id

    Device can be specified either by id or by host.

    :param str find_id: (optional) Device id to look for. If not set first node
        that responded is returned.
    :param str destination_host: (optional) Ping selected node only.
    :param float timeout: (optional) Number of seconds until discovery timeouts.
    :return: namedtuple of hardware address, device id and host name.
    :rtype: namedtuple
    :raises DiscoverTimeout: timeout exceeded while waiting for a device
    """
    assert not (find_id and destination_host)
    receive_timeout = None
    if timeout:
        receive_timeout = timeout / 2
    hw_address = device_id = ip_address = None
    start = monotonic()
    with DiscoveryInterface(
        destination_host, receive_timeout=receive_timeout
    ) as interface:
        while True:
            try:
                response = interface.recv()
            except KeyboardInterrupt:
                raise
            assert len(response) > 0
            event = response.pop(0)
            if event == b"JOINED":
                assert len(response) == 3
                hw_address, device_id, ip_address = response
                if isinstance(hw_address, bytes):
                    hw_address = hw_address.decode("utf-8")
                if isinstance(device_id, bytes):
                    device_id = device_id.decode("utf-8")
                if isinstance(ip_address, bytes):
                    ip_address = ip_address.decode("utf-8")
                if find_id is None or find_id == device_id:
                    DiscoveredDevice = collections.namedtuple(
                        "DiscoveredDevice", ["hw_address", "id", "ip_address"]
                    )
                    yield DiscoveredDevice(hw_address, device_id, ip_address)
                    if find_id == device_id:
                        return
                else:
                    log.debug(
                        "Device id {} ({}) joined: {}".format(
                            device_id, hw_address, ip_address
                        )
                    )
                if timeout and (monotonic() - start) > timeout:
                    raise DiscoverTimeout()
            elif event == b"ERROR":
                log.error(
                    "Received error from discovery. Parameters: {}".format(response)
                )
                raise Exception("Error")
            elif event == b"RECEIVE_TIMEOUT":
                assert timeout
                if monotonic() - start > timeout:
                    raise DiscoverTimeout()
                else:
                    continue
            elif event == b"ALIVE":
                if timeout and (monotonic() - start) > timeout:
                    raise DiscoverTimeout()
            else:
                log.error("Unknown event: {}".format(event))
                log.error("Parameters: {}".format(response))
                raise Exception("Unknown event")
Пример #19
0
 def start(self):
     log.debug('Starting server at %s:%d' % (self.address, self.port))
     self.listen(self.port, self.address)
     self.io_loop = tornado.ioloop.IOLoop.current()
     self.io_loop.start()
     self.stopped.set()
Пример #20
0
 def on_close(self):
     log.debug("Closed socket: code: {s.close_code}, reason: {s.close_reason}".format(s=self))
     queue.sender = None
Пример #21
0
 def action(server, sniffer):
     log.debug("Cleanup traces on sniffer %s on %s" % (sniffer.__class__.__name__, server.name))
     sniffer.clean()
Пример #22
0
    def handle_beacon(self, fd, event):
        """
        Reads response from nodes

        Creates :class:`Peer` objects and tracks them in `self.peers`. Finally
        sends messages through pipe to main application thread.

        :param fd: not used
        :param event: not used
        """
        log.debug("Waiting for a beacon.")
        data, host = self.udp.recv(64)
        if data == PING_MESSAGE:
            log.debug("Ignoring ping message received from network from %s.",
                      host)
            return
        log.debug("Received a beacon from %s.", host)
        ip_address, device_name = decode_discovery_response(data)
        # if host != ip_address:
        # print("Host {} != ip_address {}".format(host, ip_address))
        log.debug("Getting hardware address of %s.", ip_address)
        hw_address = arpreq(ip_address)
        if is_py3 and not isinstance(hw_address, bytes):
            hw_address = bytes(hw_address, "utf-8")
        if hw_address is None:
            log.error("Unable to get HW adress of %s.", ip_address)
            msg_parts = [b"ERROR", device_name, ip_address]
            try:
                self._send_to_pipe_multipart(msg_parts)
            except Exception:
                return
        # print("Host {} has MAC address {}".format(ip_address, hw_address))
        if hw_address in self.peers:
            log.debug("Peer %s seen before.", hw_address)
            self.peers[hw_address].is_alive()
            if device_name != self.peers[hw_address].device_name:
                old_device_name = self.peers[hw_address].device_name
                self.peers[hw_address].device_name = device_name
                msg_parts = [
                    b"RENAMED", hw_address, old_device_name, device_name
                ]
                try:
                    self._send_to_pipe_multipart(msg_parts)
                except Exception:
                    return
            if ip_address != self.peers[hw_address].ip_address:
                old_ip_address = self.peers[hw_address].ip_address
                self.peers[hw_address].ip_address = ip_address
                msg_parts = [
                    b"ADDRESS_CHANGED", hw_address, old_ip_address, ip_address
                ]
                try:
                    self._send_to_pipe_multipart(msg_parts)
                except Exception:
                    return
        else:
            log.debug("Never seen %s before.", hw_address)
            self.peers[hw_address] = Peer(hw_address, device_name, ip_address)
            msg_parts = [b"JOINED", hw_address, device_name, ip_address]
            try:
                self._send_to_pipe_multipart(msg_parts)
            except Exception:
                return
Пример #23
0
def decode_discovery_response(data):
    """
    Decodes response for discovery
    """
    log.debug("Received {0!r}".format(data))
    if is_py3:
        if isinstance(data, bytes):
            data = bytearray(data)
        if not isinstance(data, bytearray):
            msg = "Data must be bytearray. Was {} instead".format(type(data))
            raise TypeError(msg)
    else:
        if not isinstance(data, basestring):
            msg = "Data must be string. Was {} instead".format(type(data))
            raise TypeError(msg)
    if len(data) < 7:
        msg = "Data must be longer than 7 bytes. Was {} instead.".format(len(data))
        raise ValueError(msg)
    if data[4:6] != b"OK":
        msg = "Expected 'OK' in status of data message. Was {0!r} instead.".format(
            data[4:6]
        )
        raise ValueError(msg)
    if is_py3:
        tail = 0
    else:
        tail = b"\x00"
    if data[-1] != tail:
        msg = (
            "Expected zero character on the end of message. "
            "Was {0!r} instead.".format(data[-1])
        )
        raise ValueError(msg)

    # First four bytes in reversed order
    ip_address_data = data[3::-1]
    if is_py3:
        ip_address_data = bytes(ip_address_data)
    else:
        # Detect if ipaddress is backport to python 2 - py2-ipaddress
        if (
            hasattr(ipaddress, "bytes")
            and hasattr(ipaddress, "bytearray")
            and ipaddress.bytes == ipaddress.bytearray
        ):
            # py2-ipaddress differs from ipaddress by Google and python 3
            # module:
            #     Since Python 2 has no distinct bytes type, bytearray is used
            #     instead for the "packed" (binary) address representation
            ip_address_data = bytearray(ip_address_data)

    ip_address_obj = ipaddress.ip_address(ip_address_data)
    ip_address_exploded = ip_address_obj.exploded
    if is_py3:
        if not isinstance(ip_address_exploded, bytes):
            ip_address_exploded = bytes(ip_address_exploded, "utf-8")
    else:
        ip_address_exploded = ip_address_exploded.encode("utf-8")

    device_id = data[6:-1]
    if is_py3:
        device_id = bytes(device_id)
    else:
        device_id = device_id.encode("utf-8")

    return ip_address_exploded, device_id