rate_limit: Handle the case of request.user being a RemoteZulipServer.

For now we can just skip rate limiting for this case and rate limit by
the server uuid or simply by IP in a follow-up.
This commit is contained in:
Mateusz Mandera
2020-08-27 17:20:54 +02:00
committed by Tim Abbott
parent dbf3894c49
commit d247db37a5
2 changed files with 32 additions and 1 deletions

View File

@@ -789,7 +789,7 @@ def rate_limit(domain: str='api_by_user') -> Callable[[ViewFuncT], ViewFuncT]:
user = request.user
if isinstance(user, AnonymousUser): # nocoverage
if isinstance(user, AnonymousUser) or isinstance(user, RemoteZulipServer):
# We can only rate-limit logged-in users for now.
# We also only support rate-limiting authenticated
# views right now.

View File

@@ -10,6 +10,7 @@ from django.conf import settings
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError
from django.http import HttpRequest, HttpResponse
from django.utils.timezone import now as timezone_now
from zerver.decorator import (
api_key_only_webhook_view,
@@ -77,6 +78,7 @@ from zerver.lib.validator import (
)
from zerver.lib.webhooks.common import UnexpectedWebhookEventType
from zerver.models import Realm, UserProfile, get_realm, get_user
from zilencer.models import RemoteZulipServer
class DecoratorTestCase(ZulipTestCase):
@@ -706,6 +708,35 @@ class RateLimitTestCase(ZulipTestCase):
self.assertTrue(rate_limit_mock.called)
def test_rate_limiting_skipped_if_remote_server(self) -> None:
server_uuid = "1234-abcd"
server = RemoteZulipServer(uuid=server_uuid,
api_key="magic_secret_api_key",
hostname="demo.example.com",
last_updated=timezone_now())
class Client:
name = 'external'
class Request:
client = Client()
META = {'REMOTE_ADDR': '3.3.3.3'}
user = server
req = Request()
def f(req: Any) -> str:
return 'some value'
f = rate_limit()(f)
with self.settings(RATE_LIMITING=True):
with mock.patch('zerver.decorator.rate_limit_user') as rate_limit_mock:
with self.errors_disallowed():
self.assertEqual(f(req), 'some value')
self.assertFalse(rate_limit_mock.called)
class ValidatorTestCase(ZulipTestCase):
def test_check_string(self) -> None:
x: Any = "hello"