Merge pull request #3017 from normanjaeckel/FixViewSets
Fixed use of PATCH and PUT. Fixed #1871.
This commit is contained in:
commit
283e037cdb
@ -235,7 +235,7 @@ class AssignmentPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet)
|
|||||||
"""
|
"""
|
||||||
API endpoint for assignment polls.
|
API endpoint for assignment polls.
|
||||||
|
|
||||||
There are the following views: update and destroy.
|
There are the following views: update, partial_update and destroy.
|
||||||
"""
|
"""
|
||||||
queryset = AssignmentPoll.objects.all()
|
queryset = AssignmentPoll.objects.all()
|
||||||
serializer_class = AssignmentAllPollSerializer
|
serializer_class = AssignmentAllPollSerializer
|
||||||
|
@ -199,9 +199,7 @@ class ProjectorViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
API endpoint for the projector slide info.
|
API endpoint for the projector slide info.
|
||||||
|
|
||||||
There are the following views: metadata, list, retrieve,
|
There are the following views: See strings in check_view_permissions().
|
||||||
activate_elements, prune_elements, update_elements,
|
|
||||||
deactivate_elements, clear_elements and control_view.
|
|
||||||
"""
|
"""
|
||||||
access_permissions = ProjectorAccessPermissions()
|
access_permissions = ProjectorAccessPermissions()
|
||||||
queryset = Projector.objects.all()
|
queryset = Projector.objects.all()
|
||||||
@ -575,7 +573,7 @@ class TagViewSet(ModelViewSet):
|
|||||||
# Every authenticated user can see the metadata.
|
# Every authenticated user can see the metadata.
|
||||||
# Anonymous users can do so if they are enabled.
|
# Anonymous users can do so if they are enabled.
|
||||||
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
||||||
elif self.action in ('create', 'update', 'destroy'):
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
||||||
result = has_perm(self.request.user, 'core.can_manage_tags')
|
result = has_perm(self.request.user, 'core.can_manage_tags')
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
@ -616,7 +614,8 @@ class ConfigViewSet(ViewSet):
|
|||||||
"""
|
"""
|
||||||
API endpoint for the config.
|
API endpoint for the config.
|
||||||
|
|
||||||
There are the following views: metadata, list, retrieve and update.
|
There are the following views: metadata, list, retrieve, update and
|
||||||
|
partial_update.
|
||||||
"""
|
"""
|
||||||
access_permissions = ConfigAccessPermissions()
|
access_permissions = ConfigAccessPermissions()
|
||||||
metadata_class = ConfigMetadata
|
metadata_class = ConfigMetadata
|
||||||
@ -632,7 +631,7 @@ class ConfigViewSet(ViewSet):
|
|||||||
# retrieve the config. Anonymous users can do so if they are
|
# retrieve the config. Anonymous users can do so if they are
|
||||||
# enabled.
|
# enabled.
|
||||||
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
result = self.request.user.is_authenticated() or anonymous_is_enabled()
|
||||||
elif self.action == 'update':
|
elif self.action in ('partial_update', 'update'):
|
||||||
result = has_perm(self.request.user, 'core.can_manage_config')
|
result = has_perm(self.request.user, 'core.can_manage_config')
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
@ -742,7 +741,8 @@ class ProjectorMessageViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
API endpoint for messages.
|
API endpoint for messages.
|
||||||
|
|
||||||
There are the following views: list, retrieve, create, update and destroy.
|
There are the following views: list, retrieve, create, update,
|
||||||
|
partial_update and destroy.
|
||||||
"""
|
"""
|
||||||
access_permissions = ProjectorMessageAccessPermissions()
|
access_permissions = ProjectorMessageAccessPermissions()
|
||||||
queryset = ProjectorMessage.objects.all()
|
queryset = ProjectorMessage.objects.all()
|
||||||
@ -753,7 +753,7 @@ class ProjectorMessageViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
if self.action in ('list', 'retrieve'):
|
if self.action in ('list', 'retrieve'):
|
||||||
result = self.get_access_permissions().check_permissions(self.request.user)
|
result = self.get_access_permissions().check_permissions(self.request.user)
|
||||||
elif self.action in ('create', 'update', 'destroy'):
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
||||||
result = has_perm(self.request.user, 'core.can_manage_projector')
|
result = has_perm(self.request.user, 'core.can_manage_projector')
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
@ -764,7 +764,8 @@ class CountdownViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
API endpoint for Countdown.
|
API endpoint for Countdown.
|
||||||
|
|
||||||
There are the following views: list, retrieve, create, update and destroy.
|
There are the following views: list, retrieve, create, update,
|
||||||
|
partial_update and destroy.
|
||||||
"""
|
"""
|
||||||
access_permissions = CountdownAccessPermissions()
|
access_permissions = CountdownAccessPermissions()
|
||||||
queryset = Countdown.objects.all()
|
queryset = Countdown.objects.all()
|
||||||
@ -775,7 +776,7 @@ class CountdownViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
if self.action in ('list', 'retrieve'):
|
if self.action in ('list', 'retrieve'):
|
||||||
result = self.get_access_permissions().check_permissions(self.request.user)
|
result = self.get_access_permissions().check_permissions(self.request.user)
|
||||||
elif self.action in ('create', 'update', 'destroy'):
|
elif self.action in ('create', 'partial_update', 'update', 'destroy'):
|
||||||
result = has_perm(self.request.user, 'core.can_manage_projector')
|
result = has_perm(self.request.user, 'core.can_manage_projector')
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
|
@ -1324,7 +1324,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
// inject the changed change recommendation (copy) object back into DS store
|
// inject the changed change recommendation (copy) object back into DS store
|
||||||
MotionChangeRecommendation.inject(change);
|
MotionChangeRecommendation.inject(change);
|
||||||
// save changed change recommendation object on server
|
// save changed change recommendation object on server
|
||||||
MotionChangeRecommendation.save(change, { method: 'PATCH' }).then(
|
MotionChangeRecommendation.save(change).then(
|
||||||
function(success) {
|
function(success) {
|
||||||
$scope.closeThisDialog();
|
$scope.closeThisDialog();
|
||||||
},
|
},
|
||||||
@ -1531,7 +1531,7 @@ angular.module('OpenSlidesApp.motions.site', [
|
|||||||
// inject the changed motion (copy) object back into DS store
|
// inject the changed motion (copy) object back into DS store
|
||||||
Motion.inject(motion);
|
Motion.inject(motion);
|
||||||
// save change motion object on server
|
// save change motion object on server
|
||||||
Motion.save(motion, { method: 'PATCH' }).then(
|
Motion.save(motion).then(
|
||||||
function(success) {
|
function(success) {
|
||||||
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
|
// type: Value 1 means a non hidden agenda item, value 2 means a hidden agenda item,
|
||||||
// see openslides.agenda.models.Item.ITEM_TYPE.
|
// see openslides.agenda.models.Item.ITEM_TYPE.
|
||||||
|
@ -12,6 +12,7 @@ from rest_framework import status
|
|||||||
from ..core.config import config
|
from ..core.config import config
|
||||||
from ..utils.auth import has_perm
|
from ..utils.auth import has_perm
|
||||||
from ..utils.autoupdate import inform_changed_data
|
from ..utils.autoupdate import inform_changed_data
|
||||||
|
from ..utils.collection import CollectionElement
|
||||||
from ..utils.rest_api import (
|
from ..utils.rest_api import (
|
||||||
DestroyModelMixin,
|
DestroyModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
@ -85,13 +86,16 @@ class MotionViewSet(ModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Customized view endpoint to create a new motion.
|
Customized view endpoint to create a new motion.
|
||||||
"""
|
"""
|
||||||
# Check if parent motion exists
|
# Check if parent motion exists.
|
||||||
parent_motion = None
|
if request.data.get('parent_id') is not None:
|
||||||
if 'parent_id' in request.data:
|
|
||||||
try:
|
try:
|
||||||
parent_motion = Motion.objects.get(pk=request.data['parent_id'])
|
parent_motion = CollectionElement.from_values(
|
||||||
|
Motion.get_collection_string(),
|
||||||
|
request.data['parent_id'])
|
||||||
except Motion.DoesNotExist:
|
except Motion.DoesNotExist:
|
||||||
raise ValidationError({'detail': _('The parent motion does not exist.')})
|
raise ValidationError({'detail': _('The parent motion does not exist.')})
|
||||||
|
else:
|
||||||
|
parent_motion = None
|
||||||
|
|
||||||
# Check permission to send some data.
|
# Check permission to send some data.
|
||||||
if not has_perm(request.user, 'motions.can_manage'):
|
if not has_perm(request.user, 'motions.can_manage'):
|
||||||
@ -101,16 +105,15 @@ class MotionViewSet(ModelViewSet):
|
|||||||
'reason',
|
'reason',
|
||||||
'comments', # This is checked later.
|
'comments', # This is checked later.
|
||||||
]
|
]
|
||||||
if parent_motion: # For creating amendments.
|
if parent_motion is not None:
|
||||||
|
# For creating amendments.
|
||||||
whitelist.extend([
|
whitelist.extend([
|
||||||
'parent_id',
|
'parent_id',
|
||||||
'category_id', # This will be set to the matching
|
'category_id', # This will be set to the matching
|
||||||
'motion_block_id', # values from parent_motion.
|
'motion_block_id', # values from parent_motion.
|
||||||
])
|
])
|
||||||
request.data['category_id'] = (
|
request.data['category_id'] = parent_motion.get_full_data().get('category_id')
|
||||||
parent_motion.category.id if parent_motion.category else None)
|
request.data['motion_block_id'] = parent_motion.get_full_data().get('motion_block_id')
|
||||||
request.data['motion_block_id'] = (
|
|
||||||
parent_motion.motion_block.id if parent_motion.motion_block else None)
|
|
||||||
for key in request.data.keys():
|
for key in request.data.keys():
|
||||||
if key not in whitelist:
|
if key not in whitelist:
|
||||||
# Non-staff users are allowed to send only some data.
|
# Non-staff users are allowed to send only some data.
|
||||||
@ -155,14 +158,17 @@ class MotionViewSet(ModelViewSet):
|
|||||||
|
|
||||||
# Check permission to send only some data.
|
# Check permission to send only some data.
|
||||||
if not has_perm(request.user, 'motions.can_manage'):
|
if not has_perm(request.user, 'motions.can_manage'):
|
||||||
|
# Remove fields that the user is not allowed to change.
|
||||||
|
# The list() is required because we want to use del inside the loop.
|
||||||
|
keys = list(request.data.keys())
|
||||||
whitelist = (
|
whitelist = (
|
||||||
'title',
|
'title',
|
||||||
'text',
|
'text',
|
||||||
'reason',)
|
'reason',
|
||||||
keys = list(request.data.keys())
|
'comments', # This is checked later.
|
||||||
|
)
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if key not in whitelist:
|
if key not in whitelist:
|
||||||
# Non-staff users are allowed to send only some data. Ignore other data.
|
|
||||||
del request.data[key]
|
del request.data[key]
|
||||||
if not has_perm(request.user, 'motions.can_see_and_manage_comments'):
|
if not has_perm(request.user, 'motions.can_see_and_manage_comments'):
|
||||||
try:
|
try:
|
||||||
@ -364,7 +370,7 @@ class MotionPollViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
|
|||||||
"""
|
"""
|
||||||
API endpoint for motion polls.
|
API endpoint for motion polls.
|
||||||
|
|
||||||
There are the following views: update and destroy.
|
There are the following views: update, partial_update and destroy.
|
||||||
"""
|
"""
|
||||||
queryset = MotionPoll.objects.all()
|
queryset = MotionPoll.objects.all()
|
||||||
serializer_class = MotionPollSerializer
|
serializer_class = MotionPollSerializer
|
||||||
@ -414,7 +420,8 @@ class MotionChangeRecommendationViewSet(ModelViewSet):
|
|||||||
elif self.action == 'metadata':
|
elif self.action == 'metadata':
|
||||||
result = has_perm(self.request.user, 'motions.can_see')
|
result = has_perm(self.request.user, 'motions.can_see')
|
||||||
elif self.action in ('create', 'destroy', 'partial_update', 'update'):
|
elif self.action in ('create', 'destroy', 'partial_update', 'update'):
|
||||||
result = has_perm(self.request.user, 'motions.can_manage')
|
result = (has_perm(self.request.user, 'motions.can_see') and
|
||||||
|
has_perm(self.request.user, 'motions.can_manage'))
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
return result
|
return result
|
||||||
@ -615,6 +622,8 @@ class WorkflowViewSet(ModelViewSet):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Special API views
|
||||||
|
|
||||||
class MotionDocxTemplateView(APIView):
|
class MotionDocxTemplateView(APIView):
|
||||||
"""
|
"""
|
||||||
Returns the template for motions docx export
|
Returns the template for motions docx export
|
||||||
|
@ -10,6 +10,7 @@ class MotionViewSetCreate(TestCase):
|
|||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.request = MagicMock()
|
self.request = MagicMock()
|
||||||
|
self.request.data.get.return_value = None
|
||||||
self.view_instance = MotionViewSet()
|
self.view_instance = MotionViewSet()
|
||||||
self.view_instance.request = self.request
|
self.view_instance.request = self.request
|
||||||
self.view_instance.format_kwarg = MagicMock()
|
self.view_instance.format_kwarg = MagicMock()
|
||||||
|
Loading…
Reference in New Issue
Block a user