From cdb766b0e0115f41cf0425dcfd56927d6a293c1c Mon Sep 17 00:00:00 2001 From: Sabrina Demagny Date: Sun, 16 Feb 2025 17:57:58 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(domains)=20allow=20to=20run=20all=20f?= =?UTF-8?q?etch=20domain=20data=20from=20dimail?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fetch domain status and expected config from dimail. --- .../mailbox_manager/api/client/viewsets.py | 14 ++ .../test_api_mail_domains_fetch.py | 143 ++++++++++++++++++ .../test_api_mail_domains_retrieve.py | 3 - src/backend/mailbox_manager/utils/dimail.py | 1 + 4 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_fetch.py diff --git a/src/backend/mailbox_manager/api/client/viewsets.py b/src/backend/mailbox_manager/api/client/viewsets.py index 5c14117..048eeb7 100644 --- a/src/backend/mailbox_manager/api/client/viewsets.py +++ b/src/backend/mailbox_manager/api/client/viewsets.py @@ -35,6 +35,9 @@ class MailDomainViewSet( - name: str - support_email: str Return newly created domain + + POST /api//mail-domains//fetch/ + Fetch domain status and expected config from dimail. """ permission_classes = [permissions.AccessPermission] @@ -61,6 +64,17 @@ class MailDomainViewSet( } ) + @action(detail=True, methods=["post"], url_path="fetch") + def fetch_from_dimail(self, request, *args, **kwargs): + """Fetch domain status and expected config from dimail.""" + domain = self.get_object() + client = DimailAPIClient() + client.fetch_domain_status(domain) + client.fetch_domain_expected_config(domain) + return Response( + serializers.MailDomainSerializer(domain, context={"request": request}).data + ) + # pylint: disable=too-many-ancestors class MailDomainAccessViewSet( diff --git a/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_fetch.py b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_fetch.py new file mode 100644 index 0000000..cc2f9c4 --- /dev/null +++ b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_fetch.py @@ -0,0 +1,143 @@ +""" +Tests for MailDomains API endpoint in People's mailbox manager app. Focus on "fetch" action. +""" + +import json +import re + +import pytest +import responses +from rest_framework import status +from rest_framework.test import APIClient + +from core import factories as core_factories + +from mailbox_manager import enums, factories +from mailbox_manager.tests.fixtures import dimail as dimail_fixtures + +pytestmark = pytest.mark.django_db + + +@responses.activate +def test_api_mail_domains__fetch_from_dimail__anonymous(): + """ + Anonymous users should not be allowed to fetch a domain from dimail. + """ + client = APIClient() + + domain = factories.MailDomainFactory() + + response = client.post( + f"/api/v1.0/mail-domains/{domain.slug}/fetch/", + ) + assert response.status_code == status.HTTP_401_UNAUTHORIZED + + +@responses.activate +def test_api_mail_domains__fetch_from_dimail__unrelated(): + """ + Authenticated users shouldn't be allowed to fetch + a domain from dimail if they are not an owner or admin. + """ + user = core_factories.UserFactory() + + client = APIClient() + client.force_login(user) + + domain = factories.MailDomainFactory( + status=enums.MailDomainStatusChoices.PENDING, + ) + + response = client.post( + f"/api/v1.0/mail-domains/{domain.slug}/fetch/", + ) + + assert response.status_code == status.HTTP_404_NOT_FOUND + + +def test_api_mail_domains__fetch_from_dimail__viewer(): + """ + Authenticated users shouldn't be allowed to fetch a domain from dimail + if they are a viewer. + """ + user = core_factories.UserFactory() + + client = APIClient() + client.force_login(user) + access = factories.MailDomainAccessFactory( + user=user, + role=enums.MailDomainRoleChoices.VIEWER, + ) + response = client.post( + f"/api/v1.0/mail-domains/{access.domain.slug}/fetch/", + ) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.parametrize( + "role", + [ + enums.MailDomainRoleChoices.ADMIN, + enums.MailDomainRoleChoices.OWNER, + ], +) +@responses.activate +def test_api_mail_domains__fetch_from_dimail(role): + """ + Authenticated users should be allowed to fetch a domain + from dimail if they are an owner or admin. + """ + + user = core_factories.UserFactory() + + client = APIClient() + client.force_login(user) + + domain = factories.MailDomainFactory( + status=enums.MailDomainStatusChoices.PENDING, + ) + factories.MailDomainAccessFactory( + domain=domain, + user=user, + role=role, + ) + + assert domain.expected_config is None + assert domain.last_check_details is None + + responses.add( + responses.GET, + re.compile(rf".*/domains/{domain.name}/check/"), + json=dimail_fixtures.CHECK_DOMAIN_OK, + status=200, + ) + responses.add( + responses.GET, + re.compile(rf".*/domains/{domain.name}/spec/"), + json=dimail_fixtures.DOMAIN_SPEC, + status=200, + ) + + response = client.post( + f"/api/v1.0/mail-domains/{domain.slug}/fetch/", + ) + + domain.refresh_from_db() + assert response.status_code == status.HTTP_200_OK + assert response.json() == { + "id": str(domain.id), + "name": domain.name, + "slug": domain.slug, + "status": str(enums.MailDomainStatusChoices.ENABLED), + "created_at": domain.created_at.isoformat().replace("+00:00", "Z"), + "updated_at": domain.updated_at.isoformat().replace("+00:00", "Z"), + "abilities": domain.get_abilities(user), + "count_mailboxes": 0, + "support_email": domain.support_email, + "last_check_details": dimail_fixtures.CHECK_DOMAIN_OK, + "action_required_details": {}, + "expected_config": dimail_fixtures.DOMAIN_SPEC, + } + assert domain.expected_config == dimail_fixtures.DOMAIN_SPEC + assert domain.last_check_details == dimail_fixtures.CHECK_DOMAIN_OK + assert domain.status == enums.MailDomainStatusChoices.ENABLED diff --git a/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_retrieve.py b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_retrieve.py index 5729163..7e550c3 100644 --- a/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_retrieve.py +++ b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_retrieve.py @@ -2,9 +2,6 @@ Tests for MailDomains API endpoint in People's mailbox manager app. Focus on "retrieve" action. """ -import json -import re - import pytest import responses from rest_framework import status diff --git a/src/backend/mailbox_manager/utils/dimail.py b/src/backend/mailbox_manager/utils/dimail.py index 1a9001d..1860b8b 100644 --- a/src/backend/mailbox_manager/utils/dimail.py +++ b/src/backend/mailbox_manager/utils/dimail.py @@ -431,6 +431,7 @@ class DimailAPIClient: self.API_URL, exc_info=error, ) + raise error if response.status_code == status.HTTP_200_OK: return response.json() return self.raise_exception_for_unexpected_response(response)