Esempio n. 1
0
    def test_publish_needs_topic(self):
        """
        Test that attempted publishes without a topic will be rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer() as l:
            request = yield renderResource(
                resource,
                b"/",
                method=b"POST",
                headers={b"Content-Type": [b"application/json"]},
                body=b'{}')

        self.assertEqual(len(session._published_messages), 0)

        self.assertEqual(request.code, 400)
        errors = l.get_category("AR455")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)

        self.assertEqual(
            json.loads(native_string(request.get_written_data())), {
                "error": log_categories["AR455"].format(key="topic"),
                "args": [],
                "kwargs": {}
            })
    def test_undecodable_UTF8(self):
        """
        Undecodable UTF-8 will return an error.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer("debug") as l:
            request = self.successResultOf(
                renderResource(
                    resource,
                    b"/",
                    method=b"POST",
                    headers={
                        b"Content-Type": [b"application/json;charset=utf-8"]
                    },
                    body=
                    b'{"topic": "com.test.messages", "args": ["\x61\x62\x63\xe9"]}'
                ))

        self.assertEqual(request.code, 400)

        errors = l.get_category("AR451")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)
Esempio n. 3
0
    def test_basic(self):
        """
        A message, when a request has gone through to it, publishes a WAMP
        message on the configured topic.
        """
        session = MockPublisherSession(self)
        resource = WebhookResource({u"topic": u"com.test.webhook"}, session)

        request = yield renderResource(
            resource, b"/",
            method=b"POST",
            headers={b"Content-Type": []},
            body=b'{"foo": "has happened"}')

        self.assertEqual(len(session._published_messages), 1)
        self.assertEqual(
            {
                u"body": u'{"foo": "has happened"}',
                u"headers": {
                    u"Content-Type": [],
                    u'Date': [u'Sun, 1 Jan 2013 15:21:01 GMT'],
                    u'Host': [u'localhost:8000']
                }
            },
            session._published_messages[0]["args"][0])

        self.assertEqual(request.code, 202)
        self.assertEqual(native_string(request.get_written_data()),
                         "OK")
Esempio n. 4
0
    def test_outdated_delta(self):
        """
        If the delta between now and the timestamp in the request is larger than
        C{timestamp_delta_limit}, the request is rejected.
        """
        custOpts = {"timestamp_delta_limit": 1}
        custOpts.update(resourceOptions)
        session = MockPublisherSession(self)
        resource = PublisherResource(custOpts, session)

        signedParams = makeSignedArguments({}, "bazapp", "foobar", publishBody)
        signedParams[b'timestamp'] = [b"2011-10-14T16:59:51.123Z"]

        with LogCapturer() as l:
            request = yield renderResource(
                resource,
                b"/",
                method=b"POST",
                headers={b"Content-Type": [b"application/json"]},
                body=publishBody,
                params=signedParams)

        self.assertEqual(request.code, 400)

        errors = l.get_category("AR464")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)
Esempio n. 5
0
    def test_broken_contenttype(self):
        """
        Crossbar rejects broken content-types.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer("debug") as l:
            request = self.successResultOf(renderResource(
                resource, b"/", method=b"POST",
                headers={b"Content-Type": [b"application/json;charset=blarg;charset=boo"]},
                body=b'{"foo": "\xe2\x98\x83"}'))

        errors = l.get_category("AR450")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)

        del l

        with LogCapturer("debug") as l:
            request = self.successResultOf(renderResource(
                resource, b"/", method=b"POST",
                headers={b"Content-Type": [b"charset=blarg;application/json"]},
                body=b'{"foo": "\xe2\x98\x83"}'))

        self.assertEqual(request.code, 400)

        errors = l.get_category("AR452")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)
Esempio n. 6
0
    def test_basic_publish(self):
        """
        Test a very basic publish to a topic.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer() as l:
            request = yield renderResource(
                resource, b"/",
                method=b"POST",
                headers={b"Content-Type": [b"application/json"]},
                body=b'{"topic": "com.test.messages", "args": [1]}')

        self.assertEqual(len(session._published_messages), 1)
        self.assertEqual(session._published_messages[0]["args"], (1,))

        self.assertEqual(request.code, 200)

        logs = l.get_category("AR200")
        self.assertEqual(len(logs), 1)
        self.assertEqual(logs[0]["code"], 200)

        self.assertEqual(json.loads(native_string(request.get_written_data())),
                         {"id": session._published_messages[0]["id"]})
Esempio n. 7
0
    def test_broken_contenttype(self):
        """
        Crossbar rejects broken content-types.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json;charset=blarg;charset=boo"]},
            body=b'{"foo": "\xe2\x98\x83"}'))

        self.assertEqual(request.code, 400)
        self.assertEqual(
            b"mangled Content-Type header\n",
            request.getWrittenData())

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"charset=blarg;application/json"]},
            body=b'{"foo": "\xe2\x98\x83"}'))

        self.assertEqual(request.code, 400)
        self.assertEqual(
            b"bad or missing content type, should be 'application/json'\n",
            request.getWrittenData())
Esempio n. 8
0
    def test_basic_publish(self):
        """
        Test a very basic publish to a topic.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer() as l:
            request = yield renderResource(
                resource,
                b"/",
                method=b"POST",
                headers={b"Content-Type": [b"application/json"]},
                body=b'{"topic": "com.test.messages", "args": [1]}')

        self.assertEqual(len(session._published_messages), 1)
        self.assertEqual(session._published_messages[0]["args"], (1, ))

        self.assertEqual(request.code, 200)

        logs = l.get_category("AR200")
        self.assertEqual(len(logs), 1)
        self.assertEqual(logs[0]["code"], 200)

        self.assertEqual(json.loads(native_string(request.get_written_data())),
                         {"id": session._published_messages[0]["id"]})
        # ensure we have all the format-keys AR200 asks for (can we
        # extract these from the _log_categories string instead?)
        self.assertIn('code', logs[0])
        self.assertIn('reason', logs[0])
Esempio n. 9
0
    def test_allowed_IP_range(self):
        """
        The client having an IP in an allowed address range allows the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"require_ip": ["127.0.0.0/8"]}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody))

        self.assertEqual(request.code, 202)
Esempio n. 10
0
    def test_required_tls_with_tls(self):
        """
        Required TLS, plus a request over TLS, will allow the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"require_tls": True}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody, isSecure=True))

        self.assertEqual(request.code, 202)
Esempio n. 11
0
    def test_invalid_JSON_body(self):
        """
        A body that is not valid JSON will be rejected by the server.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=b"sometext"))

        self.assertEqual(request.code, 400)
        self.assertIn(b"invalid request event - HTTP/POST body must be valid JSON:",
                      request.getWrittenData())
Esempio n. 12
0
    def test_too_large_body(self):
        """
        A too large body will mean the request is rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"post_body_limit": 1}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertIn("HTTP/POST body length ({}) exceeds maximum ({})".format(len(publishBody), 1),
                      native_string(request.getWrittenData()))
Esempio n. 13
0
    def test_bad_method(self):
        """
        An incorrect method will mean the request is rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"PUT",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody))

        self.assertEqual(request.code, 405)
        self.assertIn(b"HTTP/PUT not allowed",
                      request.getWrittenData())
Esempio n. 14
0
    def test_bad_content_type(self):
        """
        An incorrect content type will mean the request is rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/text"]},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertIn(b"bad or missing content type",
                      request.getWrittenData())
Esempio n. 15
0
    def test_allowed_IP(self):
        """
        The client having an allowed IP address allows the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"require_ip": ["127.0.0.1"]}, session)

        request = yield renderResource(
            resource,
            b"/",
            method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody)

        self.assertEqual(request.code, 202)
Esempio n. 16
0
    def test_allow_caps_in_content_type(self):
        """
        Differently-capitalised content-type headers will be allowed.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"CONTENT-TYPE": [b"APPLICATION/JSON"]},
            body=publishBody))

        self.assertEqual(request.code, 202)
        self.assertIn(b'{"id":',
                      request.get_written_data())
Esempio n. 17
0
    def test_disallowed_IP_range(self):
        """
        The client having an IP not in allowed address range denies the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"require_ip": ["192.168.0.0/16", "10.0.0.0/8"]}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertIn(b"Request denied based on IP address",
                      request.get_written_data())
Esempio n. 18
0
    def test_UTF8_assumption(self):
        """
        A body, when the Content-Type has no charset, is assumed to be UTF-8.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=b'{"topic": "com.test.messages", "args": ["\xe2\x98\x83"]}'))

        self.assertEqual(request.code, 202)
        self.assertIn(b'{"id":',
                      request.get_written_data())
Esempio n. 19
0
    def test_allow_charset_in_content_type(self):
        """
        A charset in the content-type will be allowed.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json; charset=utf-8"]},
            body=publishBody))

        self.assertEqual(request.code, 202)
        self.assertIn(b'{"id":',
                      request.get_written_data())
Esempio n. 20
0
    def test_empty_content_type(self):
        """
        A request lacking a content-type header will be rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST", headers={},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertEqual((b"bad or missing content type, "
                          b"should be 'application/json'\n"),
                         request.getWrittenData())
Esempio n. 21
0
    def test_not_required_tls_with_tls(self):
        """
        A request over TLS even when not required, will allow the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = yield renderResource(
            resource,
            b"/",
            method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody,
            isSecure=True)

        self.assertEqual(request.code, 202)
Esempio n. 22
0
    def test_multiple_content_length(self):
        """
        Requests with multiple Content-Length headers will be rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"],
                     b"Content-Length": ["1", "10"]},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertIn("Multiple Content-Length headers are not allowed",
                      native_string(request.getWrittenData()))
Esempio n. 23
0
    def test_ASCII_denied(self):
        """
        A body with an ASCII charset is denied, it must be UTF-8.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json; charset=ascii"]},
            body=b''))

        self.assertEqual(request.code, 400)
        self.assertIn((b"'ascii' is not an accepted charset encoding, must be "
                       b"utf-8"),
                      request.getWrittenData())
Esempio n. 24
0
    def test_decodes_UTF8(self):
        """
        A body, when the Content-Type has been set to be charset=utf-8, will
        decode it as UTF8.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json;charset=utf-8"]},
            body=b'{"topic": "com.test.messages", "args": ["\xe2\x98\x83"]}'))

        self.assertEqual(request.code, 202)
        self.assertIn(b'{"id":',
                      request.getWrittenData())
Esempio n. 25
0
    def test_undecodable_UTF8(self):
        """
        Undecodable UTF-8 will return an error.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json;charset=utf-8"]},
            body=b'{"topic": "com.test.messages", "args": ["\x61\x62\x63\xe9"]}'))

        self.assertEqual(request.code, 400)
        self.assertEqual(
            (b"invalid request event - HTTP/POST body was invalid UTF-8\n"),
            request.getWrittenData())
Esempio n. 26
0
    def test_required_tls_without_tls(self):
        """
        Required TLS, plus a request NOT over TLS, will deny the request.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"require_tls": True}, session)

        request = yield renderResource(
            resource,
            b"/",
            method=b"POST",
            headers={b"Content-Type": [b"application/json"]},
            body=publishBody,
            isSecure=False)

        self.assertEqual(request.code, 400)
Esempio n. 27
0
    def test_not_matching_bodylength(self):
        """
        A body length that is different than the Content-Length header will mean
        the request is rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({"post_body_limit": 1}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json"],
                     b"Content-Length": [1]},
            body=publishBody))

        self.assertEqual(request.code, 400)
        self.assertIn("HTTP/POST body length ({}) is different to Content-Length ({})".format(len(publishBody), 1),
                      native_string(request.getWrittenData()))
Esempio n. 28
0
    def test_bad_method(self):
        """
        An incorrect method will mean the request is rejected.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer("debug") as l:
            request = self.successResultOf(renderResource(
                resource, b"/", method=b"BLBLBLB",
                headers={b"Content-Type": [b"application/json"]},
                body=publishBody))

        self.assertEqual(request.code, 405)
        errors = l.get_category("AR405")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 405)
Esempio n. 29
0
    def test_unknown_encoding(self):
        """
        A body, when the Content-Type has been set to something other than
        charset=utf-8, will error out.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        request = self.successResultOf(renderResource(
            resource, b"/", method=b"POST",
            headers={b"Content-Type": [b"application/json;charset=blarg"]},
            body=b'{"args": ["\x61\x62\x63\xe9"]}'))

        self.assertEqual(request.code, 400)
        self.assertEqual(
            (b"'blarg' is not an accepted charset encoding, must be utf-8\n"),
            request.getWrittenData())
Esempio n. 30
0
    def test_ASCII_denied(self):
        """
        A body with an ASCII charset is denied, it must be UTF-8.
        """
        session = MockPublisherSession(self)
        resource = PublisherResource({}, session)

        with LogCapturer("debug") as l:
            request = self.successResultOf(renderResource(
                resource, b"/", method=b"POST",
                headers={b"Content-Type": [b"application/json; charset=ascii"]},
                body=b''))

        self.assertEqual(request.code, 400)

        errors = l.get_category("AR450")
        self.assertEqual(len(errors), 1)
        self.assertEqual(errors[0]["code"], 400)