Coverage for paperless_mail/serialisers.py: 91%
73 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
1from django.utils.translation import gettext as _
2from rest_framework import serializers
3from rest_framework.exceptions import PermissionDenied
5from documents.permissions import get_objects_for_user_owner_aware
6from documents.permissions import has_perms_owner_aware
7from documents.serialisers import CorrespondentField
8from documents.serialisers import DocumentTypeField
9from documents.serialisers import OwnedObjectSerializer
10from documents.serialisers import TagsField
11from paperless_mail.models import MailAccount
12from paperless_mail.models import MailRule
13from paperless_mail.models import ProcessedMail
16class ObfuscatedPasswordField(serializers.CharField):
17 """
18 Sends *** string instead of password in the clear
19 """
21 def to_representation(self, value) -> str:
22 return "*" * max(10, len(value))
24 def to_internal_value(self, data):
25 return data
28class MailAccountSerializer(OwnedObjectSerializer):
29 password = ObfuscatedPasswordField()
30 imap_port = serializers.IntegerField(required=True, allow_null=False)
32 class Meta:
33 model = MailAccount
34 fields = [
35 "id",
36 "name",
37 "imap_server",
38 "imap_port",
39 "imap_security",
40 "username",
41 "password",
42 "character_set",
43 "is_token",
44 "owner",
45 "user_can_change",
46 "permissions",
47 "set_permissions",
48 "account_type",
49 "expiration",
50 ]
52 def update(self, instance, validated_data):
53 if (
54 "password" in validated_data
55 and len(validated_data.get("password").replace("*", "")) == 0
56 ):
57 validated_data.pop("password")
58 super().update(instance, validated_data)
59 return instance
62class AccountField(serializers.PrimaryKeyRelatedField[MailAccount]):
63 def get_queryset(self):
64 user = getattr(self.context.get("request"), "user", None)
65 if user is None: 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true
66 user = getattr(self.root, "user", None)
68 if user is None: 68 ↛ 69line 68 didn't jump to line 69 because the condition on line 68 was never true
69 return MailAccount.objects.none()
71 return get_objects_for_user_owner_aware(
72 user,
73 "change_mailaccount",
74 MailAccount,
75 ).order_by("-id")
78class MailRuleSerializer(OwnedObjectSerializer):
79 account = AccountField(required=True)
80 action_parameter = serializers.CharField(
81 allow_null=True,
82 required=False,
83 default="",
84 )
85 assign_correspondent = CorrespondentField(allow_null=True, required=False)
86 assign_tags = TagsField(many=True, allow_null=True, required=False)
87 assign_document_type = DocumentTypeField(allow_null=True, required=False)
88 order = serializers.IntegerField(required=False)
90 class Meta:
91 model = MailRule
92 fields = [
93 "id",
94 "name",
95 "account",
96 "enabled",
97 "folder",
98 "filter_from",
99 "filter_to",
100 "filter_subject",
101 "filter_body",
102 "filter_attachment_filename_include",
103 "filter_attachment_filename_exclude",
104 "maximum_age",
105 "action",
106 "action_parameter",
107 "assign_title_from",
108 "assign_tags",
109 "assign_correspondent_from",
110 "assign_correspondent",
111 "assign_document_type",
112 "assign_owner_from_rule",
113 "order",
114 "attachment_type",
115 "consumption_scope",
116 "pdf_layout",
117 "owner",
118 "user_can_change",
119 "permissions",
120 "set_permissions",
121 "stop_processing",
122 ]
124 def update(self, instance, validated_data):
125 super().update(instance, validated_data)
126 return instance
128 def create(self, validated_data):
129 assign_tags = validated_data.pop("assign_tags", [])
130 mail_rule = super().create(validated_data)
131 if assign_tags: 131 ↛ 132line 131 didn't jump to line 132 because the condition on line 131 was never true
132 mail_rule.assign_tags.set(assign_tags)
133 return mail_rule
135 def validate(self, attrs):
136 action = attrs.get("action")
137 action_parameter = attrs.get("action_parameter")
139 if (
140 action in [MailRule.MailAction.TAG, MailRule.MailAction.MOVE]
141 and not action_parameter
142 ):
143 raise serializers.ValidationError("An action parameter is required.")
145 return attrs
147 def validate_account(self, account):
148 if self.user is not None and has_perms_owner_aware( 148 ↛ 155line 148 didn't jump to line 155 because the condition on line 148 was always true
149 self.user,
150 "change_mailaccount",
151 account,
152 ):
153 return account
155 raise PermissionDenied(
156 _("Insufficient permissions."),
157 )
159 def validate_maximum_age(self, value):
160 if value > 36500: # ~100 years
161 raise serializers.ValidationError("Maximum mail age is unreasonably large.")
162 return value
165class ProcessedMailSerializer(OwnedObjectSerializer):
166 class Meta:
167 model = ProcessedMail
168 fields = [
169 "id",
170 "owner",
171 "rule",
172 "folder",
173 "uid",
174 "subject",
175 "received",
176 "processed",
177 "status",
178 "error",
179 ]