Esempio n. 1
0
def update_object_in_search_index(obj):
    '''
    If a search index exists for the type of `obj`, update it. Otherwise, do
    nothing
    '''
    try:
        index = haystack.connections['default'].get_unified_index().get_index(
            type(obj))
    except haystack.exceptions.NotHandled:
        # There's nothing to update because this type of object is not indexed
        logging.warning('No search index for type {}'.format(type(obj)),
                        exc_info=True)
        return
    index.update_object(obj)
Esempio n. 2
0
    def _get_metadata(self, metadata: Union[str, dict]) -> dict:
        """
        `metadata` parameter can be sent as a stringified JSON or in pure JSON.
        """
        if not isinstance(metadata, dict):
            try:
                metadata = json.loads(metadata)
                logging.warning('metadata is sent as stringified JSON')
            except TypeError:
                # Let the validator returns an explicit message to user that
                # `metadata` is required
                pass
            except ValueError:
                raise serializers.ValidationError(
                    {'metadata': _('JSON is invalid')})

        return metadata
Esempio n. 3
0
def set_kc_anonymous_permissions_xform_flags(obj,
                                             kpi_codenames,
                                             xform_id,
                                             remove=False):
    r"""
        Given a KPI object, one or more KPI permission codenames and the PK of
        a KC `XForm`, assume the KPI permisisons have been assigned to or
        removed from the anonymous user. Then, modify any corresponding flags
        on the `XForm` accordingly.
        :param obj: Object with `KC_ANONYMOUS_PERMISSIONS_XFORM_FLAGS`
            dictionary attribute
        :param kpi_codenames: One or more codenames for KPI permissions
        :type kpi_codenames: str or list(str)
        :param xform_id: PK of the KC `XForm` associated with `obj`
        :param remove: If `True`, apply the Boolean `not` operator to each
            value in `KC_ANONYMOUS_PERMISSIONS_XFORM_FLAGS`
    """
    if not settings.KOBOCAT_URL or not settings.KOBOCAT_INTERNAL_URL:
        return
    try:
        perms_to_flags = obj.KC_ANONYMOUS_PERMISSIONS_XFORM_FLAGS
    except AttributeError:
        logging.warning(
            '{} object missing KC_ANONYMOUS_PERMISSIONS_XFORM_FLAGS'.format(
                type(obj)))
        return
    if isinstance(kpi_codenames, basestring):
        kpi_codenames = [kpi_codenames]
    # Find which KC `XForm` flags need to be switched
    xform_updates = {}
    for kpi_codename in kpi_codenames:
        try:
            flags = perms_to_flags[kpi_codename]
        except KeyError:
            # This permission doesn't map to anything in KC
            continue
        if remove:
            flags = {flag: not value for flag, value in flags.iteritems()}
        xform_updates.update(flags)
    # Write to the KC database
    _models.XForm.objects.filter(pk=xform_id).update(**xform_updates)
Esempio n. 4
0
    def list(self, request, *args, **kwargs):
        format_type = kwargs.get('format', request.GET.get('format', 'json'))
        deployment = self._get_deployment()
        filters = self._filter_mongo_query(request)

        if format_type == 'geojson':
            # For GeoJSON, get the submissions as JSON and let
            # `SubmissionGeoJsonRenderer` handle the rest
            return Response(
                deployment.get_submissions(
                    user=request.user,
                    format_type=SUBMISSION_FORMAT_TYPE_JSON,
                    request=request,
                    **filters
                )
            )

        try:
            submissions = deployment.get_submissions(request.user,
                                                    format_type=format_type,
                                                    request=request,
                                                    **filters)
        except OperationFailure as err:
            message = str(err)
            # Don't show just any raw exception message out of fear of data leaking
            if message == '$all needs an array':
                raise serializers.ValidationError(message)
            logging.warning(message, exc_info=True)
            raise serializers.ValidationError('Unsupported query')
        # Create a dummy list to let the Paginator do all the calculation
        # for pagination because it does not need the list of real objects.
        # It avoids retrieving all the objects from MongoDB
        dummy_submissions_list = [None] * deployment.current_submissions_count
        page = self.paginate_queryset(dummy_submissions_list)
        if page is not None:
            return self.get_paginated_response(submissions)

        return Response(list(submissions))