Corrected create permissions for ExperimentData create endpoint
This commit is contained in:
committed by
Clinton Blackburn
parent
e71f1afdf3
commit
a42264715b
@@ -10,5 +10,5 @@ class ExperimentDataFactory(factory.DjangoModelFactory):
|
||||
|
||||
user = factory.SubFactory(UserFactory)
|
||||
experiment_id = factory.fuzzy.FuzzyInteger(0)
|
||||
key = factory.Faker('word')
|
||||
key = factory.Sequence(lambda n: n)
|
||||
value = factory.Faker('word')
|
||||
|
||||
@@ -8,5 +8,12 @@ class IsStaffOrOwner(permissions.IsStaffOrOwner):
|
||||
"""
|
||||
|
||||
def has_permission(self, request, view):
|
||||
# Staff users can create data for anyone.
|
||||
# Non-staff users can only create data for themselves.
|
||||
if view.action == 'create':
|
||||
username = request.user.username
|
||||
return super(IsStaffOrOwner, self).has_permission(request, view) or (
|
||||
username == request.data.get('user', username))
|
||||
|
||||
# The view will handle filtering for the current user
|
||||
return True
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from rest_framework import serializers
|
||||
|
||||
from .models import ExperimentData
|
||||
|
||||
User = get_user_model() # pylint:disable=invalid-name
|
||||
|
||||
|
||||
class ExperimentDataCreateSerializer(serializers.ModelSerializer):
|
||||
user = serializers.SlugRelatedField(slug_field='username', default=serializers.CurrentUserDefault(), required=False,
|
||||
queryset=User.objects.all())
|
||||
|
||||
class Meta(object):
|
||||
model = ExperimentData
|
||||
fields = ('id', 'experiment_id', 'user', 'key', 'value', 'created', 'modified',)
|
||||
|
||||
|
||||
class ExperimentDataSerializer(serializers.ModelSerializer):
|
||||
user = serializers.SlugRelatedField(read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
|
||||
|
||||
class Meta(object):
|
||||
model = ExperimentData
|
||||
fields = ('id', 'experiment_id', 'user', 'key', 'value', 'created', 'modified',)
|
||||
class Meta(ExperimentDataCreateSerializer.Meta):
|
||||
read_only_fields = ('user',)
|
||||
|
||||
@@ -96,8 +96,32 @@ class ExperimentDataViewSetTests(APITestCase):
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
self.assert_data_created_for_user(UserFactory())
|
||||
self.assert_data_created_for_user(UserFactory())
|
||||
user = UserFactory()
|
||||
data = {
|
||||
'experiment_id': 1,
|
||||
'key': 'foo',
|
||||
'value': 'bar',
|
||||
}
|
||||
self.client.login(username=user.username, password=UserFactory._DEFAULT_PASSWORD)
|
||||
|
||||
# Users can create data for themselves
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 201)
|
||||
ExperimentData.objects.get(user=user)
|
||||
|
||||
# A non-staff user cannot create data for another user
|
||||
other_user = UserFactory()
|
||||
data['user'] = other_user.username
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertFalse(ExperimentData.objects.filter(user=other_user).exists())
|
||||
|
||||
# A staff user can create data for other users
|
||||
user.is_staff = True
|
||||
user.save()
|
||||
response = self.client.post(url, data)
|
||||
self.assertEqual(response.status_code, 201)
|
||||
ExperimentData.objects.get(user=other_user)
|
||||
|
||||
def test_put_as_create(self):
|
||||
""" Users should be able to use PUT to create new data. """
|
||||
|
||||
@@ -5,7 +5,7 @@ from rest_framework.filters import DjangoFilterBackend
|
||||
from experiments import filters
|
||||
from experiments.models import ExperimentData
|
||||
from experiments.permissions import IsStaffOrOwner
|
||||
from experiments.serializers import ExperimentDataSerializer
|
||||
from experiments.serializers import ExperimentDataCreateSerializer, ExperimentDataSerializer
|
||||
from openedx.core.lib.api.authentication import SessionAuthenticationAllowInactiveUser
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
queryset = queryset.filter(user=self.request.user)
|
||||
return super(ExperimentDataViewSet, self).filter_queryset(queryset)
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action == 'create':
|
||||
return ExperimentDataCreateSerializer
|
||||
return ExperimentDataSerializer
|
||||
|
||||
def create_or_update(self, request, *args, **kwargs):
|
||||
# If we have a primary key, treat this as a regular update request
|
||||
if self.kwargs.get('pk'):
|
||||
@@ -40,4 +45,5 @@ class ExperimentDataViewSet(viewsets.ModelViewSet):
|
||||
except ExperimentData.DoesNotExist:
|
||||
pass
|
||||
|
||||
self.action = 'create'
|
||||
return self.create(request, *args, **kwargs)
|
||||
|
||||
Reference in New Issue
Block a user