From 92d9b0b39410c7bf515f71332c29a5a3e71b0335 Mon Sep 17 00:00:00 2001 From: Sabrina Demagny Date: Mon, 16 Dec 2024 22:28:42 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(maildomain)=20fix=20domain=20acces?= =?UTF-8?q?s=20creation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If creating a user or allow in dimail after domain creation fails, creation of domain access on our side is not called. So the domain is created but the user cannot see his domain and he will try to create his domain again and will get an error message. To avoid this, we make sure to create the user's domain access on our side despite a dimail failure and log a error message. --- CHANGELOG.md | 4 ++ .../mailbox_manager/api/client/serializers.py | 15 ++-- .../test_api_mail_domains_create.py | 71 +++++++++++++++++++ 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9a22afb1..abb872fed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [Unreleased] +### Fixed + +- 🐛(backend) fix manage roles on domain admin view + ### Added - ✨(organizations) add siret to name conversion #584 diff --git a/src/backend/mailbox_manager/api/client/serializers.py b/src/backend/mailbox_manager/api/client/serializers.py index ceca66dec..c01fd44c6 100644 --- a/src/backend/mailbox_manager/api/client/serializers.py +++ b/src/backend/mailbox_manager/api/client/serializers.py @@ -1,7 +1,9 @@ """Client serializers for People's mailbox manager app.""" import json +from logging import getLogger +from requests.exceptions import HTTPError from rest_framework import exceptions, serializers from core.api.client.serializers import UserSerializer @@ -10,6 +12,8 @@ from mailbox_manager import enums, models from mailbox_manager.utils.dimail import DimailAPIClient +logger = getLogger(__name__) + class MailboxSerializer(serializers.ModelSerializer): """Serialize mailbox.""" @@ -194,10 +198,13 @@ def create(self, validated_data): enums.MailDomainRoleChoices.ADMIN, enums.MailDomainRoleChoices.OWNER, ]: - dimail.create_user(validated_data["user"].sub) - dimail.create_allow( - validated_data["user"].sub, validated_data["domain"].name - ) + try: + dimail.create_user(validated_data["user"].sub) + dimail.create_allow( + validated_data["user"].sub, validated_data["domain"].name + ) + except HTTPError: + logger.error("[DIMAIL] access creation failed %s") return super().create(validated_data) diff --git a/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_create.py b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_create.py index 56aacaada..9f66c89f0 100644 --- a/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_create.py +++ b/src/backend/mailbox_manager/tests/api/mail_domain/test_api_mail_domains_create.py @@ -122,6 +122,77 @@ def test_api_mail_domains__create_authenticated(): assert domain.accesses.filter(role="owner", user=user).exists() +def test_api_mail_domains__create_authenticated__dimail_failure(): + """ + Despite a dimail failure for user and/or allow creation, + an authenticated user should be able to create a mail domain + and should automatically be added as owner of the newly created domain. + """ + user = core_factories.UserFactory() + + client = APIClient() + client.force_login(user) + + domain_name = "test.domain.fr" + + with responses.RequestsMock() as rsps: + rsps.add( + rsps.POST, + re.compile(r".*/domains/"), + body=str( + { + "name": domain_name, + } + ), + status=status.HTTP_201_CREATED, + content_type="application/json", + ) + rsps.add( + rsps.POST, + re.compile(r".*/users/"), + body=str( + { + "name": "request-user-sub", + "is_admin": "false", + "uuid": "user-uuid-on-dimail", + "perms": [], + } + ), + status=status.HTTP_201_CREATED, + content_type="application/json", + ) + rsps.add( + rsps.POST, + re.compile(r".*/allows/"), + body=str({"user": "request-user-sub", "domain": str(domain_name)}), + status=status.HTTP_403_FORBIDDEN, + content_type="application/json", + ) + response = client.post( + "/api/v1.0/mail-domains/", + {"name": domain_name, "context": "null", "features": ["webmail"]}, + format="json", + ) + assert response.status_code == status.HTTP_201_CREATED + domain = models.MailDomain.objects.get() + + # response is as expected + assert response.json() == { + "id": str(domain.id), + "name": domain.name, + "slug": domain.slug, + "status": enums.MailDomainStatusChoices.PENDING, + "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), + } + + # a new domain with status "pending" is created and authenticated user is the owner + assert domain.status == enums.MailDomainStatusChoices.PENDING + assert domain.name == domain_name + assert domain.accesses.filter(role="owner", user=user).exists() + + ## SYNC TO DIMAIL def test_api_mail_domains__create_dimail_domain(caplog): """