diff --git a/beat/web/common/api.py b/beat/web/common/api.py index e81c39e16c9a5dad1a683c188ae3596f26593484..5fb277f215719bb4b804b8e2725b2744129a904f 100644 --- a/beat/web/common/api.py +++ b/beat/web/common/api.py @@ -30,10 +30,10 @@ from django.shortcuts import get_object_or_404 from rest_framework import status from rest_framework import generics from rest_framework import permissions +from rest_framework import exceptions as drf_exceptions from rest_framework.response import Response from rest_framework.reverse import reverse -from .responses import BadRequestResponse, ForbiddenResponse from .models import Contribution, Versionable from .permissions import IsAuthor from .exceptions import ShareError, BaseCreationError @@ -86,9 +86,7 @@ class ShareView(CommonContextMixin, generics.CreateAPIView): def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - if not serializer.is_valid(): - return BadRequestResponse(serializer.errors) - + serializer.is_valid(raise_exception=True) data = serializer.data object_db = self.get_queryset() @@ -96,7 +94,9 @@ class ShareView(CommonContextMixin, generics.CreateAPIView): try: self.do_share(object_db, data) except ShareError as e: - return BadRequestResponse(e.errors) + # ShareError happens when someone does not have access to + # all dependencies that should be shared. + raise drf_exceptions.PermissionDenied(e.errors) return Response(object_db.sharing_preferences()) @@ -160,16 +160,14 @@ class ListCreateBaseView( def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) - if serializer.is_valid(): - try: - if hasattr(self.model, "author"): - db_object = serializer.save(author=request.user) - else: - db_object = serializer.save() - except BaseCreationError as e: - return BadRequestResponse(e.errors) - else: - return BadRequestResponse(serializer.errors) + serializer.is_valid(raise_exception=True) + try: + if hasattr(self.model, "author"): + db_object = serializer.save(author=request.user) + else: + db_object = serializer.save() + except BaseCreationError as e: + raise drf_exceptions.APIException(e.errors) result = { "name": db_object.name, @@ -201,32 +199,28 @@ class DiffView(generics.RetrieveAPIView): def get(self, request, author1, name1, version1, author2, name2, version2): # Retrieve the objects - try: - object1 = self.model.objects.get( - author__username__iexact=author1, - name__iexact=name1, - version=int(version1), - ) - except Exception: - return Response("%s/%s/%s" % (author1, name1, version1), status=404) + object1 = get_object_or_404( + self.model, + author__username__iexact=author1, + name__iexact=name1, + version=int(version1), + ) - try: - object2 = self.model.objects.get( - author__username__iexact=author2, - name__iexact=name2, - version=int(version2), - ) - except Exception: - return Response("%s/%s/%s" % (author2, name2, version2), status=404) + object2 = get_object_or_404( + self.model, + author__username__iexact=author2, + name__iexact=name2, + version=int(version2), + ) # Check that the user can access them accessibility = object1.accessibility_for(request.user) if not accessibility[0]: - return ForbiddenResponse(object1.fullname()) + raise drf_exceptions.PermissionDenied(object1.fullname()) accessibility = object2.accessibility_for(request.user) if not accessibility[0]: - return ForbiddenResponse(object2.fullname()) + raise drf_exceptions.PermissionDenied(object2.fullname()) # Compute the diff serializer = self.get_serializer({"object1": object1, "object2": object2}) @@ -269,13 +263,13 @@ class RetrieveUpdateDestroyContributionView( db_objects = self.get_queryset() if db_objects.count() == 0: - return Response(status=404) + raise drf_exceptions.NotFound() db_object = db_objects[0] version = int(self.kwargs.get("version", -1)) if version != -1 and db_object.version != version: - return Response(status=404) + raise drf_exceptions.NotFound() # Process the query string allow_sharing = hasattr(db_object, "author") and ( @@ -296,7 +290,9 @@ class RetrieveUpdateDestroyContributionView( # Retrieve the object if version is None: - return BadRequestResponse("A version number must be provided") + raise drf_exceptions.ValidationError( + {"version": "A version number must be provided"} + ) db_object = get_object_or_404( self.model, @@ -307,7 +303,7 @@ class RetrieveUpdateDestroyContributionView( # Check that the object can be deleted if not (db_object.deletable()): - return ForbiddenResponse( + raise drf_exceptions.MethodNotAllowed( "The {} can't be deleted anymore (needed by an attestation, an algorithm or another data format)".format( db_object.model_name() )