예제 #1
0
    def request_embargo_termination(self, auth):
        """Initiates an EmbargoTerminationApproval to lift this Embargoed Registration's
        embargo early."""
        if not self.is_embargoed:
            raise NodeStateError('This node is not under active embargo')
        if not self.root == self:
            raise NodeStateError(
                'Only the root of an embargoed registration can request termination'
            )

        approval = EmbargoTerminationApproval(
            initiated_by=auth.user,
            embargoed_registration=self,
        )
        admins = [
            admin for admin in self.root.get_admin_contributors_recursive(
                unique_users=True)
        ]
        for (admin, node) in admins:
            approval.add_authorizer(admin, node=node)
        approval.save()
        approval.ask(admins)
        self.embargo_termination_approval = approval
        self.save()
        return approval
예제 #2
0
    def retract_registration(self, user, justification=None, save=True):
        """Retract public registration. Instantiate new Retraction object
        and associate it with the respective registration.
        """

        if not self.is_public and not (self.embargo_end_date
                                       or self.is_pending_embargo):
            raise NodeStateError(
                'Only public or embargoed registrations may be withdrawn.')

        if self.root_id != self.id:
            raise NodeStateError(
                'Withdrawal of non-parent registrations is not permitted.')

        retraction = self._initiate_retraction(user, justification)
        self.registered_from.add_log(
            action=NodeLog.RETRACTION_INITIATED,
            params={
                'node': self.registered_from._id,
                'registration': self._id,
                'retraction_id': retraction._id,
            },
            auth=Auth(user),
        )
        self.retraction = retraction
        if save:
            self.save()
        return retraction
예제 #3
0
    def set_editing(self, permissions, auth=None, log=False):
        """Set the editing permissions for this node.

        :param auth: All the auth information including user, API key
        :param bool permissions: True = publicly editable
        :param bool save: Whether to save the privacy change
        :param bool log: Whether to add a NodeLog for the privacy change
            if true the node object is also saved
        """
        node = self.owner

        if permissions and not self.is_publicly_editable:
            if node.is_public:
                self.is_publicly_editable = True
            else:
                raise NodeStateError('Private components cannot be made publicly editable.')
        elif not permissions and self.is_publicly_editable:
            self.is_publicly_editable = False
        else:
            raise NodeStateError('Desired permission change is the same as current setting.')

        if log:
            node.add_log(
                action=(NodeLog.MADE_WIKI_PUBLIC
                        if self.is_publicly_editable
                        else NodeLog.MADE_WIKI_PRIVATE),
                params={
                    'project': node.parent_id,
                    'node': node._primary_key,
                },
                auth=auth,
                save=True,
            )

        self.save()
예제 #4
0
 def remove_node(self, auth, date=None):
     # QuickFilesNodes are only delete-able for disabled users
     # This is only done when doing a GDPR-delete
     if auth.user.is_disabled:
         super(QuickFilesNode, self).remove_node(auth=auth, date=date)
     else:
         raise NodeStateError('A QuickFilesNode may not be deleted.')
예제 #5
0
def new_bookmark_collection(user):
    """Create a new bookmark collection project.

    :param User user: User object
    :return Node: Created node

    """
    existing_bookmark_collection = Node.find(
        Q('is_bookmark_collection', 'eq', True) & Q('contributors', 'eq', user._id) & Q('is_deleted', 'eq', False)
    )

    if existing_bookmark_collection.count() > 0:
        raise NodeStateError('Users may only have one bookmark collection')

    node = Node(
        title='Bookmarks',
        creator=user,
        category='project',
        is_bookmark_collection=True,
        is_collection=True
    )

    node.save()

    return node
예제 #6
0
    def _on_complete(self, user):
        NodeLog = apps.get_model('osf.NodeLog')

        register = self._get_registration()
        if register.is_spammy:
            raise NodeStateError('Cannot approve a spammy registration')

        super(RegistrationApproval, self)._on_complete(user)
        self.state = Sanction.APPROVED
        self.save()
        registered_from = register.registered_from
        # Pass auth=None because the registration initiator may not be
        # an admin on components (component admins had the opportunity
        # to disapprove the registration by this point)
        register.set_privacy('public', auth=None, log=False)
        for child in register.get_descendants_recursive(primary_only=True):
            child.set_privacy('public', auth=None, log=False)
        # Accounts for system actions where no `User` performs the final approval
        auth = Auth(user) if user else None
        registered_from.add_log(
            action=NodeLog.REGISTRATION_APPROVAL_APPROVED,
            params={
                'node': registered_from._id,
                'registration': register._id,
                'registration_approval_id': self._id,
            },
            auth=auth,
        )
        for node in register.root.node_and_primary_descendants():
            self._add_success_logs(node, user)
            node.update_search()  # update search if public

        self.save()
예제 #7
0
    def terminate_embargo(self, auth):
        """Handles the actual early termination of an Embargoed registration.
        Adds a log to the registered_from Node.
        """
        if not self.is_embargoed:
            raise NodeStateError('This node is not under active embargo')

        self.registered_from.add_log(
            action=NodeLog.EMBARGO_TERMINATED,
            params={
                'project': self._id,
                'node': self.registered_from._id,
                'registration': self._id,
            },
            auth=None,
            save=True
        )
        self.embargo.mark_as_completed()
        for node in self.node_and_primary_descendants():
            node.set_privacy(
                self.PUBLIC,
                auth=None,
                log=False,
                save=True
            )
        return True
예제 #8
0
    def add_node_link(self, node, auth, save=True):
        """Add a node link to a node.

        :param Node node: Node to add
        :param Auth auth: Consolidated authorization
        :param bool save: Save changes
        :return: Created pointer
        """
        # Fail if node already in nodes / pointers. Note: cast node and node
        # to primary keys to test for conflicts with both nodes and pointers
        # contained in `self.nodes`.
        if NodeRelation.objects.filter(parent=self,
                                       child=node,
                                       is_node_link=True).exists():
            raise ValueError('Link to node {0} already exists'.format(
                node._id))

        if self.is_registration:
            raise NodeStateError('Cannot add a node link to a registration')

        # If a folder, prevent more than one pointer to that folder.
        # This will prevent infinite loops on the project organizer.
        if node.is_collection and node.linked_from.exists():
            raise ValueError(
                'Node link to folder {0} already exists. '
                'Only one node link to any given folder allowed'.format(
                    node._id))
        if node.is_collection and node.is_bookmark_collection:
            raise ValueError(
                'Node link to bookmark collection ({0}) not allowed.'.format(
                    node._id))

        # Append node link
        node_relation, created = NodeRelation.objects.get_or_create(
            parent=self, child=node, is_node_link=True)

        # Add log
        if hasattr(self, 'add_log'):
            self.add_log(
                action=NodeLog.NODE_LINK_CREATED,
                params={
                    'parent_node': self.parent_id,
                    'node': self._id,
                    'pointer': {
                        'id': node._id,
                        'url': node.url,
                        'title': node.title,
                        'category': node.category,
                    },
                },
                auth=auth,
                save=False,
            )

        # Optionally save changes
        if save:
            self.save()

        return node_relation
예제 #9
0
 def delete(self):
     """ Mark collection as deleted
     """
     if self.is_bookmark_collection:
         # Not really the right exception to raise, but it's for back-compatibility
         # TODO: Use a more correct exception and catch it in the necessary places
         raise NodeStateError('Bookmark collections may not be deleted.')
     self.deleted = timezone.now()
     self.save()
예제 #10
0
    def create_for_user(self, user):
        possessive_title = get_quickfiles_project_title(user)

        quickfiles, created = QuickFilesNode.objects.get_or_create(
            title=possessive_title, creator=user)

        if not created:
            raise NodeStateError('Users may only have one quickfiles project')

        quickfiles.add_addon('osfstorage', auth=None, log=False)

        return quickfiles
예제 #11
0
    def create_for_node(self, node, name, content, auth):
        existing_wiki_page = WikiPage.objects.get_for_node(node, name)
        if existing_wiki_page:
            raise NodeStateError('Wiki Page already exists.')

        wiki_page = WikiPage.objects.create(
            node=node,
            page_name=name,
            user=auth.user
        )
        # Creates a WikiVersion object
        wiki_page.update(auth.user, content)
        return wiki_page
예제 #12
0
    def delete(self):
        """ Mark collection as deleted
        """
        if self.is_bookmark_collection:
            # Not really the right exception to raise, but it's for back-compatibility
            # TODO: Use a more correct exception and catch it in the necessary places
            raise NodeStateError('Bookmark collections may not be deleted.')

        self.deleted = timezone.now()

        if self.is_public:
            self.bulk_update_search(list(self.collectedguidmetadata_set.all()), op='delete')

        self.save()
예제 #13
0
    def add_node_link(self, node, auth, save=True):
        """Add a node link to a node.

        :param Node node: Node to add
        :param Auth auth: Consolidated authorization
        :param bool save: Save changes
        :return: Created pointer
        """
        # Fail if node already in nodes / pointers. Note: cast node and node
        # to primary keys to test for conflicts with both nodes and pointers
        # contained in `self.nodes`.
        if NodeRelation.objects.filter(parent=self, child=node, is_node_link=True).exists():
            raise ValueError(
                'Link to node {0} already exists'.format(node._id)
            )

        if self.is_registration:
            raise NodeStateError('Cannot add a node link to a registration')

        # Append node link
        node_relation, created = NodeRelation.objects.get_or_create(
            parent=self,
            child=node,
            is_node_link=True
        )

        # Add log
        if hasattr(self, 'add_log'):
            self.add_log(
                action=NodeLog.NODE_LINK_CREATED,
                params={
                    'parent_node': self.parent_id,
                    'node': self._id,
                    'pointer': {
                        'id': node._id,
                        'url': node.url,
                        'title': node.title,
                        'category': node.category,
                    },
                },
                auth=auth,
                save=False,
            )

        # Optionally save changes
        if save:
            self.save()

        return node_relation
예제 #14
0
    def _on_complete(self, user):
        NodeLog = apps.get_model('osf.NodeLog')

        parent_registration = self._get_registration()
        if parent_registration.is_spammy:
            raise NodeStateError('Cannot complete a spammy registration.')

        super(Embargo, self)._on_complete(user)
        parent_registration.registered_from.add_log(
            action=NodeLog.EMBARGO_APPROVED,
            params={
                'node': parent_registration.registered_from._id,
                'registration': parent_registration._id,
                'embargo_id': self._id,
            },
            auth=Auth(self.initiated_by), )
        self.save()
예제 #15
0
def new_bookmark_collection(user):
    """Create a new bookmark collection project.

    :param User user: User object
    :return Node: Created node

    """
    Collection = apps.get_model('osf.Collection')
    existing_bookmark_collections = Collection.objects.filter(
        is_bookmark_collection=True, creator=user, is_deleted=False).exists()

    if existing_bookmark_collections:
        raise NodeStateError('Users may only have one bookmark collection')

    collection = Collection(title='Bookmarks',
                            creator=user,
                            is_bookmark_collection=True)
    collection.save()
    return collection
예제 #16
0
파일: __init__.py 프로젝트: envobe/osf.io
def new_bookmark_collection(user):
    """Create a new bookmark collection project.

    :param User user: User object
    :return Node: Created node

    """
    Collection = apps.get_model('osf.Collection')
    existing_bookmark_collection = Collection.find(
        Q('is_bookmark_collection', 'eq', True) & Q('creator', 'eq', user)
        & Q('is_deleted', 'eq', False))

    if existing_bookmark_collection.count() > 0:
        raise NodeStateError('Users may only have one bookmark collection')

    collection = Collection(title='Bookmarks',
                            creator=user,
                            is_bookmark_collection=True)
    collection.save()
    return collection
예제 #17
0
    def set_subjects(self, new_subjects, auth, add_log=True):
        """ Helper for setting M2M subjects field from list of hierarchies received from UI.
        Only authorized admins may set subjects.

        :param list[list[Subject._id]] new_subjects: List of subject hierarchies to be validated and flattened
        :param Auth auth: Auth object for requesting user
        :param bool add_log: Whether or not to add a log (if called on a Loggable object)

        :return: None
        """
        if getattr(self, 'is_registration', False):
            raise PermissionsError('Registrations may not be modified.')
        if getattr(self, 'is_collection', False):
            raise NodeStateError('Collections may not have subjects')
        if not self.has_permission(auth.user, ADMIN):
            raise PermissionsError('Only admins can change subjects.')

        old_subjects = list(self.subjects.values_list('id', flat=True))
        self.subjects.clear()
        for subj_list in new_subjects:
            subj_hierarchy = []
            for s in subj_list:
                subj_hierarchy.append(s)
            if subj_hierarchy:
                validate_subject_hierarchy(subj_hierarchy)
                for s_id in subj_hierarchy:
                    self.subjects.add(Subject.load(s_id))

        if add_log and hasattr(self, 'add_log'):
            self.add_log(
                action=NodeLog.SUBJECTS_UPDATED,
                params={
                    'subjects': list(self.subjects.values('_id', 'text')),
                    'old_subjects': list(Subject.objects.filter(id__in=old_subjects).values('_id', 'text'))
                },
                auth=auth,
                save=False,
            )

        self.save(old_subjects=old_subjects)
예제 #18
0
파일: __init__.py 프로젝트: pazthor/osf.io
def new_dashboard(user):
    """Create a new dashboard project.

    :param User user: User object
    :return Node: Created node

    """
    existing_dashboards = user.node__contributed.find(
        Q('category', 'eq', 'project') & Q('is_dashboard', 'eq', True))

    if existing_dashboards.count() > 0:
        raise NodeStateError("Users may only have one dashboard")

    node = Node(title='Dashboard',
                creator=user,
                category='project',
                is_dashboard=True,
                is_folder=True)

    node.save()

    return node
예제 #19
0
 def add_addon(self, name, auth, log=True):
     if name != 'osfstorage':
         raise NodeStateError(
             'A QuickFilesNode can only have the osfstorage addon.')
     return super(QuickFilesNode, self).add_addon(name, auth, log)
예제 #20
0
 def set_privacy(self, permissions, *args, **kwargs):
     raise NodeStateError('You may not set privacy for a QuickFilesNode.')
예제 #21
0
 def update_node_wiki(self, name, content, auth):
     raise NodeStateError('Registered wiki pages cannot be edited.')
예제 #22
0
 def rename_node_wiki(self, name, new_name, auth):
     raise NodeStateError('Registered wiki pages cannot be renamed.')
예제 #23
0
 def delete_node_wiki(self, name_or_page, auth):
     raise NodeStateError('Registered wiki pages cannot be deleted.')
예제 #24
0
 def remove_tags(self, tags, auth, save=True):
     if self.retraction is None:
         super(Registration, self).remove_tags(tags, auth, save)
     else:
         raise NodeStateError(
             'Cannot remove tags of withdrawn registrations.')
예제 #25
0
 def add_tags(self, tags, auth=None, save=True, log=True, system=False):
     if self.retraction is None:
         super(Registration, self).add_tags(tags, auth, save, log, system)
     else:
         raise NodeStateError('Cannot add tags to withdrawn registrations.')
예제 #26
0
 def remove_node(self, auth, date=None):
     raise NodeStateError('A QuickFilesNode may not be deleted.')
예제 #27
0
 def clone(self):
     raise NodeStateError(
         'A QuickFilesNode may not be forked, used as a template, or registered.'
     )
예제 #28
0
 def add_contributor(self, contributor, *args, **kwargs):
     raise NodeStateError(
         'A QuickFilesNode may not have additional contributors.')