Include permissions for mail rules & accounts

This commit is contained in:
shamoon
2023-07-25 20:20:56 -07:00
parent 0beb9f0b5f
commit 23fefc3ab7
10 changed files with 243 additions and 74 deletions

View File

@@ -1,6 +1,7 @@
from django import forms
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
from guardian.admin import GuardedModelAdmin
from paperless_mail.models import MailAccount
from paperless_mail.models import MailRule
@@ -31,7 +32,7 @@ class MailAccountAdminForm(forms.ModelForm):
]
class MailAccountAdmin(admin.ModelAdmin):
class MailAccountAdmin(GuardedModelAdmin):
list_display = ("name", "imap_server", "username")
fieldsets = [
@@ -45,7 +46,7 @@ class MailAccountAdmin(admin.ModelAdmin):
form = MailAccountAdminForm
class MailRuleAdmin(admin.ModelAdmin):
class MailRuleAdmin(GuardedModelAdmin):
radio_fields = {
"attachment_type": admin.VERTICAL,
"action": admin.VERTICAL,

View File

@@ -25,7 +25,6 @@ class MailAccountSerializer(OwnedObjectSerializer):
class Meta:
model = MailAccount
depth = 1
fields = [
"id",
"name",
@@ -36,6 +35,10 @@ class MailAccountSerializer(OwnedObjectSerializer):
"password",
"character_set",
"is_token",
"owner",
"user_can_change",
"permissions",
"set_permissions",
]
def update(self, instance, validated_data):
@@ -67,7 +70,6 @@ class MailRuleSerializer(OwnedObjectSerializer):
class Meta:
model = MailRule
depth = 1
fields = [
"id",
"name",
@@ -89,6 +91,10 @@ class MailRuleSerializer(OwnedObjectSerializer):
"order",
"attachment_type",
"consumption_scope",
"owner",
"user_can_change",
"permissions",
"set_permissions",
]
def update(self, instance, validated_data):

View File

@@ -1,7 +1,9 @@
import json
from unittest import mock
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm
from rest_framework import status
from rest_framework.test import APITestCase
@@ -27,7 +29,9 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
super().setUp()
self.user = User.objects.create_superuser(username="temp_admin")
self.user = User.objects.create_user(username="temp_admin")
self.user.user_permissions.add(*Permission.objects.all())
self.user.save()
self.client.force_authenticate(user=self.user)
def test_get_mail_accounts(self):
@@ -266,6 +270,73 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["success"], True)
def test_get_mail_accounts_owner_aware(self):
"""
GIVEN:
- Configured accounts with different users
WHEN:
- API call is made to get mail accounts
THEN:
- Only unowned, owned by user or granted accounts are provided
"""
user2 = User.objects.create_user(username="temp_admin2")
account1 = MailAccount.objects.create(
name="Email1",
username="username1",
password="password1",
imap_server="server.example.com",
imap_port=443,
imap_security=MailAccount.ImapSecurity.SSL,
character_set="UTF-8",
)
account2 = MailAccount.objects.create(
name="Email2",
username="username2",
password="password2",
imap_server="server.example.com",
imap_port=443,
imap_security=MailAccount.ImapSecurity.SSL,
character_set="UTF-8",
)
account2.owner = self.user
account2.save()
account3 = MailAccount.objects.create(
name="Email3",
username="username3",
password="password3",
imap_server="server.example.com",
imap_port=443,
imap_security=MailAccount.ImapSecurity.SSL,
character_set="UTF-8",
)
account3.owner = user2
account3.save()
account4 = MailAccount.objects.create(
name="Email4",
username="username4",
password="password4",
imap_server="server.example.com",
imap_port=443,
imap_security=MailAccount.ImapSecurity.SSL,
character_set="UTF-8",
)
account4.owner = user2
account4.save()
assign_perm("view_mailaccount", self.user, account4)
response = self.client.get(self.ENDPOINT)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 3)
self.assertEqual(response.data["results"][0]["name"], account1.name)
self.assertEqual(response.data["results"][1]["name"], account2.name)
self.assertEqual(response.data["results"][2]["name"], account4.name)
class TestAPIMailRules(DirectoriesMixin, APITestCase):
ENDPOINT = "/api/mail_rules/"
@@ -273,7 +344,9 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
def setUp(self):
super().setUp()
self.user = User.objects.create_superuser(username="temp_admin")
self.user = User.objects.create_user(username="temp_admin")
self.user.user_permissions.add(*Permission.objects.all())
self.user.save()
self.client.force_authenticate(user=self.user)
def test_get_mail_rules(self):
@@ -533,3 +606,72 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
returned_rule1 = MailRule.objects.get(pk=rule1.pk)
self.assertEqual(returned_rule1.name, "Updated Name 1")
self.assertEqual(returned_rule1.action, MailRule.MailAction.DELETE)
def test_get_mail_rules_owner_aware(self):
"""
GIVEN:
- Configured rules with different users
WHEN:
- API call is made to get mail rules
THEN:
- Only unowned, owned by user or granted mail rules are provided
"""
user2 = User.objects.create_user(username="temp_admin2")
account1 = MailAccount.objects.create(
name="Email1",
username="username1",
password="password1",
imap_server="server.example.com",
imap_port=443,
imap_security=MailAccount.ImapSecurity.SSL,
character_set="UTF-8",
)
rule1 = MailRule.objects.create(
name="Rule1",
account=account1,
folder="INBOX",
filter_from="from@example1.com",
order=0,
)
rule2 = MailRule.objects.create(
name="Rule2",
account=account1,
folder="INBOX",
filter_from="from@example2.com",
order=1,
)
rule2.owner = self.user
rule2.save()
rule3 = MailRule.objects.create(
name="Rule3",
account=account1,
folder="INBOX",
filter_from="from@example3.com",
order=2,
)
rule3.owner = user2
rule3.save()
rule4 = MailRule.objects.create(
name="Rule4",
account=account1,
folder="INBOX",
filter_from="from@example4.com",
order=3,
)
rule4.owner = user2
rule4.save()
assign_perm("view_mailrule", self.user, rule4)
response = self.client.get(self.ENDPOINT)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["count"], 3)
self.assertEqual(response.data["results"][0]["name"], rule1.name)
self.assertEqual(response.data["results"][1]["name"], rule2.name)
self.assertEqual(response.data["results"][2]["name"], rule4.name)

View File

@@ -7,6 +7,8 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from documents.filters import ObjectOwnedOrGrantedPermissionsFilter
from documents.permissions import PaperlessObjectPermissions
from documents.views import PassUserMixin
from paperless.views import StandardPagination
from paperless_mail.mail import MailError
@@ -24,7 +26,8 @@ class MailAccountViewSet(ModelViewSet, PassUserMixin):
queryset = MailAccount.objects.all().order_by("pk")
serializer_class = MailAccountSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
permission_classes = (IsAuthenticated, PaperlessObjectPermissions)
filter_backends = (ObjectOwnedOrGrantedPermissionsFilter,)
class MailRuleViewSet(ModelViewSet, PassUserMixin):
@@ -33,7 +36,8 @@ class MailRuleViewSet(ModelViewSet, PassUserMixin):
queryset = MailRule.objects.all().order_by("order")
serializer_class = MailRuleSerializer
pagination_class = StandardPagination
permission_classes = (IsAuthenticated,)
permission_classes = (IsAuthenticated, PaperlessObjectPermissions)
filter_backends = (ObjectOwnedOrGrantedPermissionsFilter,)
class MailAccountTestView(GenericAPIView):