mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Fix: correct serializing of auth tokens for export (#8100)
This commit is contained in:
		@@ -19,6 +19,8 @@ Options available to any installation of paperless:
 | 
			
		||||
    export. Therefore, incremental backups with `rsync` are entirely
 | 
			
		||||
    possible.
 | 
			
		||||
 | 
			
		||||
    The exporter does not include API tokens and they will need to be re-generated after importing.
 | 
			
		||||
 | 
			
		||||
!!! caution
 | 
			
		||||
 | 
			
		||||
    You cannot import the export generated with one version of paperless in
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ from django.utils import timezone
 | 
			
		||||
from filelock import FileLock
 | 
			
		||||
from guardian.models import GroupObjectPermission
 | 
			
		||||
from guardian.models import UserObjectPermission
 | 
			
		||||
from rest_framework.authtoken.models import Token
 | 
			
		||||
 | 
			
		||||
if TYPE_CHECKING:
 | 
			
		||||
    from django.db.models import QuerySet
 | 
			
		||||
@@ -271,7 +270,6 @@ class Command(CryptMixin, BaseCommand):
 | 
			
		||||
            "social_accounts": SocialAccount.objects.all(),
 | 
			
		||||
            "social_apps": SocialApp.objects.all(),
 | 
			
		||||
            "social_tokens": SocialToken.objects.all(),
 | 
			
		||||
            "auth_tokens": Token.objects.all(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if settings.AUDIT_LOG_ENABLED:
 | 
			
		||||
@@ -570,11 +568,7 @@ class Command(CryptMixin, BaseCommand):
 | 
			
		||||
                                value=manifest_record["fields"][field],
 | 
			
		||||
                            )
 | 
			
		||||
 | 
			
		||||
        elif (
 | 
			
		||||
            MailAccount.objects.count() > 0
 | 
			
		||||
            or SocialToken.objects.count() > 0
 | 
			
		||||
            or Token.objects.count() > 0
 | 
			
		||||
        ):
 | 
			
		||||
        elif MailAccount.objects.count() > 0 or SocialToken.objects.count() > 0:
 | 
			
		||||
            self.stdout.write(
 | 
			
		||||
                self.style.NOTICE(
 | 
			
		||||
                    "No passphrase was given, sensitive fields will be in plaintext",
 | 
			
		||||
 
 | 
			
		||||
@@ -108,13 +108,6 @@ class CryptMixin:
 | 
			
		||||
                "token_secret",
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "exporter_key": "auth_tokens",
 | 
			
		||||
            "model_name": "authtoken.token",
 | 
			
		||||
            "fields": [
 | 
			
		||||
                "key",
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def get_crypt_params(self) -> dict[str, dict[str, str | int]]:
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,9 @@ from pathlib import Path
 | 
			
		||||
from unittest import mock
 | 
			
		||||
from zipfile import ZipFile
 | 
			
		||||
 | 
			
		||||
from allauth.socialaccount.models import SocialAccount
 | 
			
		||||
from allauth.socialaccount.models import SocialApp
 | 
			
		||||
from allauth.socialaccount.models import SocialToken
 | 
			
		||||
from django.contrib.auth.models import Group
 | 
			
		||||
from django.contrib.auth.models import Permission
 | 
			
		||||
from django.contrib.contenttypes.models import ContentType
 | 
			
		||||
@@ -874,6 +877,23 @@ class TestCryptExportImport(
 | 
			
		||||
            password="mypassword",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        app = SocialApp.objects.create(
 | 
			
		||||
            provider="test",
 | 
			
		||||
            name="test",
 | 
			
		||||
            client_id="test",
 | 
			
		||||
        )
 | 
			
		||||
        account = SocialAccount.objects.create(
 | 
			
		||||
            user=User.objects.first(),
 | 
			
		||||
            provider="test",
 | 
			
		||||
            uid="test",
 | 
			
		||||
        )
 | 
			
		||||
        SocialToken.objects.create(
 | 
			
		||||
            app=app,
 | 
			
		||||
            account=account,
 | 
			
		||||
            token="test",
 | 
			
		||||
            token_secret="test",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        call_command(
 | 
			
		||||
            "document_exporter",
 | 
			
		||||
            "--no-progress-bar",
 | 
			
		||||
@@ -912,6 +932,9 @@ class TestCryptExportImport(
 | 
			
		||||
        self.assertIsNotNone(account)
 | 
			
		||||
        self.assertEqual(account.password, "mypassword")
 | 
			
		||||
 | 
			
		||||
        social_token = SocialToken.objects.first()
 | 
			
		||||
        self.assertIsNotNone(social_token)
 | 
			
		||||
 | 
			
		||||
    def test_import_crypt_no_passphrase(self):
 | 
			
		||||
        """
 | 
			
		||||
        GIVEN:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user