mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-08 15:43:38 +00:00
FIx: make config view permissions consistent (#14709)
This commit is contained in:
1 parent
19fdc3b815
commit
53d9aa34a1
3 files changed
+76
-2
No files matched your search
@@ -31,6 +31,7 @@ from guardian.core import ObjectPermissionChecker
|
||||
from guardian.models import GroupObjectPermission
|
||||
from guardian.models import UserObjectPermission
|
||||
from rest_framework.permissions import BasePermission
|
||||
from rest_framework.permissions import DjangoModelPermissions
|
||||
from rest_framework.permissions import DjangoObjectPermissions
|
||||
|
||||
from documents.models import Document
|
||||
@@ -63,6 +64,17 @@ class PermissionGranteesUpdate(TypedDict, total=False):
|
||||
PermissionsSpec: TypeAlias = Mapping[PermissionAction, PermissionGranteesUpdate]
|
||||
|
||||
|
||||
class PaperlessModelPermissions(DjangoModelPermissions):
|
||||
"""Require basic global model permissions."""
|
||||
|
||||
perms_map = {
|
||||
**DjangoModelPermissions.perms_map,
|
||||
"GET": ["%(app_label)s.view_%(model_name)s"],
|
||||
"OPTIONS": ["%(app_label)s.view_%(model_name)s"],
|
||||
"HEAD": ["%(app_label)s.view_%(model_name)s"],
|
||||
}
|
||||
|
||||
|
||||
class PaperlessObjectPermissions(DjangoObjectPermissions):
|
||||
"""
|
||||
A permissions backend that checks for object-level permissions
|
||||
|
||||
@@ -15,6 +15,7 @@ from paperless.models import ColorConvertChoices
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
from paperless_testing.http import read_streaming_response
|
||||
from paperless_testing.permissions import grant_global
|
||||
|
||||
|
||||
class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
||||
@@ -26,6 +27,67 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
def test_api_read_config_requires_view_permission(self) -> None:
|
||||
for permissions in (
|
||||
(),
|
||||
("change_applicationconfiguration",),
|
||||
("view_document",),
|
||||
):
|
||||
user = UserFactory()
|
||||
grant_global(user, *permissions)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
for endpoint in (self.ENDPOINT, f"{self.ENDPOINT}1/"):
|
||||
for method in ("get", "head", "options"):
|
||||
with self.subTest(
|
||||
permissions=permissions,
|
||||
endpoint=endpoint,
|
||||
method=method,
|
||||
):
|
||||
response = getattr(self.client, method)(endpoint)
|
||||
self.assertEqual(
|
||||
response.status_code,
|
||||
status.HTTP_403_FORBIDDEN,
|
||||
)
|
||||
|
||||
def test_api_read_config_with_view_permission(self) -> None:
|
||||
user = UserFactory()
|
||||
grant_global(user, "view_applicationconfiguration")
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
for endpoint in (self.ENDPOINT, f"{self.ENDPOINT}1/"):
|
||||
for method in ("get", "head", "options"):
|
||||
with self.subTest(endpoint=endpoint, method=method):
|
||||
response = getattr(self.client, method)(endpoint)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
def test_api_view_config_permission_does_not_allow_writes(self) -> None:
|
||||
user = UserFactory()
|
||||
grant_global(user, "view_applicationconfiguration")
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
for method in ("put", "patch", "delete"):
|
||||
with self.subTest(method=method):
|
||||
response = getattr(self.client, method)(f"{self.ENDPOINT}1/")
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_api_change_config_permission_allows_updates(self) -> None:
|
||||
user = UserFactory()
|
||||
grant_global(user, "change_applicationconfiguration")
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
response = self.client.patch(
|
||||
f"{self.ENDPOINT}1/",
|
||||
{"app_title": "Updated title"},
|
||||
format="json",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(
|
||||
ApplicationConfiguration.objects.get().app_title,
|
||||
"Updated title",
|
||||
)
|
||||
|
||||
def test_api_get_config(self) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
|
||||
Reference in new issue
Block a user