mirror of
https://github.com/zulip/zulip.git
synced 2025-11-18 12:54:58 +00:00
Rate limit jira and beanstalk API endpoints
(imported from commit ea299df983d53ee3f917f3c7314e78e813fe95a2)
This commit is contained in:
@@ -361,6 +361,26 @@ def statsd_increment(counter, val=1):
|
||||
return wrapped_func
|
||||
return wrapper
|
||||
|
||||
def rate_limit_user(request, user, domain):
|
||||
"""Returns whether or not a user was rate limited. Will raise a RateLimited exception
|
||||
if the user has been rate limited, otherwise returns and modifies request to contain
|
||||
the rate limit information"""
|
||||
|
||||
ratelimited, time = is_ratelimited(user, domain)
|
||||
request._ratelimit_applied_limits = True
|
||||
request._ratelimit_secs_to_freedom = time
|
||||
request._ratelimit_over_limit = ratelimited
|
||||
# Abort this request if the user is over her rate limits
|
||||
if ratelimited:
|
||||
statsd.incr("ratelimiter.limited.%s" % user.id)
|
||||
raise RateLimited()
|
||||
|
||||
incr_ratelimit(user, domain)
|
||||
calls_remaining, time_reset = api_calls_left(user, domain)
|
||||
|
||||
request._ratelimit_remaining = calls_remaining
|
||||
request._ratelimit_secs_to_freedom = time_reset
|
||||
|
||||
def rate_limit(domain='all'):
|
||||
"""Rate-limits a view. Takes an optional 'domain' param if you wish to rate limit different
|
||||
types of API calls independently.
|
||||
@@ -394,20 +414,7 @@ def rate_limit(domain='all'):
|
||||
func.__name__)
|
||||
return func(request, *args, **kwargs)
|
||||
|
||||
ratelimited, time = is_ratelimited(user, domain)
|
||||
request._ratelimit_applied_limits = True
|
||||
request._ratelimit_secs_to_freedom = time
|
||||
request._ratelimit_over_limit = ratelimited
|
||||
# Abort this request if the user is over her rate limits
|
||||
if ratelimited:
|
||||
statsd.incr("ratelimiter.limited.%s" % user.id)
|
||||
raise RateLimited()
|
||||
|
||||
incr_ratelimit(user, domain)
|
||||
calls_remaining, time_reset = api_calls_left(user, domain)
|
||||
|
||||
request._ratelimit_remaining = calls_remaining
|
||||
request._ratelimit_secs_to_freedom = time_reset
|
||||
rate_limit_user(request, user, domain)
|
||||
|
||||
return func(request, *args, **kwargs)
|
||||
return wrapped_func
|
||||
|
||||
@@ -44,7 +44,7 @@ from zephyr.decorator import require_post, \
|
||||
has_request_variables, authenticated_json_view, \
|
||||
to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \
|
||||
JsonableError, RequestVariableMissingError, get_user_profile_by_email, \
|
||||
authenticated_rest_api_view, process_as_post, REQ, rate_limit
|
||||
authenticated_rest_api_view, process_as_post, REQ, rate_limit, rate_limit_user
|
||||
from zephyr.lib.query import last_n
|
||||
from zephyr.lib.avatar import gravatar_hash
|
||||
from zephyr.lib.response import json_success, json_error, json_response, json_method_not_allowed, \
|
||||
@@ -1661,9 +1661,12 @@ def api_jira_webhook(request):
|
||||
|
||||
try:
|
||||
user_profile = UserProfile.objects.get(api_key=api_key)
|
||||
request.user = user_profile
|
||||
except UserProfile.DoesNotExist:
|
||||
return json_error("Failed to find user with API key: %s" % (api_key,))
|
||||
|
||||
rate_limit_user(request, user_profile, domain='all')
|
||||
|
||||
def get_in(payload, keys, default=''):
|
||||
try:
|
||||
for key in keys:
|
||||
@@ -1739,9 +1742,12 @@ def api_pivotal_webhook(request):
|
||||
|
||||
try:
|
||||
user_profile = UserProfile.objects.get(api_key=api_key)
|
||||
request.user = user_profile
|
||||
except UserProfile.DoesNotExist:
|
||||
return json_error("Failed to find user with API key: %s" % (api_key,))
|
||||
|
||||
rate_limit_user(request, user_profile, domain='all')
|
||||
|
||||
payload = xml_fromstring(request.body)
|
||||
|
||||
def get_text(attrs):
|
||||
|
||||
Reference in New Issue
Block a user