Files
upstream-zulip/zerver/views/development/email_log.py
upstream-mirror 64898b2c79
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
2026-09-15 15:05:30 +05:00

168 lines
6.2 KiB
Python

import os
from contextlib import suppress
from urllib.parse import urlencode
import orjson
from django.conf import settings
from django.http import HttpRequest, HttpResponse
from django.shortcuts import redirect, render
from django.views.decorators.http import require_safe
from confirmation.models import Confirmation
from zerver.actions.realm_settings import do_send_realm_reactivation_email
from zerver.actions.user_settings import do_change_user_delivery_email
from zerver.actions.users import change_user_is_active
from zerver.lib.email_notifications import enqueue_welcome_emails, send_account_registered_email
from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import typed_endpoint
from zerver.models import Realm
from zerver.models.realms import get_realm
from zerver.models.streams import get_realm_stream
from zerver.models.users import get_user_by_delivery_email
from zerver.views.invite import INVITATION_LINK_VALIDITY_MINUTES
from zproject.email_backends import get_forward_address, set_forward_address
ZULIP_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../")
@typed_endpoint
def email_page(request: HttpRequest, *, forward_address: str | None = None) -> HttpResponse:
if request.method == "POST":
assert forward_address is not None
set_forward_address(forward_address)
return json_success(request)
try:
with open(settings.EMAIL_CONTENT_LOG_PATH, "r+") as f:
content = f.read()
except FileNotFoundError:
content = ""
return render(
request,
"zerver/development/email_log.html",
{"log": content, "forward_address": get_forward_address()},
)
def clear_emails(request: HttpRequest) -> HttpResponse:
with suppress(FileNotFoundError):
os.remove(settings.EMAIL_CONTENT_LOG_PATH)
return redirect(email_page)
@require_safe
def generate_all_emails(request: HttpRequest) -> HttpResponse:
# We import Django test client and override_settings inside
# the view function, because it isn't needed in production
# elsewhere, and not importing it saves ~50ms of unnecessary
# manage.py startup time.
from django.test import Client, override_settings
# override_settings is used as a hacky workaround to disable
# rate limiting; this is fine because this view only runs in
# the development environment.
with override_settings(RATE_LIMITING=False):
client = Client()
# write fake data for all variables
registered_email = "hamlet@zulip.com"
unregistered_email_1 = "new-person@zulip.com"
unregistered_email_2 = "new-person-2@zulip.com"
invite_expires_in_minutes = INVITATION_LINK_VALIDITY_MINUTES
realm = get_realm("zulip")
other_realm = Realm.objects.exclude(string_id="zulip").first()
user = get_user_by_delivery_email(registered_email, realm)
# Password reset emails
# active account in realm
result = client.post(
"/accounts/password/reset/", {"email": registered_email}, HTTP_HOST=realm.host
)
assert result.status_code == 302
# deactivated user
change_user_is_active(user, False)
result = client.post(
"/accounts/password/reset/", {"email": registered_email}, HTTP_HOST=realm.host
)
assert result.status_code == 302
change_user_is_active(user, True)
# account on different realm
assert other_realm is not None
result = client.post(
"/accounts/password/reset/", {"email": registered_email}, HTTP_HOST=other_realm.host
)
assert result.status_code == 302
# no account anywhere
result = client.post(
"/accounts/password/reset/", {"email": unregistered_email_1}, HTTP_HOST=realm.host
)
assert result.status_code == 302
# Confirm account email
result = client.post(
"/accounts/home/", {"email": unregistered_email_1}, HTTP_HOST=realm.host
)
assert result.status_code == 302
# Find account email
result = client.post("/accounts/find/", {"emails": registered_email}, HTTP_HOST=realm.host)
assert result.status_code == 200
# New login email
logged_in = client.login(dev_auth_username=registered_email, realm=realm)
assert logged_in
# New user invite and reminder emails
stream = get_realm_stream("Denmark", user.realm.id)
result = client.post(
"/json/invites",
{
"invitee_emails": unregistered_email_2,
"invite_expires_in_minutes": invite_expires_in_minutes,
"stream_ids": orjson.dumps([stream.id]).decode(),
},
HTTP_HOST=realm.host,
)
assert result.status_code == 200
# Verification for new email
result = client.patch(
"/json/settings",
urlencode({"email": "hamlets-new@zulip.com"}),
content_type="application/x-www-form-urlencoded",
HTTP_HOST=realm.host,
)
assert result.status_code == 200
# Email change successful
key = (
Confirmation.objects.filter(type=Confirmation.EMAIL_CHANGE)
.latest("id")
.confirmation_key
)
user_profile = get_user_by_delivery_email(registered_email, realm)
result = client.post("/accounts/confirm_new_email/", {"key": key})
assert result.status_code == 200
# Reset the email value so we can run this again
do_change_user_delivery_email(user_profile, registered_email, acting_user=None)
# Initial email with new account information for normal user
send_account_registered_email(user_profile)
# Onboarding emails for normal user
enqueue_welcome_emails(user_profile)
# Initial email with new account information for admin user
send_account_registered_email(get_user_by_delivery_email("iago@zulip.com", realm))
# Onboarding emails for admin user
enqueue_welcome_emails(
get_user_by_delivery_email("iago@zulip.com", realm), realm_creation=True
)
# Realm reactivation email
do_send_realm_reactivation_email(realm, acting_user=None)
return redirect(email_page)