Skip to content

Commit 0d2889a

Browse files
committed
api: Add Note view and serializer
Added NoteList api. It allows the user to fetch all notes from a specific test or create a new one Added NoteDetail api. It allows the user to fetch, update and delete notes Signed-off-by: andrepapoti <andrepapoti@gmail.com>
1 parent 4e9bd76 commit 0d2889a

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

patchwork/api/note.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# Patchwork - automated patch tracking system
2+
# Copyright (C) 2024 Meta Platforms, Inc. and affiliates.
3+
#
4+
# SPDX-License-Identifier: GPL-2.0-or-later
5+
6+
7+
from rest_framework import permissions
8+
from rest_framework.generics import get_object_or_404
9+
from rest_framework.generics import CreateAPIView
10+
from rest_framework.generics import RetrieveUpdateDestroyAPIView
11+
from rest_framework.generics import ListAPIView
12+
from patchwork.api.patch import PatchSerializer
13+
from patchwork.api.user import UserDetailSerializer
14+
from patchwork.api.base import BaseHyperlinkedModelSerializer
15+
from patchwork.models import Note
16+
from patchwork.models import Patch
17+
18+
19+
class NoteSerializer(BaseHyperlinkedModelSerializer):
20+
submitter = UserDetailSerializer(read_only=True)
21+
patch = PatchSerializer(read_only=True)
22+
23+
class Meta:
24+
model = Note
25+
fields = [
26+
'id',
27+
'patch',
28+
'submitter',
29+
'content',
30+
'created_at',
31+
'updated_at',
32+
'maintainer_only',
33+
]
34+
read_only_fields = [
35+
'id',
36+
'patch',
37+
'submitter',
38+
'created_at',
39+
'updated_at',
40+
'maintainer_only',
41+
]
42+
43+
44+
class NoteDetailPermission(permissions.BasePermission):
45+
def has_permission(self, request, view):
46+
if not request.user.is_authenticated:
47+
return False
48+
49+
if request.method == 'POST':
50+
patch = Patch.objects.get(id=view.kwargs['patch_id'])
51+
return (
52+
patch.project in request.user.profile.maintainer_projects.all()
53+
)
54+
55+
note = Note.objects.get(id=view.kwargs['note_id'])
56+
return (
57+
note.patch.project
58+
in request.user.profile.maintainer_projects.all()
59+
)
60+
61+
def has_object_permission(self, request, view, obj):
62+
if (
63+
not obj.maintainer_only
64+
and request.method in permissions.SAFE_METHODS
65+
):
66+
return True
67+
68+
if request.method == 'POST':
69+
patch = Patch.objects.get(id=view.kwargs['patch_id'])
70+
return (
71+
patch.project in request.user.profile.maintainer_projects.all()
72+
)
73+
74+
note = Note.objects.get(id=view.kwargs['note_id'])
75+
return (
76+
note.patch.project
77+
in request.user.profile.maintainer_projects.all()
78+
)
79+
80+
81+
class NoteListPermission(permissions.BasePermission):
82+
def has_permission(self, request, view):
83+
if request.method in permissions.SAFE_METHODS:
84+
return True
85+
if not request.user.is_authenticated:
86+
return False
87+
patch = Patch.objects.get(id=view.kwargs['patch_id'])
88+
return patch.project in request.user.profile.maintainer_projects.all()
89+
90+
def has_object_permission(self, request, view, obj):
91+
if request.method in permissions.SAFE_METHODS:
92+
return True
93+
94+
95+
class NoteMixin(object):
96+
queryset = Note.objects.all()
97+
serializer_class = NoteSerializer
98+
lookup_field = 'patch_id'
99+
100+
def get_queryset(self):
101+
patch_id = self.kwargs['patch_id']
102+
get_object_or_404(Patch, id=patch_id)
103+
104+
return Note.objects.filter(patch=patch_id)
105+
106+
107+
class NoteDetail(NoteMixin, RetrieveUpdateDestroyAPIView):
108+
permission_classes = [NoteDetailPermission]
109+
110+
def get_object(self):
111+
queryset = self.filter_queryset(self.get_queryset())
112+
note_id = self.kwargs.get('note_id')
113+
instance = get_object_or_404(queryset, id=note_id)
114+
self.check_object_permissions(self.request, instance)
115+
return instance
116+
117+
118+
class NoteList(NoteMixin, CreateAPIView, ListAPIView):
119+
ordering = 'id'
120+
permission_classes = [NoteListPermission]
121+
122+
def get_queryset(self):
123+
patch_queryset = Patch.objects.all()
124+
125+
queryset = super().get_queryset()
126+
public_notes = queryset.filter(maintainer_only=False)
127+
user_patches = patch_queryset.filter(
128+
project__in=list(
129+
self.request.user.profile.maintainer_projects.all()
130+
)
131+
)
132+
maintainer_notes = queryset.filter(
133+
maintainer_only=True, patch__in=list(user_patches)
134+
)
135+
136+
return public_notes | maintainer_notes
137+
138+
def perform_create(self, serializer):
139+
serializer.save(
140+
submitter=self.request.user,
141+
patch=Patch.objects.get(id=self.kwargs['patch_id']),
142+
)
143+
return super().perform_create(serializer)

0 commit comments

Comments
 (0)