Example #1
0
 def get_meta_information(self, meta_data, value):
     """
     For retrieving meta values, otherwise returns {}
     """
     meta = {}
     for key in meta_data or {}:
         if key == 'count':
             show_related_counts = self.context['request'].query_params.get(
                 'related_counts', False)
             if utils.is_truthy(show_related_counts):
                 meta[key] = website_utils.rapply(meta_data[key],
                                                  _url_val,
                                                  obj=value,
                                                  serializer=self.parent)
             elif utils.is_falsy(show_related_counts):
                 continue
             if not utils.is_truthy(show_related_counts):
                 raise InvalidQueryStringError(
                     detail=
                     "Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'"
                     .format(show_related_counts),
                     parameter='related_counts')
         else:
             meta[key] = website_utils.rapply(meta_data[key],
                                              _url_val,
                                              obj=value,
                                              serializer=self.parent)
     return meta
Example #2
0
 def _library_list(auth, node_addon, **kwargs):
     """ Returns a list of group libraries - for use with Zotero addon
     """
     limit = request.args.get('limit')
     start = request.args.get('start')
     return_count = is_truthy(request.args.get('return_count', False))
     append_personal = is_truthy(request.args.get('append_personal', True))
     return node_addon.get_folders(limit=limit, start=start, return_count=return_count, append_personal=append_personal)
Example #3
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get(
                    'related_counts', False)
                field_counts_requested = self.process_related_counts_parameters(
                    show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key],
                                                     _url_val,
                                                     obj=value,
                                                     serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key],
                                                     _url_val,
                                                     obj=value,
                                                     serializer=self.parent)
                else:
                    continue
            else:
                meta[key] = website_utils.rapply(meta_data[key],
                                                 _url_val,
                                                 obj=value,
                                                 serializer=self.parent)
        return meta
Example #4
0
    def process_related_counts_parameters(self, params, value):
        """
        Processes related_counts parameter.

        Can either be a True/False value for fetching counts on all fields, or a comma-separated list for specifying
        individual fields.  Ensures field for which we are requesting counts is a relationship field.
        """
        if utils.is_truthy(params) or utils.is_falsy(params):
            return params

        field_counts_requested = [val for val in params.split(',')]

        countable_fields = {field for field in self.parent.fields if
                            getattr(self.parent.fields[field], 'json_api_link', False) or
                            getattr(getattr(self.parent.fields[field], 'field', None), 'json_api_link', None)}
        for count_field in field_counts_requested:
            # Some fields will hide relationships, e.g. HideIfWithdrawal
            # Ignore related_counts for these fields
            fetched_field = self.parent.fields.get(count_field)

            hidden = fetched_field and isinstance(fetched_field, HideIfWithdrawal) and getattr(value, 'is_retracted', False)

            if not hidden and count_field not in countable_fields:
                raise InvalidQueryStringError(
                    detail="Acceptable values for the related_counts query param are 'true', 'false', or any of the relationship fields; got '{0}'".format(
                        params),
                    parameter='related_counts'
                )
        return field_counts_requested
Example #5
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(value=value, field_type="bool")
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(value=value, field_type="date")
     elif isinstance(field, (self.LIST_FIELDS, self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)) or isinstance(
         (getattr(field, "field", None)), self.LIST_FIELDS
     ):
         if value == "null":
             value = None
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value)
Example #6
0
    def to_representation(self, value):
        """
        Returns nested dictionary in format {'links': {'self.link_type': ... }

        If no meta information, self.link_type is equal to a string containing link's URL.  Otherwise,
        the link is represented as a links object with 'href' and 'meta' members.
        """
        url = super(JSONAPIHyperlinkedIdentityField,
                    self).to_representation(value)

        meta = {}
        for key in self.meta or {}:
            if key == 'count':
                show_related_counts = self.context['request'].query_params.get(
                    'related_counts', False)
                if utils.is_truthy(show_related_counts):
                    meta[key] = _rapply(self.meta[key],
                                        _url_val,
                                        obj=value,
                                        serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                else:
                    raise InvalidQueryStringError(
                        detail=
                        "Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'"
                        .format(show_related_counts),
                        parameter='related_counts')
        return {'links': {self.link_type: {'href': url, 'meta': meta}}}
Example #7
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool'
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date'
             )
     elif isinstance(field, self.LIST_FIELDS):
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(
                 value=value,
             )
Example #8
0
    def get_queryset(self):
        # For bulk requests, queryset is formed from request body.
        if is_bulk_request(self.request):
            auth = get_user_auth(self.request)
            registrations = Registration.objects.filter(guids___id__in=[
                registration['id'] for registration in self.request.data
            ])

            # If skip_uneditable=True in query_params, skip nodes for which the user
            # does not have EDIT permissions.
            if is_truthy(
                    self.request.query_params.get('skip_uneditable', False)):
                has_permission = registrations.filter(
                    contributor__user_id=auth.user.id,
                    contributor__write=True).values_list('guids___id',
                                                         flat=True)
                return Registration.objects.filter(
                    guids___id__in=has_permission)

            for registration in registrations:
                if not registration.can_edit(auth):
                    raise PermissionDenied
            return registrations
        blacklisted = self.is_blacklisted()
        registrations = self.get_queryset_from_request()
        # If attempting to filter on a blacklisted field, exclude withdrawals.
        if blacklisted:
            return registrations.exclude(retraction__isnull=False)
        return registrations
Example #9
0
    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        if 'template_from' in validated_data:
            template_from = validated_data.pop('template_from')
            template_node = Node.load(key=template_from)
            if template_node is None:
                raise exceptions.NotFound
            if not template_node.has_permission(user, 'read', check_parent=False):
                raise exceptions.PermissionDenied

            validated_data.pop('creator')
            changed_data = {template_from: validated_data}
            node = template_node.use_as_template(auth=get_user_auth(request), changes=changed_data)
        else:
            node = Node(**validated_data)
        try:
            node.save()
        except ValidationValueError as e:
            raise InvalidModelValueError(detail=e.message)
        if is_truthy(request.GET.get('inherit_contributors')) and validated_data['parent'].has_permission(user, 'write'):
            auth = get_user_auth(request)
            parent = validated_data['parent']
            contributors = []
            for contributor in parent.contributors:
                if contributor is not user:
                    contributors.append({
                        'user': contributor,
                        'permissions': parent.get_permissions(contributor),
                        'visible': parent.get_visible(contributor)
                    })
            node.add_contributors(contributors, auth=auth, log=True, save=True)
        return node
Example #10
0
    def process_related_counts_parameters(self, params, value):
        """
        Processes related_counts parameter.

        Can either be a True/False value for fetching counts on all fields, or a comma-separated list for specifying
        individual fields.  Ensures field for which we are requesting counts is a relationship field.
        """
        if utils.is_truthy(params) or utils.is_falsy(params):
            return params

        field_counts_requested = [val for val in params.split(',')]

        countable_fields = {field for field in self.parent.fields if
                            getattr(self.parent.fields[field], 'json_api_link', False) or
                            getattr(getattr(self.parent.fields[field], 'field', None), 'json_api_link', None)}
        for count_field in field_counts_requested:
            # Some fields will hide relationships, e.g. HideIfWithdrawal
            # Ignore related_counts for these fields
            fetched_field = self.parent.fields.get(count_field)

            hidden = fetched_field and isinstance(fetched_field, HideIfWithdrawal) and getattr(value, 'is_retracted', False)

            if not hidden and count_field not in countable_fields:
                raise InvalidQueryStringError(
                    detail="Acceptable values for the related_counts query param are 'true', 'false', or any of the relationship fields; got '{0}'".format(
                        params),
                    parameter='related_counts'
                )
        return field_counts_requested
Example #11
0
    def get_queryset(self):
        # For bulk requests, queryset is formed from request body.
        if is_bulk_request(self.request):
            auth = get_user_auth(self.request)
            registrations = Registration.objects.filter(guids___id__in=[
                registration['id'] for registration in self.request.data
            ])

            # If skip_uneditable=True in query_params, skip nodes for which the user
            # does not have EDIT permissions.
            if is_truthy(
                    self.request.query_params.get('skip_uneditable', False)):
                return Registration.objects.get_nodes_for_user(
                    auth.user, WRITE_NODE, registrations)

            for registration in registrations:
                if not registration.can_edit(auth):
                    raise PermissionDenied
            return registrations

        blacklisted = self.is_blacklisted()
        registrations = self.get_queryset_from_request()
        # If attempting to filter on a blacklisted field, exclude withdrawals.
        if blacklisted:
            registrations = registrations.exclude(retraction__isnull=False)

        return registrations.select_related(
            'root',
            'root__embargo',
            'root__embargo_termination_approval',
            'root__retraction',
            'root__registration_approval',
        )
Example #12
0
 def update(self, registration, validated_data):
     user = self.context['request'].user
     auth = Auth(user)
     user_is_admin = registration.has_permission(user, permissions.ADMIN)
     # Update tags
     if 'tags' in validated_data:
         new_tags = validated_data.pop('tags', [])
         try:
             registration.update_tags(new_tags, auth=auth)
         except NodeStateError as err:
             raise Conflict(str(err))
     if 'custom_citation' in validated_data:
         if user_is_admin:
             registration.update_custom_citation(
                 validated_data.pop('custom_citation'), auth)
         else:
             raise exceptions.PermissionDenied()
     is_public = validated_data.get('is_public', None)
     if is_public is not None:
         if is_public:
             if user_is_admin:
                 try:
                     registration.update(validated_data, auth=auth)
                 except NodeUpdateError as err:
                     raise exceptions.ValidationError(err.reason)
                 except NodeStateError as err:
                     raise exceptions.ValidationError(str(err))
             else:
                 raise exceptions.PermissionDenied()
         else:
             raise exceptions.ValidationError(
                 'Registrations can only be turned from private to public.')
     if 'withdrawal_justification' in validated_data or 'is_pending_retraction' in validated_data:
         if user_is_admin:
             is_pending_retraction = validated_data.get(
                 'is_pending_retraction', None)
             withdrawal_justification = validated_data.get(
                 'withdrawal_justification', None)
             if withdrawal_justification and not is_pending_retraction:
                 raise exceptions.ValidationError(
                     'You cannot provide a withdrawal_justification without a concurrent withdrawal request.',
                 )
             if is_truthy(is_pending_retraction):
                 if registration.is_pending_retraction:
                     raise exceptions.ValidationError(
                         'This registration is already pending withdrawal')
                 try:
                     retraction = registration.retract_registration(
                         user, withdrawal_justification, save=True)
                 except NodeStateError as err:
                     raise exceptions.ValidationError(str(err))
                 retraction.ask(
                     registration.get_active_contributors_recursive(
                         unique_users=True))
             elif is_pending_retraction is not None:
                 raise exceptions.ValidationError(
                     'You cannot set is_pending_withdrawal to False.')
         else:
             raise exceptions.PermissionDenied()
     return registration
Example #13
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                if self.context['request'].parser_context.get('kwargs'):
                    if self.context['request'].parser_context['kwargs'].get('is_embedded'):
                        show_related_counts = False
                field_counts_requested = self.process_related_counts_parameters(show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                else:
                    continue
            elif key == 'projects_in_common':
                if not get_user_auth(self.context['request']).user:
                    continue
                if not self.context['request'].query_params.get('show_projects_in_common', False):
                    continue
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
            else:
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
        return meta
Example #14
0
    def update(self, instance, validated_data):

        # avoiding circular import
        from api.nodes.serializers import ContributorIDField

        # if PATCH request, the child serializer's partial attribute needs to be True
        if self.context['request'].method == 'PATCH':
            self.child.partial = True

        bulk_skip_uneditable = utils.is_truthy(self.context['request'].query_params.get('skip_uneditable', False))
        if not bulk_skip_uneditable:
            if len(instance) != len(validated_data):
                raise exceptions.ValidationError({'non_field_errors': 'Could not find all objects to update.'})

        id_lookup = self.child.fields['id'].source
        data_mapping = {item.get(id_lookup): item for item in validated_data}

        if isinstance(self.child.fields['id'], ContributorIDField):
            instance_mapping = {self.child.fields['id'].get_id(item): item for item in instance}
        else:
            instance_mapping = {getattr(item, id_lookup): item for item in instance}

        ret = {'data': []}

        for resource_id, resource in instance_mapping.items():
            data = data_mapping.pop(resource_id, None)
            ret['data'].append(self.child.update(resource, data))

        # If skip_uneditable in request, add validated_data for nodes in which the user did not have edit permissions to errors
        if data_mapping and bulk_skip_uneditable:
            ret.update({'errors': data_mapping.values()})
        return ret
Example #15
0
    def to_representation(self, data):
        enable_esi = self.context.get('enable_esi', False)
        envelope = self.context.update({'envelope': None})
        # Don't envelope when serializing collection
        errors = {}
        bulk_skip_uneditable = utils.is_truthy(
            self.context['request'].query_params.get('skip_uneditable', False))

        if isinstance(data, collections.Mapping):
            errors = data.get('errors', None)
            data = data.get('data', None)
        if enable_esi:
            ret = [
                self.child.to_esi_representation(item, envelope=None)
                for item in data
            ]
        else:
            ret = [
                self.child.to_representation(item, envelope=envelope)
                for item in data
            ]

        if errors and bulk_skip_uneditable:
            ret.append({'errors': errors})

        return ret
Example #16
0
    def to_representation(self, value):
        """
        Returns nested dictionary in format {'links': {'self.link_type': ... }

        If no meta information, self.link_type is equal to a string containing link's URL.  Otherwise,
        the link is represented as a links object with 'href' and 'meta' members.
        """
        url = super(JSONAPIHyperlinkedIdentityField, self).to_representation(value)

        meta = {}
        for key in self.meta or {}:
            if key == 'count':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                if utils.is_truthy(show_related_counts):
                    meta[key] = _rapply(self.meta[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                else:
                    raise InvalidQueryStringError(
                        detail="Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'".format(show_related_counts),
                        parameter='related_counts'
                    )
            else:
                meta[key] = _rapply(self.meta[key], _url_val, obj=value, serializer=self.parent)

        return {'links': {self.link_type: {'href': url, 'meta': meta}}}
Example #17
0
    def update(self, instance, validated_data):
        # if PATCH request, the child serializer's partial attribute needs to be True
        if self.context['request'].method == 'PATCH':
            self.child.partial = True

        bulk_skip_uneditable = utils.is_truthy(
            self.context['request'].query_params.get('skip_uneditable', False))
        if not bulk_skip_uneditable:
            if len(instance) != len(validated_data):
                raise exceptions.ValidationError({
                    'non_field_errors':
                    'Could not find all objects to update.'
                })

        id_lookup = self.child.fields['id'].source
        instance_mapping = {
            getattr(item, id_lookup): item
            for item in instance
        }
        data_mapping = {item.get(id_lookup): item for item in validated_data}

        ret = {'data': []}

        for resource_id, resource in instance_mapping.items():
            data = data_mapping.pop(resource_id, None)
            ret['data'].append(self.child.update(resource, data))

        # If skip_uneditable in request, add validated_data for nodes in which the user did not have edit permissions to errors
        if data_mapping and bulk_skip_uneditable:
            ret.update({'errors': data_mapping.values()})
        return ret
Example #18
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(value=value, field_type='bool')
     elif isinstance(field, self.DATE_FIELDS):
         try:
             return date_parser.parse(value)
         except ValueError:
             raise InvalidFilterValue(value=value, field_type='date')
     elif isinstance(field, (self.LIST_FIELDS, self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)) \
             or isinstance((getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = None
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value, )
Example #19
0
    def get_queryset(self):
        # For bulk requests, queryset is formed from request body.
        if is_bulk_request(self.request):
            auth = get_user_auth(self.request)
            registrations = Registration.objects.filter(guids___id__in=[registration['id'] for registration in self.request.data])

            # If skip_uneditable=True in query_params, skip nodes for which the user
            # does not have EDIT permissions.
            if is_truthy(self.request.query_params.get('skip_uneditable', False)):
                has_permission = registrations.filter(contributor__user_id=auth.user.id, contributor__write=True).values_list('guids___id', flat=True)
                return Registration.objects.filter(guids___id__in=has_permission)

            for registration in registrations:
                if not registration.can_edit(auth):
                    raise PermissionDenied
            return registrations

        blacklisted = self.is_blacklisted()
        registrations = self.get_queryset_from_request()
        # If attempting to filter on a blacklisted field, exclude withdrawals.
        if blacklisted:
            registrations = registrations.exclude(retraction__isnull=False)

        return registrations.select_related(
            'root',
            'root__embargo',
            'root__embargo_termination_approval',
            'root__retraction',
            'root__registration_approval',
        )
Example #20
0
 def get(self, request, *args, **kwargs):
     response = super(UserEmailsDetail, self).get(request, *args, **kwargs)
     if is_truthy(self.request.query_params.get('resend_confirmation')):
         user = self.get_user()
         email_id = kwargs.get('email_id')
         if user.unconfirmed_emails and user.email_verifications.get(email_id):
             response.status = response.status_code = status.HTTP_202_ACCEPTED
     return response
Example #21
0
 def get_renderer_context(self):
     context = super().get_renderer_context()
     if is_truthy(self.request.query_params.get('meta[reviews_state_counts]', False)):
         provider = self.get_provider()
         context['meta'] = {
             'reviews_state_counts': provider.get_reviewable_state_counts(),
         }
     return context
Example #22
0
 def get_renderer_context(self):
     context = super(RegistrationDetail, self).get_renderer_context()
     show_counts = is_truthy(self.request.query_params.get('related_counts', False))
     if show_counts:
         registration = self.get_object()
         context['meta'] = {
             'templated_by_count': registration.templated_list.count(),
         }
     return context
Example #23
0
 def get_renderer_context(self):
     context = super(RegistrationDetail, self).get_renderer_context()
     show_counts = is_truthy(self.request.query_params.get('related_counts', False))
     if show_counts:
         registration = self.get_object()
         context['meta'] = {
             'templated_by_count': registration.templated_list.count(),
         }
     return context
Example #24
0
    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        Node = apps.get_model('osf.Node')
        tag_instances = []
        if 'tags' in validated_data:
            tags = validated_data.pop('tags')
            for tag in tags:
                tag_instance, created = Tag.objects.get_or_create(
                    name=tag, defaults=dict(system=False))
                tag_instances.append(tag_instance)
        if 'template_from' in validated_data:
            template_from = validated_data.pop('template_from')
            template_node = Node.load(template_from)
            if template_node is None:
                raise exceptions.NotFound
            if not template_node.has_permission(
                    user, 'read', check_parent=False):
                raise exceptions.PermissionDenied

            validated_data.pop('creator')
            changed_data = {template_from: validated_data}
            node = template_node.use_as_template(auth=get_user_auth(request),
                                                 changes=changed_data)
        else:
            node = Node(**validated_data)
        try:
            node.save()
        except ValidationError as e:
            raise InvalidModelValueError(detail=e.messages[0])
        if len(tag_instances):
            for tag in tag_instances:
                node.tags.add(tag)
        if is_truthy(request.GET.get('inherit_contributors')
                     ) and validated_data['parent'].has_permission(
                         user, 'write'):
            auth = get_user_auth(request)
            parent = validated_data['parent']
            contributors = []
            for contributor in parent.contributor_set.exclude(user=user):
                contributors.append({
                    'user':
                    contributor.user,
                    'permissions':
                    parent.get_permissions(contributor.user),
                    'visible':
                    contributor.visible
                })
                if not contributor.user.is_registered:
                    node.add_unregistered_contributor(
                        fullname=contributor.user.fullname,
                        email=contributor.user.email,
                        auth=auth,
                        permissions=parent.get_permissions(contributor.user),
                        existing_user=contributor.user)
            node.add_contributors(contributors, auth=auth, log=True, save=True)
        return node
Example #25
0
 def get_renderer_context(self):
     context = super(PreprintProviderWithdrawRequestList, self).get_renderer_context()
     if is_truthy(self.request.query_params.get('meta[requests_state_counts]', False)):
         auth = get_user_auth(self.request)
         auth_user = getattr(auth, 'user', None)
         provider = self.get_provider()
         if auth_user and auth_user.has_perm('view_submissions', provider):
             context['meta'] = {
                 'requests_state_counts': provider.get_request_state_counts(),
             }
     return context
Example #26
0
 def get_meta_information(self, meta_data, value):
     """
     For retrieving meta values, otherwise returns {}
     """
     meta = {}
     for key in meta_data or {}:
         if key == 'count' or key == 'unread':
             show_related_counts = self.context['request'].query_params.get('related_counts', False)
             if utils.is_truthy(show_related_counts):
                 meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
             elif utils.is_falsy(show_related_counts):
                 continue
             if not utils.is_truthy(show_related_counts):
                 raise InvalidQueryStringError(
                     detail="Acceptable values for the related_counts query param are 'true' or 'false'; got '{0}'".format(show_related_counts),
                     parameter='related_counts'
                 )
         else:
             meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
     return meta
Example #27
0
    def get_serializer_context(self):
        """Inject request into the serializer context. Additionally, inject partial functions
        (request, object -> embed items) if the query string contains embeds.  Allows
         multiple levels of nesting.
        """
        context = super(JSONAPIBaseView, self).get_serializer_context()
        if self.kwargs.get('is_embedded'):
            embeds = []
        else:
            embeds = self.request.query_params.getlist(
                'embed') or self.request.query_params.getlist('embed[]')

        fields_check = self.get_serializer_class()._declared_fields.copy()
        serializer_class_type = get_meta_type(self.serializer_class,
                                              self.request)
        if 'fields[{}]'.format(
                serializer_class_type) in self.request.query_params:
            # Check only requested and mandatory fields
            sparse_fields = self.request.query_params['fields[{}]'.format(
                serializer_class_type)]
            for field in fields_check.copy().keys():
                if field not in ('type', 'id',
                                 'links') and field not in sparse_fields:
                    fields_check.pop(field)

        for field in fields_check:
            if getattr(fields_check[field], 'field', None):
                fields_check[field] = fields_check[field].field

        for field in fields_check:
            if getattr(fields_check[field], 'always_embed',
                       False) and field not in embeds:
                embeds.append(unicode(field))
            if getattr(fields_check[field], 'never_embed',
                       False) and field in embeds:
                embeds.remove(field)
        embeds_partials = {}
        for embed in embeds:
            embed_field = fields_check.get(embed)
            embeds_partials[embed] = self._get_embed_partial(
                embed, embed_field)

        context.update({
            'enable_esi': (utils.is_truthy(
                self.request.query_params.get('esi',
                                              django_settings.ENABLE_ESI))
                           and self.request.accepted_renderer.media_type
                           in django_settings.ESI_MEDIA_TYPES),
            'embed':
            embeds_partials,
            'envelope':
            self.request.query_params.get('envelope', 'data'),
        })
        return context
Example #28
0
 def get_renderer_context(self):
     context = super(PreprintProviderWithdrawRequestList, self).get_renderer_context()
     if is_truthy(self.request.query_params.get('meta[requests_state_counts]', False)):
         auth = get_user_auth(self.request)
         auth_user = getattr(auth, 'user', None)
         provider = self.get_provider()
         if auth_user and auth_user.has_perm('view_submissions', provider):
             context['meta'] = {
                 'requests_state_counts': provider.get_request_state_counts(),
             }
     return context
Example #29
0
 def convert_value(self, value, field):
     field_type = type(self.serializer_class._declared_fields[field])
     value = value.strip()
     if field_type == ser.BooleanField:
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         # TODO Should we handle if the value is neither TRUTHY nor FALSY (first add test for how we'd expect it to
         # work, then ensure that it works that way).
     else:
         return value
Example #30
0
 def convert_value(self, value, field):
     field_type = type(self.serializer_class._declared_fields[field])
     value = value.strip()
     if field_type == ser.BooleanField:
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         # TODO Should we handle if the value is neither TRUTHY nor FALSY (first add test for how we'd expect it to
         # work, then ensure that it works that way).
     else:
         return value
Example #31
0
    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        if 'template_from' in validated_data:
            template_from = validated_data.pop('template_from')
            template_node = Node.load(key=template_from)
            if template_node is None:
                raise exceptions.NotFound
            if not template_node.has_permission(
                    user, 'read', check_parent=False):
                raise exceptions.PermissionDenied

            validated_data.pop('creator')
            changed_data = {template_from: validated_data}
            node = template_node.use_as_template(auth=get_user_auth(request),
                                                 changes=changed_data)
        else:
            node = Node(**validated_data)
        try:
            node.save()
        except ValidationValueError as e:
            raise InvalidModelValueError(detail=e.message)
        if is_truthy(request.GET.get('inherit_contributors')
                     ) and validated_data['parent'].has_permission(
                         user, 'write'):
            auth = get_user_auth(request)
            parent = validated_data['parent']
            contributors = []
            for contributor in parent.contributors:
                if contributor is not user:
                    contributors.append({
                        'user':
                        contributor,
                        'permissions':
                        parent.get_permissions(contributor),
                        'visible':
                        parent.get_visible(contributor)
                    })

                if not contributor.is_registered:
                    node.add_unregistered_contributor(
                        fullname=contributor.fullname,
                        email=contributor.email,
                        auth=auth,
                        permissions=parent.get_permissions(contributor),
                        existing_user=contributor)

                node.add_contributors(contributors,
                                      auth=auth,
                                      log=True,
                                      save=True)
        return node
Example #32
0
 def get_renderer_context(self):
     context = super(PreprintProviderPreprintList, self).get_renderer_context()
     show_counts = is_truthy(self.request.query_params.get('meta[reviews_state_counts]', False))
     if show_counts:
         # TODO don't duplicate the above
         auth = get_user_auth(self.request)
         auth_user = getattr(auth, 'user', None)
         provider = get_object_or_error(PreprintProvider, self.kwargs['provider_id'], self.request, display_name='PreprintProvider')
         if auth_user and auth_user.has_perm('view_submissions', provider):
             context['meta'] = {
                 'reviews_state_counts': provider.get_reviewable_state_counts(),
             }
     return context
Example #33
0
 def get_renderer_context(self):
     context = super(PreprintProviderPreprintList, self).get_renderer_context()
     show_counts = is_truthy(self.request.query_params.get('meta[reviews_state_counts]', False))
     if show_counts:
         # TODO don't duplicate the above
         auth = get_user_auth(self.request)
         auth_user = getattr(auth, 'user', None)
         provider = get_object_or_error(PreprintProvider, self.kwargs['provider_id'], self.request, display_name='PreprintProvider')
         if auth_user and auth_user.has_perm('view_submissions', provider):
             context['meta'] = {
                 'reviews_state_counts': provider.get_reviewable_state_counts(),
             }
     return context
Example #34
0
    def build_query_from_field(self, field_name, operation):
        if field_name == 'parent':
            if operation['op'] == 'eq':
                if operation['value']:
                    # filter[parent]=<nid>
                    parent = utils.get_object_or_error(AbstractNode,
                                                       operation['value'],
                                                       self.request,
                                                       display_name='parent')
                    node_ids = NodeRelation.objects.filter(
                        parent=parent,
                        is_node_link=False).values_list('child_id', flat=True)
                    return Q(id__in=node_ids)
            elif operation['op'] == 'ne':
                if not operation['value']:
                    # filter[parent][ne]=null
                    child_ids = (NodeRelation.objects.filter(
                        is_node_link=False,
                        child___contributors=self.get_user(),
                    ).exclude(parent__type='osf.collection').exclude(
                        child__is_deleted=True).values_list('child_id',
                                                            flat=True))
                    return Q(id__in=set(child_ids))
                # TODO: support this case in the future:
                # else filter[parent][ne]=<nid>
                raise InvalidFilterValue(
                    detail=
                    'Only "null" is accepted as valid input to "filter[parent][ne]"'
                )
            else:
                # filter[parent][gte]=''
                raise InvalidFilterOperator(value=operation['op'],
                                            valid_operators=['eq', 'ne'])

        if field_name == 'root':
            if None in operation['value']:
                raise InvalidFilterValue(value=operation['value'])
            with_as_root_query = Q(root__guids___id__in=operation['value'])
            return ~with_as_root_query if operation[
                'op'] == 'ne' else with_as_root_query

        if field_name == 'preprint':
            not_preprint_query = (Q(preprint_file=None)
                                  | Q(_is_preprint_orphan=True)
                                  | Q(_has_abandoned_preprint=True))

            return ~not_preprint_query if utils.is_truthy(
                operation['value']) else not_preprint_query

        return super(NodesFilterMixin,
                     self).build_query_from_field(field_name, operation)
Example #35
0
    def get_object(self):
        email_id = self.kwargs['email_id']
        user = self.get_user()
        email = None

        # check to see if it's a confirmed email with hashed id
        decoded_id = hashids.decode(email_id)
        if decoded_id:
            try:
                email = user.emails.get(id=decoded_id[0])
            except Email.DoesNotExist:
                email = None
            else:
                primary = email.address == user.username
                address = email.address
                confirmed = True
                verified = True
                is_merge = False

        # check to see if it's an unconfirmed email with a token
        elif user.unconfirmed_emails:
            try:
                email = user.email_verifications[email_id]
                address = email['email']
                confirmed = email['confirmed']
                verified = False
                primary = False
                is_merge = Email.objects.filter(address=address).exists()
            except KeyError:
                email = None

        if not email:
            raise NotFound

        # check for resend confirmation email query parameter in a GET request
        if self.request.method == 'GET' and is_truthy(
                self.request.query_params.get('resend_confirmation')):
            if not confirmed and settings.CONFIRM_REGISTRATIONS_BY_EMAIL:
                if throttle_period_expired(user.email_last_sent,
                                           settings.SEND_EMAIL_THROTTLE):
                    send_confirm_email(user, email=address, renew=True)
                    user.email_last_sent = timezone.now()
                    user.save()

        return UserEmail(email_id=email_id,
                         address=address,
                         confirmed=confirmed,
                         verified=verified,
                         primary=primary,
                         is_merge=is_merge)
Example #36
0
    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        Node = apps.get_model('osf.Node')
        tag_instances = []
        if 'tags' in validated_data:
            tags = validated_data.pop('tags')
            for tag in tags:
                tag_instance, created = Tag.objects.get_or_create(name=tag, defaults=dict(system=False))
                tag_instances.append(tag_instance)
        if 'template_from' in validated_data:
            template_from = validated_data.pop('template_from')
            template_node = Node.load(template_from)
            if template_node is None:
                raise exceptions.NotFound
            if not template_node.has_permission(user, 'read', check_parent=False):
                raise exceptions.PermissionDenied

            validated_data.pop('creator')
            changed_data = {template_from: validated_data}
            node = template_node.use_as_template(auth=get_user_auth(request), changes=changed_data)
        else:
            node = Node(**validated_data)
        try:
            node.save()
        except ValidationError as e:
            raise InvalidModelValueError(detail=e.messages[0])
        if len(tag_instances):
            for tag in tag_instances:
                node.tags.add(tag)
        if is_truthy(request.GET.get('inherit_contributors')) and validated_data['parent'].has_permission(user, 'write'):
            auth = get_user_auth(request)
            parent = validated_data['parent']
            contributors = []
            for contributor in parent.contributor_set.exclude(user=user):
                contributors.append({
                    'user': contributor.user,
                    'permissions': parent.get_permissions(contributor.user),
                    'visible': contributor.visible
                })
                if not contributor.user.is_registered:
                    node.add_unregistered_contributor(
                        fullname=contributor.user.fullname, email=contributor.user.email, auth=auth,
                        permissions=parent.get_permissions(contributor.user), existing_user=contributor.user
                    )
            node.add_contributors(contributors, auth=auth, log=True, save=True)
        return node
Example #37
0
 def retract_registration(self, registration, validated_data, user):
     is_pending_retraction = validated_data.pop('is_pending_retraction', None)
     withdrawal_justification = validated_data.pop('withdrawal_justification', None)
     if withdrawal_justification and not is_pending_retraction:
         raise exceptions.ValidationError(
             'You cannot provide a withdrawal_justification without a concurrent withdrawal request.',
         )
     if is_truthy(is_pending_retraction):
         if registration.is_pending_retraction:
             raise exceptions.ValidationError('This registration is already pending withdrawal.')
         try:
             retraction = registration.retract_registration(user, withdrawal_justification, save=True)
         except NodeStateError as err:
             raise exceptions.ValidationError(str(err))
         retraction.ask(registration.get_active_contributors_recursive(unique_users=True))
     elif is_pending_retraction is not None:
         raise exceptions.ValidationError('You cannot set is_pending_withdrawal to False.')
Example #38
0
    def to_representation(self, data):
        # Don't envelope when serializing collection
        errors = {}
        bulk_skip_uneditable = utils.is_truthy(self.context['request'].query_params.get('skip_uneditable', False))

        if isinstance(data, collections.Mapping):
            errors = data.get('errors', None)
            data = data.get('data', None)

        ret = [
            self.child.to_representation(item, envelope=None) for item in data
        ]

        if errors and bulk_skip_uneditable:
            ret.append({'errors': errors})

        return ret
Example #39
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     field = utils.decompose_field(field)
     if isinstance(field, ShowIfVersion):
         field = field.field
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool',
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             ret = date_parser.parse(value, ignoretz=False)
             if not ret.tzinfo:
                 ret = ret.replace(tzinfo=pytz.utc)
             return ret
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date',
             )
     elif isinstance(field,
                     (self.RELATIONSHIP_FIELDS, ser.SerializerMethodField,
                      ser.ManyRelatedField)):
         if value == 'null':
             value = None
         return value
     elif isinstance(field, self.LIST_FIELDS) or isinstance(
         (getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = []
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(value=value, )
Example #40
0
 def parse_special_query_params(self, field_name, key, value, query):
     op = 'ne' if utils.is_truthy(value) else 'eq'
     query.get(key).update({
         field_name: [{
             'op': op,
             'value': None,
             'source_field_name': 'preprint_file'
         }, {
             'op': op,
             'value': True,
             'source_field_name': '_is_preprint_orphan'
         }, {
             'op': op,
             'value': True,
             'source_field_name': '_has_abandoned_preprint'
         }]
     })
     return query
Example #41
0
 def parse_special_query_params(self, field_name, key, value, query):
     op = 'ne' if utils.is_truthy(value) else 'eq'
     query.get(key).update({
         field_name: [{
             'op': op,
             'value': None,
             'source_field_name': 'preprint_file'
         }, {
             'op': op,
             'value': True,
             'source_field_name': '_is_preprint_orphan'
         }, {
             'op': op,
             'value': True,
             'source_field_name': '_has_abandoned_preprint'
         }]
     })
     return query
Example #42
0
 def convert_value(self, value, field):
     """Used to convert incoming values from query params to the appropriate types for filter comparisons
     :param basestring value: value to be resolved
     :param rest_framework.fields.Field field: Field instance
     """
     field = utils.decompose_field(field)
     if isinstance(field, ShowIfVersion):
         field = field.field
     if isinstance(field, ser.BooleanField):
         if utils.is_truthy(value):
             return True
         elif utils.is_falsy(value):
             return False
         else:
             raise InvalidFilterValue(
                 value=value,
                 field_type='bool',
             )
     elif isinstance(field, self.DATE_FIELDS):
         try:
             ret = date_parser.parse(value, ignoretz=False)
             if not ret.tzinfo:
                 ret = ret.replace(tzinfo=pytz.utc)
             return ret
         except ValueError:
             raise InvalidFilterValue(
                 value=value,
                 field_type='date',
             )
     elif isinstance(field, (self.RELATIONSHIP_FIELDS, ser.SerializerMethodField)):
         if value == 'null':
             value = None
         return value
     elif isinstance(field, self.LIST_FIELDS) or isinstance((getattr(field, 'field', None)), self.LIST_FIELDS):
         if value == 'null':
             value = []
         return value
     else:
         try:
             return field.to_internal_value(value)
         except ValidationError:
             raise InvalidFilterValue(
                 value=value,
             )
Example #43
0
    def build_query_from_field(self, field_name, operation):
        if field_name == 'parent':
            if operation['op'] == 'eq':
                if operation['value']:
                    # filter[parent]=<nid>
                    parent = utils.get_object_or_error(AbstractNode, operation['value'], self.request, display_name='parent')
                    node_ids = NodeRelation.objects.filter(parent=parent, is_node_link=False).values_list('child_id', flat=True)
                    return Q(id__in=node_ids)
            elif operation['op'] == 'ne':
                if not operation['value']:
                    # filter[parent][ne]=null
                    child_ids = (
                        NodeRelation.objects.filter(
                            is_node_link=False,
                            child___contributors=self.get_user()
                        )
                        .exclude(parent__type='osf.collection')
                        .exclude(child__is_deleted=True)
                        .values_list('child_id', flat=True)
                    )
                    return Q(id__in=set(child_ids))
                # TODO: support this case in the future:
                # else filter[parent][ne]=<nid>
                raise InvalidFilterValue(detail='Only "null" is accepted as valid input to "filter[parent][ne]"')
            else:
                # filter[parent][gte]=''
                raise InvalidFilterOperator(value=operation['op'], valid_operators=['eq', 'ne'])

        if field_name == 'root':
            if None in operation['value']:
                raise InvalidFilterValue(value=operation['value'])
            with_as_root_query = Q(root__guids___id__in=operation['value'])
            return ~with_as_root_query if operation['op'] == 'ne' else with_as_root_query

        if field_name == 'preprint':
            not_preprint_query = (
                Q(preprint_file=None) |
                Q(_is_preprint_orphan=True) |
                Q(_has_abandoned_preprint=True)
            )

            return ~not_preprint_query if utils.is_truthy(operation['value']) else not_preprint_query

        return super(NodesFilterMixin, self).build_query_from_field(field_name, operation)
Example #44
0
    def get_serializer_context(self):
        """Inject request into the serializer context. Additionally, inject partial functions
        (request, object -> embed items) if the query string contains embeds.  Allows
         multiple levels of nesting.
        """
        context = super(JSONAPIBaseView, self).get_serializer_context()
        if self.kwargs.get('is_embedded'):
            embeds = []
        else:
            embeds = self.request.query_params.getlist('embed') or self.request.query_params.getlist('embed[]')

        fields_check = self.get_serializer_class()._declared_fields.copy()
        serializer_class_type = get_meta_type(self.serializer_class, self.request)
        if 'fields[{}]'.format(serializer_class_type) in self.request.query_params:
            # Check only requested and mandatory fields
            sparse_fields = self.request.query_params['fields[{}]'.format(serializer_class_type)]
            for field in fields_check.copy().keys():
                if field not in ('type', 'id', 'links') and field not in sparse_fields:
                    fields_check.pop(field)

        for field in fields_check:
            if getattr(fields_check[field], 'field', None):
                fields_check[field] = fields_check[field].field

        for field in fields_check:
            if getattr(fields_check[field], 'always_embed', False) and field not in embeds:
                embeds.append(unicode(field))
            if getattr(fields_check[field], 'never_embed', False) and field in embeds:
                embeds.remove(field)
        embeds_partials = {}
        for embed in embeds:
            embed_field = fields_check.get(embed)
            embeds_partials[embed] = self._get_embed_partial(embed, embed_field)

        context.update({
            'enable_esi': (
                utils.is_truthy(self.request.query_params.get('esi', django_settings.ENABLE_ESI)) and
                self.request.accepted_renderer.media_type in django_settings.ESI_MEDIA_TYPES
            ),
            'embed': embeds_partials,
            'envelope': self.request.query_params.get('envelope', 'data'),
        })
        return context
Example #45
0
    def get_object(self):
        email_id = self.kwargs['email_id']
        user = self.get_user()
        email = None

        # check to see if it's a confirmed email with hashed id
        decoded_id = hashids.decode(email_id)
        if decoded_id:
            try:
                email = user.emails.get(id=decoded_id[0])
            except Email.DoesNotExist:
                email = None
            else:
                primary = email.address == user.username
                address = email.address
                confirmed = True
                verified = True
                is_merge = False

        # check to see if it's an unconfirmed email with a token
        elif user.unconfirmed_emails:
            try:
                email = user.email_verifications[email_id]
                address = email['email']
                confirmed = email['confirmed']
                verified = False
                primary = False
                is_merge = Email.objects.filter(address=address).exists()
            except KeyError:
                email = None

        if not email:
            raise NotFound

        # check for resend confirmation email query parameter in a GET request
        if self.request.method == 'GET' and is_truthy(self.request.query_params.get('resend_confirmation')):
            if not confirmed and settings.CONFIRM_REGISTRATIONS_BY_EMAIL:
                if throttle_period_expired(user.email_last_sent, settings.SEND_EMAIL_THROTTLE):
                    send_confirm_email(user, email=address, renew=True)
                    user.email_last_sent = timezone.now()
                    user.save()

        return UserEmail(email_id=email_id, address=address, confirmed=confirmed, verified=verified, primary=primary, is_merge=is_merge)
Example #46
0
    def get_meta_information(self, metadata, provider):
        # Clone metadata because its mutability is questionable
        metadata = dict(metadata or {})

        # Make counts opt-in
        show_counts = utils.is_truthy(self.context['request'].query_params.get('related_counts', False))
        # Only include counts on detail routes
        is_detail = self.context.get('view') and not isinstance(self.context['view'], generics.ListAPIView)
        # Weird hack to avoid being called twice
        # get_meta_information is called with both self.related_meta and self.self_meta.
        # `is` could probably be used here but this seems more comprehensive.
        is_related_meta = metadata.pop('include_state_counts', False)

        if show_counts and is_detail and is_related_meta:
            # Finally, require users to have view_actions permissions
            auth = utils.get_user_auth(self.context['request'])
            if auth and auth.logged_in and auth.user.has_perm('view_actions', provider):
                metadata.update(provider.get_reviewable_state_counts())

        return super(ReviewableCountsRelationshipField, self).get_meta_information(metadata, provider)
Example #47
0
    def get_meta_information(self, metadata, provider):
        # Clone metadata because its mutability is questionable
        metadata = dict(metadata or {})

        # Make counts opt-in
        show_counts = utils.is_truthy(self.context['request'].query_params.get('related_counts', False))
        # Only include counts on detail routes
        is_detail = self.context.get('view') and not isinstance(self.context['view'], generics.ListAPIView)
        # Weird hack to avoid being called twice
        # get_meta_information is called with both self.related_meta and self.self_meta.
        # `is` could probably be used here but this seems more comprehensive.
        is_related_meta = metadata.pop('include_state_counts', False)

        if show_counts and is_detail and is_related_meta:
            # Finally, require users to have view_actions permissions
            auth = utils.get_user_auth(self.context['request'])
            if auth and auth.logged_in and auth.user.has_perm('view_actions', provider):
                metadata.update(provider.get_reviewable_state_counts())

        return super(ReviewableCountsRelationshipField, self).get_meta_information(metadata, provider)
Example #48
0
    def get_meta_information(self, meta_data, value):
        """
        For retrieving meta values, otherwise returns {}
        """
        meta = {}
        for key in meta_data or {}:
            if key == 'count' or key == 'unread':
                show_related_counts = self.context['request'].query_params.get('related_counts', False)
                field_counts_requested = self.process_related_counts_parameters(show_related_counts, value)

                if utils.is_truthy(show_related_counts):
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                elif utils.is_falsy(show_related_counts):
                    continue
                elif self.field_name in field_counts_requested:
                    meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
                else:
                    continue
            else:
                meta[key] = website_utils.rapply(meta_data[key], _url_val, obj=value, serializer=self.parent)
        return meta
Example #49
0
    def get_serializer_context(self):
        """Inject request into the serializer context. Additionally, inject partial functions
        (request, object -> embed items) if the query string contains embeds.  Allows
         multiple levels of nesting.
        """
        context = super(JSONAPIBaseView, self).get_serializer_context()
        if self.kwargs.get("is_embedded"):
            embeds = []
        else:
            embeds = self.request.query_params.getlist("embed")

        fields_check = self.serializer_class._declared_fields.copy()

        for field in fields_check:
            if getattr(fields_check[field], "field", None):
                fields_check[field] = fields_check[field].field

        for field in fields_check:
            if getattr(fields_check[field], "always_embed", False) and field not in embeds:
                embeds.append(unicode(field))
            if getattr(fields_check[field], "never_embed", False) and field in embeds:
                embeds.remove(field)
        embeds_partials = {}
        for embed in embeds:
            embed_field = fields_check.get(embed)
            embeds_partials[embed] = self._get_embed_partial(embed, embed_field)

        context.update(
            {
                "enable_esi": (
                    utils.is_truthy(self.request.query_params.get("esi", django_settings.ENABLE_ESI))
                    and self.request.accepted_renderer.media_type in django_settings.ESI_MEDIA_TYPES
                ),
                "embed": embeds_partials,
                "envelope": self.request.query_params.get("envelope", "data"),
            }
        )
        return context
Example #50
0
    def parse_query_params(self, query_params):
        """Maps query params to a dict usable for filtering
        :param dict query_params:
        :return dict: of the format {
            <resolved_field_name>: {
                'op': <comparison_operator>,
                'value': <resolved_value>,
                'source_field_name': <model_field_source_of_serializer_field>
            }
        }
        """
        query = {}
        for key, value in query_params.iteritems():
            match = self.QUERY_PATTERN.match(key)
            if match:
                match_dict = match.groupdict()
                fields = match_dict['fields']
                field_names = re.findall(self.FILTER_FIELDS, fields.strip())
                query.update({key: {}})

                for field_name in field_names:
                    field = self._get_field_or_error(field_name)
                    op = match_dict.get('op') or self._get_default_operator(
                        field)
                    self._validate_operator(field, field_name, op)

                    source_field_name = field_name
                    if not isinstance(field, ser.SerializerMethodField):
                        source_field_name = self.convert_key(field_name, field)

                    # Special case date(time)s to allow for ambiguous date matches
                    if isinstance(field, self.DATE_FIELDS):
                        query.get(key).update({
                            field_name:
                            self._parse_date_param(field, source_field_name,
                                                   op, value)
                        })
                    elif not isinstance(
                            value, int) and (source_field_name == '_id'
                                             or source_field_name == 'root'):
                        query.get(key).update({
                            field_name: {
                                'op': 'in',
                                'value': self.bulk_get_values(value, field),
                                'source_field_name': source_field_name
                            }
                        })
                    elif source_field_name == 'is_preprint':
                        # TODO: Make this also include _is_preprint_orphan when value is false [#PREP-129]
                        op = 'ne' if utils.is_truthy(value) else 'eq'
                        query.get(key).update({
                            field_name: {
                                'op': op,
                                'value': None,
                                'source_field_name': 'preprint_file'
                            }
                        })
                        if utils.is_truthy(value):
                            query['_is_preprint_orphan'] = {
                                field_name: {
                                    'op': 'ne',
                                    'value': True,
                                    'source_field_name': '_is_preprint_orphan'
                                }
                            }
                    else:
                        query.get(key).update({
                            field_name: {
                                'op': op,
                                'value': self.convert_value(value, field),
                                'source_field_name': source_field_name
                            }
                        })

        return query
Example #51
0
 def should_resolve(request):
     query_params = getattr(request, 'query_params', request.GET)
     resolve = query_params.get('resolve')
     return resolve is None or is_truthy(resolve)
Example #52
0
    def parse_query_params(self, query_params):
        """Maps query params to a dict usable for filtering
        :param dict query_params:
        :return dict: of the format {
            <resolved_field_name>: {
                'op': <comparison_operator>,
                'value': <resolved_value>,
                'source_field_name': <model_field_source_of_serializer_field>
            }
        }
        """
        query = {}
        for key, value in query_params.iteritems():
            match = self.QUERY_PATTERN.match(key)
            if match:
                match_dict = match.groupdict()
                fields = match_dict['fields']
                field_names = re.findall(self.FILTER_FIELDS, fields.strip())
                query.update({key: {}})

                for field_name in field_names:
                    field = self._get_field_or_error(field_name)
                    op = match_dict.get('op') or self._get_default_operator(field)
                    self._validate_operator(field, field_name, op)

                    source_field_name = field_name
                    if not isinstance(field, ser.SerializerMethodField):
                        source_field_name = self.convert_key(field_name, field)

                    # Special case date(time)s to allow for ambiguous date matches
                    if isinstance(field, self.DATE_FIELDS):
                        query.get(key).update({
                            field_name: self._parse_date_param(field, source_field_name, op, value)
                        })
                    elif not isinstance(value, int) and (source_field_name == '_id' or source_field_name == 'root'):
                        query.get(key).update({
                            field_name: {
                                'op': 'in',
                                'value': self.bulk_get_values(value, field),
                                'source_field_name': source_field_name
                            }
                        })
                    elif source_field_name == 'is_preprint':
                        # TODO: Make this also include _is_preprint_orphan when value is false [#PREP-129]
                        op = 'ne' if utils.is_truthy(value) else 'eq'
                        query.get(key).update({
                            field_name: {
                                'op': op,
                                'value': None,
                                'source_field_name': 'preprint_file'
                            }
                        })
                        if utils.is_truthy(value):
                            query['_is_preprint_orphan'] = {
                                field_name: {
                                    'op': 'ne',
                                    'value': True,
                                    'source_field_name': '_is_preprint_orphan'
                                }
                            }
                    else:
                        query.get(key).update({
                            field_name: {
                                'op': op,
                                'value': self.convert_value(value, field),
                                'source_field_name': source_field_name
                            }
                        })

        return query
Example #53
0
 def should_resolve(request):
     query_params = getattr(request, 'query_params', request.GET)
     resolve = query_params.get('resolve')
     return resolve is None or is_truthy(resolve)