Changeset View
Changeset View
Standalone View
Standalone View
swh/web/api/throttling.py
Show All 11 Lines | |||||
import sentry_sdk | import sentry_sdk | ||||
from swh.web.config import get_config | from swh.web.config import get_config | ||||
APIView = TypeVar("APIView", bound="rest_framework.views.APIView") | APIView = TypeVar("APIView", bound="rest_framework.views.APIView") | ||||
Request = rest_framework.request.Request | Request = rest_framework.request.Request | ||||
API_THROTTLING_EXEMPTED_PERM = "swh.web.api.throttling_exempted" | |||||
class SwhWebRateThrottle(ScopedRateThrottle): | class SwhWebRateThrottle(ScopedRateThrottle): | ||||
"""Custom request rate limiter for DRF enabling to exempt | """Custom request rate limiter for DRF enabling to exempt | ||||
specific networks specified in swh-web configuration. | specific networks specified in swh-web configuration. | ||||
Requests are grouped into scopes. It enables to apply different | Requests are grouped into scopes. It enables to apply different | ||||
requests rate limiting based on the scope name but also the | requests rate limiting based on the scope name but also the | ||||
input HTTP request types. | input HTTP request types. | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | ) -> List[Union[IPv4Network, IPv6Network]]: | ||||
if networks: | if networks: | ||||
self.exempted_networks = [ | self.exempted_networks = [ | ||||
ip_network(network) for network in networks | ip_network(network) for network in networks | ||||
] | ] | ||||
return self.exempted_networks | return self.exempted_networks | ||||
def allow_request(self, request: Request, view: APIView) -> bool: | def allow_request(self, request: Request, view: APIView) -> bool: | ||||
# no throttling for staff users | # no throttling for staff users | ||||
if request.user.is_authenticated and request.user.is_staff: | if request.user.is_authenticated and ( | ||||
request.user.is_staff or request.user.has_perm(API_THROTTLING_EXEMPTED_PERM) | |||||
): | |||||
return True | return True | ||||
# class based view case | # class based view case | ||||
if not self.scope: | if not self.scope: | ||||
default_scope = getattr(view, self.scope_attr, None) | default_scope = getattr(view, self.scope_attr, None) | ||||
request_allowed = None | request_allowed = None | ||||
if default_scope is not None: | if default_scope is not None: | ||||
# check if there is a specific rate limiting associated | # check if there is a specific rate limiting associated | ||||
▲ Show 20 Lines • Show All 77 Lines • Show Last 20 Lines |