示例#1
0
    def move_from_storage_service(self, src_path, dst_path, package=None):
        """Move AIP in SS at path ``src_path`` to GPG space at ``dst_path``,
        encrypt it using the GPG Space's designated GPG ``key``, and update
        the AIP's pointer file accordingly.
        Note: we do *not* add the .gpg suffix to ``Package.current_path`` for
        the reason given in ``move_to_storage_service``.
        """
        LOGGER.info("in move_from_storage_service of GPG")
        LOGGER.info("GPG move_from, src_path: %s", src_path)
        LOGGER.info("GPG move_from, dst_path: %s", dst_path)
        if not package:
            raise GPGException(_("GPG spaces can only contain packages"))
        # Every time this method is called, the package is encrypted with the
        # current GPG key of this space, which may differ from the key used to
        # encrypt the package the last time around.
        key_fingerprint = self.key
        self.space.create_local_directory(dst_path)
        self.space.move_rsync(src_path, dst_path, try_mv_local=True)
        try:
            __, encr_result = _gpg_encrypt(dst_path, key_fingerprint)
        except GPGException:
            # If we fail to encrypt, then we send it back to where it came from.
            self.space.move_rsync(dst_path, src_path, try_mv_local=True)
            raise
        # Update the GPG key fingerprint in db, if necessary.
        if package.encryption_key_fingerprint != key_fingerprint:
            package.encryption_key_fingerprint = key_fingerprint
            package.save()
        # If the package should have a pointer file, return an object
        # documenting the effects of storing the package, such that this
        # ``StorageEffects`` object can be used to update the pointer file
        # accordingly. Note: we cannot update the pointer file here because it
        # may not yet exist.
        # QUESTION: doesn't encryption change the size of the package? If so,
        # shouldn't this have consequences for the pointer file?
        # QUESTION: does encryption change the format?
        if package.should_have_pointer_file():

            def composition_level_updater(existing_composition_level):
                if existing_composition_level:
                    return str(int(existing_composition_level) + 1)
                return "1"

            inhibitors = (
                "inhibitors",
                ("inhibitor_type", "GPG"),
                ("inhibitor_target", "All content"),
            )
            encryption_event = premis.create_encryption_event(
                encr_result, key_fingerprint, _get_gpg_version())
            return utils.StorageEffects(
                events=[encryption_event],
                composition_level_updater=composition_level_updater,
                inhibitors=[inhibitors],
            )
示例#2
0
    def move_from_storage_service(self, src_path, dst_path, package=None):
        """Move AIP in SS at path ``src_path`` to GPG space at ``dst_path``,
        encrypt it using the GPG Space's designated GPG ``key``, and update
        the AIP's pointer file accordingly.
        Note: we do *not* add the .gpg suffix to ``Package.current_path`` for
        the reason given in ``move_to_storage_service``.
        """
        LOGGER.info('in move_from_storage_service of GPG')
        LOGGER.info('GPG move_from, src_path: %s', src_path)
        LOGGER.info('GPG move_from, dst_path: %s', dst_path)
        if not package:
            raise GPGException(_('GPG spaces can only contain packages'))

        # NOTE: EXPERIMENTAL: every time this method is called, the package is
        # encrypted with the current GPG key of this space. This means that
        # many actions may cause the re-encryption of an AIP with a new key (if
        # the AIP's previous key differs from the space's current key) because
        # many method calls call this method.
        # PREVIOUS BEHAVIOUR: Keep using the package's current GPG key, if it
        # exists. Otherwise, use this GPG space's key.
        # key_fingerprint = package.encryption_key_fingerprint
        # if not key_fingerprint:
        #     key_fingerprint = self.key
        key_fingerprint = self.key

        self.space.create_local_directory(dst_path)
        self.space.move_rsync(src_path, dst_path, try_mv_local=True)
        try:
            __, encr_result = _gpg_encrypt(dst_path, key_fingerprint)
        except GPGException:
            # If we fail to encrypt, then we send it back to where it came from.
            # TODO/QUESTION: Is this behaviour desirable?
            self.space.move_rsync(dst_path, src_path, try_mv_local=True)
            raise
        # Update the GPG key fingerprint in db, if necessary.
        if package.encryption_key_fingerprint != key_fingerprint:
            package.encryption_key_fingerprint = key_fingerprint
            package.save()
        # If the package should have a pointer file, return an object
        # documenting the effects of storing the package, such that this
        # ``StorageEffects`` object can be used to update the pointer file
        # accordingly. Note: we cannot update the pointer file here because it
        # may not yet exist.
        # QUESTION: doesn't encryption change the size of the package? If so,
        # shouldn't this have consequences for the pointer file?
        # QUESTION: does encryption change the format?
        if package.should_have_pointer_file():

            def composition_level_updater(existing_composition_level):
                if existing_composition_level:
                    return str(int(existing_composition_level) + 1)
                return '1'

            inhibitors = ('inhibitors', ('inhibitor_type', 'GPG'),
                          ('inhibitor_target', 'All content'))
            encryption_event = create_encryption_event(encr_result,
                                                       key_fingerprint)
            return utils.StorageEffects(
                events=[encryption_event],
                composition_level_updater=composition_level_updater,
                inhibitors=[inhibitors])