From f5ddc14588f3a73346d13c3c88cdab09dcfcf9a6 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Tue, 25 Aug 2026 10:44:45 -0700 Subject: [PATCH] Fix: also check global change_mailaccount with test --- src/paperless_mail/tests/test_api.py | 75 +++++++++++++++++++++++++++ src/paperless_mail/tests/test_mail.py | 4 +- src/paperless_mail/views.py | 4 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/paperless_mail/tests/test_api.py b/src/paperless_mail/tests/test_api.py index 64f456795..b9e2d723f 100644 --- a/src/paperless_mail/tests/test_api.py +++ b/src/paperless_mail/tests/test_api.py @@ -253,6 +253,81 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data["success"], True) + def test_mail_account_test_existing_no_global_perms(self) -> None: + """ + GIVEN: + - Existing account without an owner + - User without any mail account permissions + WHEN: + - API call is made to test the account by id + THEN: + - API returns forbidden + """ + account = MailAccountFactory( + username="admin", + password="secret", + imap_server="server.example.com", + imap_port=443, + owner=None, + ) + user = User.objects.create_user(username="no_perms") + self.client.force_authenticate(user=user) + + response = self.client.post( + f"{self.ENDPOINT}test/", + json.dumps( + { + "id": account.pk, + "imap_server": "server.example.com", + "imap_port": 443, + "imap_security": MailAccount.ImapSecurity.SSL, + "username": "admin", + "password": "******", + }, + ), + content_type="application/json", + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(response.content.decode(), "Insufficient permissions") + + def test_mail_account_test_existing_object_perms_only(self) -> None: + """ + GIVEN: + - Existing account owned by another user + - User with an object level grant but no global change permission + WHEN: + - API call is made to test the account by id + THEN: + - API returns forbidden + """ + owner = User.objects.create_user(username="account_owner") + account = MailAccountFactory( + username="admin", + password="secret", + imap_server="server.example.com", + imap_port=443, + owner=owner, + ) + user = User.objects.create_user(username="object_perms_only") + assign_perm("change_mailaccount", user, account) + self.client.force_authenticate(user=user) + + response = self.client.post( + f"{self.ENDPOINT}test/", + json.dumps( + { + "id": account.pk, + "imap_server": "server.example.com", + "imap_port": 443, + "imap_security": MailAccount.ImapSecurity.SSL, + "username": "admin", + "password": "******", + }, + ), + content_type="application/json", + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + def test_mail_account_test_existing_nonexistent_id_forbidden(self) -> None: response = self.client.post( f"{self.ENDPOINT}test/", diff --git a/src/paperless_mail/tests/test_mail.py b/src/paperless_mail/tests/test_mail.py index 87d702548..61b97d699 100644 --- a/src/paperless_mail/tests/test_mail.py +++ b/src/paperless_mail/tests/test_mail.py @@ -2195,7 +2195,9 @@ class TestMailAccountTestView(APITestCase): password="testpassword", ) self.user.user_permissions.add( - *Permission.objects.filter(codename__in=["add_mailaccount"]), + *Permission.objects.filter( + codename__in=["add_mailaccount", "change_mailaccount"], + ), ) self.user.save() self.client.force_authenticate(user=self.user) diff --git a/src/paperless_mail/views.py b/src/paperless_mail/views.py index 2a8f93b9e..3faff5da5 100644 --- a/src/paperless_mail/views.py +++ b/src/paperless_mail/views.py @@ -106,7 +106,9 @@ class MailAccountViewSet(PassUserMixin, ModelViewSet[MailAccount]): except (TypeError, ValueError, MailAccount.DoesNotExist): return HttpResponseForbidden("Insufficient permissions") - if not has_perms_owner_aware( + if not request.user.has_perms( + ["paperless_mail.change_mailaccount"], + ) or not has_perms_owner_aware( request.user, "change_mailaccount", existing_account,