prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  DeviceListView permission not checked
  ### Describe the bug
  The `DeviceListView` of `api/v2` has a `IsAuthenticatedOwnerOrReadOnly` permission which is never checked as `get_object` is not used in the view.
  
  ### How to reproduce
  Steps to reproduce the behaviour:
  1. Set a breakpoint in the `IsAuthenticatedOwnerOrReadOnly` class
  2. Enable the debugger
  3. See that the `has_object_permission` method is not called on a request to the corresponding endpoint
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `website/pushnotifications/api/v2/views.py`
  Content:
  ```
  1 from django.utils.translation import get_language_from_request
  2 from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
  3 from rest_framework.filters import OrderingFilter
  4 from rest_framework.generics import (
  5     ListAPIView,
  6     RetrieveAPIView,
  7     CreateAPIView,
  8     UpdateAPIView,
  9 )
  10 
  11 from pushnotifications.api.v2.filters import CategoryFilter
  12 from pushnotifications.api.v2.permissions import IsAuthenticatedOwnerOrReadOnly
  13 from pushnotifications.api.v2.serializers import (
  14     DeviceSerializer,
  15     MessageSerializer,
  16     CategorySerializer,
  17 )
  18 from pushnotifications.models import Device, Category, Message
  19 from thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod
  20 
  21 
  22 class DeviceListView(ListAPIView, CreateAPIView):
  23     """Returns an overview of all devices that are owner by the user."""
  24 
  25     permission_classes = [
  26         IsAuthenticatedOrTokenHasScopeForMethod,
  27         IsAuthenticatedOwnerOrReadOnly,
  28     ]
  29     serializer_class = DeviceSerializer
  30     queryset = Device.objects.all()
  31     required_scopes_per_method = {
  32         "GET": ["pushnotifications:read"],
  33         "POST": ["pushnotifications:write"],
  34     }
  35 
  36     def get_queryset(self):
  37         if self.request.user:
  38             return Device.objects.filter(user=self.request.user)
  39         return super().get_queryset()
  40 
  41     def perform_create(self, serializer):
  42         language = get_language_from_request(self.request)
  43 
  44         try:
  45             serializer.instance = Device.objects.get(
  46                 user=self.request.user,
  47                 registration_id=serializer.validated_data["registration_id"],
  48             )
  49         except Device.DoesNotExist:
  50             pass
  51 
  52         data = serializer.validated_data
  53         categories = [c.pk for c in Category.objects.all()]
  54         if "receive_category" in data and len(data["receive_category"]) > 0:
  55             categories = data["receive_category"] + ["general"]
  56 
  57         serializer.save(
  58             user=self.request.user, language=language, receive_category=categories
  59         )
  60 
  61 
  62 class DeviceDetailView(RetrieveAPIView, UpdateAPIView):
  63     """Returns details of a device."""
  64 
  65     permission_classes = [
  66         IsAuthenticatedOrTokenHasScope,
  67         IsAuthenticatedOwnerOrReadOnly,
  68     ]
  69     serializer_class = DeviceSerializer
  70     required_scopes = ["pushnotifications:read", "pushnotifications:write"]
  71     queryset = Device.objects.all()
  72 
  73     def perform_update(self, serializer):
  74         serializer.save(user=self.request.user)
  75 
  76 
  77 class CategoryListView(ListAPIView):
  78     """Returns an overview of all available categories for push notifications."""
  79 
  80     serializer_class = CategorySerializer
  81     queryset = Category.objects.all()
  82     required_scopes = ["pushnotifications:read"]
  83 
  84 
  85 class MessageListView(ListAPIView):
  86     """Returns a list of message sent to the user."""
  87 
  88     serializer_class = MessageSerializer
  89     required_scopes = ["pushnotifications:read"]
  90     permission_classes = [
  91         IsAuthenticatedOrTokenHasScope,
  92     ]
  93     filter_backends = (OrderingFilter, CategoryFilter)
  94     ordering_fields = ("sent",)
  95 
  96     def get_queryset(self):
  97         if self.request.user:
  98             return Message.all_objects.filter(users=self.request.user)
  99         return Message.all_objects.all()
  100 
  101 
  102 class MessageDetailView(RetrieveAPIView):
  103     """Returns a message."""
  104 
  105     serializer_class = MessageSerializer
  106     required_scopes = ["pushnotifications:read"]
  107     permission_classes = [
  108         IsAuthenticatedOrTokenHasScope,
  109     ]
  110 
  111     def get_queryset(self):
  112         if self.request.user:
  113             return Message.all_objects.filter(users=self.request.user)
  114         return Message.all_objects.all()
  115
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/website/pushnotifications/api/v2/views.py b/website/pushnotifications/api/v2/views.py
  --- a/website/pushnotifications/api/v2/views.py
  +++ b/website/pushnotifications/api/v2/views.py
  @@ -22,10 +22,7 @@
   class DeviceListView(ListAPIView, CreateAPIView):
       """Returns an overview of all devices that are owner by the user."""
   
  -    permission_classes = [
  -        IsAuthenticatedOrTokenHasScopeForMethod,
  -        IsAuthenticatedOwnerOrReadOnly,
  -    ]
  +    permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]
       serializer_class = DeviceSerializer
       queryset = Device.objects.all()
       required_scopes_per_method = {
  
verification_info: {"golden_diff": "diff --git a/website/pushnotifications/api/v2/views.py b/website/pushnotifications/api/v2/views.py\n--- a/website/pushnotifications/api/v2/views.py\n+++ b/website/pushnotifications/api/v2/views.py\n@@ -22,10 +22,7 @@\n class DeviceListView(ListAPIView, CreateAPIView):\n     \"\"\"Returns an overview of all devices that are owner by the user.\"\"\"\n \n-    permission_classes = [\n-        IsAuthenticatedOrTokenHasScopeForMethod,\n-        IsAuthenticatedOwnerOrReadOnly,\n-    ]\n+    permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]\n     serializer_class = DeviceSerializer\n     queryset = Device.objects.all()\n     required_scopes_per_method = {\n", "issue": "DeviceListView permission not checked\n### Describe the bug\r\nThe `DeviceListView` of `api/v2` has a `IsAuthenticatedOwnerOrReadOnly` permission which is never checked as `get_object` is not used in the view.\r\n\r\n### How to reproduce\r\nSteps to reproduce the behaviour:\r\n1. Set a breakpoint in the `IsAuthenticatedOwnerOrReadOnly` class\r\n2. Enable the debugger\r\n3. See that the `has_object_permission` method is not called on a request to the corresponding endpoint\r\n\n", "before_files": [{"content": "from django.utils.translation import get_language_from_request\nfrom oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework.filters import OrderingFilter\nfrom rest_framework.generics import (\n    ListAPIView,\n    RetrieveAPIView,\n    CreateAPIView,\n    UpdateAPIView,\n)\n\nfrom pushnotifications.api.v2.filters import CategoryFilter\nfrom pushnotifications.api.v2.permissions import IsAuthenticatedOwnerOrReadOnly\nfrom pushnotifications.api.v2.serializers import (\n    DeviceSerializer,\n    MessageSerializer,\n    CategorySerializer,\n)\nfrom pushnotifications.models import Device, Category, Message\nfrom thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod\n\n\nclass DeviceListView(ListAPIView, CreateAPIView):\n    \"\"\"Returns an overview of all devices that are owner by the user.\"\"\"\n\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScopeForMethod,\n        IsAuthenticatedOwnerOrReadOnly,\n    ]\n    serializer_class = DeviceSerializer\n    queryset = Device.objects.all()\n    required_scopes_per_method = {\n        \"GET\": [\"pushnotifications:read\"],\n        \"POST\": [\"pushnotifications:write\"],\n    }\n\n    def get_queryset(self):\n        if self.request.user:\n            return Device.objects.filter(user=self.request.user)\n        return super().get_queryset()\n\n    def perform_create(self, serializer):\n        language = get_language_from_request(self.request)\n\n        try:\n            serializer.instance = Device.objects.get(\n                user=self.request.user,\n                registration_id=serializer.validated_data[\"registration_id\"],\n            )\n        except Device.DoesNotExist:\n            pass\n\n        data = serializer.validated_data\n        categories = [c.pk for c in Category.objects.all()]\n        if \"receive_category\" in data and len(data[\"receive_category\"]) > 0:\n            categories = data[\"receive_category\"] + [\"general\"]\n\n        serializer.save(\n            user=self.request.user, language=language, receive_category=categories\n        )\n\n\nclass DeviceDetailView(RetrieveAPIView, UpdateAPIView):\n    \"\"\"Returns details of a device.\"\"\"\n\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        IsAuthenticatedOwnerOrReadOnly,\n    ]\n    serializer_class = DeviceSerializer\n    required_scopes = [\"pushnotifications:read\", \"pushnotifications:write\"]\n    queryset = Device.objects.all()\n\n    def perform_update(self, serializer):\n        serializer.save(user=self.request.user)\n\n\nclass CategoryListView(ListAPIView):\n    \"\"\"Returns an overview of all available categories for push notifications.\"\"\"\n\n    serializer_class = CategorySerializer\n    queryset = Category.objects.all()\n    required_scopes = [\"pushnotifications:read\"]\n\n\nclass MessageListView(ListAPIView):\n    \"\"\"Returns a list of message sent to the user.\"\"\"\n\n    serializer_class = MessageSerializer\n    required_scopes = [\"pushnotifications:read\"]\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n    ]\n    filter_backends = (OrderingFilter, CategoryFilter)\n    ordering_fields = (\"sent\",)\n\n    def get_queryset(self):\n        if self.request.user:\n            return Message.all_objects.filter(users=self.request.user)\n        return Message.all_objects.all()\n\n\nclass MessageDetailView(RetrieveAPIView):\n    \"\"\"Returns a message.\"\"\"\n\n    serializer_class = MessageSerializer\n    required_scopes = [\"pushnotifications:read\"]\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n    ]\n\n    def get_queryset(self):\n        if self.request.user:\n            return Message.all_objects.filter(users=self.request.user)\n        return Message.all_objects.all()\n", "path": "website/pushnotifications/api/v2/views.py"}], "after_files": [{"content": "from django.utils.translation import get_language_from_request\nfrom oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework.filters import OrderingFilter\nfrom rest_framework.generics import (\n    ListAPIView,\n    RetrieveAPIView,\n    CreateAPIView,\n    UpdateAPIView,\n)\n\nfrom pushnotifications.api.v2.filters import CategoryFilter\nfrom pushnotifications.api.v2.permissions import IsAuthenticatedOwnerOrReadOnly\nfrom pushnotifications.api.v2.serializers import (\n    DeviceSerializer,\n    MessageSerializer,\n    CategorySerializer,\n)\nfrom pushnotifications.models import Device, Category, Message\nfrom thaliawebsite.api.v2.permissions import IsAuthenticatedOrTokenHasScopeForMethod\n\n\nclass DeviceListView(ListAPIView, CreateAPIView):\n    \"\"\"Returns an overview of all devices that are owner by the user.\"\"\"\n\n    permission_classes = [IsAuthenticatedOrTokenHasScopeForMethod]\n    serializer_class = DeviceSerializer\n    queryset = Device.objects.all()\n    required_scopes_per_method = {\n        \"GET\": [\"pushnotifications:read\"],\n        \"POST\": [\"pushnotifications:write\"],\n    }\n\n    def get_queryset(self):\n        if self.request.user:\n            return Device.objects.filter(user=self.request.user)\n        return super().get_queryset()\n\n    def perform_create(self, serializer):\n        language = get_language_from_request(self.request)\n\n        try:\n            serializer.instance = Device.objects.get(\n                user=self.request.user,\n                registration_id=serializer.validated_data[\"registration_id\"],\n            )\n        except Device.DoesNotExist:\n            pass\n\n        data = serializer.validated_data\n        categories = [c.pk for c in Category.objects.all()]\n        if \"receive_category\" in data and len(data[\"receive_category\"]) > 0:\n            categories = data[\"receive_category\"] + [\"general\"]\n\n        serializer.save(\n            user=self.request.user, language=language, receive_category=categories\n        )\n\n\nclass DeviceDetailView(RetrieveAPIView, UpdateAPIView):\n    \"\"\"Returns details of a device.\"\"\"\n\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n        IsAuthenticatedOwnerOrReadOnly,\n    ]\n    serializer_class = DeviceSerializer\n    required_scopes = [\"pushnotifications:read\", \"pushnotifications:write\"]\n    queryset = Device.objects.all()\n\n    def perform_update(self, serializer):\n        serializer.save(user=self.request.user)\n\n\nclass CategoryListView(ListAPIView):\n    \"\"\"Returns an overview of all available categories for push notifications.\"\"\"\n\n    serializer_class = CategorySerializer\n    queryset = Category.objects.all()\n    required_scopes = [\"pushnotifications:read\"]\n\n\nclass MessageListView(ListAPIView):\n    \"\"\"Returns a list of message sent to the user.\"\"\"\n\n    serializer_class = MessageSerializer\n    required_scopes = [\"pushnotifications:read\"]\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n    ]\n    filter_backends = (OrderingFilter, CategoryFilter)\n    ordering_fields = (\"sent\",)\n\n    def get_queryset(self):\n        if self.request.user:\n            return Message.all_objects.filter(users=self.request.user)\n        return Message.all_objects.all()\n\n\nclass MessageDetailView(RetrieveAPIView):\n    \"\"\"Returns a message.\"\"\"\n\n    serializer_class = MessageSerializer\n    required_scopes = [\"pushnotifications:read\"]\n    permission_classes = [\n        IsAuthenticatedOrTokenHasScope,\n    ]\n\n    def get_queryset(self):\n        if self.request.user:\n            return Message.all_objects.filter(users=self.request.user)\n        return Message.all_objects.all()\n", "path": "website/pushnotifications/api/v2/views.py"}]}