Skip to content

Commit

Permalink
Make permissions class more modular
Browse files Browse the repository at this point in the history
  • Loading branch information
humitos committed Jun 27, 2019
1 parent 06e9370 commit ed42f57
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
45 changes: 25 additions & 20 deletions readthedocs/api/v3/permissions.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework.permissions import BasePermission


class PublicDetailPrivateListing(IsAuthenticated):
class PublicDetailPrivateListing(BasePermission):

"""
Permission class for our custom use case.
* Always give permission for a ``detail`` request
* Only give permission for ``listing`` request if user is admin of the project
"""

def has_permission(self, request, view):
if view.detail:
return True

project = view._get_parent_project()
if view.has_admin_permission(request.user, project):
return True


class ListCreateProject(BasePermission):

"""
Permission class to grant projects listing and project creation.
* Allow access to ``/projects`` (user's projects listing)
"""

def has_permission(self, request, view):
is_authenticated = super().has_permission(request, view)
if is_authenticated:
if view.basename == 'projects' and any([
view.action == 'list',
view.action == 'create', # used to create Form in BrowsableAPIRenderer
view.action is None, # needed for BrowsableAPIRenderer
]):
# hitting ``/projects/``, allowing
return True

if view.detail:
return True

project = view._get_parent_project()
if view.has_admin_permission(request.user, project):
return True

return False
if view.basename == 'projects' and any([
view.action == 'list',
view.action == 'create', # used to create Form in BrowsableAPIRenderer
view.action is None, # needed for BrowsableAPIRenderer
]):
# hitting ``/projects/``, allowing
return True
5 changes: 3 additions & 2 deletions readthedocs/api/v3/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
UpdateModelMixin,
)
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.response import Response
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
Expand All @@ -25,7 +26,7 @@

from .filters import BuildFilter, ProjectFilter, VersionFilter
from .mixins import ProjectQuerySetMixin
from .permissions import PublicDetailPrivateListing
from .permissions import PublicDetailPrivateListing, ListCreateProject
from .renderers import AlphabeticalSortedJSONRenderer
from .serializers import (
BuildCreateSerializer,
Expand Down Expand Up @@ -54,7 +55,7 @@ class APIv3Settings:
# Using only ``TokenAuthentication`` for now, so we can give access to
# specific carefully selected users only
authentication_classes = (TokenAuthentication,)
permission_classes = (PublicDetailPrivateListing,)
permission_classes = (IsAuthenticated & (ListCreateProject | PublicDetailPrivateListing),)

pagination_class = LimitOffsetPagination
LimitOffsetPagination.default_limit = 10
Expand Down

0 comments on commit ed42f57

Please sign in to comment.