diff --git a/src/paperless_mail/tests/test_mail_oauth.py b/src/paperless_mail/tests/test_mail_oauth.py index c3ba99ce9..6745d1c54 100644 --- a/src/paperless_mail/tests/test_mail_oauth.py +++ b/src/paperless_mail/tests/test_mail_oauth.py @@ -264,6 +264,28 @@ class TestMailOAuth( MailAccount.objects.filter(imap_server="outlook.office365.com").exists(), ) + def test_oauth_callback_view_unrecognized_scope(self) -> None: + """ + GIVEN: + - A valid OAuth state and a callback scope that is not Google's + WHEN: + - OAuth callback is called + THEN: + - 400 is returned instead of a server error and no account is created + """ + session = self.client.session + session["oauth_state"] = "test_state" + session.save() + + for scope in ("", "openid", "https://example.com/other"): + with self.subTest(scope=scope): + response = self.client.get( + "/api/oauth/callback/", + {"code": "test_code", "scope": scope, "state": "test_state"}, + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertFalse(MailAccount.objects.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 ce1f6a079..1da81cf66 100644 --- a/src/paperless_mail/views.py +++ b/src/paperless_mail/views.py @@ -319,6 +319,14 @@ class OauthCallbackView(GenericAPIView[Any]): result = oauth_manager.get_outlook_access_token(code) + else: + logger.error( + f"Invalid oauth callback request: unrecognized scope {scope!r}", + ) + return HttpResponseBadRequest( + "Invalid request, see logs for more detail", + ) + access_token = result["access_token"] refresh_token = result["refresh_token"] expires_in = result["expires_in"]