Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion tests/browsable_api/no_auth_urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.urls import path

from .views import MockView
from .views import BasicModelWithUsersViewSet, MockView

urlpatterns = [
path('', MockView.as_view()),
path('basicviewset', BasicModelWithUsersViewSet.as_view({'get': 'list'})),
]
8 changes: 8 additions & 0 deletions tests/browsable_api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from rest_framework.serializers import ModelSerializer
from tests.models import BasicModelWithUsers


class BasicSerializer(ModelSerializer):
class Meta:
model = BasicModelWithUsers
fields = '__all__'
27 changes: 27 additions & 0 deletions tests/browsable_api/test_browsable_api.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,35 @@
from django.contrib.auth.models import User
from django.test import TestCase, override_settings

from rest_framework.permissions import IsAuthenticated
from rest_framework.test import APIClient

from .views import BasicModelWithUsersViewSet, OrganizationPermissions


@override_settings(ROOT_URLCONF='tests.browsable_api.no_auth_urls')
class AnonymousUserTests(TestCase):
"""Tests correct handling of anonymous user request on endpoints with IsAuthenticated permission class."""

def setUp(self):
self.client = APIClient(enforce_csrf_checks=True)

def tearDown(self):
self.client.logout()

def test_get_raises_typeerror_when_anonymous_user_in_queryset_filter(self):
with self.assertRaises(TypeError):
self.client.get('/basicviewset')

def test_get_returns_http_forbidden_when_anonymous_user(self):
old_permissions = BasicModelWithUsersViewSet.permission_classes
BasicModelWithUsersViewSet.permission_classes = [IsAuthenticated, OrganizationPermissions]

response = self.client.get('/basicviewset')

BasicModelWithUsersViewSet.permission_classes = old_permissions
self.assertEqual(response.status_code, 403)


@override_settings(ROOT_URLCONF='tests.browsable_api.auth_urls')
class DropdownWithAuthTests(TestCase):
Expand Down
22 changes: 22 additions & 0 deletions tests/browsable_api/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from rest_framework import authentication, renderers
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet

from ..models import BasicModelWithUsers
from .serializers import BasicSerializer


class OrganizationPermissions(BasePermission):
def has_object_permission(self, request, view, obj):
return request.user.is_staff or (request.user == obj.owner.organization_user.user)


class MockView(APIView):
Expand All @@ -9,3 +19,15 @@ class MockView(APIView):

def get(self, request):
return Response({'a': 1, 'b': 2, 'c': 3})


class BasicModelWithUsersViewSet(ModelViewSet):
queryset = BasicModelWithUsers.objects.all()
serializer_class = BasicSerializer
permission_classes = [OrganizationPermissions]
# permission_classes = [IsAuthenticated, OrganizationPermissions]
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)

def get_queryset(self):
qs = super().get_queryset().filter(users=self.request.user)
return qs
5 changes: 5 additions & 0 deletions tests/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import uuid

from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -33,6 +34,10 @@ class ManyToManySource(RESTFrameworkModel):
targets = models.ManyToManyField(ManyToManyTarget, related_name='sources')


class BasicModelWithUsers(RESTFrameworkModel):
users = models.ManyToManyField(User)


# ForeignKey
class ForeignKeyTarget(RESTFrameworkModel):
name = models.CharField(max_length=100)
Expand Down