[PATCH 08/13] REST: Make 'User.first_name', 'last_name' editable
Stephen Finucane
stephen at that.guru
Thu Nov 17 12:39:11 AEDT 2016
These would be valuable to change via the API.
Signed-off-by: Stephen Finucane <stephen at that.guru>
Cc: Andy Doan <andy.doan at linaro.org>
---
patchwork/api/user.py | 20 ++++++++++++++++----
patchwork/tests/test_rest_api.py | 16 +++++++++++-----
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/patchwork/api/user.py b/patchwork/api/user.py
index 8fe3e74..c5f7c05 100644
--- a/patchwork/api/user.py
+++ b/patchwork/api/user.py
@@ -19,16 +19,28 @@
from django.contrib.auth.models import User
from rest_framework.generics import ListAPIView
-from rest_framework.generics import RetrieveAPIView
-from rest_framework.permissions import IsAuthenticated
+from rest_framework.generics import RetrieveUpdateAPIView
+from rest_framework import permissions
from rest_framework.serializers import HyperlinkedModelSerializer
+class IsOwnerOrReadOnly(permissions.BasePermission):
+
+ def has_object_permission(self, request, view, obj):
+ if request.method in permissions.SAFE_METHODS:
+ return True
+
+ return obj == request.user
+
+
class UserSerializer(HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'first_name', 'last_name', 'email')
+ # we don't allow updating of emails via the API, as we need to
+ # validate that the User actually owns said email first
+ read_only_fields = ('username', 'email')
extra_kwargs = {
'url': {'view_name': 'api-user-detail'},
}
@@ -37,7 +49,7 @@ class UserSerializer(HyperlinkedModelSerializer):
class UserMixin(object):
queryset = User.objects.all()
- permission_classes = (IsAuthenticated,)
+ permission_classes = (permissions.IsAuthenticated, IsOwnerOrReadOnly)
serializer_class = UserSerializer
@@ -47,7 +59,7 @@ class UserList(UserMixin, ListAPIView):
pass
-class UserDetail(UserMixin, RetrieveAPIView):
+class UserDetail(UserMixin, RetrieveUpdateAPIView):
"""Show a user."""
pass
diff --git a/patchwork/tests/test_rest_api.py b/patchwork/tests/test_rest_api.py
index e8eb71f..667f9f3 100644
--- a/patchwork/tests/test_rest_api.py
+++ b/patchwork/tests/test_rest_api.py
@@ -233,19 +233,25 @@ class TestUserAPI(APITestCase):
self.assertNotIn('password', resp.data[0])
self.assertNotIn('is_superuser', resp.data[0])
- def test_readonly(self):
+ def test_update(self):
user = create_maintainer()
user.is_superuser = True
user.save()
self.client.force_authenticate(user=user)
- resp = self.client.delete(self.api_url(1))
- self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)
+ resp = self.client.patch(self.api_url(user.id), {'first_name': 'Tan'})
+ self.assertEqual(status.HTTP_200_OK, resp.status_code)
- resp = self.client.patch(self.api_url(1), {'email': 'foo at f.com'})
+ def test_create_delete(self):
+ user = create_maintainer()
+ user.is_superuser = True
+ user.save()
+ self.client.force_authenticate(user=user)
+
+ resp = self.client.delete(self.api_url(user.id))
self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)
- resp = self.client.post(self.api_url(), {'email': 'foo at f.com'})
+ resp = self.client.post(self.api_url(user.id), {'email': 'foo at f.com'})
self.assertEqual(status.HTTP_405_METHOD_NOT_ALLOWED, resp.status_code)
--
2.7.4
More information about the Patchwork
mailing list