Skip to content

Commit b255f78

Browse files
authored
Merge pull request from GHSA-rqfv-8rrx-prmh
Ref GHSA-rqfv-8rrx-prmh
1 parent 0957dac commit b255f78

File tree

3 files changed

+410
-139
lines changed

3 files changed

+410
-139
lines changed

readthedocs/api/v2/permissions.py

-24
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,6 @@ def has_object_permission(self, request, view, obj):
3838
)
3939

4040

41-
class APIPermission(permissions.IsAuthenticatedOrReadOnly):
42-
43-
"""
44-
Control users access to the API.
45-
46-
This permission should allow authenticated users readonly access to the API,
47-
and allow admin users write access. This should be used on API resources
48-
that need to implement write operations to resources that were based on the
49-
ReadOnlyViewSet
50-
"""
51-
52-
def has_permission(self, request, view):
53-
has_perm = super().has_permission(request, view)
54-
return has_perm or (request.user and request.user.is_staff)
55-
56-
def has_object_permission(self, request, view, obj):
57-
has_perm = super().has_object_permission(
58-
request,
59-
view,
60-
obj,
61-
)
62-
return has_perm or (request.user and request.user.is_staff)
63-
64-
6541
class APIRestrictedPermission(permissions.BasePermission):
6642

6743
"""

readthedocs/api/v2/views/model_views.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from django.shortcuts import get_object_or_404
1010
from django.template.loader import render_to_string
1111
from rest_framework import decorators, permissions, status, viewsets
12+
from rest_framework.mixins import CreateModelMixin, UpdateModelMixin
1213
from rest_framework.parsers import JSONParser, MultiPartParser
1314
from rest_framework.renderers import BaseRenderer, JSONRenderer
1415
from rest_framework.response import Response
@@ -21,7 +22,7 @@
2122
from readthedocs.projects.models import Domain, Project
2223
from readthedocs.storage import build_commands_storage
2324

24-
from ..permissions import APIPermission, APIRestrictedPermission, IsOwner
25+
from ..permissions import APIRestrictedPermission, IsOwner
2526
from ..serializers import (
2627
BuildAdminReadOnlySerializer,
2728
BuildAdminSerializer,
@@ -117,14 +118,17 @@ def list(self, *args, **kwargs):
117118
)
118119

119120

120-
class UserSelectViewSet(viewsets.ModelViewSet):
121+
class UserSelectViewSet(viewsets.ReadOnlyModelViewSet):
121122

122123
"""
123124
View set that varies serializer class based on request user credentials.
124125
125126
Viewsets using this class should have an attribute `admin_serializer_class`,
126127
which is a serializer that might have more fields that only admin/staff
127128
users require. If the user is staff, this class will be returned instead.
129+
130+
By default read-only endpoints will be allowed,
131+
to allow write endpoints, inherit from the proper ``rest_framework.mixins.*`` classes.
128132
"""
129133

130134
def get_serializer_class(self):
@@ -143,11 +147,11 @@ def get_queryset(self):
143147
return self.model.objects.api(self.request.user)
144148

145149

146-
class ProjectViewSet(DisableListEndpoint, UserSelectViewSet):
150+
class ProjectViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):
147151

148152
"""List, filter, etc, Projects."""
149153

150-
permission_classes = [APIPermission]
154+
permission_classes = [APIRestrictedPermission]
151155
renderer_classes = (JSONRenderer,)
152156
serializer_class = ProjectSerializer
153157
admin_serializer_class = ProjectAdminSerializer
@@ -196,7 +200,7 @@ def canonical_url(self, request, **kwargs):
196200
})
197201

198202

199-
class VersionViewSet(DisableListEndpoint, UserSelectViewSet):
203+
class VersionViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):
200204

201205
permission_classes = [APIRestrictedPermission]
202206
renderer_classes = (JSONRenderer,)
@@ -209,7 +213,7 @@ class VersionViewSet(DisableListEndpoint, UserSelectViewSet):
209213
)
210214

211215

212-
class BuildViewSet(DisableListEndpoint, UserSelectViewSet):
216+
class BuildViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):
213217
permission_classes = [APIRestrictedPermission]
214218
renderer_classes = (JSONRenderer, PlainTextBuildRenderer)
215219
model = Build
@@ -297,7 +301,7 @@ def reset(self, request, **kwargs):
297301
return Response(status=status.HTTP_204_NO_CONTENT)
298302

299303

300-
class BuildCommandViewSet(DisableListEndpoint, UserSelectViewSet):
304+
class BuildCommandViewSet(DisableListEndpoint, CreateModelMixin, UserSelectViewSet):
301305
parser_classes = [JSONParser, MultiPartParser]
302306
permission_classes = [APIRestrictedPermission]
303307
renderer_classes = (JSONRenderer,)

0 commit comments

Comments
 (0)