Makes it even easier to add new fields in the future

This commit is contained in:
Trenton H 2024-06-07 09:01:03 -07:00
parent 2903f7f102
commit c74e2c6622
3 changed files with 42 additions and 13 deletions

View File

@ -549,13 +549,19 @@ class Command(CryptMixin, BaseCommand):
""" """
Encrypts certain fields in the export. Currently limited to the mail account password Encrypts certain fields in the export. Currently limited to the mail account password
""" """
if self.passphrase: if self.passphrase:
self.setup_crypto(passphrase=self.passphrase) self.setup_crypto(passphrase=self.passphrase)
for mail_account_record in manifest["mail_accounts"]: for crypt_config in self.CRYPT_FIELDS:
mail_account_record["fields"]["password"] = self.encrypt_string( exporter_key = crypt_config["exporter_key"]
value=mail_account_record["fields"]["password"], crypt_fields = crypt_config["fields"]
) for manifest_record in manifest[exporter_key]:
for field in crypt_fields:
manifest_record["fields"][field] = self.encrypt_string(
value=manifest_record["fields"][field],
)
elif MailAccount.objects.count() > 0: elif MailAccount.objects.count() > 0:
self.stdout.write( self.stdout.write(
self.style.NOTICE( self.style.NOTICE(

View File

@ -404,16 +404,22 @@ class Command(CryptMixin, BaseCommand):
# Salt has been loaded from metadata.json at this point, so it cannot be None # Salt has been loaded from metadata.json at this point, so it cannot be None
self.setup_crypto(passphrase=self.passphrase, salt=self.salt) self.setup_crypto(passphrase=self.passphrase, salt=self.salt)
had_an_account = False had_at_least_one_record = False
for index, record in enumerate(self.manifest): for crypt_config in self.CRYPT_FIELDS:
if record["model"] == "paperless_mail.mailaccount": importer_model = crypt_config["model_name"]
record["fields"]["password"] = self.decrypt_string( crypt_fields = crypt_config["fields"]
value=record["fields"]["password"], for record in filter(
) lambda x: x["model"] == importer_model,
self.manifest[index] = record self.manifest,
had_an_account = True ):
if had_an_account: had_at_least_one_record = True
for field in crypt_fields:
record["fields"][field] = self.decrypt_string(
value=record["fields"][field],
)
if had_at_least_one_record:
# It's annoying, but the DB is loaded from the JSON directly # It's annoying, but the DB is loaded from the JSON directly
# Maybe could change that in the future? # Maybe could change that in the future?
(self.source / "manifest.json").write_text( (self.source / "manifest.json").write_text(

View File

@ -2,6 +2,7 @@ import base64
import os import os
from argparse import ArgumentParser from argparse import ArgumentParser
from typing import Optional from typing import Optional
from typing import TypedDict
from typing import Union from typing import Union
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
@ -16,6 +17,12 @@ from documents.settings import EXPORTER_CRYPTO_SALT_NAME
from documents.settings import EXPORTER_CRYPTO_SETTINGS_NAME from documents.settings import EXPORTER_CRYPTO_SETTINGS_NAME
class CryptFields(TypedDict):
exporter_key: str
model_name: str
fields: list[str]
class MultiProcessMixin: class MultiProcessMixin:
""" """
Small class to handle adding an argument and validating it Small class to handle adding an argument and validating it
@ -86,6 +93,16 @@ class CryptMixin:
key_size = 32 key_size = 32
kdf_algorithm = "pbkdf2_sha256" kdf_algorithm = "pbkdf2_sha256"
CRYPT_FIELDS: CryptFields = [
{
"exporter_key": "mail_accounts",
"model_name": "paperless_mail.mailaccount",
"fields": [
"password",
],
},
]
def get_crypt_params(self) -> dict[str, dict[str, Union[str, int]]]: def get_crypt_params(self) -> dict[str, dict[str, Union[str, int]]]:
return { return {
EXPORTER_CRYPTO_SETTINGS_NAME: { EXPORTER_CRYPTO_SETTINGS_NAME: {