Esempio n. 1
0
    def post(self, request, *args, **kwargs):

        self.check_object_permissions(request, self)
        try:
            kproperty_pk = request.data.pop('kproperty')
        except KeyError:
            key_exc = APIException(
                detail={'error': "field `kproperty` not specified."})
            key_exc.status_code = status.HTTP_400_BAD_REQUEST
            raise key_exc

        try:
            kproperty = Property.objects.get(pk=kproperty_pk)
        except Property.DoesNotExist:
            dne_exc = APIException(
                detail={
                    'error':
                    "property with pk {} does not exist.".format(kproperty_pk)
                })
            dne_exc.status_code = status.HTTP_400_BAD_REQUEST
            raise dne_exc

        # Add the user to property's subscription list.
        kproperty._subscribers.add(request.user)
        kproperty.save()

        response = Response({}, status=status.HTTP_201_CREATED)
        response.data['subscribed'] = kproperty_pk

        return response
Esempio n. 2
0
    def post(self, request, *args, **kwargs):

        document = self._get_parent()
        parent_field_name = 'document'

        # Get the Clause ID, and the actual clause object.
        contract = document.closing.transaction.contracts.all()[0]
        if 'clause' not in request.data.keys():
            error_msg = {'error': '`clause` must be provided.'}
            dne_exc = APIException(detail=error_msg)
            dne_exc.status_code = 401
            raise dne_exc

        clause_pk = request.data.pop('clause')
        try:
            clause = contract.static_clauses.get(pk=clause_pk)
        except StaticClause.DoesNotExist:
            try:
                clause = contract.dynamic_clauses.get(pk=clause_pk)
            except DynamicClause.DoesNotExist:
                error_msg = {
                    "error":
                    "clause with pk {} does not exist in "
                    "the transaction's contract.".format(clause_pk)
                }
                dne_exc = APIException(detail=error_msg)
                dne_exc.status_code = 404
                raise dne_exc

        # Create the serializer. Note, we need to check for duplicates here.
        serializer = self.get_serializer(data=request.data,
                                         context=request.FILES)
        if serializer.is_valid():
            try:
                serializer.save(
                    **{
                        parent_field_name: document,
                        'clause': clause,
                        'sender': request.user
                    })
            except ValueError as value_error:
                error_msg = {'error': str(value_error)}
                duplicate_exc = APIException(detail=error_msg)
                duplicate_exc.status_code = 400
                raise duplicate_exc

            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def apply_bulk_edits(self):
        """
        Apply all actions.
        """
        response_data = []
        statuses = []
        for attrs in self.validated_data:
            response = self.child.apply_action(attrs)
            statuses.append(response.status_code)
            response_data.append(response.data)

        if not self.okay_statuses.issuperset(statuses):
            # TODO: are these full content responses *useful* ?
            # Maybe we should just pass on the *errored* responses
            error_statuses = set(statuses).difference(self.okay_statuses)
            if len(error_statuses) == 1:
                # There was only one unique error status, use that
                status = set(error_statuses).pop()
            elif all(s < 500 for s in error_statuses):
                # The parsing and validation of the request happened okay,
                # but we still received a 4xx error from at least one subresource.
                # We raise a 400 here to keep things simplish.
                status = 400
            else:
                # mixed errors, including server errors
                status = 500
            e = APIException(response_data)
            e.status_code = status
            raise e
        return response_data
def custom_exception_handler(exc, context):
    # Convert UnknownOrgIDError into an appropriate API exception
    if isinstance(exc, UnknownOrgIDError):
        org_id = exc.args[0]
        exc = APIException(detail=f"Unknown organisation ID: {org_id}")
        exc.status_code = status.HTTP_400_BAD_REQUEST
    return exception_handler(exc, context)
Esempio n. 5
0
 def test_handle_exception(self):
     exc = APIException('There was a problem!')
     exc.status_code = 400  # set the status code to 400 not possible to set in init
     exc.code = 400  # rest framework APIError is not compatible with integration APIError exception type
     resp = self.endpoint.handle_exception(HttpRequest(), exc)
     assert resp.status_code == 400
     assert resp.exception is True
Esempio n. 6
0
    def _generate_filter_chain(self, filters):

        filter_args = []
        
        # Parse any map filters.
        map_filters = {}; map_coordinates = ['ne_lng', 'ne_lat', 'sw_lng', 'sw_lat']
        if any(map_filter in filters.keys() for map_filter in map_coordinates):
            if not all(map_filter in filters.keys() for map_filter in map_coordinates):
                exc = APIException(detail={'error': 'incomplete map query.'})
                exc.status_code = 401; raise exc
        
            for coordinate in map_coordinates:
                map_filters[coordinate] = filters.pop(coordinate)[0]
            
            filter_args.append(self._parse_mapkeys(map_filters))
        
        # Construct the filter chain. Note, we'll need to handle multi-keys
        # in a different manner.
        for kfilter in filters.keys():
            if len(filters.getlist(kfilter)[0].split(',')) > 1:
                filters[kfilter] = self._parse_multikey(filters[kfilter])

            next_filter = Q((kfilter, filters[kfilter]))
            filter_args.append(next_filter)

        return filter_args
Esempio n. 7
0
 def test_handle_exception(self):
     exc = APIException("There was a problem!")
     exc.status_code = 400  # set the status code to 400 not possible to set in init
     exc.code = 400  # rest framework APIError is not compatible with integration APIError exception type
     resp = self.endpoint.handle_exception(HttpRequest(), exc)
     assert resp.status_code == 400
     assert resp.exception is True
Esempio n. 8
0
    def to_internal_value(self, data):
        controller = None

        try:
            controller = Controller.objects.get(token__in=[data.get('token')])
            request = self._kwargs.get('context')['request']
        except Exception:
            return data

        if controller and request.method == 'POST':
            if request.user not in controller.owner.all():
                controller.owner.add(request.user)

                ControllerSpecification.objects.create(owner=request.user,
                                                       controller=controller,
                                                       name=data.get('name'))

                return data
            else:
                invalid_association = APIException({
                    'detail': ('This user has already been associated '
                               'with this controller.')
                })
                invalid_association.status_code = 400

                raise invalid_association
        else:
            return data
Esempio n. 9
0
def check(res):
    if res['errors']:
        print 'errors:', res
        e = APIException()
        e.status_code = 500
        e.detail = "Internal Error"
        raise e
    return res
Esempio n. 10
0
 def _raiseException(self, field):
     """
     Raise 400 exceptions for invalid or missing parameters
     """
     e = APIException(
         "The request parameter '{}' is required.".format(field))
     e.status_code = 400
     raise e
Esempio n. 11
0
 def get_object(self):
     try:
         profile = self.queryset.get(user=self.request.user)
         return profile
     except ObjectDoesNotExist:
         status_code = status.HTTP_404_NOT_FOUND
         exception = APIException()
         exception.status_code = status_code
         raise exception
Esempio n. 12
0
 def destroy(self, request, *args, **kwargs):
     try:
         return super().destroy(request, *args, **kwargs)
     except ProtectedError:
         detail = 'Can not delete package with tracking information'
         exc = APIException(detail)
         exc.status_code = status.HTTP_400_BAD_REQUEST
         response = exception_handler(exc, None)
         return response
Esempio n. 13
0
    def to_internal_value(self, data):
        if data.get('validation_key') == os.getenv('SECRET_KEY'):
            return data
        else:
            exception = APIException(
                {'error': 'Validation key not match with registration key.'})
            exception.status_code = 403

            raise exception
Esempio n. 14
0
    def get(self, request, pk):

        # Ensure the user has permission.
        if request.user.pk != int(pk):
            error_msg = 'error: you do not have permission to view this resource'
            no_auth_exc = APIException(detail=error_msg)
            no_auth_exc.status_code = status.HTTP_403_FORBIDDEN
            raise no_auth_exc

        return Response(status=status.HTTP_200_OK)
Esempio n. 15
0
    def create(self, validated_data):

        try:
            controller = Controller.objects.get(
                token=validated_data.get('token'))

            zone = controller.zone_set.get(
                name=validated_data.get('zone_name'))

            schedule = Schedule.objects.get(zone=zone,
                                            schedule=datetime.strptime(
                                                validated_data.get('time'),
                                                '%Y-%m-%d %H:%M'))

            exception = APIException(
                {'error': 'This schedule is just registered.'})
            exception.status_code = 400

            raise exception
        except Schedule.DoesNotExist:
            schedule = Schedule.objects.create(zone=zone,
                                               schedule=datetime.strptime(
                                                   validated_data.get('time'),
                                                   '%Y-%m-%d %H:%M'))

            exception = APIException({
                'zone': schedule.zone.name,
                'schedule': schedule.schedule
            })

            exception.status_code = 201

            raise exception
        except Zone.DoesNotExist:
            raise APIException({
                'error':
                'Name does not match with any controller zone name.'
            })
        except Controller.DoesNotExist:
            raise APIException(
                {'error': 'Token does not match with any controller.'})

        return schedule
Esempio n. 16
0
    def post(self, request, *args, **kwargs):

        payment = self.get_object()
        try:
            result = {"result": payment.forward()}
        except AssertionError as error:
            payment_exc = APIException(detail={"error": str(error)})
            payment_exc.status_code = 400
            raise payment_exc

        return Response(result, status=status.HTTP_201_CREATED)
Esempio n. 17
0
    def get_object(self, pk):

        try:
            kuser = User.objects.get(pk=pk)
            self.check_object_permissions(self.request, self)
            return kuser
        except User.DoesNotExist:
            dne_exc = APIException(
                detail={'error': 'user {} does not exist.'.format(pk)})
            dne_exc.status_code = 404
            raise dne_exc
Esempio n. 18
0
 def get_object(self):
     try:
         user_id = self.kwargs.get('id')
         profile = self.queryset.get(user=user_id)
         self.check_object_permissions(self.request, profile)
         return profile
     except ObjectDoesNotExist:
         status_code = status.HTTP_404_NOT_FOUND
         exception = APIException()
         exception.status_code = status_code
         raise exception
Esempio n. 19
0
    def get_object(self, pk):

        try:
            kuser = User.objects.get(pk=pk)
            self.check_object_permissions(self.request, kuser)
            return kuser
        except User.DoesNotExist:
            user_dne_exc = APIException(detail={'error': 'user with id ' + str(pk) +\
                                ' does not exist.'})
            user_dne_exc.status_code = status.HTTP_400_BAD_REQUEST
            raise user_dne_exc
Esempio n. 20
0
 def validate(self, data):
     if "username" in data:
         try:
             User.objects.get(username=data['username'])
         except ObjectDoesNotExist:
             exc = APIException(code='invalid', detail={"user": ["Unknown user " + data['username']]})
             # hack to update status code. :-(
             exc.status_code = status.HTTP_400_BAD_REQUEST
             raise exc
     data = super().validate(data)
     return data
Esempio n. 21
0
    def post(self, request, pk, *args, **kwargs):

        kuser = self.get_object(pk=pk)

        # Ensure that the user has a phone number, and has enabled
        # two-factor-auth
        error_msg = None
        if not hasattr(kuser, 'phone_num'):
            error_msg = 'user {} has no attribute `phone_num`.'.format(
                kuser.pk)
        if kuser.tfa_enabled is False:
            error_msg = 'user {} does not have two-factor authentication ' \
                'enabled.'.format(kuser.pk)
        if error_msg:
            user_exc = APIException(detail={'error': error_msg})
            user_exc.status_code = 403
            raise user_exc

        # Generate a two-factor auth code.
        tfa_code = self._generate_tfa_code()

        # Send an SMS message to the user's phone.
        client = messagebird.Client(settings.MESSAGEBIRD_ACCESS_KEY)
        try:
            message = client.message_create(
                originator=settings.MESSAGEBIRD_SENDER,
                recipients=kuser.phone_num,
                body=tfa_code,
            )
        except messagebird.client.ErrorException as e:
            sms_exc = APIException(
                detail={'error': 'the SMS message failed to send.'})
            sms_exc.status_code = 403
            raise sms_exc

        # Set the user's TFA code, and reset its validation status.
        kuser.tfa_code = tfa_code
        kuser._tfa_code_validated = False
        kuser.save()

        return Response({'success': True}, status=status.HTTP_201_CREATED)
Esempio n. 22
0
    def save(self, *args, **kwargs):

        #TODO: Move the exception raising to child classes.
        if not self.pk:
            try:
                self.full_clean()
            except ValidationError as validation_error:
                validation_exc = APIException(detail=validation_error.messages[0])
                validation_exc.status_code = 403
                raise validation_exc
            
        super(Property, self).save(*args, **kwargs)
Esempio n. 23
0
    def paginate_queryset(self, *args, **kwargs):
        """Adds a machine readable error code if the page is not found."""

        try:
            return super().paginate_queryset(*args, **kwargs)
        except NotFound as e:
            exception = APIException({
                'error': 'ERROR_INVALID_PAGE',
                'detail': str(e)
            })
            exception.status_code = HTTP_400_BAD_REQUEST
            raise exception
Esempio n. 24
0
    def get_object(self, rsvp_pk):

        try:
            rsvp = RSVP.objects.get(pk=rsvp_pk)
            self.check_object_permissions(self.request, rsvp)
            return rsvp
        except RSVP.DoesNotExist:
            error_msg = {
                'error': 'RSVP with id=' + str(pk) + ' does not exist.'
            }
            dne_exc = APIException(detail=error_msg)
            dne_exc.status_code = status.HTTP_400_BAD_REQUEST
            raise dne_exc
Esempio n. 25
0
    def get_page_size(self, request):
        page_size = super().get_page_size(request)

        if self.limit_page_size and page_size > self.limit_page_size:
            exception = APIException({
                'error':
                'ERROR_PAGE_SIZE_LIMIT',
                'detail':
                f'The page size is limited to {self.limit_page_size}.'
            })
            exception.status_code = HTTP_400_BAD_REQUEST
            raise exception

        return page_size
Esempio n. 26
0
    def get_page_size(self, request):
        page_size = super().get_page_size(request)

        if self.limit_page_size and page_size > self.limit_page_size:
            exception = APIException({
                "error":
                "ERROR_PAGE_SIZE_LIMIT",
                "detail":
                f"The page size is limited to {self.limit_page_size}.",
            })
            exception.status_code = HTTP_400_BAD_REQUEST
            raise exception

        return page_size
Esempio n. 27
0
    def get_queryset(self):
        
        queryset = Property.objects.select_subclasses()
        
        # Construct a filter chain from the given parameters.
        filter_args = self._generate_filter_chain(self.request.GET)
        if filter_args:
            try:
                queryset = queryset.filter(reduce(AND, filter_args))
            except FieldError:
                field_exc = APIException(detail={'error': 'invalid search field.'})
                field_exc.status_code = 400; raise field_exc

        return queryset
Esempio n. 28
0
    def get_object(self, oh_pk):

        try:
            open_house = OpenHouse.objects.get(pk=oh_pk)
            self.check_object_permissions(self.request, open_house)
            return open_house

        except OpenHouse.DoesNotExist:
            error_msg = {
                'error':
                'open house with id=' + str(oh_pk) + ' does not exist.'
            }
            dne_exc = APIException(detail=error_msg)
            dne_exc.status_code = status.HTTP_400_BAD_REQUEST
            raise dne_exc
Esempio n. 29
0
    def get_object(self):

        try:
            nested_parent = self._get_parent()
            nested_set = getattr(nested_parent, self.model_tree[-1][0])
            instance = nested_set.get(pk=self.kwargs[self.pk])
            self.check_object_permissions(self.request, instance)
            return instance

        except nested_set.model.DoesNotExist:
            error_msg = {'error': 'nested model with pk {} does not exist.'.\
                    format(self.kwargs[self.pk])}
            dne_exc = APIException(detail=error_msg)
            dne_exc.status_code = 404
            raise dne_exc
Esempio n. 30
0
 def get_paginator(self, request):
     
     try:
         limit, offset = request.GET.pop('limit')[0], request.GET.pop('offset')[0]
         if (int(limit) <= 0) or (int(offset) < 0):
             exc = APIException(detail={
                 'error': 'pagination params cannot be negative.'
             })
             exc.status_code = 401; raise exc
         
         paginator = self.pagination_class()
         paginator.limit = limit; paginator.offset = offset
         return paginator
     except KeyError:
         return None
Esempio n. 31
0
    def get_object(self, pk, chat_pk):
        
        try:
            chat = Chat.objects.get(pk=chat_pk)
            self.check_object_permissions(self.request, chat)
            
            # Update Chat status.
            if not chat.opened:
                chat.opened = True; chat.save()
            
            return chat

        except Chat.DoesNotExist:
            error_msg = {'error': 'chat with id={} does not exist'}
            dne_exc = APIException(detail=error_msg)
            dne_exc.status_code = status.HTTP_400_BAD_REQUEST; raise dne_exc
Esempio n. 32
0
def map_exceptions(mapping):
    """
    This utility function simplifies mapping uncaught exceptions to a standard api
    response exception.

    Example:
      with map_api_exceptions({ SomeException: 'ERROR_1' }):
          raise SomeException('This is a test')

      HTTP/1.1 400
      {
        "error": "ERROR_1",
        "detail": "This is a test"
      }

    Example 2:
      with map_api_exceptions({ SomeException: ('ERROR_1', 404, 'Other message') }):
          raise SomeException('This is a test')

      HTTP/1.1 404
      {
        "error": "ERROR_1",
        "detail": "Other message"
      }
    """

    try:
        yield
    except tuple(mapping.keys()) as e:
        value = mapping.get(e.__class__)
        status_code = status.HTTP_400_BAD_REQUEST
        detail = ""

        if isinstance(value, str):
            error = value
        if isinstance(value, tuple):
            error = value[0]
            if len(value) > 1 and value[1] is not None:
                status_code = value[1]
            if len(value) > 2 and value[2] is not None:
                detail = value[2].format(e=e)

        exc = APIException({"error": error, "detail": detail})
        exc.status_code = status_code

        raise exc