mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Merge branch 'dev' into feature-ocrmypdf
This commit is contained in:
		| @@ -353,39 +353,23 @@ Documents can be stored in Paperless using GnuPG encryption. | |||||||
|     Consider running paperless on an encrypted filesystem instead, which will then |     Consider running paperless on an encrypted filesystem instead, which will then | ||||||
|     at least provide security against physical hardware theft. |     at least provide security against physical hardware theft. | ||||||
|  |  | ||||||
| .. code:: |  | ||||||
|  |  | ||||||
|     change_storage_type [--passphrase PASSPHRASE] {gpg,unencrypted} {gpg,unencrypted} |  | ||||||
|  |  | ||||||
|     positional arguments: |  | ||||||
|       {gpg,unencrypted}     The state you want to change your documents from |  | ||||||
|       {gpg,unencrypted}     The state you want to change your documents to |  | ||||||
|  |  | ||||||
|     optional arguments: |  | ||||||
|       --passphrase PASSPHRASE |  | ||||||
|  |  | ||||||
| Enabling encryption | Enabling encryption | ||||||
| ------------------- | ------------------- | ||||||
|  |  | ||||||
| Basic usage to enable encryption of your document store (**USE A MORE SECURE PASSPHRASE**): | Enabling encryption is no longer supported. | ||||||
|  |  | ||||||
| (Note: If ``PAPERLESS_PASSPHRASE`` isn't set already, you need to specify it here) |  | ||||||
|  |  | ||||||
| .. code:: |  | ||||||
|  |  | ||||||
|     change_storage_type [--passphrase SECR3TP4SSPHRA$E] unencrypted gpg |  | ||||||
|  |  | ||||||
|  |  | ||||||
| Disabling encryption | Disabling encryption | ||||||
| -------------------- | -------------------- | ||||||
|  |  | ||||||
| Basic usage to enable encryption of your document store: | Basic usage to disable encryption of your document store: | ||||||
|  |  | ||||||
| (Note: Again, if ``PAPERLESS_PASSPHRASE`` isn't set already, you need to specify it here) | (Note: If ``PAPERLESS_PASSPHRASE`` isn't set already, you need to specify it here) | ||||||
|  |  | ||||||
| .. code:: | .. code:: | ||||||
|  |  | ||||||
|     change_storage_type [--passphrase SECR3TP4SSPHRA$E] gpg unencrypted |     decrypt_documents [--passphrase SECR3TP4SSPHRA$E] | ||||||
|  |  | ||||||
|  |  | ||||||
| .. _Pipenv: https://pipenv.pypa.io/en/latest/ | .. _Pipenv: https://pipenv.pypa.io/en/latest/ | ||||||
| @@ -12,7 +12,8 @@ next | |||||||
|     You have to specify your username. |     You have to specify your username. | ||||||
| *   Added a simple sanity checker that checks your documents for missing or orphaned files, | *   Added a simple sanity checker that checks your documents for missing or orphaned files, | ||||||
|     files with wrong checksums, inaccessible files, and documents with empty content. |     files with wrong checksums, inaccessible files, and documents with empty content. | ||||||
|  | *   It is no longer possible to encrypt your documents. For the time being, paperless will | ||||||
|  |     continue to operate with already encrypted documents. | ||||||
|  |  | ||||||
| paperless-ng 0.9.2 | paperless-ng 0.9.2 | ||||||
| ################## | ################## | ||||||
|   | |||||||
| @@ -225,10 +225,7 @@ class Consumer(LoggingMixin): | |||||||
|         created = file_info.created or date or timezone.make_aware( |         created = file_info.created or date or timezone.make_aware( | ||||||
|             datetime.datetime.fromtimestamp(stats.st_mtime)) |             datetime.datetime.fromtimestamp(stats.st_mtime)) | ||||||
|  |  | ||||||
|         if settings.PASSPHRASE: |         storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||||
|             storage_type = Document.STORAGE_TYPE_GPG |  | ||||||
|         else: |  | ||||||
|             storage_type = Document.STORAGE_TYPE_UNENCRYPTED |  | ||||||
|  |  | ||||||
|         with open(self.path, "rb") as f: |         with open(self.path, "rb") as f: | ||||||
|             document = Document.objects.create( |             document = Document.objects.create( | ||||||
| @@ -277,8 +274,4 @@ class Consumer(LoggingMixin): | |||||||
|     def _write(self, storage_type, source, target): |     def _write(self, storage_type, source, target): | ||||||
|         with open(source, "rb") as read_file: |         with open(source, "rb") as read_file: | ||||||
|             with open(target, "wb") as write_file: |             with open(target, "wb") as write_file: | ||||||
|                 if storage_type == Document.STORAGE_TYPE_UNENCRYPTED: |                 write_file.write(read_file.read()) | ||||||
|                     write_file.write(read_file.read()) |  | ||||||
|                     return |  | ||||||
|                 self.log("debug", "Encrypting") |  | ||||||
|                 write_file.write(GnuPG.encrypted(read_file)) |  | ||||||
|   | |||||||
| @@ -17,16 +17,6 @@ class Command(BaseCommand): | |||||||
| 
 | 
 | ||||||
|     def add_arguments(self, parser): |     def add_arguments(self, parser): | ||||||
| 
 | 
 | ||||||
|         parser.add_argument( |  | ||||||
|             "from", |  | ||||||
|             choices=("gpg", "unencrypted"), |  | ||||||
|             help="The state you want to change your documents from" |  | ||||||
|         ) |  | ||||||
|         parser.add_argument( |  | ||||||
|             "to", |  | ||||||
|             choices=("gpg", "unencrypted"), |  | ||||||
|             help="The state you want to change your documents to" |  | ||||||
|         ) |  | ||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             "--passphrase", |             "--passphrase", | ||||||
|             help="If PAPERLESS_PASSPHRASE isn't set already, you need to " |             help="If PAPERLESS_PASSPHRASE isn't set already, you need to " | ||||||
| @@ -50,11 +40,6 @@ class Command(BaseCommand): | |||||||
|         except KeyboardInterrupt: |         except KeyboardInterrupt: | ||||||
|             return |             return | ||||||
| 
 | 
 | ||||||
|         if options["from"] == options["to"]: |  | ||||||
|             raise CommandError( |  | ||||||
|                 'The "from" and "to" values can\'t be the same.' |  | ||||||
|             ) |  | ||||||
| 
 |  | ||||||
|         passphrase = options["passphrase"] or settings.PASSPHRASE |         passphrase = options["passphrase"] or settings.PASSPHRASE | ||||||
|         if not passphrase: |         if not passphrase: | ||||||
|             raise CommandError( |             raise CommandError( | ||||||
| @@ -62,10 +47,7 @@ class Command(BaseCommand): | |||||||
|                 "by declaring it in your environment or your config." |                 "by declaring it in your environment or your config." | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|         if options["from"] == "gpg" and options["to"] == "unencrypted": |         self.__gpg_to_unencrypted(passphrase) | ||||||
|             self.__gpg_to_unencrypted(passphrase) |  | ||||||
|         elif options["from"] == "unencrypted" and options["to"] == "gpg": |  | ||||||
|             self.__unencrypted_to_gpg(passphrase) |  | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def __gpg_to_unencrypted(passphrase): |     def __gpg_to_unencrypted(passphrase): | ||||||
| @@ -79,42 +61,28 @@ class Command(BaseCommand): | |||||||
|                 document).encode('utf-8'), "green")) |                 document).encode('utf-8'), "green")) | ||||||
| 
 | 
 | ||||||
|             old_paths = [document.source_path, document.thumbnail_path] |             old_paths = [document.source_path, document.thumbnail_path] | ||||||
|  | 
 | ||||||
|             raw_document = GnuPG.decrypted(document.source_file, passphrase) |             raw_document = GnuPG.decrypted(document.source_file, passphrase) | ||||||
|             raw_thumb = GnuPG.decrypted(document.thumbnail_file, passphrase) |             raw_thumb = GnuPG.decrypted(document.thumbnail_file, passphrase) | ||||||
| 
 | 
 | ||||||
|             document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED |             document.storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||||
| 
 | 
 | ||||||
|  |             ext = os.path.splitext(document.filename)[1] | ||||||
|  | 
 | ||||||
|  |             if not ext == '.gpg': | ||||||
|  |                 raise CommandError( | ||||||
|  |                     f"Abort: encrypted file {document.source_path} does not " | ||||||
|  |                     f"end with .gpg") | ||||||
|  | 
 | ||||||
|  |             document.filename = os.path.splitext(document.source_path)[0] | ||||||
|  | 
 | ||||||
|             with open(document.source_path, "wb") as f: |             with open(document.source_path, "wb") as f: | ||||||
|                 f.write(raw_document) |                 f.write(raw_document) | ||||||
| 
 | 
 | ||||||
|             with open(document.thumbnail_path, "wb") as f: |             with open(document.thumbnail_path, "wb") as f: | ||||||
|                 f.write(raw_thumb) |                 f.write(raw_thumb) | ||||||
| 
 | 
 | ||||||
|             document.save(update_fields=("storage_type",)) |             document.save(update_fields=("storage_type", "filename")) | ||||||
| 
 |  | ||||||
|             for path in old_paths: |  | ||||||
|                 os.unlink(path) |  | ||||||
| 
 |  | ||||||
|     @staticmethod |  | ||||||
|     def __unencrypted_to_gpg(passphrase): |  | ||||||
| 
 |  | ||||||
|         unencrypted_files = Document.objects.filter( |  | ||||||
|             storage_type=Document.STORAGE_TYPE_UNENCRYPTED) |  | ||||||
| 
 |  | ||||||
|         for document in unencrypted_files: |  | ||||||
| 
 |  | ||||||
|             print(coloured("Encrypting {}".format(document), "green")) |  | ||||||
| 
 |  | ||||||
|             old_paths = [document.source_path, document.thumbnail_path] |  | ||||||
|             with open(document.source_path, "rb") as raw_document: |  | ||||||
|                 with open(document.thumbnail_path, "rb") as raw_thumb: |  | ||||||
|                     document.storage_type = Document.STORAGE_TYPE_GPG |  | ||||||
|                     with open(document.source_path, "wb") as f: |  | ||||||
|                         f.write(GnuPG.encrypted(raw_document, passphrase)) |  | ||||||
|                     with open(document.thumbnail_path, "wb") as f: |  | ||||||
|                         f.write(GnuPG.encrypted(raw_thumb, passphrase)) |  | ||||||
| 
 |  | ||||||
|             document.save(update_fields=("storage_type",)) |  | ||||||
| 
 | 
 | ||||||
|             for path in old_paths: |             for path in old_paths: | ||||||
|                 os.unlink(path) |                 os.unlink(path) | ||||||
| @@ -82,8 +82,6 @@ class Command(Renderable, BaseCommand): | |||||||
|     def _import_files_from_manifest(self): |     def _import_files_from_manifest(self): | ||||||
|  |  | ||||||
|         storage_type = Document.STORAGE_TYPE_UNENCRYPTED |         storage_type = Document.STORAGE_TYPE_UNENCRYPTED | ||||||
|         if settings.PASSPHRASE: |  | ||||||
|             storage_type = Document.STORAGE_TYPE_GPG |  | ||||||
|  |  | ||||||
|         for record in self.manifest: |         for record in self.manifest: | ||||||
|  |  | ||||||
| @@ -105,23 +103,8 @@ class Command(Renderable, BaseCommand): | |||||||
|  |  | ||||||
|             create_source_path_directory(document.source_path) |             create_source_path_directory(document.source_path) | ||||||
|  |  | ||||||
|             if settings.PASSPHRASE: |             print(f"Moving {document_path} to {document.source_path}") | ||||||
|  |             shutil.copy(document_path, document.source_path) | ||||||
|                 with open(document_path, "rb") as unencrypted: |             shutil.copy(thumbnail_path, document.thumbnail_path) | ||||||
|                     with open(document.source_path, "wb") as encrypted: |  | ||||||
|                         print("Encrypting {} and saving it to {}".format( |  | ||||||
|                             doc_file, document.source_path)) |  | ||||||
|                         encrypted.write(GnuPG.encrypted(unencrypted)) |  | ||||||
|  |  | ||||||
|                 with open(thumbnail_path, "rb") as unencrypted: |  | ||||||
|                     with open(document.thumbnail_path, "wb") as encrypted: |  | ||||||
|                         print("Encrypting {} and saving it to {}".format( |  | ||||||
|                             thumb_file, document.thumbnail_path)) |  | ||||||
|                         encrypted.write(GnuPG.encrypted(unencrypted)) |  | ||||||
|  |  | ||||||
|             else: |  | ||||||
|                 print(f"Moving {document_path} to {document.source_path}") |  | ||||||
|                 shutil.copy(document_path, document.source_path) |  | ||||||
|                 shutil.copy(thumbnail_path, document.thumbnail_path) |  | ||||||
|  |  | ||||||
|             document.save() |             document.save() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler