diff -r 23416a833ca8 -r f3875fbe206a server/python/django2/renkanmanager/api/views.py --- a/server/python/django2/renkanmanager/api/views.py Wed Jun 15 16:31:43 2016 +0200 +++ b/server/python/django2/renkanmanager/api/views.py Mon Jun 20 14:44:40 2016 +0200 @@ -10,6 +10,7 @@ import uuid from django.db import transaction +from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.http import Http404 from django.http.response import HttpResponse, HttpResponseBadRequest @@ -41,32 +42,52 @@ def post(self, request, workspace_guid='', format=None): create_data = {key:request.data[key] for key in request.data.keys()} - source_renkan_guid = request.GET.get("source_renkan_id", request.data.get("source_renkan_id", None)) - source_revision_guid = request.GET.get("source_revision_id", request.data.get("source_revision_id", None)) + logger.debug("HELLO %r", create_data) + + source_renkan_guid_str = request.GET.get("source_renkan_id", request.data.get("source_renkan_id", None)) + source_revision_guid_str = request.GET.get("source_revision_id", request.data.get("source_revision_id", None)) + try: + source_renkan_guid = source_renkan_guid_str and uuid.UUID(source_renkan_guid_str) or None + source_revision_guid = source_revision_guid_str and uuid.UUID(source_revision_guid_str) or None + except ValueError: + return Response({'detail': 'Source renkan guid %s or source revision guid %s not correctly formatted'%(source_revision_guid_str, source_revision_guid_str)}, status=status.HTTP_400_BAD_REQUEST) + + source_revision = None if source_renkan_guid is not None: try: source_renkan=Renkan.objects.get(renkan_guid=source_renkan_guid) except Renkan.DoesNotExist: - return Response({'detail': 'Source renkan '+source_renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) - source_revision_guid = source_renkan.current_revision.revision_guid - if source_revision_guid is not None: + return Response({'detail': 'Source renkan %s does not exist'%source_renkan_guid}, status=status.HTTP_404_NOT_FOUND) + source_revision = source_renkan.current_revision + elif source_revision_guid is not None: try: source_revision=Revision.objects.get(revision_guid=source_revision_guid) except Revision.DoesNotExist: - return Response({'detail': 'Source revision '+source_revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Source revision %s does not exist'%source_revision_guid}, status=status.HTTP_404_NOT_FOUND) + + if source_revision: create_data["source_revision_id"] = source_revision.revision_guid create_data["title"] = request.data.get("title", source_revision.title) create_data["content"] = source_revision.content - if workspace_guid: + logger.debug("SOURCE_REVISION CONTENT %r", create_data["content"]) + + try: + workspace_guid_uuid = workspace_guid and uuid.UUID(workspace_guid) or None + except ValueError: + return Response({'detail': 'workspace guid %r not correctly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST) + + if workspace_guid_uuid: try: - workspace = Workspace.objects.get(workspace_guid=workspace_guid) + workspace = Workspace.objects.get(workspace_guid=workspace_guid_uuid) except Workspace.DoesNotExist: return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) create_data["workspace_id"] = workspace_guid serializer = RenkanSerializer(data=create_data) + logger.debug("BEFORE SERIALIZER VALID %r", create_data) if serializer.is_valid(): creator = request.user if request.user and not request.user.is_anonymous() else None serializer.save(creator=creator) + logger.debug("AFTER SAVE SERIALIZER DATA %r", serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, content_type='application/json') return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -79,7 +100,11 @@ queryset = Renkan.objects def get_object(self, renkan_guid): - return self.queryset.get(renkan_guid=renkan_guid) + try: + renkan_uuid = uuid.UUID(renkan_guid) + except: + raise ValueError('renkan guid %r bad format'%renkan_guid) + return self.queryset.get(renkan_guid=renkan_uuid) def dispatch(self, *args, **kwargs): return super(RenkanDetail, self).dispatch(*args, **kwargs) @@ -87,8 +112,11 @@ def get(self, request, renkan_guid, format=None): try: renkan = self.get_object(renkan_guid=renkan_guid) + except ValueError: + return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST) except Renkan.DoesNotExist: - return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND) + self.check_object_permissions(request, renkan) serializer = RenkanSerializer(renkan) if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()): @@ -98,8 +126,10 @@ def put(self, request, renkan_guid, format=None): try: renkan = self.get_object(renkan_guid=renkan_guid) + except ValueError: + return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST) except Renkan.DoesNotExist: - return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND) logger.debug("RENKAN PUT %r : CHECKING OBJECT PERMISSION", renkan_guid) logger.debug("RENKAN PUT: permission? %r", request.user.has_perm("change_renkan", renkan)) self.check_object_permissions(request, renkan) @@ -117,6 +147,7 @@ serializer.save(updator=request.user) if {'true': True, 'false': False, "0": False, "1": True}.get(request.GET.get("content_only", "false").lower()): return Response(json.loads(serializer.data["content"]), status=status.HTTP_200_OK, content_type='application/json') + logger.debug("RENKAN PUT: SERIALIZER DATA %r", serializer.data) return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json') return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -124,8 +155,10 @@ def delete(self, request, renkan_guid, format=None): try: to_delete_renkan = self.get_object(renkan_guid=renkan_guid) + except ValueError: + return Response({'detail': 'Renkan project %r guid badly formatted'%renkan_guid}, status=status.HTTP_400_BAD_REQUEST) except Renkan.DoesNotExist: - return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Renkan project %r does not exist'%renkan_guid}, status=status.HTTP_404_NOT_FOUND) self.check_object_permissions(request, to_delete_renkan) to_delete_renkan.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -159,13 +192,22 @@ queryset = Workspace.objects def get_object(self, workspace_guid): - return self.queryset.get(workspace_guid=workspace_guid) + try: + workspace_uuid = uuid.UUID(workspace_guid) + except: + raise ValueError('workspace guid %r bad format'%workspace_guid) + + return self.queryset.get(workspace_guid=workspace_uuid) def get(self, request, workspace_guid, format=None): try: workspace = self.get_object(workspace_guid=workspace_guid) + except ValueError: + return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST) except Workspace.DoesNotExist: - return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND) + + self.check_object_permissions(request, workspace) serializer = WorkspaceSerializer(workspace) return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json') @@ -173,8 +215,11 @@ def put(self, request, workspace_guid, format=None): try: workspace = self.get_object(workspace_guid=workspace_guid) + except ValueError: + return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST) except Workspace.DoesNotExist: - return Response({'detail': 'Workspace '+workspace_guid+' does not exist.'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND) + self.check_object_permissions(request, workspace) serializer = WorkspaceSerializer(workspace, data=request.data) if serializer.is_valid(): @@ -185,8 +230,11 @@ def delete(self, request, workspace_guid, format=None): try: to_delete_workspace = self.get_object(workspace_guid=workspace_guid) + except ValueError: + return Response({'detail': 'Workspace %r guid badly formatted'%workspace_guid}, status=status.HTTP_400_BAD_REQUEST) except Workspace.DoesNotExist: - return Response({'detail': 'Workspace '+workspace_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Workspace %r does not exist.'%workspace_guid}, status=status.HTTP_404_NOT_FOUND) + self.check_object_permissions(request, to_delete_workspace) if to_delete_workspace.renkan_count != 0: return Response({'detail': 'Workspace '+workspace_guid+' cannot be deleted because it is not empty'}, status=status.HTTP_400_BAD_REQUEST) @@ -219,31 +267,56 @@ lookup_field = "revision_guid" def get_queryset(self, renkan_guid=""): - if renkan_guid: - return Revision.objects.filter(parent_renkan__renkan_guid=renkan_guid) + try: + renkan_uuid = renkan_guid and uuid.UUID(renkan_guid) + except: + raise ValueError("renkan guid %r not correctly formatted"%renkan_guid) + + + def get_revision(self, renkan_guid, revision_guid): + try: + renkan_uuid = renkan_guid and uuid.UUID(renkan_guid) + except: + raise ValueError('Renkan project %r guid bad format'%renkan_guid) + try: + revision_uuid = revision_guid and uuid.UUID(revision_guid) + except: + raise ValueError('Revision %r guid bad format'%revision_guid) + + revisions = None + if renkan_uuid: + revisions = Revision.objects.filter(parent_renkan__renkan_guid=renkan_uuid) else: - return Revision.objects + revisions = Revision.objects + if not revisions: + raise ObjectDoesNotExist('Renkan project %r does not exist'%renkan_guid) + try: + revision = revisions.get(revision_guid=revision_uuid) + except Revision.DoesNotExist: + raise ObjectDoesNotExist('Revision %r does not exist'%revision_guid) + return revisions, revision def get(self, request, renkan_guid, revision_guid, format=None): - revisions = self.get_queryset(renkan_guid) - if not revisions: - return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + try: - revision = revisions.get(revision_guid=revision_guid) - except Revision.DoesNotExist: - return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + _, revision = self.get_revision(renkan_guid, revision_guid) + except ValueError as e: + return Response({'detail': e.args[0]}, status=status.HTTP_400_BAD_REQUEST) + except ObjectDoesNotExist as e: + return Response({'detail': e.args[0]}, status=status.HTTP_404_NOT_FOUND) + self.check_object_permissions(request, revision) serializer = RevisionSerializer(revision) return Response(serializer.data, status=status.HTTP_200_OK, content_type='application/json') def delete(self, request, renkan_guid, revision_guid, format=None): - revisions = self.get_queryset(renkan_guid) - if not revisions: - return Response({'detail': 'Renkan project '+renkan_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) try: - revision = revisions.get(revision_guid=revision_guid) - except Revision.DoesNotExist: - return Response({'detail': 'Revision '+revision_guid+' does not exist'}, status=status.HTTP_404_NOT_FOUND) + revisions, revision = self.get_revision(renkan_guid, revision_guid) + except ValueError as e: + return Response({'detail': e.args[0]}, status=status.HTTP_400_BAD_REQUEST) + except ObjectDoesNotExist as e: + return Response({'detail': e.args[0]}, status=status.HTTP_404_NOT_FOUND) + self.check_object_permissions(request, revision) if revisions.count() == 1: return Response({'detail': 'You cannot delete the last remaining revision of a renkan from the Revision API. Try deleting the parent Renkan with the Renkan API'}, status=status.HTTP_400_BAD_REQUEST)