Skip to content

Commit

Permalink
Merge pull request from GHSA-rqfv-8rrx-prmh
Browse files Browse the repository at this point in the history
  • Loading branch information
stsewd committed May 30, 2023
1 parent 0957dac commit b255f78
Show file tree
Hide file tree
Showing 3 changed files with 410 additions and 139 deletions.
24 changes: 0 additions & 24 deletions readthedocs/api/v2/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,6 @@ def has_object_permission(self, request, view, obj):
)


class APIPermission(permissions.IsAuthenticatedOrReadOnly):

"""
Control users access to the API.
This permission should allow authenticated users readonly access to the API,
and allow admin users write access. This should be used on API resources
that need to implement write operations to resources that were based on the
ReadOnlyViewSet
"""

def has_permission(self, request, view):
has_perm = super().has_permission(request, view)
return has_perm or (request.user and request.user.is_staff)

def has_object_permission(self, request, view, obj):
has_perm = super().has_object_permission(
request,
view,
obj,
)
return has_perm or (request.user and request.user.is_staff)


class APIRestrictedPermission(permissions.BasePermission):

"""
Expand Down
18 changes: 11 additions & 7 deletions readthedocs/api/v2/views/model_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string
from rest_framework import decorators, permissions, status, viewsets
from rest_framework.mixins import CreateModelMixin, UpdateModelMixin
from rest_framework.parsers import JSONParser, MultiPartParser
from rest_framework.renderers import BaseRenderer, JSONRenderer
from rest_framework.response import Response
Expand All @@ -21,7 +22,7 @@
from readthedocs.projects.models import Domain, Project
from readthedocs.storage import build_commands_storage

from ..permissions import APIPermission, APIRestrictedPermission, IsOwner
from ..permissions import APIRestrictedPermission, IsOwner
from ..serializers import (
BuildAdminReadOnlySerializer,
BuildAdminSerializer,
Expand Down Expand Up @@ -117,14 +118,17 @@ def list(self, *args, **kwargs):
)


class UserSelectViewSet(viewsets.ModelViewSet):
class UserSelectViewSet(viewsets.ReadOnlyModelViewSet):

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

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


class ProjectViewSet(DisableListEndpoint, UserSelectViewSet):
class ProjectViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):

"""List, filter, etc, Projects."""

permission_classes = [APIPermission]
permission_classes = [APIRestrictedPermission]
renderer_classes = (JSONRenderer,)
serializer_class = ProjectSerializer
admin_serializer_class = ProjectAdminSerializer
Expand Down Expand Up @@ -196,7 +200,7 @@ def canonical_url(self, request, **kwargs):
})


class VersionViewSet(DisableListEndpoint, UserSelectViewSet):
class VersionViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):

permission_classes = [APIRestrictedPermission]
renderer_classes = (JSONRenderer,)
Expand All @@ -209,7 +213,7 @@ class VersionViewSet(DisableListEndpoint, UserSelectViewSet):
)


class BuildViewSet(DisableListEndpoint, UserSelectViewSet):
class BuildViewSet(DisableListEndpoint, UpdateModelMixin, UserSelectViewSet):
permission_classes = [APIRestrictedPermission]
renderer_classes = (JSONRenderer, PlainTextBuildRenderer)
model = Build
Expand Down Expand Up @@ -297,7 +301,7 @@ def reset(self, request, **kwargs):
return Response(status=status.HTTP_204_NO_CONTENT)


class BuildCommandViewSet(DisableListEndpoint, UserSelectViewSet):
class BuildCommandViewSet(DisableListEndpoint, CreateModelMixin, UserSelectViewSet):
parser_classes = [JSONParser, MultiPartParser]
permission_classes = [APIRestrictedPermission]
renderer_classes = (JSONRenderer,)
Expand Down

0 comments on commit b255f78

Please sign in to comment.