diff --git a/confirmation/models.py b/confirmation/models.py index 441607119f..f0bd55c0a8 100644 --- a/confirmation/models.py +++ b/confirmation/models.py @@ -273,7 +273,7 @@ _properties = { "join", validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS ), Confirmation.REALM_CREATION: ConfirmationType("get_prereg_key_and_redirect"), - Confirmation.REALM_REACTIVATION: ConfirmationType("realm_reactivation"), + Confirmation.REALM_REACTIVATION: ConfirmationType("realm_reactivation_get"), } if settings.ZILENCER_ENABLED: _properties[Confirmation.REMOTE_SERVER_BILLING_LEGACY_LOGIN] = ConfirmationType( diff --git a/zerver/tests/test_realm.py b/zerver/tests/test_realm.py index 5425b4bb49..e58573f65e 100644 --- a/zerver/tests/test_realm.py +++ b/zerver/tests/test_realm.py @@ -514,7 +514,11 @@ class RealmTest(ZulipTestCase): obj = RealmReactivationStatus.objects.create(realm=realm) confirmation_url = create_confirmation_link(obj, Confirmation.REALM_REACTIVATION) + key = confirmation_url.split("/")[-1] response = self.client_get(confirmation_url) + self.assert_in_success_response(["redirect-to-post-form"], response) + + response = self.client_post("/reactivate/", {"key": key}) self.assert_in_success_response( ["Your organization has been successfully reactivated"], response ) @@ -527,6 +531,8 @@ class RealmTest(ZulipTestCase): ) response = self.client_get(confirmation_url) self.assertEqual(response.status_code, 404) + response = self.client_post("/reactivate/", {"key": key}) + self.assertEqual(response.status_code, 404) def test_realm_reactivation_confirmation_object(self) -> None: realm = get_realm("zulip") @@ -650,7 +656,12 @@ class RealmTest(ZulipTestCase): self.assertIn("Dear former administrators", mail.outbox[0].body) admins = realm.get_human_admin_users() confirmation_url = self.get_confirmation_url_from_outbox(admins[0].delivery_email) + key = confirmation_url.split("/")[-1] + response = self.client_get(confirmation_url) + self.assert_in_success_response(["redirect-to-post-form"], response) + + response = self.client_post("/reactivate/", {"key": key}) self.assert_in_success_response( ["Your organization has been successfully reactivated"], response ) diff --git a/zerver/views/realm.py b/zerver/views/realm.py index 27bab5ccd7..0674f9d732 100644 --- a/zerver/views/realm.py +++ b/zerver/views/realm.py @@ -6,6 +6,7 @@ from django.core.exceptions import ValidationError from django.db import transaction from django.http import HttpRequest, HttpResponse from django.shortcuts import render +from django.urls import reverse from django.utils.translation import gettext as _ from django.views.decorators.http import require_safe from pydantic import Json, NonNegativeInt, StringConstraints @@ -28,7 +29,7 @@ from zerver.actions.realm_settings import ( parse_and_set_setting_value_if_required, validate_authentication_methods_dict_from_api, ) -from zerver.decorator import require_realm_admin, require_realm_owner +from zerver.decorator import require_post, require_realm_admin, require_realm_owner from zerver.forms import check_subdomain_available as check_subdomain from zerver.lib.demo_organizations import check_demo_organization_has_set_email from zerver.lib.exceptions import JsonableError, OrganizationOwnerRequiredError @@ -576,11 +577,29 @@ def check_subdomain_available(request: HttpRequest, subdomain: str) -> HttpRespo return json_success(request, data={"msg": e.message}) -def realm_reactivation(request: HttpRequest, confirmation_key: str) -> HttpResponse: +def realm_reactivation_get(request: HttpRequest, confirmation_key: str) -> HttpResponse: try: - obj = get_object_from_key( - confirmation_key, [Confirmation.REALM_REACTIVATION], mark_object_used=True + get_object_from_key( + confirmation_key, [Confirmation.REALM_REACTIVATION], mark_object_used=False ) + except ConfirmationKeyError: # nocoverage + return render(request, "zerver/realm_reactivation_link_error.html", status=404) + + return render( + request, + "confirmation/redirect_to_post.html", + context={ + "target_url": reverse("realm_reactivation"), + "key": confirmation_key, + }, + ) + + +@require_post +@typed_endpoint +def realm_reactivation(request: HttpRequest, *, key: str) -> HttpResponse: + try: + obj = get_object_from_key(key, [Confirmation.REALM_REACTIVATION], mark_object_used=True) except ConfirmationKeyError: return render(request, "zerver/realm_reactivation_link_error.html", status=404) diff --git a/zproject/urls.py b/zproject/urls.py index 5b2afd22d9..0cfa2e169c 100644 --- a/zproject/urls.py +++ b/zproject/urls.py @@ -124,6 +124,7 @@ from zerver.views.realm import ( check_subdomain_available, deactivate_realm, realm_reactivation, + realm_reactivation_get, update_realm, update_realm_user_settings_defaults, ) @@ -698,7 +699,8 @@ i18n_urls = [ path("new/", create_realm), path("new/", create_realm, name="create_realm"), # Realm reactivation - path("reactivate/", realm_reactivation, name="realm_reactivation"), + path("reactivate/", realm_reactivation, name="realm_reactivation"), + path("reactivate/", realm_reactivation_get, name="realm_reactivation_get"), # Login/registration path("register/", accounts_home, name="register"), path("login/", login_page, {"template_name": "zerver/login.html"}, name="login_page"),