Exemplo n.º 1
0
    def test_limited_to_length(self) -> None:
        hamlet = self.example_user("hamlet")
        # This is exactly the max length
        limit_length_name = "澳" * 61
        hamlet.full_name = limit_length_name
        hamlet.save()

        mail = build_email(
            "zerver/emails/password_reset",
            to_user_ids=[hamlet.id],
            from_name="Noreply",
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.to[0],
                         f"{hamlet.full_name} <{hamlet.delivery_email}>")

        # One more character makes it flip to just the address, with no name
        hamlet.full_name += "澳"
        hamlet.save()
        mail = build_email(
            "zerver/emails/password_reset",
            to_user_ids=[hamlet.id],
            from_name="Noreply",
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.to[0], hamlet.delivery_email)
Exemplo n.º 2
0
 def test_build_SES_incompatible_From_field(self) -> None:
     hamlet = self.example_user("hamlet")
     mail = build_email(
         "zerver/emails/password_reset",
         to_emails=[hamlet],
         from_name=OVERLY_LONG_NAME,
         from_address=FromAddress.NOREPLY,
         language="en",
     )
     self.assertEqual(mail.extra_headers["From"], FromAddress.NOREPLY)
Exemplo n.º 3
0
 def test_build_SES_incompatible_From_field_limit(self) -> None:
     hamlet = self.example_user("hamlet")
     limit_length_name = "a" * (321 - len(sanitize_address(FromAddress.NOREPLY, "utf-8")) - 3)
     mail = build_email(
         "zerver/emails/password_reset",
         to_emails=[hamlet],
         from_name=limit_length_name,
         from_address=FromAddress.NOREPLY,
         language="en",
     )
     self.assertEqual(mail.extra_headers["From"], FromAddress.NOREPLY)
Exemplo n.º 4
0
 def test_build_SES_compatible_From_field(self) -> None:
     hamlet = self.example_user("hamlet")
     from_name = FromAddress.security_email_from_name(language="en")
     mail = build_email(
         "zerver/emails/password_reset",
         to_emails=[hamlet],
         from_name=from_name,
         from_address=FromAddress.NOREPLY,
         language="en",
     )
     self.assertEqual(mail.extra_headers["From"],
                      "{} <{}>".format(from_name, FromAddress.NOREPLY))
Exemplo n.º 5
0
    def test_send_email_exceptions(self) -> None:
        hamlet = self.example_user("hamlet")
        from_name = FromAddress.security_email_from_name(language="en")
        address = FromAddress.NOREPLY
        # Used to check the output
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=from_name,
            from_address=address,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"],
                         f"{from_name} <{FromAddress.NOREPLY}>")

        # We test the cases that should raise an EmailNotDeliveredException
        errors = {
            f"Unknown error sending password_reset email to {mail.to}": [0],
            f"Error sending password_reset email to {mail.to}":
            [SMTPException()],
            f"Error sending password_reset email to {mail.to}: {{'{address}': (550, b'User unknown')}}":
            [
                SMTPRecipientsRefused(
                    recipients={address: (550, b"User unknown")})
            ],
            f"Error sending password_reset email to {mail.to} with error code 242: From field too long":
            [SMTPDataError(242, "From field too long.")],
        }

        for message, side_effect in errors.items():
            with mock.patch.object(EmailBackend,
                                   "send_messages",
                                   side_effect=side_effect):
                with self.assertLogs(logger=logger) as info_log:
                    with self.assertRaises(EmailNotDeliveredException):
                        send_email(
                            "zerver/emails/password_reset",
                            to_emails=[hamlet],
                            from_name=from_name,
                            from_address=FromAddress.NOREPLY,
                            language="en",
                        )
                self.assert_length(info_log.records, 2)
                self.assertEqual(
                    info_log.output[0],
                    f"INFO:{logger.name}:Sending password_reset email to {mail.to}",
                )
                self.assertTrue(info_log.output[1].startswith(
                    f"ERROR:zulip.send_email:{message}"))
Exemplo n.º 6
0
    def test_limited_from_length(self) -> None:
        hamlet = self.example_user("hamlet")
        # This is exactly the max length
        limit_length_name = "a" * (
            320 - len(sanitize_address(FromAddress.NOREPLY, "utf-8")) - 3)
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=limit_length_name,
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"],
                         f"{limit_length_name} <{FromAddress.NOREPLY}>")

        # One more character makes it flip to just the address, with no name
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=limit_length_name + "a",
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"], FromAddress.NOREPLY)
Exemplo n.º 7
0
    def test_send_email_exceptions(self) -> None:
        hamlet = self.example_user("hamlet")
        from_name = FromAddress.security_email_from_name(language="en")
        # Used to check the output
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=from_name,
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"],
                         "{} <{}>".format(from_name, FromAddress.NOREPLY))

        # We test the two cases that should raise an EmailNotDeliveredException
        errors = {
            f"Unknown error sending password_reset email to {mail.to}": [0],
            f"Error sending password_reset email to {mail.to}":
            [SMTPException()],
        }

        for message, side_effect in errors.items():
            with mock.patch.object(EmailBackend,
                                   "send_messages",
                                   side_effect=side_effect):
                with self.assertLogs(logger=logger) as info_log:
                    with self.assertRaises(EmailNotDeliveredException):
                        send_email(
                            "zerver/emails/password_reset",
                            to_emails=[hamlet],
                            from_name=from_name,
                            from_address=FromAddress.NOREPLY,
                            language="en",
                        )
                self.assert_length(info_log.records, 2)
                self.assertEqual(
                    info_log.output[0],
                    f"INFO:{logger.name}:Sending password_reset email to {mail.to}",
                )
                self.assertTrue(info_log.output[1].startswith(
                    f"ERROR:zulip.send_email:{message}"))
Exemplo n.º 8
0
    def test_send_email_exceptions(self) -> None:
        hamlet = self.example_user("hamlet")
        from_name = FromAddress.security_email_from_name(language="en")
        # Used to check the output
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=from_name,
            from_address=FromAddress.NOREPLY,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"],
                         "{} <{}>".format(from_name, FromAddress.NOREPLY))

        # We test the two cases that should raise an EmailNotDeliveredException
        side_effect = [0, SMTPException]

        with mock.patch.object(EmailBackend,
                               "send_messages",
                               side_effect=side_effect):
            for i in range(len(side_effect)):
                with self.assertLogs(logger=logger) as info_log:
                    with self.assertRaises(EmailNotDeliveredException):
                        send_email(
                            "zerver/emails/password_reset",
                            to_emails=[hamlet],
                            from_name=from_name,
                            from_address=FromAddress.NOREPLY,
                            language="en",
                        )
                self.assertEqual(len(info_log.records), 2)
                self.assertEqual(
                    info_log.output,
                    [
                        f"INFO:{logger.name}:Sending password_reset email to {mail.to}",
                        f"ERROR:{logger.name}:Error sending password_reset email to {mail.to}",
                    ],
                )
Exemplo n.º 9
0
    def test_build_and_send_SES_incompatible_From_address(self) -> None:
        hamlet = self.example_user("hamlet")
        from_name = "Zulip"
        # Address by itself is > 320 bytes even without the name. Should trigger exception.
        overly_long_address = "a" * 320 + "@zulip.com"
        mail = build_email(
            "zerver/emails/password_reset",
            to_emails=[hamlet],
            from_name=from_name,
            from_address=overly_long_address,
            language="en",
        )
        self.assertEqual(mail.extra_headers["From"], overly_long_address)
        self.assertTrue(
            len(sanitize_address(mail.extra_headers["From"], "utf-8")) > 320)

        with mock.patch.object(EmailBackend,
                               "send_messages",
                               side_effect=SMTPDataError(
                                   242, "From field too long.")):
            with self.assertLogs(logger=logger) as info_log:
                with self.assertRaises(EmailNotDeliveredException):
                    send_email(
                        "zerver/emails/password_reset",
                        to_emails=[hamlet],
                        from_name=from_name,
                        from_address=overly_long_address,
                        language="en",
                    )
        self.assertEqual(len(info_log.records), 2)
        self.assertEqual(
            info_log.output,
            [
                f"INFO:{logger.name}:Sending password_reset email to {mail.to}",
                f"ERROR:{logger.name}:Error sending password_reset email to {mail.to}",
            ],
        )
Exemplo n.º 10
0
def email_page(request):
    # type: (HttpRequest) -> HttpResponse
    # write fake data for all variables
    realm = get_realm('zulip')
    test_context = {
        'user_profile': {
            'full_name': 'Wile E. Coyote',
            'email': '*****@*****.**',
            'realm': {
                'uri': realm.uri,
                'name': 'Acme Corporation',
            },
        },
        'realm': {
            'uri': realm.uri,
            'name': 'Acme Corporation',
        },
        'device_info': {
            'login_time': "12/12/12, 12:12:12",
            'device_browser': "Firefox",
            'device_os': "ZulipOS",
            'device_ip': '3.14.15.92',
        },
        'referrer': {
            'full_name': 'Road Runner',
            'email': '*****@*****.**',
        },
        'user': {
            'full_name': 'Wile E. Coyote',
            'email': '*****@*****.**',
        },
        'referrer_name': 'Road Runner',
        'referrer_email': '*****@*****.**',
        'realm_uri': realm.uri,
        'server_uri': settings.SERVER_URI,
        'old_email': '*****@*****.**',
        'new_email': '*****@*****.**',
        'activate_url': '%s/accounts/do_confirm/5348720e4af7d2e8f296cbbd04d439489917ddc0' % (settings.SERVER_URI,),
        'unsubscribe_link': '%s/accounts/unsubscribe/<type>/cf88931365ef1b0f12eae8d488bbc7af3563d7f0' % (settings.SERVER_URI,),
    }

    templates = [
        'confirm_registration', 'invitation', 'invitation_reminder', 'confirm_registration_mit',
        'invitation_mit', 'followup_day1', 'followup_day2', 'missed_message', 'digest', 'find_team',
        'password_reset', 'confirm_new_email', 'notify_change_in_email', 'notify_new_login']

    for f in os.listdir(os.path.join(ZULIP_PATH, 'templates', 'zerver', 'emails')):
        template = f.split('.')[0]
        if template not in templates:
            templates.append(template)

    # Do not render these templates,
    # as they are currently unsupported
    ignore = [
        'email_base',
        'digest',
        'missed_message',
        'password_reset',
    ]

    data = []  # type: List[Dict[str, Any]]
    for template in templates:
        if template not in ignore:
            try:
                email = build_email('zerver/emails/' + template, '*****@*****.**', context=test_context)
                email_data = {
                    'template': template,
                    'subject': email.subject,
                    'body': email.body,
                    'html_message': email.alternatives[0][0] if len(email.alternatives) > 0 else 'Missing HTML message'}
                data.append(email_data)
            except Exception as e:  # nocoverage
                data.append({'template': template, 'failed': True, 'reason': e})
    return render(request, 'zerver/test_emails.html', {'emails': data})
Exemplo n.º 11
0
def email_page(request):
    # type: (HttpRequest) -> HttpResponse
    # write fake data for all variables
    realm = get_realm('zulip')
    test_context = {
        'user_profile': {
            'full_name': 'Wile E. Coyote',
            'email': '*****@*****.**',
            'realm': {
                'uri': realm.uri,
                'name': 'Acme Corporation',
            },
        },
        'realm': {
            'uri': realm.uri,
            'name': 'Acme Corporation',
        },
        'device_info': {
            'login_time': "12/12/12, 12:12:12",
            'device_browser': "Firefox",
            'device_os': "ZulipOS",
            'device_ip': '3.14.15.92',
        },
        'referrer': {
            'full_name': 'Road Runner',
            'email': '*****@*****.**',
        },
        'user': {
            'full_name': 'Wile E. Coyote',
            'email': '*****@*****.**',
        },
        'referrer_name': 'Road Runner',
        'referrer_email': '*****@*****.**',
        'referrer_realm_name': 'Acme Corporation',
        'realm_uri': realm.uri,
        'server_uri': settings.SERVER_URI,
        'old_email': '*****@*****.**',
        'new_email': '*****@*****.**',
        'activate_url': '%s/accounts/do_confirm/5348720e4af7d2e8f296cbbd04d439489917ddc0' % (settings.SERVER_URI,),
        'unsubscribe_link': '%s/accounts/unsubscribe/<type>/cf88931365ef1b0f12eae8d488bbc7af3563d7f0' % (settings.SERVER_URI,),
    }

    templates = [
        'confirm_registration', 'invitation', 'invitation_reminder', 'followup_day1',
        'followup_day2', 'missed_message', 'digest', 'find_team', 'password_reset',
        'confirm_new_email', 'notify_change_in_email', 'notify_new_login']

    for f in os.listdir(os.path.join(ZULIP_PATH, 'templates', 'zerver', 'emails')):
        template = f.split('.')[0]
        if template not in templates:
            templates.append(template)

    # Do not render these templates,
    # as they are currently unsupported
    ignore = [
        'email_base',
        'digest',
        'missed_message',
        'password_reset',
    ]

    data = []  # type: List[Dict[str, Any]]
    for template in templates:
        if template not in ignore:
            try:
                email = build_email('zerver/emails/' + template, '*****@*****.**', context=test_context)
                email_data = {
                    'template': template,
                    'subject': email.subject,
                    'body': email.body,
                    'html_message': email.alternatives[0][0] if len(email.alternatives) > 0 else 'Missing HTML message'}
                data.append(email_data)
            except Exception as e:  # nocoverage
                data.append({'template': template, 'failed': True, 'reason': e})
    return render(request, 'zerver/test_emails.html', {'emails': data})