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], )
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])