示例#1
0
        def handle(t):
            if not self.check_signature(
                    request.query.timestamp,
                    request.query.nonce,
                    request.query.signature
            ):
                return abort(403)

            body = request.body.read()
            message_dict = parse_xml(body)
            if "Encrypt" in message_dict:
                xml = self.crypto.decrypt_message(
                    timestamp=request.query.timestamp,
                    nonce=request.query.nonce,
                    msg_signature=request.query.msg_signature,
                    encrypt_msg=message_dict["Encrypt"]
                )
                message_dict = parse_xml(xml)
            message = process_message(message_dict)
            logging.info("Receive message %s" % message)
            reply = self.get_reply(message)
            if not reply:
                self.logger.warning("No handler responded message %s"
                                    % message)
                return ''
            response.content_type = 'application/xml'
            if self.use_encryption:
                return self.crypto.encrypt_message(reply)
            else:
                return reply.render()
示例#2
0
def test_django():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_test.settings")
    sys.path.append(
        os.path.join(
            os.path.abspath(os.path.dirname(__file__)), 'django_test_env'
        )
    )

    from django.test.utils import setup_test_environment
    setup_test_environment()
    from django.test.client import Client
    from werobot.parser import parse_xml, process_message
    import django

    django.setup()
    client = Client()

    token = 'TestDjango'
    timestamp = str(time.time())
    nonce = str(random.randint(0, 10000))
    signature = get_signature(token, timestamp, nonce)
    echostr = generate_token()

    response = client.get(
        '/robot/', {
            'signature': signature,
            'timestamp': timestamp,
            'nonce': nonce,
            'echostr': echostr
        }
    )
    assert response.status_code == 200
    assert response.content.decode('utf-8') == echostr

    xml = """
    <xml>
        <ToUserName><![CDATA[toUser]]></ToUserName>
        <FromUserName><![CDATA[fromUser]]></FromUserName>
        <CreateTime>1348831860</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[this is a test]]></Content>
        <MsgId>1234567890123456</MsgId>
    </xml>"""
    params = "?timestamp=%s&nonce=%s&signature=%s" % \
             (timestamp, nonce, signature)
    url = '/robot/'
    response = client.post(url, data=xml, content_type="text/xml")

    assert response.status_code == 403
    assert response.content.decode('utf-8') == u'喵'

    url += params
    response = client.post(url, data=xml, content_type="text/xml")

    assert response.status_code == 200
    response = process_message(parse_xml(response.content))
    assert response.content == 'hello'

    response = client.options(url)
    assert response.status_code == 405
示例#3
0
 def parse_message(self, body, timestamp=None, nonce=None, msg_signature=None):
     """
     解析获取到的 Raw XML ,如果需要的话进行解密,返回 WeRoBot Message。
     :param body: 微信服务器发来的请求中的 Body。
     :return: WeRoBot Message
     """
     message_dict = parse_xml(body)
     if "Encrypt" in message_dict:
         xml = self.crypto.decrypt_message(
             timestamp=timestamp,
             nonce=nonce,
             msg_signature=msg_signature,
             encrypt_msg=message_dict["Encrypt"]
         )
         message_dict = parse_xml(xml)
     return process_message(message_dict)
示例#4
0
def test_django():
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_test.settings")
    sys.path.append(
        os.path.join(
            os.path.abspath(os.path.dirname(__file__)), 'django_test_env'
        )
    )

    from django.test.utils import setup_test_environment
    setup_test_environment()
    from django.test.client import Client
    from werobot.parser import parse_xml, process_message
    import django

    django.setup()
    client = Client()

    token = 'TestDjango'
    timestamp = str(time.time())
    nonce = str(random.randint(0, 10000))
    signature = get_signature(token, timestamp, nonce)
    echostr = generate_token()

    response = client.get(
        '/robot/', {
            'signature': signature,
            'timestamp': timestamp,
            'nonce': nonce,
            'echostr': echostr
        }
    )
    assert response.status_code == 200
    assert response.content.decode('utf-8') == echostr

    xml = """
    <xml>
        <ToUserName><![CDATA[toUser]]></ToUserName>
        <FromUserName><![CDATA[fromUser]]></FromUserName>
        <CreateTime>1348831860</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[this is a test]]></Content>
        <MsgId>1234567890123456</MsgId>
    </xml>"""
    params = "?timestamp=%s&nonce=%s&signature=%s" % \
             (timestamp, nonce, signature)
    url = '/robot/'
    response = client.post(url, data=xml, content_type="text/xml")

    assert response.status_code == 403
    assert response.content.decode('utf-8') == u'喵'

    url += params
    response = client.post(url, data=xml, content_type="text/xml")

    assert response.status_code == 200
    response = process_message(parse_xml(response.content))
    assert response.content == 'hello'

    response = client.options(url)
    assert response.status_code == 405
示例#5
0
 def parse_message(
     self, body, timestamp=None, nonce=None, msg_signature=None
 ):
     """
     解析获取到的 Raw XML ,如果需要的话进行解密,返回 WeRoBot Message。
     :param body: 微信服务器发来的请求中的 Body。
     :return: WeRoBot Message
     """
     message_dict = parse_xml(body)
     if "Encrypt" in message_dict:
         xml = self.crypto.decrypt_message(
             timestamp=timestamp,
             nonce=nonce,
             msg_signature=msg_signature,
             encrypt_msg=message_dict["Encrypt"]
         )
         message_dict = parse_xml(xml)
     return process_message(message_dict)
示例#6
0
    def test_tornado(self):
        token = self.token
        timestamp = str(time.time())
        nonce = str(random.randint(0, 10000))
        signature = get_signature(token, timestamp, nonce)
        echostr = generate_token()

        params = "?timestamp=%s&nonce=%s&signature=%s&echostr=%s" % (
            timestamp, nonce, signature, echostr
        )

        response = self.fetch(path=self.endpoint + params)
        assert response.code == 200
        assert response.body.decode('utf-8') == echostr

        response = self.fetch(path=self.endpoint, )
        assert response.code == 403
        assert response.body.decode('utf-8') == u'喵'

        xml = """
        <xml>
            <ToUserName><![CDATA[toUser]]></ToUserName>
            <FromUserName><![CDATA[fromUser]]></FromUserName>
            <CreateTime>1348831860</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[this is a test]]></Content>
            <MsgId>1234567890123456</MsgId>
        </xml>"""

        response = self.fetch(
            path=self.endpoint + params,
            method='POST',
            body=xml,
            headers={'Content-Type': 'text/xml'}
        )
        self.assertEqual(response.code, 200)
        self.assertEqual(
            process_message(parse_xml(response.body)).content, 'hello'
        )

        response = self.fetch(
            path=self.endpoint,
            method='POST',
            body=xml,
            headers={'Content-Type': 'text/xml'}
        )
        self.assertEqual(response.code, 403)
示例#7
0
        def test_tornado(self):
            token = self.token
            timestamp = str(time.time())
            nonce = str(random.randint(0, 10000))
            signature = get_signature(token, timestamp, nonce)
            echostr = generate_token()

            params = "?timestamp=%s&nonce=%s&signature=%s&echostr=%s" % (
                timestamp, nonce, signature, echostr
            )

            response = self.fetch(path=self.endpoint + params)
            assert response.code == 200
            assert response.body.decode('utf-8') == echostr

            response = self.fetch(path=self.endpoint, )
            assert response.code == 403
            assert response.body.decode('utf-8') == u'喵'

            xml = """
            <xml>
                <ToUserName><![CDATA[toUser]]></ToUserName>
                <FromUserName><![CDATA[fromUser]]></FromUserName>
                <CreateTime>1348831860</CreateTime>
                <MsgType><![CDATA[text]]></MsgType>
                <Content><![CDATA[this is a test]]></Content>
                <MsgId>1234567890123456</MsgId>
            </xml>"""

            response = self.fetch(
                path=self.endpoint + params,
                method='POST',
                body=xml,
                headers={'Content-Type': 'text/xml'}
            )
            self.assertEqual(response.code, 200)
            self.assertEqual(
                process_message(parse_xml(response.body)).content, 'hello'
            )

            response = self.fetch(
                path=self.endpoint,
                method='POST',
                body=xml,
                headers={'Content-Type': 'text/xml'}
            )
            self.assertEqual(response.code, 403)
示例#8
0
    def tester(app, token, endpoint):
        test_app = webtest.TestApp(app)

        response = test_app.get(endpoint, expect_errors=True)
        assert response.status_code == 403

        timestamp = str(time.time())
        nonce = str(random.randint(0, 10000))
        signature = get_signature(token, timestamp, nonce)
        echostr = generate_token()

        params = "?timestamp=%s&nonce=%s&signature=%s&echostr=%s" % (
            timestamp, nonce, signature, echostr
        )
        response = test_app.get(endpoint + params)

        assert response.status_code == 200
        assert response.body.decode('utf-8') == echostr

        response = test_app.get(endpoint, expect_errors=True)

        assert response.status_code == 403
        assert response.body.decode('utf-8') == u'喵'

        xml = """
                <xml>
                    <ToUserName><![CDATA[toUser]]></ToUserName>
                    <FromUserName><![CDATA[fromUser]]></FromUserName>
                    <CreateTime>1348831860</CreateTime>
                    <MsgType><![CDATA[text]]></MsgType>
                    <Content><![CDATA[this is a test]]></Content>
                    <MsgId>1234567890123456</MsgId>
                </xml>
                """
        with pytest.raises(AppError):
            # WebTest will raise an AppError
            # if the status_code is not >= 200 and < 400.
            test_app.post(endpoint, xml, content_type="text/xml")

        response = test_app.post(
            endpoint + params, xml, content_type="text/xml"
        )

        assert response.status_code == 200
        response = process_message(parse_xml(response.body))
        assert response.content == 'hello'
示例#9
0
    def tester(app, token, endpoint):
        test_app = webtest.TestApp(app)

        response = test_app.get(endpoint, expect_errors=True)
        assert response.status_code == 403

        timestamp = str(time.time())
        nonce = str(random.randint(0, 10000))
        signature = get_signature(token, timestamp, nonce)
        echostr = generate_token()

        params = "?timestamp=%s&nonce=%s&signature=%s&echostr=%s" % (
            timestamp, nonce, signature, echostr
        )
        response = test_app.get(endpoint + params)

        assert response.status_code == 200
        assert response.body.decode('utf-8') == echostr

        response = test_app.get(endpoint, expect_errors=True)

        assert response.status_code == 403
        assert response.body.decode('utf-8') == u'喵'

        xml = """
                <xml>
                    <ToUserName><![CDATA[toUser]]></ToUserName>
                    <FromUserName><![CDATA[fromUser]]></FromUserName>
                    <CreateTime>1348831860</CreateTime>
                    <MsgType><![CDATA[text]]></MsgType>
                    <Content><![CDATA[this is a test]]></Content>
                    <MsgId>1234567890123456</MsgId>
                </xml>
                """
        with pytest.raises(AppError):
            # WebTest will raise an AppError
            # if the status_code is not >= 200 and < 400.
            test_app.post(endpoint, xml, content_type="text/xml")

        response = test_app.post(
            endpoint + params, xml, content_type="text/xml"
        )

        assert response.status_code == 200
        response = process_message(parse_xml(response.body))
        assert response.content == 'hello'
示例#10
0
def test_message_crypt():
    encoding_aes_key = generate_token(32) + generate_token(11)
    token = generate_token()
    timestamp = to_text(int(time.time()))
    nonce = generate_token(5)
    app_id = generate_token(18)
    crypt = MessageCrypt(token=token,
                         encoding_aes_key=encoding_aes_key,
                         app_id=app_id)

    message = crypt.encrypt_message('hello', timestamp, nonce)
    assert message is not None
    message = parse_xml(message)
    assert message is not None
    message = crypt.decrypt_message(message['TimeStamp'], message['Nonce'],
                                    message['MsgSignature'],
                                    message['Encrypt'])
    assert message == to_binary('hello')
示例#11
0
def test_message_crypt():
    encoding_aes_key = generate_token(32) + generate_token(11)
    token = generate_token()
    timestamp = to_text(int(time.time()))
    nonce = generate_token(5)
    app_id = generate_token(18)
    crypt = MessageCrypt(
        token=token, encoding_aes_key=encoding_aes_key, app_id=app_id
    )

    message = crypt.encrypt_message('hello', timestamp, nonce)
    assert message is not None
    message = parse_xml(message)
    assert message is not None
    message = crypt.decrypt_message(
        message['TimeStamp'], message['Nonce'], message['MsgSignature'],
        message['Encrypt']
    )
    assert message == to_binary('hello')