浏览代码

fix(api): return 404 for endpoints under non-existing tokens

Peter Thomassen 1 年之前
父节点
当前提交
cb34a9f880
共有 2 个文件被更改,包括 23 次插入6 次删除
  1. 11 0
      api/desecapi/tests/test_token_domain_policy.py
  2. 12 6
      api/desecapi/views/tokens.py

+ 11 - 0
api/desecapi/tests/test_token_domain_policy.py

@@ -219,6 +219,11 @@ class TokenDomainPolicyTestCase(DomainOwnerTestCase):
         self.assertStatus(response, status.HTTP_200_OK)
         self.assertEqual(response.data, [])
 
+        # Other token gives 404
+        other_token = self.create_token(user=self.create_user())
+        response = self.client.list_policies(other_token, using=self.token_manage)
+        self.assertStatus(response, status.HTTP_404_NOT_FOUND)
+
         # Create
         ## default policy
         data = {"domain": None, "subname": None, "type": None, "perm_write": True}
@@ -246,6 +251,12 @@ class TokenDomainPolicyTestCase(DomainOwnerTestCase):
             response.data, self.default_data | data | {"id": default_policy_id}
         )
 
+        ## Non-existing policy gives 404
+        response = self.client.get_policy(
+            self.token, using=self.token_manage, policy_id=other_token.pk
+        )
+        self.assertStatus(response, status.HTTP_404_NOT_FOUND)
+
         ## can't create policy for other user's domain
         data = {
             "domain": self.other_domain.name,

+ 12 - 6
api/desecapi/views/tokens.py

@@ -1,13 +1,13 @@
 import django.core.exceptions
 from rest_framework import viewsets
 from rest_framework.exceptions import ValidationError
+from rest_framework.generics import get_object_or_404, RetrieveAPIView
 from rest_framework.permissions import IsAuthenticated, SAFE_METHODS
 from rest_framework.response import Response
 from rest_framework.reverse import reverse
-from rest_framework.views import APIView
 
 from desecapi import permissions
-from desecapi.models import TokenDomainPolicy
+from desecapi.models import Token
 from desecapi.serializers import TokenDomainPolicySerializer, TokenSerializer
 
 from .base import IdempotentDestroyMixin
@@ -35,7 +35,10 @@ class TokenViewSet(IdempotentDestroyMixin, viewsets.ModelViewSet):
         serializer.save(user=self.request.user)
 
 
-class TokenPoliciesRoot(APIView):
+class TokenPoliciesRoot(RetrieveAPIView):
+    serializer_class = TokenSerializer
+    lookup_url_kwarg = "token_id"
+    throttle_scope = "account_management_passive"
     permission_classes = [
         IsAuthenticated,
         permissions.IsAPIToken | permissions.MFARequiredIfEnabled,
@@ -43,7 +46,11 @@ class TokenPoliciesRoot(APIView):
         | permissions.AuthTokenCorrespondsToViewToken,
     ]
 
+    def get_queryset(self):
+        return self.request.user.token_set.all()
+
     def get(self, request, *args, **kwargs):
+        self.get_object()  # raises if token does not exist
         return Response(
             {
                 "domain": reverse(
@@ -74,9 +81,8 @@ class TokenDomainPolicyViewSet(IdempotentDestroyMixin, viewsets.ModelViewSet):
         return ret
 
     def get_queryset(self):
-        return TokenDomainPolicy.objects.filter(
-            token_id=self.kwargs["token_id"], token__user=self.request.user
-        )
+        qs = Token.objects.filter(user=self.request.user)
+        return get_object_or_404(qs, pk=self.kwargs["token_id"]).tokendomainpolicy_set
 
     def perform_destroy(self, instance):
         try: