Browse Source

API tokens have no permissions to view/modify API tokens

David Burke 4 years ago
parent
commit
2d9c120057
3 changed files with 30 additions and 0 deletions
  1. 17 0
      api_tokens/tests.py
  2. 2 0
      api_tokens/views.py
  3. 11 0
      glitchtip/permissions.py

+ 17 - 0
api_tokens/tests.py

@@ -1,6 +1,7 @@
 from django.urls import reverse
 from rest_framework.test import APITestCase
 from model_bakery import baker
+from glitchtip import test_utils  # pylint: disable=unused-import
 
 
 class APITokenTests(APITestCase):
@@ -48,3 +49,19 @@ class APITokenTests(APITestCase):
         url = reverse("api-tokens-detail", args=[other_api_token.id])
         res = self.client.delete(url)
         self.assertEqual(res.status_code, 404)
+
+    def test_token_auth(self):
+        """ Token based auth should not be able to create it's own token """
+        organization = baker.make("organizations_ext.Organization")
+        organization.add_user(self.user)
+        auth_token = baker.make("api_tokens.APIToken", user=self.user)
+        self.client.credentials(HTTP_AUTHORIZATION="Bearer " + auth_token.token)
+
+        url = reverse("api-tokens-list")
+        scope_name = "member:read"
+        data = {"scopes": [scope_name]}
+        res = self.client.post(url, data, format="json")
+        self.assertEqual(res.status_code, 403)
+
+        res = self.client.get(url)
+        self.assertEqual(res.status_code, 403)

+ 2 - 0
api_tokens/views.py

@@ -1,11 +1,13 @@
 from rest_framework import viewsets
 from .models import APIToken
 from .serializers import APITokenSerializer
+from glitchtip.permissions import UserOnlyPermission
 
 
 class APITokenViewSet(viewsets.ModelViewSet):
     queryset = APIToken.objects.all()
     serializer_class = APITokenSerializer
+    permission_classes = [UserOnlyPermission]
 
     def get_queryset(self):
         if not self.request.user.is_authenticated:

+ 11 - 0
glitchtip/permissions.py

@@ -25,3 +25,14 @@ class ScopedPermission(BasePermission):
         allowed_scopes = self.get_allowed_scopes(request, view)
         current_scopes = self.get_user_scopes(obj, request.user)
         return any(s in allowed_scopes for s in current_scopes)
+
+
+class UserOnlyPermission(BasePermission):
+    """
+    Authentication method disallows tokens. User must be logged in via session.
+    """
+
+    def has_permission(self, request, view):
+        if request.auth:
+            return False
+        return bool(request.user and request.user.is_authenticated)