mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-10-10 02:16:12 -05:00
Merge branch 'dev' into feature-remote-ocr-2
This commit is contained in:
@@ -161,3 +161,21 @@ class PaperlessNotePermissions(BasePermission):
|
||||
perms = self.perms_map[request.method]
|
||||
|
||||
return request.user.has_perms(perms)
|
||||
|
||||
|
||||
class AcknowledgeTasksPermissions(BasePermission):
|
||||
"""
|
||||
Permissions class that checks for model permissions for acknowledging tasks.
|
||||
"""
|
||||
|
||||
perms_map = {
|
||||
"POST": ["documents.change_paperlesstask"],
|
||||
}
|
||||
|
||||
def has_permission(self, request, view):
|
||||
if not request.user or not request.user.is_authenticated: # pragma: no cover
|
||||
return False
|
||||
|
||||
perms = self.perms_map.get(request.method, [])
|
||||
|
||||
return request.user.has_perms(perms)
|
||||
|
@@ -76,7 +76,9 @@ def check_sanity(*, progress=False, scheduled=True) -> SanityCheckMessages:
|
||||
messages = SanityCheckMessages()
|
||||
|
||||
present_files = {
|
||||
x.resolve() for x in Path(settings.MEDIA_ROOT).glob("**/*") if not x.is_dir()
|
||||
x.resolve()
|
||||
for x in Path(settings.MEDIA_ROOT).glob("**/*")
|
||||
if not x.is_dir() and x.name not in settings.IGNORABLE_FILES
|
||||
}
|
||||
|
||||
lockfile = Path(settings.MEDIA_LOCK).resolve()
|
||||
|
@@ -135,6 +135,44 @@ class TestTasks(DirectoriesMixin, APITestCase):
|
||||
response = self.client.get(self.ENDPOINT + "?acknowledged=false")
|
||||
self.assertEqual(len(response.data), 0)
|
||||
|
||||
def test_acknowledge_tasks_requires_change_permission(self):
|
||||
"""
|
||||
GIVEN:
|
||||
- A regular user initially without change permissions
|
||||
- A regular user with change permissions
|
||||
WHEN:
|
||||
- API call is made to acknowledge tasks
|
||||
THEN:
|
||||
- The first user is forbidden from acknowledging tasks
|
||||
- The second user is allowed to acknowledge tasks
|
||||
"""
|
||||
regular_user = User.objects.create_user(username="test")
|
||||
self.client.force_authenticate(user=regular_user)
|
||||
|
||||
task = PaperlessTask.objects.create(
|
||||
task_id=str(uuid.uuid4()),
|
||||
task_file_name="task_one.pdf",
|
||||
)
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT + "acknowledge/",
|
||||
{"tasks": [task.id]},
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
regular_user2 = User.objects.create_user(username="test2")
|
||||
regular_user2.user_permissions.add(
|
||||
Permission.objects.get(codename="change_paperlesstask"),
|
||||
)
|
||||
regular_user2.save()
|
||||
self.client.force_authenticate(user=regular_user2)
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT + "acknowledge/",
|
||||
{"tasks": [task.id]},
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test_tasks_owner_aware(self):
|
||||
"""
|
||||
GIVEN:
|
||||
|
@@ -169,6 +169,13 @@ class TestSanityCheck(DirectoriesMixin, TestCase):
|
||||
messages = check_sanity()
|
||||
self.assertFalse(messages.has_warning)
|
||||
|
||||
def test_ignore_ignorable_files(self):
|
||||
self.make_test_data()
|
||||
Path(self.dirs.media_dir, ".DS_Store").touch()
|
||||
Path(self.dirs.media_dir, "desktop.ini").touch()
|
||||
messages = check_sanity()
|
||||
self.assertFalse(messages.has_warning)
|
||||
|
||||
def test_archive_filename_no_checksum(self):
|
||||
doc = self.make_test_data()
|
||||
doc.archive_checksum = None
|
||||
|
@@ -136,6 +136,7 @@ from documents.models import WorkflowAction
|
||||
from documents.models import WorkflowTrigger
|
||||
from documents.parsers import get_parser_class_for_mime_type
|
||||
from documents.parsers import parse_date_generator
|
||||
from documents.permissions import AcknowledgeTasksPermissions
|
||||
from documents.permissions import PaperlessAdminPermissions
|
||||
from documents.permissions import PaperlessNotePermissions
|
||||
from documents.permissions import PaperlessObjectPermissions
|
||||
@@ -2487,7 +2488,11 @@ class TasksViewSet(ReadOnlyModelViewSet):
|
||||
queryset = PaperlessTask.objects.filter(task_id=task_id)
|
||||
return queryset
|
||||
|
||||
@action(methods=["post"], detail=False)
|
||||
@action(
|
||||
methods=["post"],
|
||||
detail=False,
|
||||
permission_classes=[IsAuthenticated, AcknowledgeTasksPermissions],
|
||||
)
|
||||
def acknowledge(self, request):
|
||||
serializer = AcknowledgeTasksViewSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
@@ -1004,6 +1004,18 @@ THREADS_PER_WORKER = os.getenv(
|
||||
# Paperless Specific Settings #
|
||||
###############################################################################
|
||||
|
||||
IGNORABLE_FILES: Final[list[str]] = [
|
||||
".DS_Store",
|
||||
".DS_STORE",
|
||||
"._*",
|
||||
".stfolder/*",
|
||||
".stversions/*",
|
||||
".localized/*",
|
||||
"desktop.ini",
|
||||
"@eaDir/*",
|
||||
"Thumbs.db",
|
||||
]
|
||||
|
||||
CONSUMER_POLLING = int(os.getenv("PAPERLESS_CONSUMER_POLLING", 0))
|
||||
|
||||
CONSUMER_POLLING_DELAY = int(os.getenv("PAPERLESS_CONSUMER_POLLING_DELAY", 5))
|
||||
@@ -1026,7 +1038,7 @@ CONSUMER_IGNORE_PATTERNS = list(
|
||||
json.loads(
|
||||
os.getenv(
|
||||
"PAPERLESS_CONSUMER_IGNORE_PATTERNS",
|
||||
'[".DS_Store", ".DS_STORE", "._*", ".stfolder/*", ".stversions/*", ".localized/*", "desktop.ini", "@eaDir/*", "Thumbs.db"]',
|
||||
json.dumps(IGNORABLE_FILES),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
Reference in New Issue
Block a user