def lift_embargo(self, identity, _id, uow=None): """Lifts embargo from the record and draft (if exists). It's an error if you try to lift an embargo that has not yet expired. Use this method in combination with scan_expired_embargos(). """ # Get the record record = self.record_cls.pid.resolve(_id) # Check permissions self.require_permission(identity, "lift_embargo", record=record) # Modify draft embargo if draft exists and it's the same as the record. draft = None if record.has_draft: draft = self.draft_cls.pid.resolve(_id, registered_only=False) if record.access == draft.access: if not draft.access.lift_embargo(): raise EmbargoNotLiftedError(_id) uow.register(RecordCommitOp(draft, indexer=self.indexer)) if not record.access.lift_embargo(): raise EmbargoNotLiftedError(_id) uow.register(RecordCommitOp(record, indexer=self.indexer))
def delete( self, identity, id_, link_id, links_config=None, uow=None ): """Delete a secret link for a record (resp. its parent).""" record, parent = self.get_parent_and_record_or_draft(id_) # Permissions self.require_permission(identity, "manage", record=record) # Fetching link_ids = [link.link_id for link in parent.access.links] if str(link_id) not in link_ids: raise LookupError(str(link_id)) link_idx = link_ids.index(link_id) link = parent.access.links[link_idx].resolve() # Deletion parent.access.links.pop(link_idx) link.revoke() # Commit uow.register(RecordCommitOp(parent)) if record: uow.register(RecordCommitOp(record)) # Index all child records of the parent self._index_related_records(record, parent, uow=uow) return True
def update( self, identity, id_, link_id, data, links_config=None, uow=None, ): """Update a secret link for a record (resp. its parent).""" record, parent = self.get_parent_and_record_or_draft(id_) # Permissions self.require_permission(identity, "manage", record=record) # Fetching (required for parts of the validation) link_ids = [link.link_id for link in parent.access.links] if str(link_id) not in link_ids: raise LookupError(str(link_id)) link_idx = link_ids.index(link_id) link = parent.access.links[link_idx].resolve() # Validation data, __ = self.schema_secret_link.load( data, context=dict(identity=identity), raise_errors=True ) permission = data.get("permission") expires_at = self._validate_secret_link_expires_at( data.get("expires_at"), is_specified=("expires_at" in data), secret_link=link, ) # Update # we can't update the link's extra data, as that is encoded # in the token and would thus require a new token link.expires_at = expires_at or link.expires_at link.permission_level = permission or link.permission_level # Commit uow.register(RecordCommitOp(parent)) if record: uow.register(RecordCommitOp(record)) # Index all child records of the parent self._index_related_records(record, parent, uow=uow) return self.link_result_item( self, identity, link, links_config=links_config, )
def create( self, identity, id_, data, links_config=None, uow=None ): """Create a secret link for a record (resp. its parent).""" record, parent = self.get_parent_and_record_or_draft(id_) # Permissions self.require_permission(identity, "manage", record=record) # Validation data, __ = self.schema_secret_link.load( data, context=dict(identity=identity), raise_errors=True ) expires_at = self._validate_secret_link_expires_at( data.get("expires_at") ) if "permission" not in data: raise ValidationError( _("An access permission level is required"), field_name="permission", ) # Creation try: link = parent.access.links.create( permission_level=data["permission"], expires_at=expires_at, extra_data=data.get("extra_data", {}), ) except InvalidPermissionLevelError: raise ValidationError( _("Invalid access permission level."), field_name="permission", ) # Commit uow.register(RecordCommitOp(parent)) if record: uow.register(RecordCommitOp(record)) # Index all child records of the parent self._index_related_records(record, parent, uow=uow) return self.link_result_item( self, identity, link, links_config=links_config, )
def delete(self, identity, id_, revision_id=None, uow=None): """Delete a review.""" draft = self.draft_cls.pid.resolve(id_, registered_only=False) self.require_permission(identity, 'update_draft', record=draft) # Preconditions if draft.parent.review is None: raise ReviewNotFoundError() if draft.is_published: raise ReviewStateError( _("You cannot delete a review for a draft that has already " "been published.") ) if draft.parent.review.is_open: raise ReviewStateError(_("An open review cannot be deleted.")) # Keep the request when not open or not closed so that the user can see # the request's events. The request is deleted only when in `draft` # status if not (draft.parent.review.is_closed or draft.parent.review.is_open): current_requests_service.delete( identity, draft.parent.review.id, uow=uow ) # Unset on record draft.parent.review = None uow.register(RecordCommitOp(draft.parent)) uow.register(RecordIndexOp(draft, indexer=self.indexer)) return True
def execute(self, identity, uow): """Accept record into community.""" # Resolve the topic and community - the request type only allow for # community receivers and record topics. draft = self.request.topic.resolve() community = self.request.receiver.resolve() service._validate_draft(identity, draft) # Unset review from record (still accessible from request) # The curator (receiver) should still have access, via the community # The creator (uploader) should also still have access, because # they're the uploader draft.parent.review = None # TODO: # - Put below into a service method # - Check permissions # Add community to record. is_default = self.request.type.set_as_default draft.parent.communities.add(community, request=self.request, default=is_default) uow.register(RecordCommitOp(draft.parent)) # Publish the record # TODO: Ensure that the accpeting user has permissions to publish. service.publish(identity, draft.pid.pid_value, uow=uow) super().execute(identity, uow)
def create(self, identity, data, record, uow=None): """Create a new review request in draft state (to be completed.""" if record.parent.review is not None: raise ReviewExistsError( _('A review already exists for this record')) # Validate that record has not been published. if record.is_published or record.versions.index > 1: raise ReviewStateError( _("You cannot create a review for an already published " "record.")) # Validate the review type (only review requests are valid) type_ = current_request_type_registry.lookup(data.pop('type', None), quiet=True) if type_ is None or type_.type_id not in self.supported_types: raise ValidationError(_('Invalid review type.'), field_name='type') # Resolve receiver receiver = ResolverRegistry.resolve_entity_proxy( data.pop('receiver', None)).resolve() # Delegate to requests service to create the request request_item = current_requests_service.create( identity, data, type_, receiver, topic=record, uow=uow, ) # Set the request on the record and commit the record record.parent.review = request_item._request uow.register(RecordCommitOp(record.parent)) return request_item
def execute(self, identity, uow): """Execute action.""" # Remove draft from request # Same reasoning as in 'decline' draft = self.request.topic.resolve() draft.parent.review = None uow.register(RecordCommitOp(draft.parent)) super().execute(identity, uow)
def execute(self, identity, uow): """Execute action.""" # Same reasoning as in 'decline' draft = self.request.topic.resolve() # TODO: What more to do? simply close the request? Similarly to # decline, how does a user resubmits the request to the same community. super().execute(identity, uow) # TODO: this shouldn't be required BUT because of the caching mechanism # in the review systemfield, the review should be set with the updated # request object draft.parent.review = self.request uow.register(RecordCommitOp(draft.parent))
def execute(self, identity, uow): """Execute action.""" # Keeps the record and the review connected so the user can see the # outcome of the request # The receiver (curator) won't have access anymore to the draft # The creator (uploader) should still have access to the record/draft draft = self.request.topic.resolve() super().execute(identity, uow) # TODO: this shouldn't be required BUT because of the caching mechanism # in the review systemfield, the review should be set with the updated # request object draft.parent.review = self.request uow.register(RecordCommitOp(draft.parent))
def create(self, identity, id_, scheme, provider=None, uow=None): """Create a `NEW` PID for a given record.""" draft = self.draft_cls.pid.resolve(id_, registered_only=False) self.require_permission(identity, "pid_create", record=draft) draft.pids[scheme] = self._manager.create(draft, scheme, provider_name=provider) uow.register(RecordCommitOp(draft, indexer=self.indexer)) return self.result_item( self, identity, draft, links_tpl=self.links_item_tpl, )
def submit(self, identity, id_, data=None, revision_id=None, uow=None): """Submit record for review.""" # Get record and check permission draft = self.draft_cls.pid.resolve(id_, registered_only=False) self.require_permission(identity, 'update_draft', record=draft) # Preconditions if draft.parent.review is None: raise ReviewNotFoundError() # All other preconditions can be checked by the action itself which can # raise appropriate exceptions. request_item = current_requests_service.execute_action( identity, draft.parent.review.id, 'submit', data=data, uow=uow) # TODO: this shouldn't be required BUT because of the caching mechanism # in the review systemfield, the review should be set with the updated # request object draft.parent.review = request_item._request uow.register(RecordCommitOp(draft.parent)) return request_item
def discard(self, identity, id_, scheme, provider=None, uow=None): """Discard a PID for a given draft. If the status was `NEW` it will be hard deleted. Otherwise, it will be soft deleted (`RESERVED`/`REGISTERED`). """ draft = self.draft_cls.pid.resolve(id_, registered_only=False) self.require_permission(identity, "pid_discard", record=draft, scheme=scheme) self.pid_manager.validate(draft.pids, draft, raise_errors=True) identifier = draft.pids.get(scheme, {}).get("identifier") self._manager.discard(scheme, identifier, provider) draft.pids.pop(scheme) uow.register(RecordCommitOp(draft, indexer=self.indexer)) return self.result_item( self, identity, draft, links_tpl=self.links_item_tpl, )