From 2436df6fa621f49119d381c066a7a2bf534b9d84 Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Thu, 4 Jan 2024 16:58:52 -0800 Subject: [PATCH] zilencer: Don't migrate plans with sponsorship pending. --- corporate/tests/test_remote_billing.py | 17 +++++++++++++++++ zilencer/views.py | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/corporate/tests/test_remote_billing.py b/corporate/tests/test_remote_billing.py index 501c2f7f31..097fc3ab34 100644 --- a/corporate/tests/test_remote_billing.py +++ b/corporate/tests/test_remote_billing.py @@ -488,6 +488,11 @@ class RemoteBillingAuthenticationTest(RemoteRealmBillingTestCase): # Delete any existing remote realms. RemoteRealm.objects.all().delete() + # First, set a sponsorship as pending. + # TODO: Ideally, we'd submit a proper sponsorship request. + server_customer.sponsorship_pending = True + server_customer.save() + # Send server data to push bouncer. self.add_mock_response() send_server_data_to_push_bouncer(consider_usage_statistics=False) @@ -495,6 +500,18 @@ class RemoteBillingAuthenticationTest(RemoteRealmBillingTestCase): # RemoteRealm objects should be created for all realms on the server. self.assert_length(RemoteRealm.objects.all(), 4) + # Server's plan should not have been migrated yet. + self.server.refresh_from_db() + self.assertEqual(self.server.plan_type, RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY) + + # Now clear sponsorship_pending. + # TODO: Ideally, this would approve the sponsorship. + server_customer.sponsorship_pending = False + server_customer.save() + + # Send server data to push bouncer again. + send_server_data_to_push_bouncer(consider_usage_statistics=False) + # Server plan status was reset self.server.refresh_from_db() self.assertEqual(self.server.plan_type, RemoteZulipServer.PLAN_TYPE_SELF_MANAGED) diff --git a/zilencer/views.py b/zilencer/views.py index b001d806d8..ac681721ea 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -847,6 +847,15 @@ def handle_customer_migration_from_server_to_realms( if server_customer is None: return + if server_customer.sponsorship_pending: + # If we have a pending sponsorship request, defer moving any + # data until the sponsorship request has been processed. This + # avoids a race where a sponsorship request made at the server + # level gets approved after the legacy plan has already been + # moved to the sole human RemoteRealm, which would violate + # invariants. + return + server_plan = get_current_plan_by_customer(server_customer) if server_plan is None: # If the server has no current plan, either because it never