mirror of https://github.com/zulip/zulip.git
avatar: Add rate limit similar to attachments on medium avatars.
Followup on #20136
This commit is contained in:
parent
b4feb673f1
commit
5ee4f71701
|
@ -1182,6 +1182,18 @@ class AvatarTest(UploadSerializeMixin, ZulipTestCase):
|
||||||
status_code=401,
|
status_code=401,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
with self.settings(RATE_LIMITING=True):
|
||||||
|
# Allow unauthenticated/spectator requests by ID for a reasonable number of requests.
|
||||||
|
add_ratelimit_rule(86400, 1000, domain="spectator_attachment_access_by_file")
|
||||||
|
response = self.client_get(f"/avatar/{cordelia.id}/medium", {"foo": "bar"})
|
||||||
|
self.assertEqual(302, response.status_code)
|
||||||
|
remove_ratelimit_rule(86400, 1000, domain="spectator_attachment_access_by_file")
|
||||||
|
|
||||||
|
# Deny file access since rate limited
|
||||||
|
add_ratelimit_rule(86400, 0, domain="spectator_attachment_access_by_file")
|
||||||
|
response = self.client_get(f"/avatar/{cordelia.id}/medium", {"foo": "bar"})
|
||||||
|
self.assertEqual(429, response.status_code)
|
||||||
|
|
||||||
def test_non_valid_user_avatar(self) -> None:
|
def test_non_valid_user_avatar(self) -> None:
|
||||||
|
|
||||||
# It's debatable whether we should generate avatars for non-users,
|
# It's debatable whether we should generate avatars for non-users,
|
||||||
|
|
|
@ -40,10 +40,12 @@ from zerver.lib.exceptions import (
|
||||||
JsonableError,
|
JsonableError,
|
||||||
MissingAuthenticationError,
|
MissingAuthenticationError,
|
||||||
OrganizationOwnerRequired,
|
OrganizationOwnerRequired,
|
||||||
|
RateLimited,
|
||||||
)
|
)
|
||||||
from zerver.lib.integrations import EMBEDDED_BOTS
|
from zerver.lib.integrations import EMBEDDED_BOTS
|
||||||
|
from zerver.lib.rate_limiter import rate_limit_spectator_attachment_access_by_file
|
||||||
from zerver.lib.request import REQ, has_request_variables
|
from zerver.lib.request import REQ, has_request_variables
|
||||||
from zerver.lib.response import json_success
|
from zerver.lib.response import json_response_from_error, json_success
|
||||||
from zerver.lib.streams import access_stream_by_id, access_stream_by_name, subscribed_to_stream
|
from zerver.lib.streams import access_stream_by_id, access_stream_by_name, subscribed_to_stream
|
||||||
from zerver.lib.types import ProfileDataElementValue, Validator
|
from zerver.lib.types import ProfileDataElementValue, Validator
|
||||||
from zerver.lib.upload import upload_avatar_image
|
from zerver.lib.upload import upload_avatar_image
|
||||||
|
@ -251,6 +253,15 @@ def avatar(
|
||||||
# interact with fake email addresses anyway.
|
# interact with fake email addresses anyway.
|
||||||
if is_email:
|
if is_email:
|
||||||
raise MissingAuthenticationError()
|
raise MissingAuthenticationError()
|
||||||
|
|
||||||
|
if settings.RATE_LIMITING:
|
||||||
|
try:
|
||||||
|
unique_avatar_key = f"{realm.id}/{email_or_id}/{medium}"
|
||||||
|
rate_limit_spectator_attachment_access_by_file(unique_avatar_key)
|
||||||
|
except RateLimited:
|
||||||
|
return json_response_from_error(
|
||||||
|
RateLimited(_("Too many attempts, please try after some time."))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
realm = maybe_user_profile.realm
|
realm = maybe_user_profile.realm
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue