diff --git a/zerver/models/realm_audit_logs.py b/zerver/models/realm_audit_logs.py index f1ab308536..1a161dfcb9 100644 --- a/zerver/models/realm_audit_logs.py +++ b/zerver/models/realm_audit_logs.py @@ -144,6 +144,7 @@ class AbstractRealmAuditLog(models.Model): REMOTE_REALM_VALUE_UPDATED = 20001 REMOTE_PLAN_TRANSFERRED_SERVER_TO_REALM = 20002 REMOTE_REALM_LOCALLY_DELETED = 20003 + REMOTE_REALM_LOCALLY_DELETED_RESTORED = 20004 event_type = models.PositiveSmallIntegerField() diff --git a/zerver/tests/test_push_notifications.py b/zerver/tests/test_push_notifications.py index d9c5d8e442..fcde17f65b 100644 --- a/zerver/tests/test_push_notifications.py +++ b/zerver/tests/test_push_notifications.py @@ -27,6 +27,7 @@ from analytics.lib.counts import CountStat, LoggingCountStat from analytics.models import InstallationCount, RealmCount from corporate.models import CustomerPlan from version import ZULIP_VERSION +from zerver.actions.create_realm import do_create_realm from zerver.actions.message_delete import do_delete_messages from zerver.actions.message_flags import do_mark_stream_messages_as_read, do_update_message_flags from zerver.actions.realm_settings import ( @@ -2509,10 +2510,10 @@ class AnalyticsBouncerTest(BouncerTestCase): realm_info = get_realms_info_for_push_bouncer() # Hard-delete a realm to test the non existent realm uuid case. - realm = get_realm("zephyr") - assert realm is not None - deleted_realm_uuid = realm.uuid - realm.delete() + zephyr_realm = get_realm("zephyr") + assert zephyr_realm is not None + deleted_realm_uuid = zephyr_realm.uuid + zephyr_realm.delete() # This mock causes us to still send data to the bouncer as if the realm existed, # causing the bouncer to include its corresponding info in the response. Through @@ -2557,6 +2558,22 @@ class AnalyticsBouncerTest(BouncerTestCase): self.assertEqual(audit_log.event_type, RemoteRealmAuditLog.REMOTE_REALM_LOCALLY_DELETED) self.assertEqual(audit_log.remote_realm, remote_realm_for_deleted_realm) + # Restore the deleted realm to verify that the bouncer correctly handles that + # by togglin off .realm_locally_deleted. + restored_zephyr_realm = do_create_realm("zephyr", "Zephyr") + restored_zephyr_realm.uuid = deleted_realm_uuid + restored_zephyr_realm.save() + + send_server_data_to_push_bouncer(consider_usage_statistics=False) + remote_realm_for_deleted_realm.refresh_from_db() + self.assertEqual(remote_realm_for_deleted_realm.realm_locally_deleted, False) + + audit_log = RemoteRealmAuditLog.objects.latest("id") + self.assertEqual( + audit_log.event_type, RemoteRealmAuditLog.REMOTE_REALM_LOCALLY_DELETED_RESTORED + ) + self.assertEqual(audit_log.remote_realm, remote_realm_for_deleted_realm) + class PushNotificationTest(BouncerTestCase): @override diff --git a/zilencer/views.py b/zilencer/views.py index 054370a11d..b76e66a458 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -830,10 +830,6 @@ def update_remote_realm_data_for_server( # Update RemoteRealm entries, for which the corresponding realm's info has changed # (for the attributes that make sense to sync like this). for remote_realm in already_registered_remote_realms: - # TODO: We'll also want to check if .realm_locally_deleted is True, and if so, - # toggle it off, - # since the server is now sending us data for this realm again. - modified = False realm = uuid_to_realm_dict[str(remote_realm.uuid)] for remote_realm_attr, realm_dict_key in [ @@ -868,6 +864,20 @@ def update_remote_realm_data_for_server( ) modified = True + if remote_realm.realm_locally_deleted and remote_realm.uuid in uuids: + remote_realm.realm_locally_deleted = False + remote_realm_audit_logs.append( + RemoteRealmAuditLog( + server=server, + remote_id=None, + remote_realm=remote_realm, + realm_id=uuid_to_realm_dict[str(remote_realm.uuid)].id, + event_type=RemoteRealmAuditLog.REMOTE_REALM_LOCALLY_DELETED_RESTORED, + event_time=now, + ) + ) + modified = True + if modified: remote_realms_to_update.append(remote_realm) @@ -880,6 +890,7 @@ def update_remote_realm_data_for_server( "authentication_methods", "org_type", "is_system_bot_realm", + "realm_locally_deleted", ], ) RemoteRealmAuditLog.objects.bulk_create(remote_realm_audit_logs)