Skip to content

Commit a9541d6

Browse files
andrepapotivictor-accarini
authored andcommitted
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 <[email protected]>
1 parent cb13754 commit a9541d6

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

patchwork/api/note.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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 request.user.is_superuser:
47+
return True
48+
49+
if request.method == 'POST':
50+
if not request.user.is_authenticated:
51+
return False
52+
53+
patch = Patch.objects.get(id=view.kwargs['patch_id'])
54+
return (
55+
patch.project in request.user.profile.maintainer_projects.all()
56+
)
57+
58+
note = Note.objects.get(id=view.kwargs['note_id'])
59+
if not note.maintainer_only:
60+
return True
61+
elif not request.user.is_authenticated:
62+
return False
63+
64+
return (
65+
note.patch.project
66+
in request.user.profile.maintainer_projects.all()
67+
)
68+
69+
def has_object_permission(self, request, view, obj):
70+
if request.user.is_superuser:
71+
return True
72+
73+
if (
74+
not obj.maintainer_only
75+
and request.method in permissions.SAFE_METHODS
76+
):
77+
return True
78+
79+
if request.method == 'POST':
80+
return (
81+
obj.patch.project in request.user.profile.maintainer_projects.all()
82+
)
83+
84+
return (
85+
obj.patch.project
86+
in request.user.profile.maintainer_projects.all()
87+
)
88+
89+
90+
class NoteListPermission(permissions.BasePermission):
91+
def has_permission(self, request, view):
92+
if request.method in permissions.SAFE_METHODS:
93+
return True
94+
if not request.user.is_authenticated:
95+
return False
96+
patch = Patch.objects.get(id=view.kwargs['patch_id'])
97+
return patch.project in request.user.profile.maintainer_projects.all()
98+
99+
def has_object_permission(self, request, view, obj):
100+
if request.method in permissions.SAFE_METHODS:
101+
return True
102+
103+
104+
class NoteMixin(object):
105+
queryset = Note.objects.all()
106+
serializer_class = NoteSerializer
107+
108+
def get_queryset(self):
109+
patch_id = self.kwargs['patch_id']
110+
patch = get_object_or_404(Patch, id=patch_id)
111+
112+
return patch.notes
113+
114+
115+
class NoteDetail(NoteMixin, RetrieveUpdateDestroyAPIView):
116+
permission_classes = [NoteDetailPermission]
117+
118+
def get_object(self):
119+
queryset = self.filter_queryset(self.get_queryset())
120+
note_id = self.kwargs.get('note_id')
121+
instance = get_object_or_404(queryset, id=note_id)
122+
self.check_object_permissions(self.request, instance)
123+
return instance
124+
125+
126+
class NoteList(NoteMixin, CreateAPIView, ListAPIView):
127+
ordering = 'id'
128+
permission_classes = [NoteListPermission]
129+
130+
def get_queryset(self):
131+
user = self.request.user
132+
patch_id = self.kwargs['patch_id']
133+
134+
queryset = super().get_queryset()
135+
public_notes = queryset.filter(maintainer_only=False)
136+
is_maintainer = user.is_authenticated and \
137+
get_object_or_404(Patch, id=patch_id).project \
138+
in user.profile.maintainer_projects.all()
139+
140+
maintainer_notes = queryset.none()
141+
if user.is_superuser or (user.is_authenticated and is_maintainer):
142+
maintainer_notes = queryset.filter(maintainer_only=True)
143+
144+
return public_notes | maintainer_notes
145+
146+
def perform_create(self, serializer):
147+
serializer.save(
148+
submitter=self.request.user,
149+
patch=Patch.objects.get(id=self.kwargs['patch_id']),
150+
)
151+
return super().perform_create(serializer)

0 commit comments

Comments
 (0)