Rate limit jira and beanstalk API endpoints

(imported from commit ea299df983d53ee3f917f3c7314e78e813fe95a2)
This commit is contained in:
Leo Franchi
2013-06-06 14:08:02 -04:00
parent f41d9c8c5d
commit 3cb34cf246
2 changed files with 28 additions and 15 deletions

View File

@@ -361,6 +361,26 @@ def statsd_increment(counter, val=1):
return wrapped_func return wrapped_func
return wrapper 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'): def rate_limit(domain='all'):
"""Rate-limits a view. Takes an optional 'domain' param if you wish to rate limit different """Rate-limits a view. Takes an optional 'domain' param if you wish to rate limit different
types of API calls independently. types of API calls independently.
@@ -394,20 +414,7 @@ def rate_limit(domain='all'):
func.__name__) func.__name__)
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
ratelimited, time = is_ratelimited(user, domain) rate_limit_user(request, 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
return func(request, *args, **kwargs) return func(request, *args, **kwargs)
return wrapped_func return wrapped_func

View File

@@ -44,7 +44,7 @@ from zephyr.decorator import require_post, \
has_request_variables, authenticated_json_view, \ has_request_variables, authenticated_json_view, \
to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \ to_non_negative_int, json_to_dict, json_to_list, json_to_bool, \
JsonableError, RequestVariableMissingError, get_user_profile_by_email, \ 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.query import last_n
from zephyr.lib.avatar import gravatar_hash from zephyr.lib.avatar import gravatar_hash
from zephyr.lib.response import json_success, json_error, json_response, json_method_not_allowed, \ 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: try:
user_profile = UserProfile.objects.get(api_key=api_key) user_profile = UserProfile.objects.get(api_key=api_key)
request.user = user_profile
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
return json_error("Failed to find user with API key: %s" % (api_key,)) 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=''): def get_in(payload, keys, default=''):
try: try:
for key in keys: for key in keys:
@@ -1739,9 +1742,12 @@ def api_pivotal_webhook(request):
try: try:
user_profile = UserProfile.objects.get(api_key=api_key) user_profile = UserProfile.objects.get(api_key=api_key)
request.user = user_profile
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
return json_error("Failed to find user with API key: %s" % (api_key,)) 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) payload = xml_fromstring(request.body)
def get_text(attrs): def get_text(attrs):