mirror of https://github.com/zulip/zulip.git
rate_limit: Move rate_limit_remote_server to zilencer.auth.
This allows us to avoid importing from zilencer conditionally in zerver.lib.rate_limiter, as we make rate limiting self-contained now. Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
parent
f158c86ae1
commit
2aac1dc40a
|
@ -2,7 +2,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple, Type, cast
|
from typing import Dict, List, Optional, Set, Tuple, Type, cast
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
import redis
|
import redis
|
||||||
|
@ -16,9 +16,6 @@ from zerver.lib.redis_utils import get_redis_client
|
||||||
from zerver.lib.utils import statsd
|
from zerver.lib.utils import statsd
|
||||||
from zerver.models import UserProfile
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from zilencer.models import RemoteZulipServer
|
|
||||||
|
|
||||||
# Implement a rate-limiting scheme inspired by the one described here, but heavily modified
|
# Implement a rate-limiting scheme inspired by the one described here, but heavily modified
|
||||||
# https://www.domaintools.com/resources/blog/rate-limiting-with-redis
|
# https://www.domaintools.com/resources/blog/rate-limiting-with-redis
|
||||||
|
|
||||||
|
@ -620,18 +617,6 @@ def rate_limit_request_by_ip(request: HttpRequest, domain: str) -> None:
|
||||||
rate_limit_ip(request, ip_addr, domain=domain)
|
rate_limit_ip(request, ip_addr, domain=domain)
|
||||||
|
|
||||||
|
|
||||||
def rate_limit_remote_server(
|
|
||||||
request: HttpRequest, remote_server: "RemoteZulipServer", domain: str
|
|
||||||
) -> None:
|
|
||||||
if settings.ZILENCER_ENABLED:
|
|
||||||
from zilencer.models import RateLimitedRemoteZulipServer
|
|
||||||
try:
|
|
||||||
RateLimitedRemoteZulipServer(remote_server, domain=domain).rate_limit_request(request)
|
|
||||||
except RateLimited as e:
|
|
||||||
logger.warning("Remote server %s exceeded rate limits on domain %s", remote_server, domain)
|
|
||||||
raise e
|
|
||||||
|
|
||||||
|
|
||||||
def should_rate_limit(request: HttpRequest) -> bool:
|
def should_rate_limit(request: HttpRequest) -> bool:
|
||||||
if not settings.RATE_LIMITING:
|
if not settings.RATE_LIMITING:
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -718,7 +718,7 @@ class RateLimitTestCase(ZulipTestCase):
|
||||||
server.save()
|
server.save()
|
||||||
|
|
||||||
with self.settings(RATE_LIMITING=True), mock.patch(
|
with self.settings(RATE_LIMITING=True), mock.patch(
|
||||||
"zerver.lib.rate_limiter.rate_limit_remote_server"
|
"zilencer.auth.rate_limit_remote_server"
|
||||||
) as rate_limit_mock:
|
) as rate_limit_mock:
|
||||||
result = self.uuid_post(
|
result = self.uuid_post(
|
||||||
server_uuid,
|
server_uuid,
|
||||||
|
|
|
@ -430,12 +430,12 @@ class RateLimitTests(ZulipTestCase):
|
||||||
self.DEFAULT_SUBDOMAIN = ""
|
self.DEFAULT_SUBDOMAIN = ""
|
||||||
|
|
||||||
RateLimitedRemoteZulipServer(server).clear_history()
|
RateLimitedRemoteZulipServer(server).clear_history()
|
||||||
with self.assertLogs("zerver.lib.rate_limiter", level="WARNING") as m:
|
with self.assertLogs("zilencer.auth", level="WARNING") as m:
|
||||||
self.do_test_hit_ratelimits(lambda: self.uuid_post(server_uuid, endpoint, payload))
|
self.do_test_hit_ratelimits(lambda: self.uuid_post(server_uuid, endpoint, payload))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
m.output,
|
m.output,
|
||||||
[
|
[
|
||||||
f"WARNING:zerver.lib.rate_limiter:Remote server <RemoteZulipServer demo.example.com {server_uuid[:12]}> exceeded rate limits on domain api_by_remote_server"
|
f"WARNING:zilencer.auth:Remote server <RemoteZulipServer demo.example.com {server_uuid[:12]}> exceeded rate limits on domain api_by_remote_server"
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
|
@ -12,15 +13,22 @@ from zerver.decorator import get_basic_credentials, process_client
|
||||||
from zerver.lib.exceptions import (
|
from zerver.lib.exceptions import (
|
||||||
ErrorCode,
|
ErrorCode,
|
||||||
JsonableError,
|
JsonableError,
|
||||||
|
RateLimited,
|
||||||
RemoteServerDeactivatedError,
|
RemoteServerDeactivatedError,
|
||||||
UnauthorizedError,
|
UnauthorizedError,
|
||||||
)
|
)
|
||||||
from zerver.lib.rate_limiter import rate_limit_remote_server, should_rate_limit
|
from zerver.lib.rate_limiter import should_rate_limit
|
||||||
from zerver.lib.request import RequestNotes
|
from zerver.lib.request import RequestNotes
|
||||||
from zerver.lib.rest import get_target_view_function_or_response
|
from zerver.lib.rest import get_target_view_function_or_response
|
||||||
from zerver.lib.subdomains import get_subdomain
|
from zerver.lib.subdomains import get_subdomain
|
||||||
from zerver.models import Realm
|
from zerver.models import Realm
|
||||||
from zilencer.models import RemoteZulipServer, get_remote_server_by_uuid
|
from zilencer.models import (
|
||||||
|
RateLimitedRemoteZulipServer,
|
||||||
|
RemoteZulipServer,
|
||||||
|
get_remote_server_by_uuid,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
ParamT = ParamSpec("ParamT")
|
ParamT = ParamSpec("ParamT")
|
||||||
|
|
||||||
|
@ -43,6 +51,16 @@ class InvalidZulipServerKeyError(InvalidZulipServerError):
|
||||||
return "Zulip server auth failure: key does not match role {role}"
|
return "Zulip server auth failure: key does not match role {role}"
|
||||||
|
|
||||||
|
|
||||||
|
def rate_limit_remote_server(
|
||||||
|
request: HttpRequest, remote_server: RemoteZulipServer, domain: str
|
||||||
|
) -> None:
|
||||||
|
try:
|
||||||
|
RateLimitedRemoteZulipServer(remote_server, domain=domain).rate_limit_request(request)
|
||||||
|
except RateLimited as e:
|
||||||
|
logger.warning("Remote server %s exceeded rate limits on domain %s", remote_server, domain)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def validate_remote_server(
|
def validate_remote_server(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
role: str,
|
role: str,
|
||||||
|
|
Loading…
Reference in New Issue