Exemple #1
0
class ReviewActionSerializer(BaseActionSerializer):
    class Meta:
        type_ = 'review-actions'

    filterable_fields = frozenset([
        'id',
        'trigger',
        'from_state',
        'to_state',
        'date_created',
        'date_modified',
        'provider',
        'target',
    ])

    comment = HideIfProviderCommentsPrivate(
        ser.CharField(max_length=65535, required=False))

    provider = RelationshipField(
        read_only=True,
        related_view='preprint_providers:preprint_provider-detail',
        related_view_kwargs={'provider_id': '<target.provider._id>'},
        filter_key='target__provider___id',
    )

    creator = HideIfProviderCommentsAnonymous(
        RelationshipField(
            read_only=True,
            related_view='users:user-detail',
            related_view_kwargs={'user_id': '<creator._id>'},
            filter_key='creator__guids___id',
            always_embed=True,
        ))

    target = TargetRelationshipField(
        target_class=PreprintService,
        read_only=False,
        required=True,
        related_view='preprints:preprint-detail',
        related_view_kwargs={'preprint_id': '<target._id>'},
        filter_key='target__guids___id',
    )
Exemple #2
0
class NodeLogSerializer(JSONAPISerializer):

    filterable_fields = frozenset(['action', 'date'])
    non_anonymized_fields = [
        'id',
        'date',
        'action',
    ]

    id = ser.CharField(read_only=True, source='_id')
    date = ser.DateTimeField(read_only=True)
    action = ser.CharField(read_only=True)
    params = NodeLogParamsSerializer(read_only=True)
    links = LinksField({'self': 'get_absolute_url'})

    class Meta:
        type_ = 'logs'

    nodes = RelationshipField(
        related_view='logs:log-nodes',
        related_view_kwargs={'log_id': '<pk>'},
    )
    user = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<user._id>'},
    )

    contributors = RelationshipField(
        related_view='logs:log-contributors',
        related_view_kwargs={'log_id': '<pk>'},
    )

    # This would be a node_link, except that data isn't stored in the node log params
    linked_node = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<params.pointer.id>'})
    template_node = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<params.template_node.id>'})

    def get_absolute_url(self, obj):
        return obj.absolute_url
Exemple #3
0
class NodeLinksSerializer(JSONAPISerializer):

    id = IDField(source='_id')
    type = TypeField()
    target_type = TargetTypeField(target_type='nodes')

    # TODO: We don't show the title because the current user may not have access to this node. We may want to conditionally
    # include this field in the future.
    # title = ser.CharField(read_only=True, source='node.title', help_text='The title of the node that this Node Link '
    #                                                                      'points to')

    target_node = RelationshipField(related_view='nodes:node-detail',
                                    related_view_kwargs={'node_id': '<pk>'},
                                    always_embed=True)

    class Meta:
        type_ = 'node_links'

    links = LinksField({'self': 'get_absolute_url'})

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'nodes:node-pointer-detail',
            kwargs={
                'node_link_id':
                obj._id,
                'node_id':
                self.context['request'].parser_context['kwargs']['node_id'],
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        auth = Auth(user)
        node = self.context['view'].get_node()
        target_node_id = validated_data['_id']
        pointer_node = Node.load(target_node_id)
        if not pointer_node or pointer_node.is_collection:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/node_links/data/id'},
                detail='Target Node \'{}\' not found.'.format(target_node_id))
        try:
            pointer = node.add_pointer(pointer_node, auth, save=True)
            return pointer
        except ValueError:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/node_links/data/id'},
                detail='Target Node \'{}\' already pointed to by \'{}\'.'.
                format(target_node_id, node._id))

    def update(self, instance, validated_data):
        pass
Exemple #4
0
class NodeContributorsCreateSerializer(NodeContributorsSerializer):
    """
    Overrides NodeContributorsSerializer to add email, full_name, send_email, and non-required index and users field.
    """

    id = IDField(source='_id', required=False, allow_null=True)
    full_name = ser.CharField(required=False)
    email = ser.EmailField(required=False, source='user.email')
    index = ser.IntegerField(required=False, source='_order')

    users = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<user._id>'},
        required=False
    )

    email_preferences = ['default', 'preprint', 'false']

    def validate_data(self, node, user_id=None, full_name=None, email=None, index=None):
        if user_id and (full_name or email):
            raise Conflict(detail='Full name and/or email should not be included with a user ID.')
        if not user_id and not full_name:
            raise exceptions.ValidationError(detail='A user ID or full name must be provided to add a contributor.')
        if index > len(node.contributors):
            raise exceptions.ValidationError(detail='{} is not a valid contributor index for node with id {}'.format(index, node._id))

    def create(self, validated_data):
        id = validated_data.get('_id')
        email = validated_data.get('user', {}).get('email', None)
        index = None
        if '_order' in validated_data:
            index = validated_data.pop('_order')
        node = self.context['view'].get_node()
        auth = Auth(self.context['request'].user)
        full_name = validated_data.get('full_name')
        bibliographic = validated_data.get('bibliographic')
        send_email = self.context['request'].GET.get('send_email') or 'default'
        permissions = osf_permissions.expand_permissions(validated_data.get('permission')) or osf_permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS

        self.validate_data(node, user_id=id, full_name=full_name, email=email, index=index)

        if send_email not in self.email_preferences:
            raise exceptions.ValidationError(detail='{} is not a valid email preference.'.format(send_email))

        try:
            contributor_obj = node.add_contributor_registered_or_not(
                auth=auth, user_id=id, email=email, full_name=full_name, send_email=send_email,
                permissions=permissions, bibliographic=bibliographic, index=index, save=True
            )
        except ValidationError as e:
            raise exceptions.ValidationError(detail=e.messages[0])
        except ValueError as e:
            raise exceptions.NotFound(detail=e.args[0])
        return contributor_obj
Exemple #5
0
class ReviewActionSerializer(BaseActionSerializer):
    class Meta:
        type_ = 'review-actions'

    filterable_fields = frozenset([
        'id',
        'trigger',
        'from_state',
        'to_state',
        'date_created',
        'date_modified',
        'provider',
        'target',
    ])

    provider = RelationshipField(
        read_only=True,
        related_view='preprint_providers:preprint_provider-detail',
        related_view_kwargs={'provider_id': '<target.provider._id>'},
        filter_key='target__provider___id',
    )

    creator = HideIfProviderCommentsAnonymous(RelationshipField(
        read_only=True,
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<creator._id>'},
        filter_key='creator__guids___id',
        always_embed=True,
    ))

    target = TargetRelationshipField(
        target_class=PreprintService,
        read_only=False,
        required=True,
        related_view='preprints:preprint-detail',
        related_view_kwargs={'preprint_id': '<target._id>'},
        filter_key='target__guids___id',
    )

    def get_action_url(self, obj):
        return utils.absolute_reverse('actions:action-detail', kwargs={'action_id': obj._id, 'version': self.context['request'].parser_context['kwargs']['version']})
Exemple #6
0
class InstitutionSerializer(JSONAPISerializer):

    filterable_fields = frozenset([
        'id',
        'name',
        'auth_url',
    ])

    name = ser.CharField(read_only=True)
    id = ser.CharField(read_only=True, source='_id')
    logo_path = ser.CharField(read_only=True)
    description = ser.CharField(read_only=True)
    auth_url = ser.CharField(read_only=True)
    links = LinksField({
        'self': 'get_api_url',
        'html': 'get_absolute_html_url',
    })

    nodes = RelationshipField(
        related_view='institutions:institution-nodes',
        related_view_kwargs={'institution_id': '<_id>'},
    )

    registrations = RelationshipField(
        related_view='institutions:institution-registrations',
        related_view_kwargs={'institution_id': '<_id>'},
    )

    users = RelationshipField(
        related_view='institutions:institution-users',
        related_view_kwargs={'institution_id': '<_id>'},
    )

    def get_api_url(self, obj):
        return obj.absolute_api_v2_url

    def get_absolute_url(self, obj):
        return obj.absolute_api_v2_url

    class Meta:
        type_ = 'institutions'
class NodeLogSerializer(JSONAPISerializer):

    filterable_fields = frozenset(['action', 'date'])
    non_anonymized_fields = [
        'id',
        'date',
        'action',
    ]

    id = ser.CharField(read_only=True, source='_id')
    date = DateByVersion(read_only=True)
    action = ser.CharField(read_only=True)
    params = ser.SerializerMethodField(read_only=True)
    links = LinksField({'self': 'get_absolute_url'})

    class Meta:
        type_ = 'logs'

    node = RelationshipField(
        related_view=lambda n: 'registrations:registration-detail'
        if getattr(n, 'is_registration', False) else 'nodes:node-detail',
        related_view_kwargs={'node_id': '<node._id>'},
    )

    original_node = RelationshipField(
        related_view=lambda n: 'registrations:registration-detail'
        if getattr(n, 'is_registration', False) else 'nodes:node-detail',
        related_view_kwargs={'node_id': '<original_node._id>'},
    )

    user = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<user._id>'},
    )

    # This would be a node_link, except that data isn't stored in the node log params
    linked_node = HideIfNotNodePointerLog(
        RelationshipField(
            related_view='nodes:node-detail',
            related_view_kwargs={'node_id': '<params.pointer.id>'}))

    linked_registration = HideIfNotRegistrationPointerLog(
        RelationshipField(
            related_view='registrations:registration-detail',
            related_view_kwargs={'node_id': '<params.pointer.id>'}))

    template_node = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<params.template_node.id>'})

    def get_absolute_url(self, obj):
        return obj.absolute_url

    def get_params(self, obj):
        if obj.action == 'osf_storage_folder_created' and obj.params.get(
                'urls'):
            obj.params.pop('urls')
        return NodeLogParamsSerializer(obj.params,
                                       context=self.context,
                                       read_only=True).data
Exemple #8
0
class NodeRequestSerializer(RequestSerializer):
    class Meta:
        type_ = 'node-requests'

    target = RelationshipField(
        read_only=True,
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<target._id>'},
        filter_key='target__guids___id',
    )

    def get_target_url(self, obj):
        return absolute_reverse('nodes:node-detail', kwargs={'node_id': obj.target._id, 'version': self.context['request'].parser_context['kwargs']['version']})
Exemple #9
0
class ChronosSubmissionSerializer(JSONAPISerializer):
    class Meta:
        type_ = 'chronos-submissions'

    id = ser.CharField(source='publication_id', read_only=True)
    submission_url = ser.CharField(read_only=True)
    status = ser.SerializerMethodField()
    modified = ser.DateTimeField(read_only=True)

    journal = RelationshipField(
        read_only=True,
        related_view='chronos:chronos-journal-detail',
        related_view_kwargs={'journal_id': '<journal.journal_id>'},
    )
    preprint = RelationshipField(
        read_only=True,
        related_view='preprints:preprint-detail',
        related_view_kwargs={'preprint_id': '<preprint._id>'},
    )
    submitter = RelationshipField(
        read_only=True,
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<submitter._id>'},
    )
    links = LinksField({'self': 'get_absolute_url'})

    def get_absolute_url(self, obj):
        return absolute_reverse('chronos:chronos-submission-detail',
                                kwargs={
                                    'preprint_id': obj.preprint._id,
                                    'submission_id': obj.publication_id
                                })

    def get_status(self, obj):
        value_lookup = {
            val.value: key
            for key, val in ChronosSubmissionStatus.__members__.items()
        }
        return value_lookup[obj.status]
Exemple #10
0
class MeetingSerializer(CollectionSerializer):
    location = serializers.CharField(allow_blank=True, allow_null=True, required=False)
    address = serializers.CharField(allow_blank=True, allow_null=True, required=False)
    start_date = serializers.DateTimeField(allow_null=True, required=False)
    end_date = serializers.DateTimeField(allow_null=True, required=False)
    groups = RelationshipField(
        related_view='meeting-group-list',
        related_view_kwargs={'pk': '<pk>'}
    )
    items = RelationshipField(
        related_view='meeting-item-list',
        related_view_kwargs={'pk': '<pk>'}
    )

    class Meta:
        model = Meeting

    class JSONAPIMeta:
        resource_name = 'meetings'

    def create(self, validated_data):
        user = self.context['request'].user
        meeting = Meeting.objects.create(created_by=user, **validated_data)
        assign_perm('api.approve_meeting_items', user, CollectionBase(meeting))
        return meeting

    def update(self, meeting, validated_data):
        meeting.title = validated_data.get('title', meeting.title)
        meeting.description = validated_data.get('description', meeting.description)
        meeting.tags = validated_data.get('tags', meeting.tags)
        meeting.settings = validated_data.get('settings', meeting.settings)
        meeting.submission_settings = validated_data.get('submission_settings', meeting.submission_settings)
        meeting.created_by_org = validated_data.get('created_by_org', meeting.created_by_org)
        meeting.location = validated_data.get('location', meeting.location)
        meeting.start_date = validated_data.get('start_date', meeting.start_date)
        meeting.end_date = validated_data.get('end_date', meeting.end_date)
        meeting.save()
        return meeting
class FakeSerializer(ser.Serializer):

    filterable_fields = ('id', 'string_field', 'second_string_field','list_field', 'date_field', 'int_field', 'bool_field', 'relationship_field')

    id = ser.CharField()
    string_field = ser.CharField()
    second_string_field = ser.CharField()
    list_field = ser.ListField()
    date_field = ser.DateField()
    datetime_field = ser.DateTimeField()
    int_field = ser.IntegerField()
    float_field = ser.FloatField()
    bool_field = ser.BooleanField(source='foobar')
    relationship_field = RelationshipField(related_view='fake', related_view_kwargs={})
Exemple #12
0
class RequestSerializer(JSONAPISerializer):
    class Meta:
        type_ = 'node-requests'

    filterable_fields = frozenset([
        'creator', 'request_type', 'machine_state', 'created', 'id', 'target'
    ])
    id = ser.CharField(source='_id', read_only=True)
    request_type = ser.ChoiceField(read_only=True,
                                   required=False,
                                   choices=RequestTypes.choices())
    machine_state = ser.ChoiceField(read_only=True,
                                    required=False,
                                    choices=DefaultStates.choices())
    comment = ser.CharField(required=False, allow_blank=True, max_length=65535)
    created = VersionedDateTimeField(read_only=True)
    modified = VersionedDateTimeField(read_only=True)
    date_last_transitioned = VersionedDateTimeField(read_only=True)

    creator = RelationshipField(
        read_only=True,
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<creator._id>'},
        filter_key='creator___id',
    )

    links = LinksField({
        'self': 'get_absolute_url',
        'target': 'get_target_url'
    })

    @property
    def target(self):
        raise NotImplementedError()

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'requests:request-detail',
            kwargs={
                'request_id':
                obj._id,
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def get_target_url(self, obj):
        raise NotImplementedError()

    def create(self, validated_data):
        raise NotImplementedError()
Exemple #13
0
class RegistrationActionSerializer(BaseActionSerializer):
    class Meta:
        type_ = 'registration-actions'

    target = RelationshipField(
        read_only=True,
        related_view='registrations:registration-detail',
        related_view_kwargs={'node_id': '<target._id>'},
        filter_key='target__guids___id',
    )

    permissions = ser.ChoiceField(
        choices=permissions.API_CONTRIBUTOR_PERMISSIONS, required=False)
    visible = ser.BooleanField(default=True, required=False)
Exemple #14
0
class GuidSerializer(JSONAPISerializer):

    class Meta:
        type_ = 'guids'

    filterable_fields = tuple()

    id = IDField(source='_id', read_only=True)
    type = TypeField()

    referent = RelationshipField(
        related_view=get_related_view,
        related_view_kwargs=get_related_view_kwargs,
        related_meta={
            'type': 'get_type',
        },
    )
    links = LinksField({
        'self': 'get_absolute_url',
        'html': 'get_absolute_html_url',
    })

    def get_type(self, guid):
        return get_type(guid.referent)

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'guids:guid-detail', kwargs={
                'guids': obj._id,
                'version': self.context['request'].parser_context['kwargs']['version'],
            },
        )

    def get_absolute_html_url(self, obj):
        if not isinstance(obj.referent, BaseFileNode):
            return obj.referent.absolute_url
        return urlparse.urljoin(website_settings.DOMAIN, '/{}/'.format(obj._id))

    def to_representation(self, obj):
        if self.context['view'].kwargs.get('is_embedded'):
            # Force the referent to serialize instead.
            obj = obj.referent
            ser = resolve(reverse(
                get_related_view(obj),
                kwargs={'node_id': obj._id, 'version': self.context['view'].kwargs.get('version', '2')},
            )).func.cls.serializer_class(context=self.context)
            [ser.context.update({k: v}) for k, v in self.context.items()]
            return ser.to_representation(obj)
        return super(GuidSerializer, self).to_representation(obj)
class RegistrationSchemaSerializer(SchemaSerializer):
    description = ser.CharField(read_only=True, allow_blank=True)

    schema_blocks = RelationshipField(
        related_view='schemas:registration-schema-blocks',
        related_view_kwargs={'schema_id': '<_id>'},
    )

    filterable_fields = ['active']

    class Meta:
        @staticmethod
        def get_type(request):
            return get_kebab_snake_case_field(request.version,
                                              'registration-schemas')
Exemple #16
0
class SubjectSerializer(JSONAPISerializer):
    filterable_fields = frozenset([
        'text',
        'parent',
        'id',
    ])
    id = ser.CharField(source='_id', required=True)
    text = ser.CharField(max_length=200)
    taxonomy_name = ser.CharField(source='provider.share_title',
                                  read_only=True)

    parent = RelationshipField(
        related_view='subjects:subject-detail',
        related_view_kwargs={'subject_id': '<parent._id>'},
        always_embed=True,
    )

    children = RelationshipField(
        related_view='subjects:subject-children',
        related_view_kwargs={'subject_id': '<_id>'},
        related_meta={'count': 'get_children_count'},
    )

    links = LinksField({
        'self': 'get_absolute_url',
    })

    def get_absolute_url(self, obj):
        return obj.absolute_api_v2_subject_url

    def get_children_count(self, obj):
        return obj.children_count if hasattr(
            obj, 'children_count') else obj.child_count

    class Meta:
        type_ = 'subjects'
Exemple #17
0
class ViewOnlyLinkDetailSerializer(JSONAPISerializer):
    key = ser.CharField(read_only=True)
    id = IDField(source='_id', read_only=True)
    date_created = ser.DateTimeField(read_only=True)
    anonymous = ser.BooleanField(required=False)
    name = ser.CharField(required=False)

    nodes = RelationshipField(
        related_view='view-only-links:view-only-link-nodes',
        related_view_kwargs={'link_id': '<_id>'},
        self_view='view-only-links:view-only-link-nodes-relationships',
        self_view_kwargs={'link_id': '<_id>'})

    creator = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<creator._id>'},
    )

    def get_absolute_url(self, obj):
        return absolute_reverse('nodes:node-view-only-link-detail',
                                kwargs={'link_id': obj._id})

    class Meta:
        type_ = 'view-only-links'
class CollectionSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    title = serializers.CharField(required=True)
    description = serializers.CharField(allow_blank=True)
    tags = serializers.CharField(allow_blank=True)
    settings = serializers.CharField(required=False)
    created_by = UserSerializer(read_only=True)
    date_created = serializers.DateTimeField(read_only=True)
    date_updated = serializers.DateTimeField(read_only=True)
    groups = RelationshipField(related_view='collection-group-list',
                               related_view_kwargs={'pk': '<pk>'})
    items = RelationshipField(related_view='collection-item-list',
                              related_view_kwargs={'pk': '<pk>'})

    class Meta:
        model = Collection

    class JSONAPIMeta:
        resource_name = 'collections'

    def create(self, validated_data):
        user = self.context['request'].user
        collection = Collection.objects.create(created_by=user,
                                               **validated_data)
        assign_perm('api.approve_items', user, collection)
        return collection

    def update(self, collection, validated_data):
        collection.title = validated_data.get('title', collection.title)
        collection.description = validated_data.get('description',
                                                    collection.description)
        collection.tags = validated_data.get('tags', collection.tags)
        collection.settings = validated_data.get('settings',
                                                 collection.settings)
        collection.save()
        return collection
Exemple #19
0
class NodeContributorsSerializer(JSONAPISerializer):
    """ Separate from UserSerializer due to necessity to override almost every field as read only
    """
    non_anonymized_fields = ['bibliographic', 'permission']
    filterable_fields = frozenset([
        'id',
        'bibliographic',
        'permission'
    ])

    id = IDField(source='_id', required=True)
    type = TypeField()

    bibliographic = ser.BooleanField(help_text='Whether the user will be included in citations for this node or not.',
                                     default=True)
    permission = ser.ChoiceField(choices=osf_permissions.PERMISSIONS, required=False, allow_null=True,
                                 default=osf_permissions.reduce_permissions(osf_permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS),
                                 help_text='User permission level. Must be "read", "write", or "admin". Defaults to "write".')
    unregistered_contributor = ser.SerializerMethodField()

    links = LinksField({
        'self': 'get_absolute_url'
    })

    users = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<pk>'},
        always_embed=True
    )

    class Meta:
        type_ = 'contributors'

    def get_absolute_url(self, obj):
        node_id = self.context['request'].parser_context['kwargs']['node_id']
        return absolute_reverse(
            'nodes:node-contributor-detail',
            kwargs={
                'node_id': node_id,
                'user_id': obj._id
            }
        )

    def get_unregistered_contributor(self, obj):
        unclaimed_records = obj.unclaimed_records.get(obj.node_id, None)
        if unclaimed_records:
            return unclaimed_records.get('name', None)
Exemple #20
0
class CollectionProviderSerializer(ProviderSerializer):
    class Meta:
        type_ = 'collection-providers'

    primary_collection = RelationshipField(
        related_view='collections:collection-detail',
        related_view_kwargs={'collection_id': '<primary_collection._id>'})

    filterable_fields = frozenset([
        'allow_submissions',
        'allow_commenting',
        'description',
        'domain',
        'domain_redirect_enabled',
        'id',
        'name',
    ])
Exemple #21
0
class RegistrationFileSerializer(OsfStorageFileSerializer):

    files = NodeFileHyperLinkField(
        related_view='registrations:registration-files',
        related_view_kwargs={'node_id': '<node._id>', 'path': '<path>', 'provider': '<provider>'},
        kind='folder'
    )

    comments = FileCommentRelationshipField(related_view='registrations:registration-comments',
                                            related_view_kwargs={'node_id': '<node._id>'},
                                            related_meta={'unread': 'get_unread_comments_count'},
                                            filter={'target': 'get_file_guid'}
                                            )

    node = RelationshipField(related_view='registrations:registration-detail',
                                     related_view_kwargs={'node_id': '<node._id>'},
                                     help_text='The registration that this file belongs to'
                             )
Exemple #22
0
class RegistrationIdentifierSerializer(JSONAPISerializer):

    category = ser.SerializerMethodField()

    filterable_fields = frozenset(['category'])

    value = ser.CharField(read_only=True)

    referent = RelationshipField(
        related_view='registrations:registration-detail',
        related_view_kwargs={'node_id': '<referent._id>'},
    )

    id = IDField(source='_id', read_only=True)

    links = LinksField({'self': 'self_url'})

    class Meta:
        type_ = 'identifiers'

    def get_category(self, obj):
        if obj.category == 'legacy_doi':
            return 'doi'
        return obj.category

    def get_absolute_url(self, obj):
        return obj.absolute_api_v2_url

    def get_id(self, obj):
        return obj._id

    def get_detail_url(self, obj):
        return '{}/identifiers/{}'.format(obj.absolute_api_v2_url, obj._id)

    def self_url(self, obj):
        return absolute_reverse(
            'identifiers:identifier-detail',
            kwargs={
                'identifier_id':
                obj._id,
                'version':
                self.context['request'].parser_context['kwargs']['version'],
            },
        )
class CollectionNodeLinkSerializer(NodeLinksSerializer):
    target_node = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<guid.referent._id>'},
        always_embed=True,
    )

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'collections:node-pointer-detail',
            kwargs={
                'collection_id':
                self.context['request'].parser_context['kwargs']
                ['collection_id'],
                'node_link_id':
                obj.guid._id,
                'version':
                self.context['request'].parser_context['kwargs']['version'],
            },
        )

    # Override NodeLinksSerializer
    def create(self, validated_data):
        request = self.context['request']
        user = request.user
        collection = self.context['view'].get_collection()
        target_node_id = validated_data['_id']
        pointer_node = AbstractNode.load(target_node_id)
        if not pointer_node:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/node_links/data/id'},
                detail='Target Node \'{}\' not found.'.format(target_node_id),
            )
        try:
            pointer = collection.collect_object(pointer_node, user)
        except ValidationError:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/node_links/data/id'},
                detail='Target Node \'{}\' already pointed to by \'{}\'.'.
                format(target_node_id, collection._id),
            )
        return pointer
Exemple #24
0
class GroupSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    title = serializers.CharField(required=True)
    description = serializers.CharField(allow_blank=True, required=False)
    created_by = UserSerializer(read_only=True)
    date_created = serializers.DateTimeField(read_only=True)
    date_updated = serializers.DateTimeField(read_only=True)
    items = RelationshipField(
        related_view='group-item-list',
        related_view_kwargs={'pk': '<collection.id>', 'group_id': '<pk>'}
    )
    items = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='track-detail'
    )

    class Meta:
        model = Group

    class JSONAPIMeta:
        resource_name = 'groups'

    def create(self, validated_data):
        user = self.context['request'].user
        collection_id = self.context.get('collection_id', None) or self.context['request'].parser_context['kwargs'].get(
            'pk', None)
        collection = CollectionBase.objects.get(id=collection_id)
        return Group.objects.create(
            created_by=user,
            collection=collection,
            **validated_data
        )

    def update(self, group, validated_data):
        group.title = validated_data.get('title', None)
        description = validated_data.get('description', None)
        if description:
            group.description = description
        group.save()
        return group
class GroupSerializer(JSONAPISerializer):
    filterable_fields = frozenset([
        'name',
    ])

    non_anonymized_fields = [
        'type',
    ]

    id = IDField(source='_id', read_only=True)
    type = TypeField()
    name = ser.CharField(required=True)
    date_created = VersionedDateTimeField(source='created', read_only=True)
    date_modified = VersionedDateTimeField(source='modified', read_only=True)

    links = LinksField({
        'self': 'get_absolute_url',
    })

    def get_absolute_url(self, obj):
        return obj.get_absolute_url()

    members = RelationshipField(
        related_view='groups:group-members',
        related_view_kwargs={'group_id': '<_id>'},
    )

    class Meta:
        type_ = 'groups'

    def create(self, validated_data):
        group = OSFGroup(creator=validated_data['creator'],
                         name=validated_data['name'])
        group.save()
        return group

    def update(self, instance, validated_data):
        if 'name' in validated_data:
            instance.set_group_name(validated_data.get('name'))
            instance.save()
        return instance
class InstitutionUserMetricsSerializer(JSONAPISerializer):
    class Meta:
        type_ = 'institution-users'

    id = IDField(source='user_id', read_only=True)
    user_name = ser.CharField(read_only=True)
    public_projects = ser.IntegerField(source='public_project_count',
                                       read_only=True)
    private_projects = ser.IntegerField(source='private_project_count',
                                        read_only=True)
    department = ser.CharField(read_only=True)

    user = RelationshipField(
        related_view='users:user-detail',
        related_view_kwargs={'user_id': '<user_id>'},
    )

    links = LinksField({
        'self': 'get_absolute_url',
    })

    filterable_fields = frozenset([
        'id',
        'user_name',
        'public_projects',
        'private_projects',
        'department',
    ])

    def get_absolute_url(self, obj):
        return absolute_reverse(
            'institutions:institution-user-metrics',
            kwargs={
                'institution_id':
                self.context['request'].parser_context['kwargs']
                ['institution_id'],
                'version':
                'v2',
            },
        )
Exemple #27
0
class PreprintProviderSerializer(JSONAPISerializer):

    filterable_fields = frozenset(['name', 'description', 'id'])

    name = ser.CharField(required=True)
    description = ser.CharField(required=False)
    id = ser.CharField(max_length=200, source='_id')

    logo_path = ser.CharField(read_only=True)
    banner_path = ser.CharField(read_only=True)

    preprints = RelationshipField(
        related_view='preprint_providers:preprints-list',
        related_view_kwargs={'provider_id': '<_id>'})

    links = LinksField({
        'self': 'get_absolute_url',
        'preprints': 'get_preprints_url',
        'external_url': 'get_external_url'
    })

    class Meta:
        type_ = 'preprint_providers'

    def get_absolute_url(self, obj):
        return obj.absolute_api_v2_url

    def get_preprints_url(self, obj):
        return absolute_reverse(
            'preprint_providers:preprints-list',
            kwargs={
                'provider_id':
                obj._id,
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def get_external_url(self, obj):
        return obj.external_url
Exemple #28
0
    def __init__(self, *args, **kwargs):
        super(ApiOAuth2PersonalTokenSerializer, self).__init__(*args, **kwargs)

        request = kwargs['context']['request']

        # Dynamically adding scopes field here, depending on the version
        if expect_scopes_as_relationships(request):
            field = TokenScopesRelationshipField(
                related_view='tokens:token-scopes-list',
                related_view_kwargs={'_id': '<_id>'},
                always_embed=True,
                read_only=False,
            )
            self.fields['scopes'] = field
            self.fields['owner'] = RelationshipField(
                related_view='users:user-detail',
                related_view_kwargs={'user_id': '<owner._id>'},
            )
            # Making scopes embeddable
            self.context['embed']['scopes'] = self.context[
                'view']._get_embed_partial('scopes', field)
        else:
            self.fields['scopes'] = ser.SerializerMethodField()
            self.fields['owner'] = ser.SerializerMethodField()
Exemple #29
0
class PreprintProviderSerializer(JSONAPISerializer):

    filterable_fields = frozenset([
        'allow_submissions',
        'description',
        'domain',
        'domain_redirect_enabled',
        'id',
        'name',
        'share_publish_type',
        'reviews_workflow',
        'permissions',
    ])

    name = ser.CharField(read_only=True)
    description = ser.CharField(read_only=True)
    id = ser.CharField(read_only=True, max_length=200, source='_id')
    advisory_board = ser.CharField(read_only=True)
    example = ser.CharField(read_only=True, allow_null=True)
    domain = ser.CharField(read_only=True, allow_null=False)
    domain_redirect_enabled = ser.BooleanField(read_only=True)
    footer_links = ser.CharField(read_only=True)
    share_source = ser.CharField(read_only=True)
    share_publish_type = ser.CharField(read_only=True)
    email_support = ser.CharField(read_only=True, allow_null=True)
    preprint_word = ser.CharField(read_only=True, allow_null=True)
    allow_submissions = ser.BooleanField(read_only=True)
    additional_providers = ser.ListField(read_only=True, child=ser.CharField())
    facebook_app_id = ser.IntegerField(read_only=True, allow_null=True)

    # Reviews settings are the only writable fields
    reviews_workflow = ser.ChoiceField(choices=Workflows.choices())
    reviews_comments_private = ser.BooleanField()
    reviews_comments_anonymous = ser.BooleanField()

    permissions = ser.SerializerMethodField()

    preprints = ReviewableCountsRelationshipField(
        related_view='preprint_providers:preprints-list',
        related_view_kwargs={'provider_id': '<_id>'})

    taxonomies = RelationshipField(
        related_view='preprint_providers:taxonomy-list',
        related_view_kwargs={'provider_id': '<_id>'})

    highlighted_taxonomies = RelationshipField(
        related_view='preprint_providers:highlighted-taxonomy-list',
        related_view_kwargs={'provider_id': '<_id>'},
        related_meta={
            'has_highlighted_subjects': 'get_has_highlighted_subjects'
        })

    licenses_acceptable = RelationshipField(
        related_view='preprint_providers:license-list',
        related_view_kwargs={'provider_id': '<_id>'})

    links = LinksField({
        'self': 'get_absolute_url',
        'preprints': 'get_preprints_url',
        'external_url': 'get_external_url'
    })

    # Deprecated fields
    header_text = ShowIfVersion(ser.CharField(read_only=True, default=''),
                                min_version='2.0',
                                max_version='2.3')
    banner_path = ShowIfVersion(ser.CharField(read_only=True, default=''),
                                min_version='2.0',
                                max_version='2.3')
    logo_path = ShowIfVersion(ser.CharField(read_only=True, default=''),
                              min_version='2.0',
                              max_version='2.3')
    email_contact = ShowIfVersion(ser.CharField(read_only=True,
                                                allow_null=True),
                                  min_version='2.0',
                                  max_version='2.3')
    social_twitter = ShowIfVersion(ser.CharField(read_only=True,
                                                 allow_null=True),
                                   min_version='2.0',
                                   max_version='2.3')
    social_facebook = ShowIfVersion(ser.CharField(read_only=True,
                                                  allow_null=True),
                                    min_version='2.0',
                                    max_version='2.3')
    social_instagram = ShowIfVersion(ser.CharField(read_only=True,
                                                   allow_null=True),
                                     min_version='2.0',
                                     max_version='2.3')
    subjects_acceptable = ShowIfVersion(ser.ListField(read_only=True,
                                                      default=[]),
                                        min_version='2.0',
                                        max_version='2.4')

    class Meta:
        type_ = 'preprint_providers'

    def get_has_highlighted_subjects(self, obj):
        return obj.has_highlighted_subjects

    def get_absolute_url(self, obj):
        return obj.absolute_api_v2_url

    def get_preprints_url(self, obj):
        return absolute_reverse(
            'preprint_providers:preprints-list',
            kwargs={
                'provider_id':
                obj._id,
                'version':
                self.context['request'].parser_context['kwargs']['version']
            })

    def get_external_url(self, obj):
        return obj.external_url

    def get_permissions(self, obj):
        auth = get_user_auth(self.context['request'])
        if not auth.user:
            return []
        return get_perms(auth.user, obj)

    def validate(self, data):
        required_fields = ('reviews_workflow', 'reviews_comments_private',
                           'reviews_comments_anonymous')
        for field in required_fields:
            if data.get(field) is None:
                raise ValidationError(
                    'All reviews fields must be set at once: `{}`'.format(
                        '`, `'.join(required_fields)))
        return data

    def update(self, instance, validated_data):
        instance.reviews_workflow = validated_data['reviews_workflow']
        instance.reviews_comments_private = validated_data[
            'reviews_comments_private']
        instance.reviews_comments_anonymous = validated_data[
            'reviews_comments_anonymous']
        instance.save()
        return instance
Exemple #30
0
class NodeSerializer(JSONAPISerializer):
    # TODO: If we have to redo this implementation in any of the other serializers, subclass ChoiceField and make it
    # handle blank choices properly. Currently DRF ChoiceFields ignore blank options, which is incorrect in this
    # instance
    filterable_fields = frozenset([
        'title',
        'description',
        'public',
        'tags',
        'category',
        'date_created',
        'date_modified',
        'registration'
    ])

    id = IDField(source='_id', read_only=True)
    type = TypeField()

    category_choices = Node.CATEGORY_MAP.keys()
    category_choices_string = ', '.join(["'{}'".format(choice) for choice in category_choices])

    title = ser.CharField(required=True)
    description = ser.CharField(required=False, allow_blank=True, allow_null=True)
    category = ser.ChoiceField(choices=category_choices, help_text="Choices: " + category_choices_string)
    date_created = ser.DateTimeField(read_only=True)
    date_modified = ser.DateTimeField(read_only=True)
    registration = ser.BooleanField(read_only=True, source='is_registration')
    fork = ser.BooleanField(read_only=True, source='is_fork')
    collection = DevOnly(ser.BooleanField(read_only=True, source='is_folder'))
    dashboard = ser.BooleanField(read_only=True, source='is_dashboard')
    tags = JSONAPIListField(child=NodeTagField(), required=False)

    # Public is only write-able by admins--see update method
    public = ser.BooleanField(source='is_public', required=False,
                              help_text='Nodes that are made public will give read-only access '
                                        'to everyone. Private nodes require explicit read '
                                        'permission. Write and admin access are the same for '
                                        'public and private nodes. Administrators on a parent '
                                        'node have implicit read permissions for all child nodes')

    links = LinksField({'html': 'get_absolute_url'})
    # TODO: When we have osf_permissions.ADMIN permissions, make this writable for admins

    children = RelationshipField(
        related_view='nodes:node-children',
        related_view_kwargs={'node_id': '<pk>'},
        related_meta={'count': 'get_node_count'},
    )

    comments = RelationshipField(
        related_view='nodes:node-comments',
        related_view_kwargs={'node_id': '<pk>'},
        related_meta={'unread': 'get_unread_comments_count'})

    contributors = RelationshipField(
        related_view='nodes:node-contributors',
        related_view_kwargs={'node_id': '<pk>'},
        related_meta={'count': 'get_contrib_count'},
    )

    files = RelationshipField(
        related_view='nodes:node-providers',
        related_view_kwargs={'node_id': '<pk>'}
    )

    forked_from = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<forked_from_id>'}
    )

    node_links = DevOnly(RelationshipField(
        related_view='nodes:node-pointers',
        related_view_kwargs={'node_id': '<pk>'},
        related_meta={'count': 'get_pointers_count'},
    ))

    parent = RelationshipField(
        related_view='nodes:node-detail',
        related_view_kwargs={'node_id': '<parent_id>'}
    )

    registrations = DevOnly(HideIfRegistration(RelationshipField(
        related_view='nodes:node-registrations',
        related_view_kwargs={'node_id': '<pk>'},
        related_meta={'count': 'get_registration_count'}
    )))

    logs = RelationshipField(
        related_view='nodes:node-logs',
        related_view_kwargs={'node_id': '<pk>'},
    )

    class Meta:
        type_ = 'nodes'

    def get_absolute_url(self, obj):
        return obj.absolute_url

    # TODO: See if we can get the count filters into the filter rather than the serializer.

    def get_user_auth(self, request):
        user = request.user
        if user.is_anonymous():
            auth = Auth(None)
        else:
            auth = Auth(user)
        return auth

    def get_node_count(self, obj):
        auth = self.get_user_auth(self.context['request'])
        nodes = [node for node in obj.nodes if node.can_view(auth) and node.primary and not node.is_deleted]
        return len(nodes)

    def get_contrib_count(self, obj):
        return len(obj.contributors)

    def get_registration_count(self, obj):
        auth = self.get_user_auth(self.context['request'])
        registrations = [node for node in obj.node__registrations if node.can_view(auth)]
        return len(registrations)

    def get_pointers_count(self, obj):
        return len(obj.nodes_pointer)

    def get_unread_comments_count(self, obj):
        auth = self.get_user_auth(self.context['request'])
        user = auth.user
        return Comment.find_unread(user=user, node=obj)

    def create(self, validated_data):
        node = Node(**validated_data)
        try:
            node.save()
        except ValidationValueError as e:
            raise InvalidModelValueError(detail=e.message)
        return node

    def update(self, node, validated_data):
        """Update instance with the validated data. Requires
        the request to be in the serializer context.
        """
        assert isinstance(node, Node), 'node must be a Node'
        auth = self.get_user_auth(self.context['request'])
        old_tags = set([tag._id for tag in node.tags])
        if 'tags' in validated_data:
            current_tags = set(validated_data.get('tags'))
            del validated_data['tags']
        elif self.partial:
            current_tags = set(old_tags)
        else:
            current_tags = set()

        for new_tag in (current_tags - old_tags):
            node.add_tag(new_tag, auth=auth)
        for deleted_tag in (old_tags - current_tags):
            node.remove_tag(deleted_tag, auth=auth)

        if validated_data:
            try:
                node.update(validated_data, auth=auth)
            except ValidationValueError as e:
                raise InvalidModelValueError(detail=e.message)
            except PermissionsError:
                raise exceptions.PermissionDenied

        return node