Ejemplo n.º 1
0
 def handle_channel_message(self, channel, message):
     if channel not in self.subscriptions:
         raise Return((True, None))
     response = Response(method='message', body=message)
     prepared_response = response.as_message()
     for uid, client in six.iteritems(self.subscriptions[channel]):
         if channel in self.subscriptions and uid in self.subscriptions[channel]:
             client.send(prepared_response)
Ejemplo n.º 2
0
 def handle_channel_message(self, channel, message):
     if channel not in self.subscriptions:
         raise Return((True, None))
     response = Response(method='message', body=message)
     prepared_response = response.as_message()
     for uid, client in six.iteritems(self.subscriptions[channel]):
         if channel in self.subscriptions and uid in self.subscriptions[
                 channel]:
             client.send(prepared_response)
Ejemplo n.º 3
0
 def publish_message(self, channel, body, method="message"):
     """
     Publish message into channel of stream.
     """
     response = Response()
     response.method = method
     response.body = body
     to_publish = response.as_message()
     result = self._publish(channel, to_publish)
     raise Return((result, None))
Ejemplo n.º 4
0
 def publish_message(self, channel, body, method="message"):
     """
     Publish message into channel of stream.
     """
     response = Response()
     response.method = method
     response.body = body
     to_publish = response.as_message()
     result = self._publish(channel, to_publish)
     raise Return((result, None))
Ejemplo n.º 5
0
 def send_disconnect_message(self, reason=None):
     """
     Send disconnect message - after receiving it proper client
     must close connection and do not reconnect.
     """
     reason = reason or "go away!"
     message_body = {"reason": reason}
     response = Response(method="disconnect", body=message_body)
     result, error = yield self.send(response.as_message())
     raise Return((result, error))
Ejemplo n.º 6
0
 def publish_message(self, channel, body, method=BaseEngine.DEFAULT_PUBLISH_METHOD):
     """
     Publish message into channel of stream.
     """
     response = Response()
     method = method or self.DEFAULT_PUBLISH_METHOD
     response.method = method
     response.body = body
     to_publish = response.as_message()
     result = self._publish(channel, to_publish)
     raise Return((result, None))
Ejemplo n.º 7
0
 def send_disconnect_message(self, reason=None):
     """
     Send disconnect message - after receiving it proper client
     must close connection and do not reconnect.
     """
     reason = reason or "go away!"
     message_body = {
         "reason": reason
     }
     response = Response(method="disconnect", body=message_body)
     result, error = yield self.send(response.as_message())
     raise Return((result, error))
Ejemplo n.º 8
0
    def message_received(self, message):
        """
        Called when message from client received.
        """
        response = Response()

        try:
            data = json_decode(message)
        except ValueError:
            response.error = 'malformed JSON data'
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        try:
            validate(data, req_schema)
        except ValidationError as e:
            response.error = str(e)
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        uid = data.get('uid', None)
        method = data.get('method')
        params = data.get('params')

        response.uid = uid
        response.method = method
        response.params = params

        if method != 'connect' and not self.is_authenticated:
            response.error = self.application.UNAUTHORIZED
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        func = getattr(self, 'handle_%s' % method, None)

        if not func:
            response.error = "unknown method %s" % method
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        if method not in client_api_schema:
            raise Return((None, 'unknown method %s' % method))

        try:
            validate(params, client_api_schema[method])
        except ValidationError as e:
            response = Response(uid=uid, method=method, error=str(e))
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        response.body, response.error = yield func(params)
        self.send(response.as_message())
        raise Return((True, None))
Ejemplo n.º 9
0
    def message_received(self, message):
        """
        Called when message from client received.
        """
        response = Response()

        try:
            data = json_decode(message)
        except ValueError:
            response.error = 'malformed JSON data'
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        try:
            validate(data, req_schema)
        except ValidationError as e:
            response.error = str(e)
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        uid = data.get('uid', None)
        method = data.get('method')
        params = data.get('params')

        response.uid = uid
        response.method = method
        response.params = params

        if method != 'connect' and not self.is_authenticated:
            response.error = self.application.UNAUTHORIZED
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        func = getattr(self, 'handle_%s' % method, None)

        if not func:
            response.error = "unknown method %s" % method
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        if method not in client_api_schema:
            raise Return((None, 'unknown method %s' % method))

        try:
            validate(params, client_api_schema[method])
        except ValidationError as e:
            response = Response(uid=uid, method=method, error=str(e))
            self.send(response.as_message())
            yield self.sock.close()
            raise Return((True, None))

        response.body, response.error = yield func(params)
        self.send(response.as_message())
        raise Return((True, None))
Ejemplo n.º 10
0
    def handle_message(self, channel, method, body):

        if channel not in self.subscriptions:
            raise Return((True, None))

        timer = None
        if self.application.collector:
            timer = self.application.collector.get_timer('broadcast')

        response = Response(method=method, body=body)
        prepared_response = response.as_message()
        for uid, client in six.iteritems(self.subscriptions[channel]):
            if channel in self.subscriptions and uid in self.subscriptions[channel]:
                yield client.send(prepared_response)

        if timer:
            timer.stop()

        raise Return((True, None))
Ejemplo n.º 11
0
    def handle_message(self, channel, method, body):

        if channel not in self.subscriptions:
            raise Return((True, None))

        timer = None
        if self.application.collector:
            timer = self.application.collector.get_timer('broadcast')

        response = Response(method=method, body=body)
        prepared_response = response.as_message()
        for uid, client in six.iteritems(self.subscriptions[channel]):
            if channel in self.subscriptions and uid in self.subscriptions[
                    channel]:
                yield client.send(prepared_response)

        if timer:
            timer.stop()

        raise Return((True, None))
Ejemplo n.º 12
0
    def post(self, project_id):
        """
        Handle API HTTP requests.
        """
        if not self.request.body:
            raise tornado.web.HTTPError(400, log_message="empty request")

        sign = self.get_argument('sign', None)

        if not sign:
            raise tornado.web.HTTPError(400, log_message="no data sign")

        encoded_data = self.get_argument('data', None)
        if not encoded_data:
            raise tornado.web.HTTPError(400, log_message="no data")

        is_owner_request = False

        if project_id == self.application.MAGIC_PROJECT_ID:
            # API request aims to be from superuser
            is_owner_request = True

        if is_owner_request:
            # use api secret key from configuration to check sign
            secret = self.application.settings["config"].get("api_secret")
            if not secret:
                raise tornado.web.HTTPError(501, log_message="no api_secret in configuration file")
            project = None

        else:
            project, error = yield self.application.structure.get_project_by_id(project_id)
            if error:
                raise tornado.web.HTTPError(500, log_message=str(error))
            if not project:
                raise tornado.web.HTTPError(404, log_message="project not found")

            # use project secret key to validate sign
            secret = project['secret_key']

        is_valid = auth.check_sign(
            secret, project_id, encoded_data, sign
        )

        if not is_valid:
            raise tornado.web.HTTPError(401, log_message="unauthorized")

        data = auth.decode_data(encoded_data)
        if not data:
            raise tornado.web.HTTPError(400, log_message="malformed data")

        response = Response()

        try:
            validate(data, req_schema)
        except ValidationError as e:
            response.error = str(e)
        else:
            req_id = data.get("uid", None)
            method = data.get("method")
            params = data.get("params")

            response.uid = req_id
            response.method = method

            schema = server_api_schema

            if is_owner_request and self.application.MAGIC_PROJECT_PARAM in params:

                project_id = params[self.application.MAGIC_PROJECT_PARAM]

                project, error = yield self.application.structure.get_project_by_id(
                    project_id
                )
                if error:
                    logger.error(error)
                    response.error = self.application.INTERNAL_SERVER_ERROR
                if not project:
                    response.error = self.application.PROJECT_NOT_FOUND

            try:
                params.pop(self.application.MAGIC_PROJECT_PARAM)
            except KeyError:
                pass

            if not is_owner_request and method in owner_api_methods:
                response.error = self.application.PERMISSION_DENIED

            if not response.error:
                if method not in schema:
                    response.error = self.application.METHOD_NOT_FOUND
                else:
                    try:
                        validate(params, schema[method])
                    except ValidationError as e:
                        response.error = str(e)
                    else:
                        result, error = yield self.application.process_call(
                            project, method, params
                        )
                        response.body = result
                        response.error = error

        self.json_response(response.as_message())
Ejemplo n.º 13
0
    def post(self, project_id):
        """
        Handle API HTTP requests.
        """
        if not self.request.body:
            raise tornado.web.HTTPError(400, log_message="empty request")

        sign = self.get_argument('sign', None)

        if not sign:
            raise tornado.web.HTTPError(400, log_message="no data sign")

        encoded_data = self.get_argument('data', None)
        if not encoded_data:
            raise tornado.web.HTTPError(400, log_message="no data")

        is_owner_request = False

        if project_id == self.application.MAGIC_PROJECT_ID:
            # API request aims to be from superuser
            is_owner_request = True

        if is_owner_request:
            # use api secret key from configuration to check sign
            secret = self.application.settings["config"].get("api_secret")
            if not secret:
                raise tornado.web.HTTPError(
                    501, log_message="no api_secret in configuration file")
            project = None

        else:
            project, error = yield self.application.structure.get_project_by_id(
                project_id)
            if error:
                raise tornado.web.HTTPError(500, log_message=str(error))
            if not project:
                raise tornado.web.HTTPError(404,
                                            log_message="project not found")

            # use project secret key to validate sign
            secret = project['secret_key']

        is_valid = auth.check_sign(secret, project_id, encoded_data, sign)

        if not is_valid:
            raise tornado.web.HTTPError(401, log_message="unauthorized")

        data = auth.decode_data(encoded_data)
        if not data:
            raise tornado.web.HTTPError(400, log_message="malformed data")

        response = Response()

        try:
            validate(data, req_schema)
        except ValidationError as e:
            response.error = str(e)
        else:
            req_id = data.get("uid", None)
            method = data.get("method")
            params = data.get("params")

            response.uid = req_id
            response.method = method

            schema = server_api_schema

            if is_owner_request and self.application.MAGIC_PROJECT_PARAM in params:

                project_id = params[self.application.MAGIC_PROJECT_PARAM]

                project, error = yield self.application.structure.get_project_by_id(
                    project_id)
                if error:
                    logger.error(error)
                    response.error = self.application.INTERNAL_SERVER_ERROR
                if not project:
                    response.error = self.application.PROJECT_NOT_FOUND

            try:
                params.pop(self.application.MAGIC_PROJECT_PARAM)
            except KeyError:
                pass

            if not is_owner_request and method in owner_api_methods:
                response.error = self.application.PERMISSION_DENIED

            if not response.error:
                if method not in schema:
                    response.error = self.application.METHOD_NOT_FOUND
                else:
                    try:
                        validate(params, schema[method])
                    except ValidationError as e:
                        response.error = str(e)
                    else:
                        result, error = yield self.application.process_call(
                            project, method, params)
                        response.body = result
                        response.error = error

        self.json_response(response.as_message())