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
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
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()
def _on_complete(self, event_data): user = event_data.kwargs.get('user') if user is None and event_data.args: user = event_data.args[0] NodeLog = apps.get_model('osf.NodeLog') registration = self._get_registration() if registration.is_spammy: raise NodeStateError('Cannot approve a spammy registration') super()._on_complete(event_data) self.save() registered_from = registration.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) registration.set_privacy('public', auth=None, log=False) for child in registration.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': registration._id, 'registration_approval_id': self._id, }, auth=auth, ) for node in registration.root.node_and_primary_descendants(): self._add_success_logs(node, user) node.update_search() # update search if public self.save()
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.')
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
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
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
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.collectionsubmission_set.all()), op='delete') self.save()
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()
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, deleted__isnull=True).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
def register(self, auth, save=False, child_ids=None): node = self.branched_from if not self.title: raise NodeStateError( 'Draft Registration must have title to be registered') # Create the registration register = node.register_node(schema=self.registration_schema, auth=auth, draft_registration=self, child_ids=child_ids, provider=self.provider) self.registered_node = register self.add_status_log(auth.user, DraftRegistrationLog.REGISTERED) self.copy_contributors_from(node) if save: self.save() return register
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.')
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.')
def clone(self): raise NodeStateError( 'A DraftNode may not be forked, used as a template, or registered.' )
def set_privacy(self, permissions, *args, **kwargs): raise NodeStateError('You may not set privacy for a DraftNode.')
def add_contributor(self, contributor, *args, **kwargs): if contributor == self.creator: return super(QuickFilesNode, self).add_contributor(contributor, *args, **kwargs) raise NodeStateError( 'A QuickFilesNode may not have additional contributors.')
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)
def add_contributor(self, contributor, *args, **kwargs): raise NodeStateError( 'A QuickFilesNode may not have additional contributors.')