mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-10-16 13:07:14 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09a48138e4 |
No files matched your search
@@ -109,20 +109,6 @@ def has_system_status_permission(user: User | None) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_groups_with_only_permission(obj, codename):
|
|
||||||
ctype = ContentType.objects.get_for_model(obj)
|
|
||||||
permission = Permission.objects.get(content_type=ctype, codename=codename)
|
|
||||||
group_object_perm_group_ids = (
|
|
||||||
GroupObjectPermission.objects.filter(
|
|
||||||
object_pk=obj.pk,
|
|
||||||
content_type=ctype,
|
|
||||||
)
|
|
||||||
.filter(permission=permission)
|
|
||||||
.values_list("group_id")
|
|
||||||
)
|
|
||||||
return Group.objects.filter(id__in=group_object_perm_group_ids).distinct()
|
|
||||||
|
|
||||||
|
|
||||||
def _resolve_permissions(codenames: set[str], ctype: ContentType) -> list[Permission]:
|
def _resolve_permissions(codenames: set[str], ctype: ContentType) -> list[Permission]:
|
||||||
"""
|
"""
|
||||||
Resolve ``codenames`` to Permission rows, raising for any that don't exist
|
Resolve ``codenames`` to Permission rows, raising for any that don't exist
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ from drf_spectacular.utils import extend_schema_field
|
|||||||
from drf_spectacular.utils import extend_schema_serializer
|
from drf_spectacular.utils import extend_schema_serializer
|
||||||
from drf_writable_nested.serializers import NestedUpdateMixin
|
from drf_writable_nested.serializers import NestedUpdateMixin
|
||||||
from guardian.core import ObjectPermissionChecker
|
from guardian.core import ObjectPermissionChecker
|
||||||
|
from guardian.shortcuts import get_groups_with_perms
|
||||||
from guardian.shortcuts import get_users_with_perms
|
from guardian.shortcuts import get_users_with_perms
|
||||||
from guardian.utils import get_group_obj_perms_model
|
from guardian.utils import get_group_obj_perms_model
|
||||||
from guardian.utils import get_user_obj_perms_model
|
from guardian.utils import get_user_obj_perms_model
|
||||||
@@ -83,7 +84,6 @@ from documents.permissions import PermissionAction
|
|||||||
from documents.permissions import PermissionGrantees
|
from documents.permissions import PermissionGrantees
|
||||||
from documents.permissions import PermissionsSpec
|
from documents.permissions import PermissionsSpec
|
||||||
from documents.permissions import get_document_count_filter_for_user
|
from documents.permissions import get_document_count_filter_for_user
|
||||||
from documents.permissions import get_groups_with_only_permission
|
|
||||||
from documents.permissions import has_perms_owner_aware
|
from documents.permissions import has_perms_owner_aware
|
||||||
from documents.permissions import permitted_document_ids
|
from documents.permissions import permitted_document_ids
|
||||||
from documents.permissions import restrict_queryset_to_visible
|
from documents.permissions import restrict_queryset_to_visible
|
||||||
@@ -337,9 +337,9 @@ class OwnedObjectSerializer(
|
|||||||
)
|
)
|
||||||
else: # groups
|
else: # groups
|
||||||
return list(
|
return list(
|
||||||
get_groups_with_only_permission(
|
get_groups_with_perms(
|
||||||
obj,
|
obj,
|
||||||
codename=f"{codename}_{obj.__class__.__name__.lower()}",
|
only_with_perms_in=[f"{codename}_{obj.__class__.__name__.lower()}"],
|
||||||
).values_list("id", flat=True),
|
).values_list("id", flat=True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -292,6 +292,33 @@ class TestViews(DirectoriesMixin, TestCase):
|
|||||||
else:
|
else:
|
||||||
assert False, f"Unexpected tag found: {tag['name']}"
|
assert False, f"Unexpected tag found: {tag['name']}"
|
||||||
|
|
||||||
|
def test_retrieve_with_full_permissions(self) -> None:
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- A tag with view granted to two groups and change granted to only
|
||||||
|
one of them
|
||||||
|
WHEN:
|
||||||
|
- The single tag is requested with full permissions
|
||||||
|
THEN:
|
||||||
|
- Each action lists only the groups granted that action
|
||||||
|
"""
|
||||||
|
view_only = Group.objects.create(name="view_only")
|
||||||
|
view_and_change = Group.objects.create(name="view_and_change")
|
||||||
|
tag = Tag.objects.create(name="invoice")
|
||||||
|
grant_object(view_only, tag, "view_tag")
|
||||||
|
grant_object(view_and_change, tag, "view_tag", "change_tag")
|
||||||
|
grant_global(self.user, "view_tag")
|
||||||
|
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
response = self.client.get(f"/api/tags/{tag.pk}/?full_perms=true")
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
permissions = response.json()["permissions"]
|
||||||
|
assert sorted(permissions["view"]["groups"]) == sorted(
|
||||||
|
[view_only.pk, view_and_change.pk],
|
||||||
|
)
|
||||||
|
assert permissions["change"]["groups"] == [view_and_change.pk]
|
||||||
|
|
||||||
def test_list_no_n_plus_1_queries(self) -> None:
|
def test_list_no_n_plus_1_queries(self) -> None:
|
||||||
"""
|
"""
|
||||||
GIVEN:
|
GIVEN:
|
||||||
|
|||||||
Reference in new issue
Block a user