Skip to content

Commit 6028154

Browse files
committed
Make project serializer return subset of fields to authenticated users
Admin users will get an extended list of fields, for use in the build instances. Normal users get a different project serializer with limited fields.
1 parent d10c091 commit 6028154

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

readthedocs/restapi/serializers.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@ class Meta(object):
2424
'users',
2525
'canonical_url',
2626
)
27-
# Fields needed for properly passing data to the builds
28-
build_extra = (
27+
28+
29+
class ProjectSerializerFull(ProjectSerializer):
30+
31+
"""Serializer to return all Project fields, for use by builder instances"""
32+
33+
class Meta(object):
34+
model = Project
35+
# The following fields are required by builder processes
36+
fields = ProjectSerializer.Meta.fields + (
2937
'enable_epub_build',
3038
'enable_pdf_build',
3139
'conf_py_file',
@@ -41,7 +49,6 @@ class Meta(object):
4149
'requirements_file',
4250
'python_interpreter',
4351
)
44-
fields += build_extra
4552

4653

4754
class VersionSerializer(serializers.ModelSerializer):

readthedocs/restapi/views/model_views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
RelatedProjectIsOwner, IsOwner)
2323
from ..serializers import (BuildSerializerFull, BuildSerializer,
2424
BuildCommandSerializer, ProjectSerializer,
25-
VersionSerializer, DomainSerializer,
26-
RemoteOrganizationSerializer,
25+
ProjectSerializerFull, VersionSerializer,
26+
DomainSerializer, RemoteOrganizationSerializer,
2727
RemoteRepositorySerializer)
2828
from .. import utils as api_utils
2929

@@ -45,6 +45,11 @@ class ProjectViewSet(viewsets.ModelViewSet):
4545
def get_queryset(self):
4646
return self.model.objects.api(self.request.user)
4747

48+
def get_serializer_class(self):
49+
if self.request.user.is_staff:
50+
return ProjectSerializerFull
51+
return self.serializer_class
52+
4853
@decorators.detail_route()
4954
def valid_versions(self, request, **kwargs):
5055
"""Maintain state of versions that are wanted."""

readthedocs/rtd_tests/tests/test_api.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import absolute_import
2-
from builtins import str
2+
33
import json
44
import base64
55
import datetime
66

77
import mock
8+
from builtins import str
89
from django.test import TestCase
910
from django.contrib.auth.models import User
1011
from django_dynamic_fixture import get
@@ -168,6 +169,23 @@ def test_make_project(self):
168169
obj = json.loads(resp.content)
169170
self.assertEqual(obj['slug'], 'awesome-project')
170171

172+
def test_user_doesnt_get_full_api_return(self):
173+
user_normal = get(User, is_staff=False)
174+
user_admin = get(User, is_staff=True)
175+
project = get(Project, main_language_project=None, conf_py_file='foo')
176+
client = APIClient()
177+
178+
client.force_authenticate(user=user_normal)
179+
resp = client.get('/api/v2/project/%s/' % (project.pk))
180+
self.assertEqual(resp.status_code, 200)
181+
self.assertNotIn('conf_py_file', resp.data)
182+
183+
client.force_authenticate(user=user_admin)
184+
resp = client.get('/api/v2/project/%s/' % (project.pk))
185+
self.assertEqual(resp.status_code, 200)
186+
self.assertIn('conf_py_file', resp.data)
187+
self.assertEqual(resp.data['conf_py_file'], 'foo')
188+
171189
def test_invalid_make_project(self):
172190
"""
173191
Test that the authentication is turned on.

0 commit comments

Comments
 (0)