コード例 #1
0
ファイル: serializers.py プロジェクト: brianjgeiger/osf.io
    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
コード例 #2
0
ファイル: serializers.py プロジェクト: mfraezz/osf.io
    def update(self, node, validated_data):
        """Update instance with the validated data. Requires
        the request to be in the serializer context.
        """
        assert isinstance(node, AbstractNode), 'node must be a Node'
        auth = get_user_auth(self.context['request'])

        # Update tags
        if 'tags' in validated_data:
            new_tags = set(validated_data.pop('tags', []))
            node.update_tags(new_tags, auth=auth)

        if validated_data:

            if 'license_type' in validated_data or 'license' in validated_data:
                license_details = get_license_details(node, validated_data)
                validated_data['node_license'] = license_details

            try:
                node.update(validated_data, auth=auth)
            except ValidationError as e:
                raise InvalidModelValueError(detail=e.message)
            except PermissionsError:
                raise exceptions.PermissionDenied
            except NodeUpdateError as e:
                raise exceptions.ValidationError(detail=e.reason)
            except NodeStateError as e:
                raise InvalidModelValueError(detail=e.message)

        return node
コード例 #3
0
ファイル: serializers.py プロジェクト: icereval/osf.io
    def create(self, validated_data):
        auth = get_user_auth(self.context['request'])
        if not auth.user:
            raise exceptions.PermissionDenied

        try:
            node = self.context['view'].get_node()
        except exceptions.PermissionDenied:
            node = self.context['view'].get_node(check_object_permissions=False)
            if auth.user in node.contributors:
                raise exceptions.PermissionDenied('You cannot request access to a node you contribute to.')
            raise

        comment = validated_data.pop('comment', '')
        request_type = validated_data.pop('request_type', None)

        if not request_type:
            raise exceptions.ValidationError('You must specify a valid request_type.')

        try:
            node_request = NodeRequest.objects.create(
                target=node,
                creator=auth.user,
                comment=comment,
                machine_state=DefaultStates.INITIAL.value,
                request_type=request_type
            )
            node_request.save()
        except IntegrityError:
            raise Conflict('Users may not have more than one {} request per node.'.format(request_type))
        node_request.run_submit(auth.user)
        return node_request
コード例 #4
0
ファイル: views.py プロジェクト: CenterForOpenScience/osf.io
    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',
        )
コード例 #5
0
    def has_object_permission(self, request, view, obj):
        if isinstance(obj, ChronosSubmission):
            submission = ChronosSubmission.objects.get(publication_id=view.kwargs.get('submission_id', None))
            auth = get_user_auth(request)

            is_submission_accepted = submission.status == 3
            is_submission_published = submission.status == 4

            user_has_perm = False
            # If the request is a GET, then check whether the user is a CONTRIBUTOR
            # Because it is okay for us to show contributors detail of all submissions of this preprint
            if request.method == 'GET':
                is_preprint_contributor = obj.preprint.is_contributor(auth.user)
                user_has_perm = is_preprint_contributor or is_submission_published or is_submission_accepted
                if not user_has_perm:
                    raise exceptions.NotFound

            # However if the request is a PATCH or PUT, check whether the user is an ADMIN of this preprint
            # Because only preprint admins can update a submission
            if request.method in ['PATCH', 'PUT']:
                is_preprint_admin = obj.preprint.has_permission(auth.user, osf_permissions.ADMIN)
                user_has_perm = is_preprint_admin
                if not user_has_perm:
                    raise exceptions.PermissionDenied

            return user_has_perm
コード例 #6
0
ファイル: permissions.py プロジェクト: alexschiller/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, NodeWikiPage), 'obj must be a NodeWikiPage, got {}'.format(obj)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return obj.node.is_public or obj.node.can_view(auth)
     else:
         return obj.node.can_edit(auth)
コード例 #7
0
ファイル: serializers.py プロジェクト: DanielSBrown/osf.io
    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 = 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
            except NodeUpdateError as e:
                raise exceptions.ValidationError(detail=e.reason)

        return node
コード例 #8
0
ファイル: serializers.py プロジェクト: DanielSBrown/osf.io
    def get_unread_comments_count(self, obj):
        user = get_user_auth(self.context['request']).user
        node_comments = Comment.find_n_unread(user=user, node=obj, page='node')

        return {
            'node': node_comments
        }
コード例 #9
0
ファイル: permissions.py プロジェクト: aaxelb/osf.io
 def has_object_permission(self, request, view, obj):
     assert_resource_type(obj, self.acceptable_models)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return obj.is_public or obj.can_view(auth)
     else:
         return obj.has_permission(auth.user, osf_permissions.ADMIN)
コード例 #10
0
ファイル: views.py プロジェクト: digideskio/osf.io
 def get_queryset(self):
     log = self.get_log()
     auth_user = get_user_auth(self.request)
     return [
         node for node in log.node__logged
         if node.can_view(auth_user)
     ]
コード例 #11
0
ファイル: serializers.py プロジェクト: adlius/osf.io
 def get_node_links_count(self, obj):
     count = 0
     auth = get_user_auth(self.context['request'])
     for pointer in obj.linked_nodes.filter(is_deleted=False, type='osf.node'):
         if pointer.can_view(auth):
             count += 1
     return count
コード例 #12
0
ファイル: permissions.py プロジェクト: KAsante95/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, (Node, Pointer)), "obj must be a Node or Pointer, got {}".format(obj)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return obj.is_public or obj.can_view(auth)
     else:
         return obj.can_edit(auth)
コード例 #13
0
ファイル: views.py プロジェクト: mfraezz/osf.io
    def get_default_queryset(self):
        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')

        # Permissions on the list objects are handled by the query
        return self.preprints_queryset(provider.preprint_services.all(), auth_user)
コード例 #14
0
ファイル: serializers.py プロジェクト: brianjgeiger/osf.io
 def get_node_links_count(self, obj):
     count = 0
     auth = get_user_auth(self.context['request'])
     for pointer in obj.nodes_pointer:
         if not pointer.node.is_deleted and not pointer.node.is_collection and pointer.node.can_view(auth):
             count += 1
     return count
コード例 #15
0
ファイル: serializers.py プロジェクト: leb2dg/osf.io
    def create(self, validated_data):
        auth = get_user_auth(self.context['request'])
        draft = validated_data.pop('draft')
        registration_choice = validated_data.pop('registration_choice', 'immediate')
        embargo_lifted = validated_data.pop('lift_embargo', None)
        reviewer = is_prereg_admin_not_project_admin(self.context['request'], draft)

        try:
            draft.validate_metadata(metadata=draft.registration_metadata, reviewer=reviewer, required_fields=True)
        except ValidationValueError as e:
            raise exceptions.ValidationError(e.message)

        registration = draft.register(auth, save=True)

        if registration_choice == 'embargo':
            if not embargo_lifted:
                raise exceptions.ValidationError('lift_embargo must be specified.')
            embargo_end_date = embargo_lifted.replace(tzinfo=pytz.utc)
            try:
                registration.embargo_registration(auth.user, embargo_end_date)
            except ValidationError as err:
                raise exceptions.ValidationError(err.message)
        else:
            try:
                registration.require_approval(auth.user)
            except NodeStateError as err:
                raise exceptions.ValidationError(err)

        registration.save()
        return registration
コード例 #16
0
ファイル: serializers.py プロジェクト: erinspace/osf.io
    def create(self, validated_data):
        node = validated_data.pop('node', {})
        if isinstance(node, dict):
            node = Node.objects.create(creator=self.context['request'].user, **node)

        if node.is_deleted:
            raise exceptions.ValidationError('Cannot create a preprint from a deleted node.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.')

        node_preprints = node.preprints.filter(provider=provider)
        if node_preprints.exists():
            raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': node_preprints.first()._id})

        preprint = PreprintService(node=node, provider=provider)
        preprint.save()
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #17
0
ファイル: permissions.py プロジェクト: erinspace/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, AbstractNode), 'obj must be an Node, got {}'.format(obj)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return obj.is_contributor(auth.user)
     else:
         return obj.has_permission(auth.user, 'write')
コード例 #18
0
 def perform_destroy(self, instance):
     auth = get_user_auth(self.request)
     try:
         instance.remove_node(auth=auth)
     except NodeStateError as err:
         raise ValidationError(err.message)
     instance.save()
コード例 #19
0
ファイル: permissions.py プロジェクト: erinspace/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, (AbstractNode, OSFUser, Institution, BaseAddonSettings, DraftRegistration, PrivateLink)), 'obj must be an Node, User, Institution, Draft Registration, PrivateLink, or AddonSettings; got {}'.format(obj)
     auth = get_user_auth(request)
     if request.method in permissions.SAFE_METHODS:
         return obj.is_public or obj.can_view(auth)
     else:
         return obj.has_permission(auth.user, osf_permissions.ADMIN)
コード例 #20
0
ファイル: permissions.py プロジェクト: baylee-d/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(obj, (Node, DraftRegistration, PrivateLink)), 'obj must be a Node, Draft Registration, or PrivateLink, got {}'.format(obj)
     auth = get_user_auth(request)
     node = Node.load(request.parser_context['kwargs']['node_id'])
     if request.method != 'DELETE' and is_prereg_admin(auth.user):
         return True
     return node.has_permission(auth.user, osf_permissions.ADMIN)
コード例 #21
0
ファイル: permissions.py プロジェクト: erinspace/osf.io
    def has_object_permission(self, request, view, obj):
        assert isinstance(obj, dict)
        auth = get_user_auth(request)
        parent_node = obj['self']

        if request.method in permissions.SAFE_METHODS:
            return parent_node.can_view(auth)
        elif request.method == 'DELETE':
            return parent_node.can_edit(auth)
        else:
            has_parent_auth = parent_node.can_edit(auth)
            if not has_parent_auth:
                return False
            pointer_nodes = []
            for pointer in request.data.get('data', []):
                node = AbstractNode.load(pointer['id'])
                if not node or node.is_collection:
                    raise exceptions.NotFound(detail='Node with id "{}" was not found'.format(pointer['id']))
                pointer_nodes.append(node)
            has_pointer_auth = True
            for pointer in pointer_nodes:
                if not pointer.can_view(auth):
                    has_pointer_auth = False
                    break
            return has_pointer_auth
コード例 #22
0
ファイル: serializers.py プロジェクト: erinspace/osf.io
    def create(self, validated_data):
        auth = get_user_auth(self.context['request'])
        if not auth.user:
            raise exceptions.PermissionDenied

        preprint = self.context['view'].get_target()

        if not preprint.has_permission(auth.user, osf_permissions.ADMIN):
            raise exceptions.PermissionDenied

        comment = validated_data.pop('comment', '')
        request_type = validated_data.pop('request_type', None)

        if PreprintRequest.objects.filter(target_id=preprint.id, creator_id=auth.user.id, request_type=request_type).exists():
            raise Conflict('Users may not have more than one {} request per preprint.'.format(request_type))

        if request_type != RequestTypes.WITHDRAWAL.value:
            raise exceptions.ValidationError('You must specify a valid request_type.')

        preprint_request = PreprintRequest.objects.create(
            target=preprint,
            creator=auth.user,
            comment=comment,
            machine_state=DefaultStates.INITIAL.value,
            request_type=request_type
        )
        preprint_request.save()
        preprint_request.run_submit(auth.user)
        return preprint_request
コード例 #23
0
ファイル: serializers.py プロジェクト: cslzchen/osf.io
    def create(self, validated_data):
        node = Node.load(validated_data.pop('node', None))
        if not node:
            raise exceptions.NotFound('Unable to find Node with specified id.')

        auth = get_user_auth(self.context['request'])
        if not node.has_permission(auth.user, permissions.ADMIN):
            raise exceptions.PermissionDenied

        primary_file = validated_data.pop('primary_file', None)
        if not primary_file:
            raise exceptions.ValidationError(detail='You must specify a valid primary_file to create a preprint.')

        provider = validated_data.pop('provider', None)
        if not provider:
            raise exceptions.ValidationError(detail='You must specify a valid provider to create a preprint.')

        if PreprintService.find(Q('node', 'eq', node) & Q('provider', 'eq', provider)).count():
            conflict = PreprintService.find_one(Q('node', 'eq', node) & Q('provider', 'eq', provider))
            raise Conflict('Only one preprint per provider can be submitted for a node. Check `meta[existing_resource_id]`.', meta={'existing_resource_id': conflict._id})

        preprint = PreprintService(node=node, provider=provider)
        self.set_field(preprint.set_primary_file, primary_file, auth, save=True)
        preprint.node._has_abandoned_preprint = True
        preprint.node.save()

        return self.update(preprint, validated_data)
コード例 #24
0
ファイル: views.py プロジェクト: CenterForOpenScience/osf.io
 def perform_destroy(self, instance):
     auth = get_user_auth(self.request)
     wiki_page = self.get_object()
     try:
         wiki_page.delete(auth)
     except django_exceptions.ValidationError as err:
         raise ValidationError(err.message)
コード例 #25
0
ファイル: serializers.py プロジェクト: leodomingo/osf.io
    def update(self, instance, validated_data):
        addon_name = instance.config.short_name
        if addon_name not in ADDONS_FOLDER_CONFIGURABLE:
            raise EndpointNotImplementedError('Requested addon not currently configurable via API.')

        auth = get_user_auth(self.context['request'])

        set_account, external_account_id = self.get_account_info(validated_data)
        set_folder, folder_info = self.get_folder_info(validated_data, addon_name)

        # Maybe raise errors
        self.check_for_update_errors(instance, folder_info, external_account_id)

        if instance and instance.configured and set_folder and not folder_info:
            # Enabled and configured, user requesting folder unset
            instance.clear_settings()
            instance.save()

        if instance and instance.has_auth and set_account and not external_account_id:
            # Settings authorized, User requesting deauthorization
            instance.deauthorize(auth=auth)  # clear_auth performs save
        elif external_account_id:
            # Settings may or may not be authorized, user requesting to set instance.external_account
            account = self.get_account_or_error(addon_name, external_account_id, auth)
            if instance.external_account and external_account_id != instance.external_account._id:
                # Ensure node settings are deauthorized first, logs
                instance.deauthorize(auth=auth)
            instance.set_auth(account, auth.user)

        if set_folder and self.should_call_set_folder(folder_info, instance, auth, instance):
            # Enabled, user requesting to set folder
            instance.set_folder(folder_info, auth)

        return instance
コード例 #26
0
 def make_instance_obj(self, obj):
     # Convenience method to format instance based on view's get_object
     return {
         'data':
             list(self.context['view'].collection_preprints(obj, user=get_user_auth(self.context['request']).user)),
         'self': obj,
     }
コード例 #27
0
ファイル: permissions.py プロジェクト: erinspace/osf.io
    def has_object_permission(self, request, view, obj):
        assert isinstance(obj, dict)
        auth = get_user_auth(request)
        collection = obj['self']
        has_collection_auth = auth.user and auth.user.has_perm('write_collection', collection)

        if request.method in permissions.SAFE_METHODS:
            if collection.is_public:
                return True
        elif request.method == 'DELETE':
            return has_collection_auth

        if not has_collection_auth:
            return False
        pointer_nodes = []
        for pointer in request.data.get('data', []):
            node = AbstractNode.load(pointer['id'])
            if not node:
                raise NotFound(detail='Node with id "{}" was not found'.format(pointer['id']))
            pointer_nodes.append(node)
        has_pointer_auth = True
        # TODO: is this necessary? get_object checks can_view
        for pointer in pointer_nodes:
            if not pointer.can_view(auth):
                has_pointer_auth = False
                break
        return has_pointer_auth
コード例 #28
0
ファイル: serializers.py プロジェクト: adlius/osf.io
 def get_registration_links_count(self, obj):
     count = 0
     auth = get_user_auth(self.context['request'])
     for pointer in obj.linked_nodes.filter(is_deleted=False, type='osf.registration').exclude(type='osf.collection'):
         if pointer.can_view(auth):
             count += 1
     return count
コード例 #29
0
ファイル: serializers.py プロジェクト: monikagrabowska/osf.io
    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
コード例 #30
0
ファイル: serializers.py プロジェクト: adlius/osf.io
    def get_node_count(self, obj):
        auth = get_user_auth(self.context['request'])
        user_id = getattr(auth.user, 'id', None)
        with connection.cursor() as cursor:
            cursor.execute('''
                WITH RECURSIVE parents AS (
                  SELECT parent_id, child_id
                  FROM osf_noderelation
                  WHERE child_id = %s AND is_node_link IS FALSE
                UNION ALL
                  SELECT osf_noderelation.parent_id, parents.parent_id AS child_id
                  FROM parents JOIN osf_noderelation ON parents.PARENT_ID = osf_noderelation.child_id
                  WHERE osf_noderelation.is_node_link IS FALSE
                ), has_admin AS (SELECT * FROM osf_contributor WHERE (node_id IN (SELECT parent_id FROM parents) OR node_id = %s) AND user_id = %s AND admin IS TRUE LIMIT 1)
                SELECT DISTINCT
                  COUNT(child_id)
                FROM
                  osf_noderelation
                JOIN osf_abstractnode ON osf_noderelation.child_id = osf_abstractnode.id
                JOIN osf_contributor ON osf_abstractnode.id = osf_contributor.node_id
                LEFT JOIN osf_privatelink_nodes ON osf_abstractnode.id = osf_privatelink_nodes.abstractnode_id
                LEFT JOIN osf_privatelink ON osf_privatelink_nodes.privatelink_id = osf_privatelink.id
                WHERE parent_id = %s AND is_node_link IS FALSE
                AND osf_abstractnode.is_deleted IS FALSE
                AND (
                  osf_abstractnode.is_public
                  OR (TRUE IN (SELECT TRUE FROM has_admin))
                  OR (osf_contributor.user_id = %s AND osf_contributor.read IS TRUE)
                  OR (osf_privatelink.key = %s AND osf_privatelink.is_deleted = FALSE)
                );
            ''', [obj.id, obj.id, user_id, obj.id, user_id, auth.private_key])

            return int(cursor.fetchone()[0])
コード例 #31
0
ファイル: permissions.py プロジェクト: summerdefalut/osf.io
 def has_permission(self, request, view):
     if request.method not in ['PATCH', 'PUT']:
         return True
     auth = get_user_auth(request)
     return auth.user.has_perm('update_moderator', view.get_provider())
コード例 #32
0
ファイル: permissions.py プロジェクト: summerdefalut/osf.io
 def has_permission(self, request, view):
     if request.method != 'POST':
         return True
     auth = get_user_auth(request)
     return auth.user.has_perm('add_moderator', view.get_provider())
コード例 #33
0
ファイル: permissions.py プロジェクト: jwalz/osf.io
 def has_object_permission(self, request, view, obj):
     assert_resource_type(obj, self.acceptable_models)
     auth = get_user_auth(request)
     return obj.has_permission(auth.user, 'admin')
コード例 #34
0
    def update(self, preprint, validated_data):
        assert isinstance(
            preprint,
            PreprintService), 'You must specify a valid preprint to be updated'
        assert isinstance(
            preprint.node, Node
        ), 'You must specify a preprint with a valid node to be updated.'

        auth = get_user_auth(self.context['request'])
        if not preprint.node.has_permission(auth.user, 'admin'):
            raise exceptions.PermissionDenied(
                detail='User must be an admin to update a preprint.')

        published = validated_data.pop('is_published', None)
        if published and preprint.provider.is_reviewed:
            raise Conflict(
                '{} uses a moderation workflow, so preprints must be submitted for review instead of published directly. Submit a preprint by creating a `submit` Action at {}'
                .format(
                    preprint.provider.name,
                    absolute_reverse(
                        'preprints:preprint-review-action-list',
                        kwargs={
                            'version':
                            self.context['request'].parser_context['kwargs']
                            ['version'],
                            'preprint_id':
                            preprint._id
                        })))

        save_node = False
        save_preprint = False
        recently_published = False
        primary_file = validated_data.pop('primary_file', None)
        if primary_file:
            self.set_field(preprint.set_primary_file, primary_file, auth)
            save_node = True

        old_tags = set(preprint.node.tags.values_list('name', flat=True))
        if validated_data.get('node') and 'tags' in validated_data['node']:
            current_tags = set(validated_data['node'].pop('tags', []))
        elif self.partial:
            current_tags = set(old_tags)
        else:
            current_tags = set()

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

        if 'node' in validated_data:
            preprint.node.update(fields=validated_data.pop('node'))
            save_node = True

        if 'subjects' in validated_data:
            subjects = validated_data.pop('subjects', None)
            self.set_field(preprint.set_subjects, subjects, auth)
            save_preprint = True

        if 'article_doi' in validated_data:
            preprint.node.preprint_article_doi = validated_data['article_doi']
            save_node = True

        if 'license_type' in validated_data or 'license' in validated_data:
            license_details = get_license_details(preprint, validated_data)
            self.set_field(preprint.set_preprint_license, license_details,
                           auth)
            save_preprint = True

        if 'original_publication_date' in validated_data:
            preprint.original_publication_date = validated_data[
                'original_publication_date']
            save_preprint = True

        if published is not None:
            if not preprint.primary_file:
                raise exceptions.ValidationError(
                    detail=
                    'A valid primary_file must be set before publishing a preprint.'
                )
            self.set_field(preprint.set_published, published, auth)
            save_preprint = True
            recently_published = published
            preprint.node.set_privacy('public')
            save_node = True

        if save_node:
            try:
                preprint.node.save()
            except ValidationError as e:
                # Raised from invalid DOI
                raise exceptions.ValidationError(detail=e.messages[0])

        if save_preprint:
            preprint.save()

        # Send preprint confirmation email signal to new authors on preprint! -- only when published
        # TODO: Some more thought might be required on this; preprints made from existing
        # nodes will send emails making it seem like a new node.
        if recently_published:
            for author in preprint.node.contributors:
                if author != auth.user:
                    project_signals.contributor_added.send(
                        preprint.node,
                        contributor=author,
                        auth=auth,
                        email_template='preprint')

        return preprint
コード例 #35
0
 def has_object_permission(self, request, view, obj):
     if request.method in drf_permissions.SAFE_METHODS:
         return True
     auth = get_user_auth(request)
     return auth.user.has_perm('set_up_moderation', obj)
コード例 #36
0
 def get_registration_count(self, obj):
     auth = get_user_auth(self.context['request'])
     user_registration = default_node_list_queryset(model_cls=Registration).filter(contributor__user__id=obj.id)
     return user_registration.can_view(user=auth.user, private_link=auth.private_link).count()
コード例 #37
0
 def get_registration_count(self, obj):
     auth = get_user_auth(self.context['request'])
     registrations = [
         node for node in obj.registrations_all if node.can_view(auth)
     ]
     return len(registrations)
コード例 #38
0
 def update(self, instance, validated_data):
     auth = get_user_auth(self.context['request'])
     preprint = instance['self']
     preprint.unset_supplemental_node(auth=auth)
     preprint.save()
     return self.make_instance_obj(preprint)
コード例 #39
0
    def update(self, preprint, validated_data):
        assert isinstance(preprint, Preprint), 'You must specify a valid preprint to be updated'

        auth = get_user_auth(self.context['request'])
        if not preprint.has_permission(auth.user, osf_permissions.WRITE):
            raise exceptions.PermissionDenied(detail='User must have admin or write permissions to update a preprint.')

        published = validated_data.pop('is_published', None)
        if published and preprint.provider.is_reviewed:
            raise Conflict('{} uses a moderation workflow, so preprints must be submitted for review instead of published directly. Submit a preprint by creating a `submit` Action at {}'.format(
                preprint.provider.name,
                absolute_reverse(
                    'preprints:preprint-review-action-list', kwargs={
                        'version': self.context['request'].parser_context['kwargs']['version'],
                        'preprint_id': preprint._id,
                    },
                ),
            ))

        save_preprint = False
        recently_published = False

        primary_file = validated_data.pop('primary_file', None)
        if primary_file:
            self.set_field(preprint.set_primary_file, primary_file, auth)
            save_preprint = True

        old_tags = set(preprint.tags.values_list('name', flat=True))
        if 'tags' in validated_data:
            current_tags = set(validated_data.pop('tags', []))
        elif self.partial:
            current_tags = set(old_tags)
        else:
            current_tags = set()

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

        if 'node' in validated_data:
            node = validated_data.pop('node', None)
            self.set_field(preprint.set_supplemental_node, node, auth)
            save_preprint = True

        if 'subjects' in validated_data:
            subjects = validated_data.pop('subjects', None)
            self.update_subjects(preprint, subjects, auth)
            save_preprint = True

        if 'title' in validated_data:
            title = validated_data['title']
            self.set_field(preprint.set_title, title, auth)
            save_preprint = True

        if 'description' in validated_data:
            description = validated_data['description']
            self.set_field(preprint.set_description, description, auth)
            save_preprint = True

        if 'article_doi' in validated_data:
            preprint.article_doi = validated_data['article_doi']
            save_preprint = True

        if 'license_type' in validated_data or 'license' in validated_data:
            license_details = get_license_details(preprint, validated_data)
            self.set_field(preprint.set_preprint_license, license_details, auth)
            save_preprint = True

        if 'original_publication_date' in validated_data:
            preprint.original_publication_date = validated_data['original_publication_date'] or None
            save_preprint = True

        if 'has_coi' in validated_data:
            try:
                preprint.update_has_coi(auth, validated_data['has_coi'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'conflict_of_interest_statement' in validated_data:
            try:
                preprint.update_conflict_of_interest_statement(auth, validated_data['conflict_of_interest_statement'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'has_data_links' in validated_data:
            try:
                preprint.update_has_data_links(auth, validated_data['has_data_links'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'why_no_data' in validated_data:
            try:
                preprint.update_why_no_data(auth, validated_data['why_no_data'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'data_links' in validated_data:
            try:
                preprint.update_data_links(auth, validated_data['data_links'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'has_prereg_links' in validated_data:
            try:
                preprint.update_has_prereg_links(auth, validated_data['has_prereg_links'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'why_no_prereg' in validated_data:
            try:
                preprint.update_why_no_prereg(auth, validated_data['why_no_prereg'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'prereg_links' in validated_data:
            try:
                preprint.update_prereg_links(auth, validated_data['prereg_links'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if 'prereg_link_info' in validated_data:
            try:
                preprint.update_prereg_link_info(auth, validated_data['prereg_link_info'])
            except PreprintStateError as e:
                raise exceptions.ValidationError(detail=str(e))

        if published is not None:
            if not preprint.primary_file:
                raise exceptions.ValidationError(detail='A valid primary_file must be set before publishing a preprint.')
            self.set_field(preprint.set_published, published, auth)
            save_preprint = True
            recently_published = published
            preprint.set_privacy('public', log=False, save=True)

        if save_preprint:
            preprint.save()

        if recently_published:
            for author in preprint.contributors:
                if author != auth.user:
                    project_signals.contributor_added.send(preprint, contributor=author, auth=auth, email_template='preprint')

        return preprint
コード例 #40
0
 def get_preprint_count(self, obj):
     auth_user = get_user_auth(self.context['request']).user
     user_preprints_query = Preprint.objects.filter(_contributors__guids___id=obj._id).exclude(machine_state='initial')
     return Preprint.objects.can_view(user_preprints_query, auth_user, allow_contribs=False).count()
コード例 #41
0
 def get_projects_in_common(self, obj):
     user = get_user_auth(self.context['request']).user
     if obj == user:
         return user.contributor_to.count()
     return obj.n_projects_in_common(user)
コード例 #42
0
    def get_node_count(self, obj):
        auth = get_user_auth(self.context['request'])
        if obj != auth.user:
            return default_node_list_permission_queryset(user=auth.user, model_cls=Node).filter(contributor__user__id=obj.id).count()

        return default_node_list_queryset(model_cls=Node).filter(contributor__user__id=obj.id).count()
コード例 #43
0
ファイル: permissions.py プロジェクト: slamdunking/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(
         obj, AbstractNode), 'obj must be an Node, got {}'.format(obj)
     auth = get_user_auth(request)
     return obj.has_permission(auth.user, osf_permissions.ADMIN)
コード例 #44
0
ファイル: views.py プロジェクト: tosh1ck/osf.io
    def get_default_queryset(self):
        auth = get_user_auth(self.request)
        auth_user = getattr(auth, 'user', None)

        # Permissions on the list objects are handled by the query
        return self.preprints_queryset(PreprintService.objects.all(), auth_user)
コード例 #45
0
ファイル: permissions.py プロジェクト: rdm-dev12/RDM-osf.io
 def has_permission(self, request, view):
     auth = get_user_auth(request)
     return bool(get_perms(auth.user, view.get_provider()))
コード例 #46
0
ファイル: permissions.py プロジェクト: slamdunking/osf.io
 def has_object_permission(self, request, view, obj):
     assert isinstance(
         obj, AbstractNode), 'obj must be an Node got {}'.format(obj)
     auth = get_user_auth(request)
     return obj.is_public or obj.can_view(auth)
コード例 #47
0
    def update(self, preprint, validated_data):
        assert isinstance(
            preprint,
            PreprintService), 'You must specify a valid preprint to be updated'
        assert isinstance(
            preprint.node, Node
        ), 'You must specify a preprint with a valid node to be updated.'

        auth = get_user_auth(self.context['request'])
        if not preprint.node.has_permission(auth.user, 'admin'):
            raise exceptions.PermissionDenied(
                detail='User must be an admin to update a preprint.')

        save_node = False
        save_preprint = False
        recently_published = False

        primary_file = validated_data.pop('primary_file', None)
        if primary_file:
            self.set_field(preprint.set_primary_file, primary_file, auth)
            save_node = True

        if 'subjects' in validated_data:
            subjects = validated_data.pop('subjects', None)
            self.set_field(preprint.set_subjects, subjects, auth)
            save_preprint = True

        if 'article_doi' in validated_data:
            preprint.node.preprint_article_doi = validated_data['article_doi']
            save_node = True

        published = validated_data.pop('is_published', None)
        if published is not None:
            self.set_field(preprint.set_published, published, auth)
            save_preprint = True
            recently_published = published

        if 'license_type' in validated_data or 'license' in validated_data:
            license_details = get_license_details(preprint, validated_data)
            self.set_field(preprint.set_preprint_license, license_details,
                           auth)
            save_preprint = True

        if save_node:
            try:
                preprint.node.save()
            except ValidationValueError as e:
                # Raised from invalid DOI
                raise exceptions.ValidationError(detail=e.message)

        if save_preprint:
            preprint.save()

        # Send preprint confirmation email signal to new authors on preprint! -- only when published
        # TODO: Some more thought might be required on this; preprints made from existing
        # nodes will send emails making it seem like a new node.
        if recently_published:
            for author in preprint.node.contributors:
                if author != auth.user:
                    project_signals.contributor_added.send(
                        preprint.node,
                        contributor=author,
                        auth=auth,
                        email_template='preprint')

        return preprint
コード例 #48
0
 def has_object_permission(self, request, view, obj):
     assert_resource_type(obj, self.acceptable_models)
     if isinstance(obj, PrivateLink):
         obj = view.get_node()
     auth = get_user_auth(request)
     return obj.has_permission(auth.user, osf_permissions.ADMIN)
コード例 #49
0
    def create(self, validated_data):
        auth = get_user_auth(self.context['request'])
        user_id = validated_data.pop('_id', '')
        address = validated_data.pop('email', '')
        provider = self.context['provider']
        context = {
            'referrer': auth.user,
        }
        if user_id and address:
            raise ValidationError('Cannot specify both "id" and "email".')

        user = None
        if user_id:
            user = OSFUser.load(user_id)
        elif address:
            try:
                email = Email.objects.get(address=address.lower())
            except Email.DoesNotExist:
                full_name = validated_data.pop('fullname', '')
                if not full_name:
                    raise ValidationError(
                        '"full_name" is required when adding a moderator via email.'
                    )
                user = OSFUser.create_unregistered(full_name, email=address)
                user.add_unclaimed_record(
                    provider,
                    referrer=auth.user,
                    given_name=full_name,
                    email=address,
                )
                user.save()
                claim_url = user.get_claim_url(provider._id, external=True)
                context['claim_url'] = claim_url
            else:
                user = email.user
        else:
            raise ValidationError('Must specify either "id" or "email".')

        if not user:
            raise ValidationError('Unable to find specified user.')
        context['user'] = user
        context['provider'] = provider

        if bool(get_perms(user, provider)):
            raise ValidationError('Specified user is already a moderator.')
        if 'claim_url' in context:
            template = mails.CONFIRM_EMAIL_MODERATION(provider)
        else:
            template = mails.MODERATOR_ADDED(provider)

        perm_group = validated_data.pop('permission_group', '')
        if perm_group not in REVIEW_GROUPS:
            raise ValidationError('Unrecognized permission_group')
        context[
            'notification_settings_url'] = '{}reviews/preprints/{}/notifications'.format(
                DOMAIN, provider._id)
        context['provider_name'] = provider.name
        context['is_reviews_moderator_notification'] = True
        context['is_admin'] = perm_group == 'admin'

        provider.add_to_group(user, perm_group)
        setattr(user, 'permission_group', perm_group)  # Allows reserialization
        mails.send_mail(user.username, template, mimetype='html', **context)
        return user
コード例 #50
0
 def get_permissions(self, obj):
     auth = get_user_auth(self.context['request'])
     if not auth.user:
         return []
     return get_perms(auth.user, obj)
コード例 #51
0
 def has_object_permission(self, request, view, obj):
     auth = get_user_auth(request)
     return obj.can_edit(auth)
コード例 #52
0
ファイル: serializers.py プロジェクト: scooley/osf.io
 def get_projects_in_common(self, obj):
     user = get_user_auth(self.context['request']).user
     if obj == user:
         return len(user.contributor_to)
     return len(obj.get_projects_in_common(user, primary_keys=True))
コード例 #53
0
 def perform_destroy(self, instance):
     auth = get_user_auth(self.request)
     instance.remove_group(auth=auth)
コード例 #54
0
 def has_object_permission(self, request, view, obj):
     assert_resource_type(obj, self.acceptable_models)
     auth = get_user_auth(request)
     return obj.is_public or obj.can_view(auth)
コード例 #55
0
ファイル: serializers.py プロジェクト: rdm-dev12/RDM-osf.io
 def get_registration_links_count(self, obj):
     auth = get_user_auth(self.context['request'])
     return Registration.objects.filter(
         guids__in=obj.guid_links.all(),
         is_deleted=False).can_view(user=auth.user,
                                    private_link=auth.private_link).count()
コード例 #56
0
ファイル: views.py プロジェクト: futa-ikeda/osf.io
 def get_queryset(self):
     auth = get_user_auth(self.request)
     return self.collection_preprints(self.get_collection(), auth.user)
コード例 #57
0
 def get_queryset(self):
     auth = get_user_auth(self.request)
     return Registration.objects.filter(guids__in=self.get_collection().guid_links.all(), is_deleted=False).can_view(user=auth.user, private_link=auth.private_link).order_by('-modified')
コード例 #58
0
ファイル: views.py プロジェクト: BRosenblatt/osf.io
    def get_queryset(self):
        auth = get_user_auth(self.request)

        return self.get_node().linked_nodes.filter(is_deleted=False).exclude(type='osf.collection').can_view(user=auth.user, private_link=auth.private_link).order_by('-date_modified')
コード例 #59
0
    def get_unread_comments_count(self, obj):
        user = get_user_auth(self.context['request']).user
        node_comments = Comment.find_n_unread(user=user, node=obj, page='node')

        return {'node': node_comments}
コード例 #60
0
    def has_object_permission(self, request, view, obj):
        auth = get_user_auth(request)

        # If a user has perms on the provider, they must be a moderator or admin
        is_moderator = bool(get_perms(auth.user, obj.provider))
        return obj.is_admin_contributor(auth.user) or is_moderator