Exemplo n.º 1
0
    def test_garbage_input(self):
        # Test that we can survive garbage input for common field types
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        account = namedtuple('Account', ['default_timezone'])(default_timezone=tz)
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo>THIS_IS_GARBAGE</t:Foo>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        for field_cls in (Base64Field, BooleanField, IntegerField, DateField, DateTimeField, DecimalField):
            field = field_cls('foo', field_uri='item:Foo', is_required=True, default='DUMMY')
            self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Test MS timezones
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo Id="THIS_IS_GARBAGE"></t:Foo>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        field = TimeZoneField('foo', field_uri='item:Foo', default='DUMMY')
        self.assertEqual(field.from_xml(elem=elem, account=account), None)
    def test_garbage_input(self):
        # Test that we can survive garbage input for common field types
        tz = zoneinfo.ZoneInfo("Europe/Copenhagen")
        account = namedtuple("Account",
                             ["default_timezone"])(default_timezone=tz)
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo>THIS_IS_GARBAGE</t:Foo>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        for field_cls in (Base64Field, BooleanField, IntegerField, DateField,
                          DateTimeField, DecimalField):
            field = field_cls("foo",
                              field_uri="item:Foo",
                              is_required=True,
                              default="DUMMY")
            self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Test MS timezones
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:Foo Id="THIS_IS_GARBAGE"></t:Foo>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        field = TimeZoneField("foo", field_uri="item:Foo", default="DUMMY")
        self.assertEqual(field.from_xml(elem=elem, account=account), None)
Exemplo n.º 3
0
 def test_to_xml_failure_3(self, m):
     # Not all lxml versions throw ParseError on the same XML, so we have to mock
     with self.assertRaises(ParseError) as e:
         to_xml(b"<t:Foo><t:Bar>Baz</t:Bar></t:Foo>")
     self.assertEqual(
         e.exception.args[0],
         "This is not XML: b'<t:Foo><t:Bar>Baz</t:Bar></t:Foo>'")
    def test_naive_datetime(self):
        # Test that we can survive naive datetimes on a datetime field
        tz = zoneinfo.ZoneInfo("Europe/Copenhagen")
        utc = zoneinfo.ZoneInfo("UTC")
        account = namedtuple("Account",
                             ["default_timezone"])(default_timezone=tz)
        default_value = datetime.datetime(2017, 1, 2, 3, 4, tzinfo=tz)
        field = DateTimeField("foo",
                              field_uri="item:DateTimeSent",
                              default=default_value)

        # TZ-aware datetime string
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02Z</t:DateTimeSent>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         datetime.datetime(2017, 6, 21, 18, 40, 2, tzinfo=utc))

        # Naive datetime string is localized to tz of the account
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02</t:DateTimeSent>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         datetime.datetime(2017, 6, 21, 18, 40, 2, tzinfo=tz))

        # Garbage string returns None
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>THIS_IS_GARBAGE</t:DateTimeSent>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Element not found returns default value
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
    </t:Item>
</Envelope>"""
        elem = to_xml(payload).find(f"{{{TNS}}}Item")
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         default_value)
Exemplo n.º 5
0
    def test_naive_datetime(self):
        # Test that we can survive naive datetimes on a datetime field
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        account = namedtuple('Account',
                             ['default_timezone'])(default_timezone=tz)
        default_value = tz.localize(EWSDateTime(2017, 1, 2, 3, 4))
        field = DateTimeField('foo',
                              field_uri='item:DateTimeSent',
                              default=default_value)

        # TZ-aware datetime string
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02Z</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         UTC.localize(EWSDateTime(2017, 6, 21, 18, 40, 2)))

        # Naive datetime string is localized to tz of the account
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>2017-06-21T18:40:02</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         tz.localize(EWSDateTime(2017, 6, 21, 18, 40, 2)))

        # Garbage string returns None
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
        <t:DateTimeSent>THIS_IS_GARBAGE</t:DateTimeSent>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account), None)

        # Element not found returns default value
        payload = b'''\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:Item>
    </t:Item>
</Envelope>'''
        elem = to_xml(payload).find('{%s}Item' % TNS)
        self.assertEqual(field.from_xml(elem=elem, account=account),
                         default_value)
Exemplo n.º 6
0
 def test_to_xml(self):
     to_xml(b'<?xml version="1.0" encoding="UTF-8"?><foo></foo>')
     to_xml(BOM_UTF8+b'<?xml version="1.0" encoding="UTF-8"?><foo></foo>')
     to_xml(BOM_UTF8+b'<?xml version="1.0" encoding="UTF-8"?><foo>&broken</foo>')
     with self.assertRaises(ParseError):
         to_xml(b'foo')
     try:
         to_xml(b'<t:Foo><t:Bar>Baz</t:Bar></t:Foo>')
     except ParseError as e:
         # Not all lxml versions throw an error here, so we can't use assertRaises
         self.assertIn('Offending text: [...]<t:Foo><t:Bar>Baz</t[...]', e.args[0])
Exemplo n.º 7
0
 def test_to_xml(self):
     to_xml(b'<?xml version="1.0" encoding="UTF-8"?><foo></foo>')
     to_xml(BOM_UTF8 + b'<?xml version="1.0" encoding="UTF-8"?><foo></foo>')
     to_xml(BOM_UTF8 +
            b'<?xml version="1.0" encoding="UTF-8"?><foo>&broken</foo>')
     with self.assertRaises(ParseError):
         to_xml(b"foo")
Exemplo n.º 8
0
    def test_internet_message_headers(self):
        # Message headers are read-only, and an integration test is difficult because we can't reliably AND quickly
        # generate emails that pass through some relay server that adds headers. Create a unit test instead.
        payload = b"""\
<?xml version="1.0" encoding="utf-8"?>
<Envelope xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <t:InternetMessageHeaders>
        <t:InternetMessageHeader HeaderName="Received">from foo by bar</t:InternetMessageHeader>
        <t:InternetMessageHeader HeaderName="DKIM-Signature">Hello from DKIM</t:InternetMessageHeader>
        <t:InternetMessageHeader HeaderName="MIME-Version">1.0</t:InternetMessageHeader>
        <t:InternetMessageHeader HeaderName="X-Mailer">Contoso Mail</t:InternetMessageHeader>
        <t:InternetMessageHeader HeaderName="Return-Path">[email protected]</t:InternetMessageHeader>
    </t:InternetMessageHeaders>
</Envelope>"""
        headers_elem = to_xml(payload).find(f"{{{TNS}}}InternetMessageHeaders")
        headers = {}
        for elem in headers_elem.findall(f"{{{TNS}}}InternetMessageHeader"):
            header = MessageHeader.from_xml(elem=elem, account=None)
            headers[header.name] = header.value
        self.assertDictEqual(
            headers,
            {
                "Received": "from foo by bar",
                "DKIM-Signature": "Hello from DKIM",
                "MIME-Version": "1.0",
                "X-Mailer": "Contoso Mail",
                "Return-Path": "*****@*****.**",
            },
        )
Exemplo n.º 9
0
    def test_from_response(self, m):
        # Test fallback to suggested api_version value when there is a version mismatch and response version is fishy
        version = Version.from_soap_header(
            'Exchange2007',
            to_xml(b'''\
<s:Header>
    <h:ServerVersionInfo
        MajorBuildNumber="845" MajorVersion="15" MinorBuildNumber="22" MinorVersion="1" Version="V2016_10_10"
        xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"/>
</s:Header>'''))
        self.assertEqual(version.api_version, EXCHANGE_2007.api_version())
        self.assertEqual(version.api_version, 'Exchange2007')
        self.assertEqual(version.build, Build(15, 1, 845, 22))

        # Test that override the suggested version if the response version is not fishy
        version = Version.from_soap_header(
            'Exchange2013',
            to_xml(b'''\
<s:Header>
    <h:ServerVersionInfo
        MajorBuildNumber="845" MajorVersion="15" MinorBuildNumber="22" MinorVersion="1" Version="HELLO_FROM_EXCHANGELIB"
        xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"/>
</s:Header>'''))
        self.assertEqual(version.api_version, 'HELLO_FROM_EXCHANGELIB')

        # Test that we override the suggested version with the version deduced from the build number if a version is not
        # present in the response
        version = Version.from_soap_header(
            'Exchange2013',
            to_xml(b'''\
<s:Header>
    <h:ServerVersionInfo
        MajorBuildNumber="845" MajorVersion="15" MinorBuildNumber="22" MinorVersion="1"
        xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"/>
</s:Header>'''))
        self.assertEqual(version.api_version, 'Exchange2016')

        # Test that we use the version deduced from the build number when a version is not present in the response and
        # there was no suggested version.
        version = Version.from_soap_header(
            None,
            to_xml(b'''\
<s:Header>
    <h:ServerVersionInfo
        MajorBuildNumber="845" MajorVersion="15" MinorBuildNumber="22" MinorVersion="1"
        xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"/>
</s:Header>'''))
        self.assertEqual(version.api_version, 'Exchange2016')

        # Test various parse failures
        with self.assertRaises(TransportError) as e:
            Version.from_soap_header(
                'Exchange2013',
                to_xml(b'''\
<s:Header>
    <foo/>
</s:Header>'''))
        self.assertIn('No ServerVersionInfo in header', e.exception.args[0])
        with self.assertRaises(TransportError) as e:
            Version.from_soap_header(
                'Exchange2013',
                to_xml(b'''\
<s:Header>
    <h:ServerVersionInfo MajorBuildNumber="845" MajorVersion="15" Version="V2016_10_10"
        xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"/>
</s:Header>'''))
        self.assertIn('Bad ServerVersionInfo in response', e.exception.args[0])
Exemplo n.º 10
0
 def test_to_xml_failure_2(self, m):
     # Not all lxml versions throw ParseError on the same XML, so we have to mock
     with self.assertRaises(ParseError) as e:
         to_xml(b"<t:Foo><t:Bar>Baz</t:Bar></t:Foo>")
     self.assertIn("XXX", e.exception.args[0])