From 947245a9300f9b00f84079884d34a89b355a5add Mon Sep 17 00:00:00 2001
From: shamoon <4887959+shamoon@users.noreply.github.com>
Date: Mon, 7 Oct 2024 12:51:07 -0700
Subject: [PATCH] Respect add mailaccount perms
---
.../manage/mail/mail.component.html | 4 +-
src/paperless_mail/tests/test_mail_oauth.py | 85 ++++++++++++++-----
src/paperless_mail/views.py | 7 ++
3 files changed, 71 insertions(+), 25 deletions(-)
diff --git a/src-ui/src/app/components/manage/mail/mail.component.html b/src-ui/src/app/components/manage/mail/mail.component.html
index 84fbb3f84..9058e6884 100644
--- a/src-ui/src/app/components/manage/mail/mail.component.html
+++ b/src-ui/src/app/components/manage/mail/mail.component.html
@@ -14,12 +14,12 @@
Add Account
@if (gmailOAuthUrl) {
-
+
Connect Gmail Account
}
@if (outlookOAuthUrl) {
-
+
Connect Outlook Account
}
diff --git a/src/paperless_mail/tests/test_mail_oauth.py b/src/paperless_mail/tests/test_mail_oauth.py
index 5812e3601..9eb68d3e5 100644
--- a/src/paperless_mail/tests/test_mail_oauth.py
+++ b/src/paperless_mail/tests/test_mail_oauth.py
@@ -2,6 +2,7 @@ from datetime import timedelta
from unittest import mock
from django.conf import settings
+from django.contrib.auth.models import Permission
from django.contrib.auth.models import User
from django.test import TestCase
from django.test import override_settings
@@ -20,6 +21,14 @@ class TestMailOAuth(
):
def setUp(self) -> None:
self.user = User.objects.create_user("testuser")
+ self.user.user_permissions.add(
+ *Permission.objects.filter(
+ codename__in=[
+ "add_mailaccount",
+ ],
+ ),
+ )
+ self.user.save()
self.client.force_login(self.user)
self.mail_account_handler = MailAccountHandler()
# Mock settings
@@ -82,7 +91,7 @@ class TestMailOAuth(
@mock.patch(
"paperless_mail.oauth.PaperlessMailOAuth2Manager.get_outlook_access_token",
)
- def test_oauth_callback_view(
+ def test_oauth_callback_view_success(
self,
mock_get_outlook_access_token,
mock_get_gmail_access_token,
@@ -128,29 +137,8 @@ class TestMailOAuth(
MailAccount.objects.filter(imap_server="outlook.office365.com").exists(),
)
- def test_oauth_callback_view_no_code(self):
- """
- GIVEN:
- - Mocked settings for Gmail and Outlook OAuth client IDs and secrets
- WHEN:
- - OAuth callback is called without a code
- THEN:
- - 400 bad request returned, no mail accounts are created
- """
-
- response = self.client.get(
- "/api/oauth/callback/",
- )
- self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
- self.assertFalse(
- MailAccount.objects.filter(imap_server="imap.gmail.com").exists(),
- )
- self.assertFalse(
- MailAccount.objects.filter(imap_server="outlook.office365.com").exists(),
- )
-
@mock.patch("httpx_oauth.oauth2.BaseOAuth2.get_access_token")
- def test_oauth_callback_view_error(self, mock_get_access_token):
+ def test_oauth_callback_view_fails(self, mock_get_access_token):
"""
GIVEN:
- Mocked settings for Gmail and Outlook OAuth client IDs and secrets
@@ -185,6 +173,57 @@ class TestMailOAuth(
self.assertIn("Error getting access token: test_error", cm.output[0])
+ def test_oauth_callback_view_insufficient_permissions(self):
+ """
+ GIVEN:
+ - Mocked settings for Gmail and Outlook OAuth client IDs and secrets
+ - User without add_mailaccount permission
+ WHEN:
+ - OAuth callback is called
+ THEN:
+ - 400 bad request returned, no mail accounts are created
+ """
+ self.user.user_permissions.remove(
+ *Permission.objects.filter(
+ codename__in=[
+ "add_mailaccount",
+ ],
+ ),
+ )
+ self.user.save()
+
+ response = self.client.get(
+ "/api/oauth/callback/?code=test_code&scope=https://mail.google.com/",
+ )
+ self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+ self.assertFalse(
+ MailAccount.objects.filter(imap_server="imap.gmail.com").exists(),
+ )
+ self.assertFalse(
+ MailAccount.objects.filter(imap_server="outlook.office365.com").exists(),
+ )
+
+ def test_oauth_callback_view_no_code(self):
+ """
+ GIVEN:
+ - Mocked settings for Gmail and Outlook OAuth client IDs and secrets
+ WHEN:
+ - OAuth callback is called without a code
+ THEN:
+ - 400 bad request returned, no mail accounts are created
+ """
+
+ response = self.client.get(
+ "/api/oauth/callback/",
+ )
+ self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+ self.assertFalse(
+ MailAccount.objects.filter(imap_server="imap.gmail.com").exists(),
+ )
+ self.assertFalse(
+ MailAccount.objects.filter(imap_server="outlook.office365.com").exists(),
+ )
+
@mock.patch("paperless_mail.mail.get_mailbox")
@mock.patch(
"httpx_oauth.oauth2.BaseOAuth2.refresh_token",
diff --git a/src/paperless_mail/views.py b/src/paperless_mail/views.py
index 718dc4eec..745ecb5fb 100644
--- a/src/paperless_mail/views.py
+++ b/src/paperless_mail/views.py
@@ -99,6 +99,13 @@ class OauthCallbackView(GenericAPIView):
permission_classes = (IsAuthenticated,)
def get(self, request, format=None):
+ if not (
+ request.user and request.user.has_perms(["paperless_mail.add_mailaccount"])
+ ):
+ return HttpResponseBadRequest(
+ "You do not have permission to add mail accounts",
+ )
+
logger = logging.getLogger("paperless_mail")
code = request.query_params.get("code")
# Gmail passes scope as a query param, Outlook does not