mirror of https://github.com/zulip/zulip.git
zilencer: Add last_request_datetime to RemoteRealm + RemoteZulipServer.
For the RemoteRealm case, we can only set this in endpoints where the
remote server sends us the realm_uuid. So we're missing that for the
endpoints:
- remotes/push/unregister and remotes/push/unregister/all
- remotes/push/test_notification
This should be added in a follow-up commit.
(cherry picked from commit 3dca333b8d
)
This commit is contained in:
parent
81b42e3c41
commit
3a4d45022f
|
@ -606,6 +606,8 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
def test_send_notification_endpoint(self) -> None:
|
||||
hamlet = self.example_user("hamlet")
|
||||
server = self.server
|
||||
remote_realm = RemoteRealm.objects.get(server=server, uuid=hamlet.realm.uuid)
|
||||
|
||||
token = "aaaa"
|
||||
android_tokens = []
|
||||
uuid_android_tokens = []
|
||||
|
@ -649,6 +651,8 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
},
|
||||
"gcm_options": {},
|
||||
}
|
||||
|
||||
time_sent = now()
|
||||
with mock.patch(
|
||||
"zilencer.views.send_android_push_notification", return_value=2
|
||||
) as android_push, mock.patch(
|
||||
|
@ -656,6 +660,8 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
) as apple_push, mock.patch(
|
||||
"corporate.lib.stripe.RemoteServerBillingSession.current_count_for_billed_licenses",
|
||||
return_value=10,
|
||||
), time_machine.travel(
|
||||
time_sent, tick=False
|
||||
), self.assertLogs(
|
||||
"zilencer.views", level="INFO"
|
||||
) as logger:
|
||||
|
@ -711,6 +717,11 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
remote=server,
|
||||
)
|
||||
|
||||
remote_realm.refresh_from_db()
|
||||
server.refresh_from_db()
|
||||
self.assertEqual(remote_realm.last_request_datetime, time_sent)
|
||||
self.assertEqual(server.last_request_datetime, time_sent)
|
||||
|
||||
def test_send_notification_endpoint_on_free_plans(self) -> None:
|
||||
hamlet = self.example_user("hamlet")
|
||||
remote_server = self.server
|
||||
|
@ -1221,12 +1232,14 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
# normal setup.
|
||||
update_remote_realm_data_for_server(self.server, get_realms_info_for_push_bouncer())
|
||||
|
||||
# Test that we can push more times
|
||||
result = self.client_post(endpoint, {"token": token, **appid}, subdomain="zulip")
|
||||
self.assert_json_success(result)
|
||||
time_sent = now()
|
||||
with time_machine.travel(time_sent, tick=False):
|
||||
result = self.client_post(endpoint, {"token": token, **appid}, subdomain="zulip")
|
||||
self.assert_json_success(result)
|
||||
|
||||
result = self.client_post(endpoint, {"token": token, **appid}, subdomain="zulip")
|
||||
self.assert_json_success(result)
|
||||
# Test that we can push more times
|
||||
result = self.client_post(endpoint, {"token": token, **appid}, subdomain="zulip")
|
||||
self.assert_json_success(result)
|
||||
|
||||
tokens = list(
|
||||
RemotePushDeviceToken.objects.filter(
|
||||
|
@ -1237,9 +1250,16 @@ class PushBouncerNotificationTest(BouncerTestCase):
|
|||
self.assertEqual(tokens[0].kind, kind)
|
||||
# These new registrations have .remote_realm set properly.
|
||||
assert tokens[0].remote_realm is not None
|
||||
self.assertEqual(tokens[0].remote_realm.uuid, user.realm.uuid)
|
||||
remote_realm = tokens[0].remote_realm
|
||||
self.assertEqual(remote_realm.uuid, user.realm.uuid)
|
||||
self.assertEqual(tokens[0].ios_app_id, appid.get("appid"))
|
||||
|
||||
# Both RemoteRealm and RemoteZulipServer should have last_request_datetime
|
||||
# updated.
|
||||
self.assertEqual(remote_realm.last_request_datetime, time_sent)
|
||||
server.refresh_from_db()
|
||||
self.assertEqual(server.last_request_datetime, time_sent)
|
||||
|
||||
# User should have tokens for both devices now.
|
||||
tokens = list(RemotePushDeviceToken.objects.filter(user_uuid=user.uuid, server=server))
|
||||
self.assert_length(tokens, 2)
|
||||
|
@ -4748,11 +4768,16 @@ class PushBouncerSignupTest(ZulipTestCase):
|
|||
hostname="example.com",
|
||||
contact_email="server-admin@example.com",
|
||||
)
|
||||
result = self.client_post("/api/v1/remotes/server/register", request)
|
||||
|
||||
time_sent = now()
|
||||
|
||||
with time_machine.travel(time_sent, tick=False):
|
||||
result = self.client_post("/api/v1/remotes/server/register", request)
|
||||
self.assert_json_success(result)
|
||||
server = RemoteZulipServer.objects.get(uuid=zulip_org_id)
|
||||
self.assertEqual(server.hostname, "example.com")
|
||||
self.assertEqual(server.contact_email, "server-admin@example.com")
|
||||
self.assertEqual(server.last_request_datetime, time_sent)
|
||||
|
||||
# Update our hostname
|
||||
request = dict(
|
||||
|
@ -4761,11 +4786,14 @@ class PushBouncerSignupTest(ZulipTestCase):
|
|||
hostname="zulip.example.com",
|
||||
contact_email="server-admin@example.com",
|
||||
)
|
||||
result = self.client_post("/api/v1/remotes/server/register", request)
|
||||
|
||||
with time_machine.travel(time_sent + timedelta(minutes=1), tick=False):
|
||||
result = self.client_post("/api/v1/remotes/server/register", request)
|
||||
self.assert_json_success(result)
|
||||
server = RemoteZulipServer.objects.get(uuid=zulip_org_id)
|
||||
self.assertEqual(server.hostname, "zulip.example.com")
|
||||
self.assertEqual(server.contact_email, "server-admin@example.com")
|
||||
self.assertEqual(server.last_request_datetime, time_sent + timedelta(minutes=1))
|
||||
|
||||
# Now test rotating our key
|
||||
request = dict(
|
||||
|
@ -4783,7 +4811,7 @@ class PushBouncerSignupTest(ZulipTestCase):
|
|||
zulip_org_key = request["new_org_key"]
|
||||
self.assertEqual(server.api_key, zulip_org_key)
|
||||
|
||||
# Update our hostname
|
||||
# Update contact_email
|
||||
request = dict(
|
||||
zulip_org_id=zulip_org_id,
|
||||
zulip_org_key=zulip_org_key,
|
||||
|
|
|
@ -8,6 +8,7 @@ from django.http import HttpRequest, HttpResponse
|
|||
from django.urls import path
|
||||
from django.urls.resolvers import URLPattern
|
||||
from django.utils.crypto import constant_time_compare
|
||||
from django.utils.timezone import now as timezone_now
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from typing_extensions import Concatenate, ParamSpec, override
|
||||
|
@ -120,6 +121,10 @@ def authenticated_remote_server_view(
|
|||
raise UnauthorizedError(e.msg)
|
||||
|
||||
rate_limit_remote_server(request, remote_server, domain="api_by_remote_server")
|
||||
|
||||
remote_server.last_request_datetime = timezone_now()
|
||||
remote_server.save(update_fields=["last_request_datetime"])
|
||||
|
||||
return view_func(request, remote_server, *args, **kwargs)
|
||||
|
||||
return _wrapped_view_func
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 4.2.8 on 2023-12-25 00:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("zilencer", "0056_remoterealm_realm_locally_deleted"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="remoterealm",
|
||||
name="last_request_datetime",
|
||||
field=models.DateTimeField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="remotezulipserver",
|
||||
name="last_request_datetime",
|
||||
field=models.DateTimeField(null=True),
|
||||
),
|
||||
]
|
|
@ -47,6 +47,7 @@ class RemoteZulipServer(models.Model):
|
|||
hostname = models.CharField(max_length=HOSTNAME_MAX_LENGTH)
|
||||
contact_email = models.EmailField(blank=True, null=False)
|
||||
last_updated = models.DateTimeField("last updated", auto_now=True)
|
||||
last_request_datetime = models.DateTimeField(null=True)
|
||||
last_version = models.CharField(max_length=VERSION_MAX_LENGTH, null=True)
|
||||
last_api_feature_level = models.PositiveIntegerField(null=True)
|
||||
|
||||
|
@ -142,6 +143,7 @@ class RemoteRealm(models.Model):
|
|||
# The fields below are analogical to RemoteZulipServer fields.
|
||||
|
||||
last_updated = models.DateTimeField("last updated", auto_now=True)
|
||||
last_request_datetime = models.DateTimeField(null=True)
|
||||
|
||||
# Whether the realm registration has been deactivated.
|
||||
registration_deactivated = models.BooleanField(default=False)
|
||||
|
|
|
@ -144,6 +144,7 @@ def register_remote_server(
|
|||
"hostname": hostname,
|
||||
"contact_email": contact_email,
|
||||
"api_key": zulip_org_key,
|
||||
"last_request_datetime": timezone_now(),
|
||||
},
|
||||
)
|
||||
if created:
|
||||
|
@ -163,6 +164,8 @@ def register_remote_server(
|
|||
remote_server.contact_email = contact_email
|
||||
if new_org_key is not None:
|
||||
remote_server.api_key = new_org_key
|
||||
|
||||
remote_server.last_request_datetime = timezone_now()
|
||||
remote_server.save()
|
||||
|
||||
return json_success(request, data={"created": created})
|
||||
|
@ -207,6 +210,9 @@ def register_remote_push_device(
|
|||
# We want to associate the RemotePushDeviceToken with the RemoteRealm.
|
||||
kwargs["remote_realm_id"] = remote_realm.id
|
||||
|
||||
remote_realm.last_request_datetime = timezone_now()
|
||||
remote_realm.save(update_fields=["last_request_datetime"])
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
RemotePushDeviceToken.objects.create(
|
||||
|
@ -505,6 +511,9 @@ def remote_server_notify_push(
|
|||
increment=len(android_devices) + len(apple_devices),
|
||||
)
|
||||
|
||||
remote_realm.last_request_datetime = timezone_now()
|
||||
remote_realm.save(update_fields=["last_request_datetime"])
|
||||
|
||||
# Truncate incoming pushes to 200, due to APNs maximum message
|
||||
# sizes; see handle_remove_push_notification for the version of
|
||||
# this for notifications generated natively on the server. We
|
||||
|
|
Loading…
Reference in New Issue