diff --git a/readthedocs/api/v2/permissions.py b/readthedocs/api/v2/permissions.py index 4044af52813..843bbd5ddfc 100644 --- a/readthedocs/api/v2/permissions.py +++ b/readthedocs/api/v2/permissions.py @@ -85,7 +85,8 @@ class HasBuildAPIKey(BaseHasAPIKey): """ Custom permission to inject the build API key into the request. - This avoids having to parse the key again on each view. + We completely override the ``has_permission`` method + to avoid having to parse and validate the key again on each view. The key is injected in the ``request.build_api_key`` attribute only if it's valid, otherwise it's set to ``None``. """ @@ -94,10 +95,18 @@ class HasBuildAPIKey(BaseHasAPIKey): key_parser = TokenKeyParser() def has_permission(self, request, view): - build_api_key = None - has_permission = super().has_permission(request, view) - if has_permission: - key = self.get_key(request) + request.build_api_key = None + key = self.get_key(request) + if not key: + return False + + try: build_api_key = self.model.objects.get_from_key(key) + except self.model.DoesNotExist: + return False + + if build_api_key.has_expired: + return False + request.build_api_key = build_api_key - return has_permission + return True