More permissions on mail account test endpoint

This commit is contained in:
shamoon
2026-02-21 16:43:28 -08:00
parent f85094dc2b
commit 1bb4b9b473
3 changed files with 55 additions and 5 deletions

View File

@@ -272,6 +272,24 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["success"], True) self.assertEqual(response.data["success"], True)
def test_mail_account_test_existing_nonexistent_id_forbidden(self):
response = self.client.post(
f"{self.ENDPOINT}test/",
json.dumps(
{
"id": 999999,
"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_get_mail_accounts_owner_aware(self): def test_get_mail_accounts_owner_aware(self):
""" """
GIVEN: GIVEN:

View File

@@ -9,6 +9,7 @@ from datetime import timedelta
from unittest import mock from unittest import mock
import pytest import pytest
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.management import call_command from django.core.management import call_command
from django.db import DatabaseError from django.db import DatabaseError
@@ -1699,6 +1700,10 @@ class TestMailAccountTestView(APITestCase):
username="testuser", username="testuser",
password="testpassword", password="testpassword",
) )
self.user.user_permissions.add(
*Permission.objects.filter(codename__in=["add_mailaccount"]),
)
self.user.save()
self.client.force_authenticate(user=self.user) self.client.force_authenticate(user=self.user)
self.url = "/api/mail_accounts/test/" self.url = "/api/mail_accounts/test/"
@@ -1844,6 +1849,25 @@ class TestMailAccountTestView(APITestCase):
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(response.content.decode(), "Insufficient permissions") self.assertEqual(response.content.decode(), "Insufficient permissions")
def test_mail_account_test_view_requires_add_permission_without_account_id(self):
self.user.user_permissions.remove(
*Permission.objects.filter(codename__in=["add_mailaccount"]),
)
self.user.save()
data = {
"imap_server": "imap.example.com",
"imap_port": 993,
"imap_security": MailAccount.ImapSecurity.SSL,
"username": "admin",
"password": "secret",
"is_token": False,
}
response = self.client.post(self.url, data, format="json")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
self.assertEqual(response.content.decode(), "Insufficient permissions")
class TestMailAccountProcess(APITestCase): class TestMailAccountProcess(APITestCase):
def setUp(self): def setUp(self):

View File

@@ -89,15 +89,18 @@ class MailAccountViewSet(ModelViewSet, PassUserMixin):
existing_account = None existing_account = None
account_id = request.data.get("id") account_id = request.data.get("id")
# account exists, use the password from there instead of *** and refresh_token / expiration # testing a new connection requires add permission
if ( if account_id is None and not request.user.has_perms(
len(serializer.validated_data.get("password").replace("*", "")) == 0 ["paperless_mail.add_mailaccount"],
and account_id is not None
): ):
return HttpResponseForbidden("Insufficient permissions")
# testing an existing account requires change permission on that account
if account_id is not None:
try: try:
existing_account = MailAccount.objects.get(pk=account_id) existing_account = MailAccount.objects.get(pk=account_id)
except (TypeError, ValueError, MailAccount.DoesNotExist): except (TypeError, ValueError, MailAccount.DoesNotExist):
return HttpResponseBadRequest("Invalid account") return HttpResponseForbidden("Insufficient permissions")
if not has_perms_owner_aware( if not has_perms_owner_aware(
request.user, request.user,
@@ -106,6 +109,11 @@ class MailAccountViewSet(ModelViewSet, PassUserMixin):
): ):
return HttpResponseForbidden("Insufficient permissions") return HttpResponseForbidden("Insufficient permissions")
# account exists, use the password from there instead of ***
if (
len(serializer.validated_data.get("password").replace("*", "")) == 0
and existing_account is not None
):
serializer.validated_data["password"] = existing_account.password serializer.validated_data["password"] = existing_account.password
serializer.validated_data["account_type"] = existing_account.account_type serializer.validated_data["account_type"] = existing_account.account_type
serializer.validated_data["refresh_token"] = existing_account.refresh_token serializer.validated_data["refresh_token"] = existing_account.refresh_token