Exemple #1
0
    def delete_related_detail(self, request, **kwargs):
        bundle = Bundle(request=request)
        dataset_id = kwargs.get('dataset_id')
        story_id = kwargs.pop('story_id', None)
        asset_id = kwargs.pop('asset_id', None)

        if asset_id:
            try:
                asset = Asset.objects.get(asset_id=asset_id) 
                if not asset.has_perm(bundle.request.user, 'change'):
                    raise ImmediateHttpResponse(response=http.HttpUnauthorized("You are not authorized to change the asset matching the provided asset ID"))
            except ObjectDoesNotExist:
                raise ImmediateHttpResponse(response=http.HttpNotFound("An asset matching the provided asset ID could not be found"))
        elif story_id:
            try:
                story = Story.objects.get(story_id=story_id) 
                if not story.has_perm(bundle.request.user, 'change'):
                    raise ImmediateHttpResponse(response=http.HttpUnauthorized("You are not authorized to change the story matching the provided story ID"))
            except ObjectDoesNotExist:
                raise ImmediateHttpResponse(response=http.HttpNotFound("A story matching the provided story ID could not be found"))

        self.obj_get(bundle, dataset_id=dataset_id)

        if asset_id:
            asset.datasets.remove(bundle.obj)
        elif story_id:
            story.datasets.remove(bundle.obj)

        return http.HttpNoContent()
    def put_detail(self, request, **kwargs):
        """
        Copied from tastypie ModelResource so we dont try to create one
        if it doesn't exist.
        """
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)

        try:
            updated_bundle = self.obj_update(
                bundle=bundle, **self.remove_api_resource_names(kwargs))

            if not self._meta.always_return_data:
                return http.HttpNoContent()
            else:
                # Invalidate prefetched_objects_cache for bundled object
                # because we might have changed a prefetched field
                updated_bundle.obj._prefetched_objects_cache = {}
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request, updated_bundle)
        except (NotFound, MultipleObjectsReturned):
            return self.create_response(request,
                                        'Object not found',
                                        response_class=HttpNotFound)
Exemple #3
0
    def delete_detail(self, request, **kwargs):
        """Attempt to redirect to QGIS Server Style management."""
        from geonode.qgis_server.views import qml_style
        style_id = kwargs.get('id')

        qgis_style = QGISServerStyle.objects.get(id=style_id)
        layername = qgis_style.layer_styles.first().layer.name

        response = qml_style(request, layername, style_name=qgis_style.name)

        if isinstance(response, TemplateResponse):
            if response.status_code == 200:
                # style deleted
                return http.HttpNoContent()
            else:
                context = response.context_data
                # Check form valid
                style_upload_form = context['style_upload_form']
                if not style_upload_form.is_valid():
                    raise BadRequest(style_upload_form.errors.as_text())
                alert_message = context['alert_message']
                raise BadRequest(alert_message)
        elif isinstance(response, HttpResponse):
            response_class = None
            if response.status_code == 403:
                response_class = http.HttpForbidden
            return self.error_response(request,
                                       response.content,
                                       response_class=response_class)
Exemple #4
0
 def get_user_notifications(self, request, **kwargs):
     from core.api import BanyanUserNotificationsResource
     notifications_resource = BanyanUserNotificationsResource()
     if request.user.is_authenticated():
         return notifications_resource.get_list(request, user=request.user)
     else:
         return http.HttpNoContent()
Exemple #5
0
    def post_list(self, request, **kwargs):
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)
        content_object = self.content_object.hydrate(bundle).obj
        obj = Accuracy.objects.filter(
            user=bundle.request.user,
            content_type=ContentType.objects.get_for_model(content_object),
            object_id=content_object.id)
        if obj.exists():
            bundle = self.full_bundle(obj[0], bundle.request)
            super(AccuracyResource, self).obj_delete(bundle, **kwargs)
            return http.HttpNoContent()
        updated_bundle = self.obj_create(
            bundle, **self.remove_api_resource_names(kwargs))
        location = self.get_resource_uri(updated_bundle)

        if not self._meta.always_return_data:
            return http.HttpCreated(location=location)
        else:
            updated_bundle = self.full_dehydrate(updated_bundle)
            updated_bundle = self.alter_detail_data_to_serialize(
                request, updated_bundle)
            return self.create_response(request,
                                        updated_bundle,
                                        response_class=http.HttpCreated,
                                        location=location)
    def dismiss_all(self, request, **kwargs):
        if (request.method != "PUT") or (not request.user.is_authenticated()):
            return http.HttpUnauthorized()

        Command.objects.filter(dismissed=False, complete=True).update(dismissed=True)

        return http.HttpNoContent()
Exemple #7
0
    def _remove_files_from_package(self, request, bundle, **kwargs):
        """
        Removes all file records associated with this package.
        """

        bundle.obj.file_set.all().delete()
        return http.HttpNoContent()
Exemple #8
0
    def dispatch(self, request_type, request, **kwargs):
        """
        Overrides Tastypie and calls get_list.
        """

        try:
            self.top_lvl_location_id = LocationPermission.objects.get(
                user_id = request.user.id).top_lvl_location_id
        except LocationPermission.DoesNotExist:
            self.top_lvl_location_id = Location.objects\
                .filter(parent_location_id = None)[0].id

        allowed_methods = getattr(self._meta, "%s_allowed_methods" % request_type, None)
        #
        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        # if method is None:
        #     raise ImmediateHttpResponse(response=http.HttpNotImplemented())

        self.is_authenticated(request)
        self.throttle_check(request)
        # All clear. Process the request.

        # If what comes back isn't a ``HttpResponse``, assume that the
        # request was accepted and that some action occurred. This also
        # prevents Django from freaking out.

        # request = convert_post_to_put(request)

        try:
            response = method(request, **kwargs)
        except Exception as error:

            error_code = DatapointsException.defaultCode
            error_message = DatapointsException.defaultMessage

            if isinstance(error, DatapointsException):
                error_code = error.code
                error_message = error.message

            data = {
                'traceback': traceback.format_exc(),
                'error': error_message,
                'code': error_code
            }

            return self.error_response(
                request,
                data,
                response_class=http.HttpApplicationError
            )

        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
Exemple #9
0
    def mark_as_state(self, request, invoicebase_state, **kwargs):
        """Set state for an InvoiceBase."""
        self.method_check(request, allowed=['put'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            previous_state, new_state = obj.set_state(
                invoicebase_state.upper(), issuer=request.vosae_user)
            invoicing_signals.post_client_changed_invoice_state.send(
                obj.__class__,
                issuer=request.vosae_user,
                document=obj,
                previous_state=previous_state)
        except (obj.InvalidState, InvalidInvoiceBaseState) as e:
            raise BadRequest(e)

        self.log_throttled_access(request)

        return http.HttpNoContent()
Exemple #10
0
    def dispatch(self, request_type, request, **kwargs):
        """
        Handles the common operations (allowed HTTP method, authentication,
        throttling, method lookup) surrounding most CRUD interactions.

        This version moves the authorization check to later in the pipeline
        """
        allowed_methods = getattr(self._meta, "%s_allowed_methods" % request_type, None)
        request_method = self.method_check(request, allowed=allowed_methods)
        method_name = "%s_%s" % (request_method, request_type)
        method = getattr(self, method_name, None)

        if method is None:
            raise ImmediateHttpResponse(response=http.HttpNotImplemented())

        self.is_authenticated(request)
        if method_name not in self._meta.delayed_authorization_methods:
            self.is_authorized(request, **kwargs)
        self.throttle_check(request)

        # All clear. Process the request.
        request = convert_post_to_put(request)
        response = method(request, **kwargs)

        # Add the throttled request.
        self.log_throttled_access(request)

        # If what comes back isn't a ``HttpResponse``, assume that the
        # request was accepted and that some action occurred. This also
        # prevents Django from freaking out.
        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
Exemple #11
0
    def put_detail(self, request, **kwargs):
        """Override put_detail so that it doesn't create a new resource when
        One doesn't exists, I don't like this reflex"""
        if VERSION >= (1, 4):
            body = request.body
        else:
            body = request.raw_post_data
        deserialized = self.deserialize(request,
                                        body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)

        try:
            updated_bundle = self.obj_update(
                bundle=bundle, **self.remove_api_resource_names(kwargs))

            if not self._meta.always_return_data:
                return http.HttpNoContent()
            else:
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request,
                                            updated_bundle,
                                            response_class=http.HttpAccepted)
        except (NotFound, MultipleObjectsReturned):
            raise NotFound(
                "A model instance matching the provided arguments could not be found."
            )
Exemple #12
0
    def nested_dispatch_list(self, request, **kwargs):
        """
        Handles the common operations (allowed HTTP method, authentication,
        throttling, method lookup) surrounding most CRUD interactions.
        """
        allowed_methods = self._meta.nested_allowed_methods

        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_list" % request_method, None)

        if method is None:
            raise ImmediateHttpResponse(response=http.HttpNotImplemented())

        self.is_authenticated(request)
        self.throttle_check(request)

        # All clear. Process the request.
        request = convert_post_to_put(request)
        response = method(request, **kwargs)

        # Add the throttled request.
        self.log_throttled_access(request)

        # If what comes back isn't a ``HttpResponse``, assume that the
        # request was accepted and that some action occurred. This also
        # prevents Django from freaking out.
        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
Exemple #13
0
    def dispatch_public(self, request_type, request, **kwargs):
        """
            Same as `tastypie.resources.Resource.dispatch` except that
            we don't check if the user is authenticated
        """
        allowed_methods = getattr(self._meta,
                                  "%s_allowed_methods" % request_type, None)

        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        if method is None:
            raise ImmediateHttpResponse(response=http.HttpNotImplemented())

        self.throttle_check(request)

        # All clear. Process the request.
        request = convert_post_to_put(request)
        response = method(request, **kwargs)

        # Add the throttled request.
        self.log_throttled_access(request)

        # If what comes back isn't a ``HttpResponse``, assume that the
        # request was accepted and that some action occurred. This also
        # prevents Django from freaking out.
        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
    def dismiss_all(self, request, **kwargs):
        if (request.method != 'PUT') or (not request.user.is_authenticated()):
            return http.HttpUnauthorized()

        AlertState.objects.filter(dismissed=False).exclude(
            active=True, severity__in=[40, 30]).update(dismissed=True)

        return http.HttpNoContent()
Exemple #15
0
    def put_detail(self, request, **kwargs):
        """
        Either updates an existing resource or creates a new one with the
        provided data.

        Calls ``obj_update`` with the provided data first, but falls back to
        ``obj_create`` if the object does not already exist.

        If a new resource is created, return ``HttpCreated`` (201 Created).
        If ``Meta.always_return_data = True``, there will be a populated body
        of serialized data.

        If an existing resource is modified and
        ``Meta.always_return_data = False`` (default), return ``HttpNoContent``
        (204 No Content).
        If an existing resource is modified and
        ``Meta.always_return_data = True``, return ``HttpAccepted`` (202
        Accepted).
        """
        fmt = request.META.get('CONTENT_TYPE', 'application/json')
        if fmt.startswith('multipart'):
            body = None
        else:
            body = request.body
        deserialized = self.deserialize(request, body, format=fmt)
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)

        try:
            updated_bundle = self.obj_update(
                bundle=bundle, **self.remove_api_resource_names(kwargs))

            if not self._meta.always_return_data:
                return http.HttpNoContent()
            else:
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request,
                                            updated_bundle,
                                            response_class=http.HttpAccepted)
        except (NotFound, MultipleObjectsReturned):
            updated_bundle = self.obj_create(
                bundle=bundle, **self.remove_api_resource_names(kwargs))
            location = self.get_resource_uri(updated_bundle)

            if not self._meta.always_return_data:
                return http.HttpCreated(location=location)
            else:
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request,
                                            updated_bundle,
                                            response_class=http.HttpCreated,
                                            location=location)
Exemple #16
0
    def put_list(self, request, **kwargs):
        deserialized = self.deserialize(request, request.raw_post_data, format=request.META.get('CONTENT_TYPE', 'application/json'))
        deserialized = self.alter_deserialized_list_data(request, deserialized)

        for object_data in deserialized:
            notification = Notification.objects.get(id=object_data['id'])
            notification.delivered = True
            notification.save()

        return http.HttpNoContent()
Exemple #17
0
    def put_list(self, request, **kwargs):
        """
        Replaces a collection of resources with another collection.

        Unlike the default put_list, this doesn't expect the new collections
        to be wrapped in an 'objects' property.
        """
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_list_data(request, deserialized)

        basic_bundle = self.build_bundle(request=request)
        self.obj_delete_list_for_update(
            bundle=basic_bundle, **self.remove_api_resource_names(kwargs))
        bundles_seen = []

        for object_data in deserialized:
            bundle = self.build_bundle(
                data=dict_strip_unicode_keys(object_data), request=request)

            # Attempt to be transactional, deleting any previously created
            # objects if validation fails.
            try:
                self.obj_create(bundle,
                                request=request,
                                **self.remove_api_resource_names(kwargs))
                bundles_seen.append(bundle)
            except ImmediateHttpResponse:
                self.rollback(bundles_seen)
                raise

        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            to_be_serialized = {}
            to_be_serialized[self._meta.collection_name] = [
                self.full_dehydrate(bundle) for bundle in bundles_seen
            ]
            to_be_serialized = self.alter_list_data_to_serialize(
                request, to_be_serialized)
            return self.create_response(request,
                                        to_be_serialized,
                                        response_class=http.HttpAccepted)
Exemple #18
0
    def delete_detail(self, request, **kwargs):
        from freenasUI.freeadmin.navtree import navtree
        bundle = Bundle(request=request)
        bundle.obj = self.obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs))
        if bundle.obj._meta.model._admin.delete_form:
            deserialized = self.deserialize(
                request,
                request.body or '{}',
                format=request.META.get('CONTENT_TYPE', 'application/json'),
            )

            Form = __import__(
                f'{bundle.obj._meta.app_label}.forms',
                globals(),
                locals(),
                [bundle.obj._meta.model._admin.delete_form],
                0,
            )
            Form = getattr(Form, bundle.obj._meta.model._admin.delete_form)

            form = Form(data=deserialized, instance=bundle.obj)
            if not form.is_valid():
                raise ImmediateHttpResponse(
                    response=self.error_response(request, form.errors)
                )

        # Grab the form to call delete on same as in freeadmin
        m = bundle.obj._meta.model
        mf = None
        if not isinstance(navtree._modelforms[m], dict):
            mf = navtree._modelforms[m]
        else:
            if mf is None:
                try:
                    mf = navtree._modelforms[m][m._admin.edit_modelform]
                except Exception:
                    mf = list(navtree._modelforms[m].values())[-1]
            else:
                mf = navtree._modelforms[m][mf]

        if mf:
            form = mf(instance=bundle.obj)
            form.delete()
            return http.HttpNoContent()
        else:
            return super().delete_detail(request, **kwargs)
    def put_detail(self, request, **kwargs):
        """
        Either updates an existing resource or creates a new one with the
        provided data.
        """
        try:
            body = request.body
        except Exception:  # pylint: disable=I0011,W0703
            body = None
        deserialized = self.deserialize(request,
                                        body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)

        try:
            updated_bundle = self.obj_update(
                bundle=bundle, **self.remove_api_resource_names(kwargs))

            if not self._meta.always_return_data:
                return http.HttpNoContent()
            else:
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request, updated_bundle)
        except (NotFound, MultipleObjectsReturned):
            updated_bundle = self.obj_create(
                bundle=bundle, **self.remove_api_resource_names(kwargs))
            location = self.get_resource_uri(updated_bundle)

            if not self._meta.always_return_data:
                return http.HttpCreated(location=location)
            else:
                updated_bundle = self.full_dehydrate(updated_bundle)
                updated_bundle = self.alter_detail_data_to_serialize(
                    request, updated_bundle)
                return self.create_response(request,
                                            updated_bundle,
                                            response_class=http.HttpCreated,
                                            location=location)
Exemple #20
0
    def delete_list(self, request, **kwargs):
        """
        Delete all ``Data`` in a ``Dataset``. Must be called from a data
        url nested under a Dataset. Deleting *all* ``Data`` objects is
        not supported.
        """
        dataset = Dataset.objects.get(slug=kwargs['dataset_slug'])

        # Because users may have authenticated via headers the request.user may
        # not be a full User instance. To be sure, we fetch one.
        user = UserProxy.objects.get(id=request.user.id)

        try:
            dataset.delete_all_rows(user)
        except DatasetLockedError:
            raise ImmediateHttpResponse(response=http.HttpForbidden(
                'Dataset is currently locked by another process.'))

        return http.HttpNoContent()
Exemple #21
0
    def dispatch(self, request_type, request, **kwargs):
        """
        Overrides Tastypie and calls get_list for GET, obj_create for POST,
        get_detail and obj_delete when fetching or delete an object with
        primary key requested
        """

        try:
            self.top_lvl_location_id = LocationPermission.objects.get(
                user_id=request.user.id).top_lvl_location_id
        except LocationPermission.DoesNotExist:
            self.top_lvl_location_id = Location.objects\
                .filter(parent_location_id=None)[0].id

        allowed_methods = getattr(self._meta,
                                  "%s_allowed_methods" % request_type, None)

        if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
            request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']

        request_method = self.method_check(request, allowed=allowed_methods)
        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            response = method(request, **kwargs)
        # except RhizomeApiException as error: ## use more specific exception.
        except Exception as error:  ## use more specific exception.
            data = {
                'traceback': traceback.format_exc(),
                'error': error.message,
                # 'code': error.code
            }
            return self.error_response(
                request, data, response_class=http.HttpApplicationError)

        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
    def mark_as_read(self, request, **kwargs):
        """Mark notification read by its recipient."""
        from invoicing.exceptions import InvalidInvoiceBaseState
        self.method_check(request, allowed=['put'])
        self.is_authenticated(request)
        self.throttle_check(request)

        try:
            bundle = self.build_bundle(request=request)
            obj = self.cached_obj_get(bundle=bundle, **self.remove_api_resource_names(kwargs))
        except ObjectDoesNotExist:
            return http.HttpNotFound()

        try:
            obj.read = True
            obj.save()
        except (obj.InvalidState, InvalidInvoiceBaseState) as e:
            raise BadRequest(e)

        self.log_throttled_access(request)

        return http.HttpNoContent()
Exemple #23
0
    def delete_detail(self, request, **kwargs):
        bundle = Bundle(request=request)
        bundle.obj = self.obj_get(bundle=bundle,
                                  **self.remove_api_resource_names(kwargs))
        if bundle.obj._meta.model._admin.delete_form:
            deserialized = self.deserialize(
                request,
                request.body or '{}',
                format=request.META.get('CONTENT_TYPE', 'application/json'),
            )

            Form = __import__(
                f'{bundle.obj._meta.app_label}.forms',
                globals(),
                locals(),
                [bundle.obj._meta.model._admin.delete_form],
                0,
            )
            Form = getattr(Form, bundle.obj._meta.model._admin.delete_form)

            form = Form(data=deserialized, instance=bundle.obj)
            if not form.is_valid():
                raise ImmediateHttpResponse(
                    response=self.error_response(request, form.errors))
        if bundle.obj._meta.model._admin.edit_modelform:
            ModelForm = __import__(
                f'{bundle.obj._meta.app_label}.forms',
                globals(),
                locals(),
                [bundle.obj._meta.model._admin.edit_modelform],
                0,
            )
            ModelForm = getattr(ModelForm,
                                bundle.obj._meta.model._admin.edit_modelform)
            mf = ModelForm(instance=bundle.obj)
            mf.delete()
            return http.HttpNoContent()
        else:
            return super().delete_detail(request, **kwargs)
    def dispatch(self, request_type, request, **kwargs):
        """
        Same as the usual dispatch, but knows if its being called from a nested
        resource.
        """
        allowed_methods = getattr(self._meta,
                                  "%s_allowed_methods" % request_type, None)
        request_method = self.method_check(request, allowed=allowed_methods)

        method = getattr(self, "%s_%s" % (request_method, request_type), None)

        if method is None:
            raise ImmediateHttpResponse(response=http.HttpNotImplemented())

        self.is_authenticated(request)
        self.throttle_check(request)

        parent_resource = kwargs.get('parent_resource', None)
        if parent_resource is None:
            self.is_authorized(request)
        else:
            self.is_authorized_nested(request, kwargs['nested_name'],
                                      parent_resource, kwargs['parent_object'])

        # All clear. Process the request.
        request = convert_post_to_put(request)
        response = method(request, **kwargs)

        # Add the throttled request.
        self.log_throttled_access(request)

        # If what comes back isn't a ``HttpResponse``, assume that the
        # request was accepted and that some action occurred. This also
        # prevents Django from freaking out.
        if not isinstance(response, HttpResponse):
            return http.HttpNoContent()

        return response
    def put_detail(self, request, **kwargs):
        deserialized = self.deserialize(request,
                                        request.raw_post_data,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)
        self.is_valid(bundle, request)

        updated_bundle = self.obj_update(
            bundle, request=request, **self.remove_api_resource_names(kwargs))

        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            updated_bundle = self.full_dehydrate(updated_bundle)
            updated_bundle = self.alter_detail_data_to_serialize(
                request, updated_bundle)
            return self.create_response(request,
                                        updated_bundle,
                                        response_class=http.HttpAccepted)
Exemple #26
0
    def aip_store_callback_request(self, request, bundle, **kwargs):
        package = bundle.obj

        callbacks = Callback.objects.filter(event="post_store")
        if len(callbacks) == 0:
            return http.HttpNoContent()

        fail = 0

        if package.is_compressed:
            # Don't extract the entire AIP, which could take forever;
            # instead, just extract bagit.txt and manifest-sha512.txt,
            # which is enough to get bag.entries with the
            # precalculated sha512 checksums
            try:
                basedir = package.get_base_directory()
            # Currently we only support this for local packages.
            except NotImplementedError:
                return http.HttpNoContent()

            _, tmpdir = package.extract_file(os.path.join(
                basedir, 'bagit.txt'))
            package.extract_file(os.path.join(basedir, 'manifest-sha512.txt'),
                                 extract_path=tmpdir)

            package_dir = os.path.join(tmpdir, basedir)
        else:
            package_dir = package.full_path()
            tmpdir = None

        safe_files = ('bag-info.txt', 'manifest-sha512.txt', 'bagit.txt')

        bag = bagit.Bag(package_dir)
        for f, checksums in bag.entries.iteritems():
            try:
                cksum = checksums['sha512']
            except KeyError:
                # These files do not typically have an sha512 hash, so it's
                # fine for these to be missing that key; every other file should.
                if f not in safe_files:
                    LOGGER.warning(
                        "Post-store callback: sha512 missing for file %s", f)
                continue

            files = File.objects.filter(checksum=cksum, stored=False)
            if len(files) > 1:
                LOGGER.warning("Multiple File entries found for sha512 %s",
                               cksum)

            for file_ in files:
                for callback in callbacks:
                    uri = callback.uri.replace('<source_id>', file_.source_id)
                    try:
                        callback.execute(uri)
                        file_.stored = True
                        file_.save()
                    except CallbackError:
                        fail += 1

        if tmpdir is not None:
            shutil.rmtree(tmpdir)

        if fail > 0:
            response = {
                "message":
                "Failed to POST {} responses to callback URI".format(fail),
                "failure_count":
                fail,
                "callback_uris": [c.uri for c in callbacks]
            }
            return http.HttpApplicationError(json.dumps(response),
                                             mimetype="application/json")
        else:
            return http.HttpNoContent()
Exemple #27
0
 def create_user_device(self, request, **kwargs):
     user_devices_resource = BanyanUserDevicesResource()
     if request.user.is_authenticated():
         return user_devices_resource.put_detail(request, user=request.user)
     else:
         return http.HttpNoContent()
Exemple #28
0
class AssetResource(IframePostDetailResource):
    # Explicitly declare fields that are on the translation model, or the
    # subclass
    title = fields.CharField(attribute='title', blank=True, default='')
    caption = fields.CharField(attribute='caption', blank=True, default='')
    body = fields.CharField(attribute='body', null=True)
    url = fields.CharField(attribute='url', null=True)
    image = fields.FileField(attribute='image', blank=True, null=True)
    content = fields.CharField(readonly=True)
    thumbnail_url = fields.CharField(readonly=True)
    display_title = fields.CharField(attribute='display_title', readonly=True)
    # A "write-only" field for specifying the filename when uploading images
    # This is removed from responses to GET requests
    filename = fields.CharField(null=True)

    class Meta:
        always_return_data = True
        queryset = Asset.objects.select_subclasses()
        resource_name = 'assets'
        list_allowed_methods = ['get', 'post', 'put']
        detail_allowed_methods = ['get', 'post', 'put', 'delete']
        authentication = Authentication()
        authorization = PublishedOwnerAuthorization()
        # Hide the underlying id
        excludes = ['id']

        featured_list_allowed_methods = ['get', 'put']
        featured_detail_allowed_methods = []
        date_fields = ['asset_created', 'published']

    def get_object_class(self, bundle=None, **kwargs):
        if bundle and bundle.obj and bundle.obj.asset_id:
            return bundle.obj.__class__

        content_fields = ('body', 'image', 'url')
        num_content_fields = 0
        for name in content_fields:
            if bundle.data.get(name):
                num_content_fields = num_content_fields + 1
        if num_content_fields > 1:
            raise BadRequest("You must specify only one of the following fields: image, body, or url")
        if bundle.data.get('body'):
            return HtmlAsset
        elif bundle.data.get('url'):
            return ExternalAsset
        elif bundle.data.get('image'):
            return LocalImageAsset
        else:
            raise BadRequest("You must specify an image, body, or url") 


    def prepend_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/(?P<asset_id>[0-9a-f]{32,32})%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_detail'),
                name="api_dispatch_detail"),
            url(r"^(?P<resource_name>%s)/stories/(?P<story_id>[0-9a-f]{32,32})%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/stories/(?P<story_id>[0-9a-f]{32,32})/featured%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_featured_list'),
                kwargs={'featured': True},
                name="api_dispatch_featured_list"),
            url(r"^(?P<resource_name>%s)/stories/(?P<story_id>[0-9a-f]{32,32})/sections/none%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_list'),
                kwargs={'no_section': True},
                name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/sections/(?P<section_id>[0-9a-f]{32,32})%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('dispatch_list'),
                name="api_dispatch_list"),
        ]

    def dispatch_featured_list(self, request, **kwargs):
        # This is defined as a separate method
        # so dispatch will check which method is allowed separately
        # from the other method handlers
        return self.dispatch('featured_list', request, **kwargs)

    def get_featured_list(self, request, **kwargs):
        # Just call through to get_list.  The filtering is handled
        # in apply_request_kwargs. 
        #
        # This is defined as a separate method
        # to match the naming conventions expected by dispatch().  
        # We do this so dispatch() will do a separate check for allowed
        # methods.
        return self.get_list(request, **kwargs)

    def put_featured_list(self, request, **kwargs):
        story_id = kwargs.pop('story_id')
        story = Story.objects.get(story_id=story_id)
        try:
            self._meta.authorization.obj_has_perms(story, 
                    request.user, ['change']) 
        except Unauthorized, e:
            self.unauthorized_result(e)

        deserialized = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))
        deserialized = self.alter_deserialized_list_data(request, deserialized)
        # Clear out existing relations
        story.featured_assets.clear()
        bundles = []
        asset_ids = [asset_data['asset_id'] for asset_data in deserialized]
        qs = self.get_object_list(request)
        assets = qs.filter(asset_id__in=asset_ids)
        for asset in assets:
            story.featured_assets.add(asset)
            bundles.append(self.build_bundle(obj=asset, request=request))
        story.save()

        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            to_be_serialized = {}
            to_be_serialized['objects'] = [self.full_dehydrate(bundle) for bundle in bundles]
            to_be_serialized = self.alter_list_data_to_serialize(request, to_be_serialized)
            return self.create_response(request, to_be_serialized, response_class=http.HttpAccepted)
Exemple #29
0
    def put_list(self, request, **kwargs):
        """
        A custom bulk create/update handler. Notes: 

        * ``obj_delete_list`` is never called, objects are overwritten instead.
        * All objects are validated before any objects are created, so ``rollback`` is unnecessary.
        * A single dataset save and Solr commit are made at the end (optimization!).
        """
        deserialized = self.deserialize(request,
                                        request.raw_post_data,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))
        deserialized = self.alter_deserialized_list_data(request, deserialized)

        if not 'objects' in deserialized:
            raise BadRequest("Invalid data sent.")

        bundles = []
        data = []

        dataset = self.get_dataset_from_kwargs(None, **kwargs)

        for object_data in deserialized['objects']:
            bundle = self.build_bundle(
                data=dict_strip_unicode_keys(object_data), request=request)

            self.is_valid(bundle, request)

            if bundle.errors:
                self.error_response(bundle.errors, request)

            bundles.append(bundle)
            data.append(
                (bundle.data['data'], bundle.data.get('external_id', None)))

            self.validate_bundle_data(bundle, request, dataset)

        # Because users may have authenticated via headers the request.user may
        # not be a full User instance. To be sure, we fetch one.
        user = UserProxy.objects.get(id=request.user.id)

        try:
            solr_rows = dataset.add_many_rows(user, data)
        except DatasetLockedError:
            raise ImmediateHttpResponse(response=http.HttpForbidden(
                'Dataset is currently locked by another process.'))

        for bundle, solr_row in zip(bundles, solr_rows):
            bundle.obj = SolrObject(solr_row)

        if not self._meta.always_return_data:
            return http.HttpNoContent()
        else:
            to_be_serialized = {}
            to_be_serialized['objects'] = [
                self.full_dehydrate(bundle) for bundle in bundles
            ]
            to_be_serialized = self.alter_list_data_to_serialize(
                request, to_be_serialized)

            return self.create_response(request,
                                        to_be_serialized,
                                        response_class=http.HttpAccepted)
Exemple #30
0
    def process_file(self, request, **kwargs):
        """
        :param request:     incoming http request
        :param pk:          ID of the object that has file fields
        :param attr_name:   name of the attribute where the file is stored
        :return:            Http Response
        """
        attr_name = kwargs.pop('attr_name')

        if not request.method in ['GET', 'POST']:
            return http.HttpMethodNotAllowed("Use GET or POST to manage files")

        try:
            bundle = self.build_bundle(data={'pk': kwargs['pk']},
                                       request=request)
            obj = self.cached_obj_get(bundle=bundle,
                                      **self.remove_api_resource_names(kwargs))

        except ObjectDoesNotExist:
            return http.HttpGone()

        except MultipleObjectsReturned:
            return http.HttpMultipleChoices("More than one object found "
                                            "at this URL.")
        try:
            field = self._meta.object_class._meta.get_field_by_name(
                attr_name)[0]

        except FieldDoesNotExist:
            return http.HttpBadRequest("Attribute %s does not exist" %
                                       attr_name)

        if not isinstance(field, models.FileField):
            return http.HttpBadRequest("Attribute %s is not a data-field" %
                                       attr_name)

        if request.method == 'GET':
            ffile = getattr(obj, attr_name)
            try:
                filepath = ffile.path
            except ValueError:  # file is not set, empty
                return http.HttpNoContent()

            with open(filepath, 'r') as f:
                response = HttpResponse(f.read(),
                                        content_type='application/x-hdf')
                response['Content-Disposition'] = "attachment; filename=%s" % \
                                                  os.path.basename(filepath)
                response['Content-Length'] = os.path.getsize(f.name)
                return response

        if not obj.is_editable(request.user):
            return http.HttpUnauthorized("No access to the update this object")

        if not len(request.FILES) > 0:
            return http.HttpNoContent()

        # take first file in the multipart/form request
        setattr(obj, attr_name, request.FILES.values()[0])
        obj.save()
        return http.HttpAccepted("File content updated successfully")