diff --git a/Makefile b/Makefile index b4043f8..1d700b4 100644 --- a/Makefile +++ b/Makefile @@ -296,7 +296,7 @@ recreate-dimail-container: dimail-setup-db: @echo "$(BOLD)Populating database of local dimail API container$(RESET)" - @$(MANAGE) setup_dimail_db + @$(MANAGE) setup_dimail_db --populate-from-people .PHONY: dimail-setup-db # -- Mail generator diff --git a/src/backend/mailbox_manager/management/commands/setup_dimail_db.py b/src/backend/mailbox_manager/management/commands/setup_dimail_db.py index 40d4bce..d0a005e 100644 --- a/src/backend/mailbox_manager/management/commands/setup_dimail_db.py +++ b/src/backend/mailbox_manager/management/commands/setup_dimail_db.py @@ -9,6 +9,7 @@ from rest_framework import status from mailbox_manager import enums from mailbox_manager.models import MailDomain, MailDomainAccess +from mailbox_manager.utils.dimail import DimailAPIClient User = get_user_model() @@ -23,6 +24,8 @@ class Command(BaseCommand): Management command populate local dimail database, to ease dev """ + client = DimailAPIClient() + help = "Populate local dimail database, for dev purposes." def add_arguments(self, parser): @@ -84,7 +87,7 @@ class Command(BaseCommand): else: # create accesses for john doe self.create_user(name=people_base_user.sub) - self.create_allows(people_base_user.sub, domain_name) + self.create_allow(people_base_user.sub, domain_name) MailDomainAccess.objects.get_or_create( user=people_base_user, domain=domain, @@ -128,20 +131,11 @@ class Command(BaseCommand): ) ) - def create_domain(self, name, auth=(regie["username"], regie["password"])): + def create_domain(self, name): """ - Send a request to create a new domain. + Send a request to create a new domain using DimailAPIClient. """ - response = requests.post( - url=f"{DIMAIL_URL}/domains/", - json={ - "name": name, - "context_name": "context", - "features": ["webmail", "mailbox", "alias"], - }, - auth=auth, - timeout=10, - ) + response = self.client.create_domain(name, request_user="setup_dimail_db.py") if response.status_code == status.HTTP_201_CREATED: self.stdout.write( @@ -154,19 +148,11 @@ class Command(BaseCommand): ) ) - def create_allows(self, user, domain, auth=(regie["username"], regie["password"])): + def create_allow(self, user, domain): """ - Send a request to create a new allows between user and domain. + Send a request to create a new allows between user and domain using DimailAPIClient. """ - response = requests.post( - url=f"{DIMAIL_URL}/allows/", - json={ - "domain": domain, - "user": user, - }, - auth=auth, - timeout=10, - ) + response = self.client.create_allow(user, domain) if response.status_code == status.HTTP_201_CREATED: self.stdout.write( @@ -216,4 +202,4 @@ class Command(BaseCommand): # create missing accesses for access in access_to_create: - self.create_allows(access.user.sub, access.domain.name) + self.create_allow(access.user.sub, access.domain.name) diff --git a/src/backend/mailbox_manager/tests/commands/test_dimail_setup_db.py b/src/backend/mailbox_manager/tests/commands/test_dimail_setup_db.py index 52e0bc1..adf32db 100644 --- a/src/backend/mailbox_manager/tests/commands/test_dimail_setup_db.py +++ b/src/backend/mailbox_manager/tests/commands/test_dimail_setup_db.py @@ -74,8 +74,9 @@ def test_commands_setup_dimail_db(settings): assert responses.calls[2].request.url == f"{DIMAIL_URL}/domains/" assert responses.calls[2].request.body == ( - b'{"name": "test.domain.com", "context_name": "context", ' - b'"features": ["webmail", "mailbox", "alias"]}' + b'{"name": "test.domain.com", "context_name": "test.domain.com", ' + b'"features": ["webmail", "mailbox", "alias"], ' + b'"delivery": "virtual"}' ) assert responses.calls[3].request.url == f"{DIMAIL_URL}/users/" @@ -87,7 +88,7 @@ def test_commands_setup_dimail_db(settings): assert responses.calls[4].request.url == f"{DIMAIL_URL}/allows/" assert ( responses.calls[4].request.body - == b'{"domain": "test.domain.com", "user": "sub.john.doe"}' + == b'{"user": "sub.john.doe", "domain": "test.domain.com"}' ) # reset the responses counter @@ -112,8 +113,9 @@ def test_commands_setup_dimail_db(settings): assert ( f"{DIMAIL_URL}/domains/", ( - b'{"name": "some.domain.com", "context_name": "context", ' - b'"features": ["webmail", "mailbox", "alias"]}' + b'{"name": "some.domain.com", "context_name": "some.domain.com", ' + b'"features": ["webmail", "mailbox", "alias"], ' + b'"delivery": "virtual"}' ), ) in dimail_calls @@ -124,5 +126,5 @@ def test_commands_setup_dimail_db(settings): assert ( f"{DIMAIL_URL}/allows/", - b'{"domain": "some.domain.com", "user": "sub.toto.123"}', + b'{"user": "sub.toto.123", "domain": "some.domain.com"}', ) in dimail_calls diff --git a/src/backend/mailbox_manager/utils/dimail.py b/src/backend/mailbox_manager/utils/dimail.py index fb15111..b319632 100644 --- a/src/backend/mailbox_manager/utils/dimail.py +++ b/src/backend/mailbox_manager/utils/dimail.py @@ -44,18 +44,18 @@ class DimailAPIClient: API_CREDENTIALS = settings.MAIL_PROVISIONING_API_CREDENTIALS API_TIMEOUT = settings.MAIL_PROVISIONING_API_TIMEOUT - def get_headers(self, user_sub=None): + def get_headers(self, request_user=None): """ Build headers dictionary. Requires MAIL_PROVISIONING_API_CREDENTIALS setting, to get a token from dimail /token/ endpoint. - If provided, request user' sub is used for la regie to log in as this user, + If provided, request user' sub is used for la regie to log in on behalf of this user, thus allowing for more precise logs. """ headers = {"Content-Type": "application/json"} params = None - if user_sub: - params = {"username": str(user_sub)} + if request_user: + params = {"username": str(request_user)} response = requests.get( f"{self.API_URL}/token/", @@ -86,7 +86,7 @@ class DimailAPIClient: payload = { "name": domain_name, "context_name": domain_name, # for now, we put each domain on its own context - "features": ["webmail", "mailbox"], + "features": ["webmail", "mailbox", "alias"], "delivery": "virtual", } try: @@ -115,7 +115,7 @@ class DimailAPIClient: return self.raise_exception_for_unexpected_response(response) - def create_mailbox(self, mailbox, user_sub=None): + def create_mailbox(self, mailbox, request_user=None): """Send a CREATE mailbox request to mail provisioning API.""" payload = { @@ -126,7 +126,7 @@ class DimailAPIClient: # displayName value has to be unique "displayName": f"{mailbox.first_name} {mailbox.last_name}", } - headers = self.get_headers(user_sub) + headers = self.get_headers(request_user) try: response = session.post( @@ -148,7 +148,7 @@ class DimailAPIClient: logger.info( "Mailbox successfully created on domain %s by user %s", str(mailbox.domain), - user_sub, + request_user, ) return response @@ -163,10 +163,10 @@ class DimailAPIClient: return self.raise_exception_for_unexpected_response(response) - def create_user(self, user_sub): - """Send a request to dimail, to create a new user there.""" + def create_user(self, user_id): + """Send a request to dimail, to create a new user there. In dimail, user ids are subs.""" - payload = {"name": user_sub, "password": "no", "is_admin": "false", "perms": []} + payload = {"name": user_id, "password": "no", "is_admin": "false", "perms": []} try: response = session.post( @@ -187,24 +187,24 @@ class DimailAPIClient: if response.status_code == status.HTTP_201_CREATED: logger.info( '[DIMAIL] User "%s" successfully created on dimail', - user_sub, + user_id, ) return response if response.status_code == status.HTTP_409_CONFLICT: logger.info( '[DIMAIL] Attempt to create user "%s" which already exists.', - user_sub, + user_id, ) return response return self.raise_exception_for_unexpected_response(response) - def create_allow(self, user_sub, domain_name): + def create_allow(self, user_id, domain_name): """Send a request to dimail for a new 'allow' between user and the domain.""" payload = { - "user": user_sub, + "user": user_id, "domain": domain_name, } @@ -227,7 +227,7 @@ class DimailAPIClient: if response.status_code == status.HTTP_201_CREATED: logger.info( '[DIMAIL] Permissions granted for user "%s" on domain %s.', - user_sub, + user_id, domain_name, ) return response @@ -235,7 +235,7 @@ class DimailAPIClient: if response.status_code == status.HTTP_409_CONFLICT: logger.info( '[DIMAIL] Attempt to create already existing permission between "%s" and "%s".', - user_sub, + user_id, domain_name, ) return response @@ -361,12 +361,12 @@ class DimailAPIClient: ) return imported_mailboxes - def disable_mailbox(self, mailbox, user_sub=None): + def disable_mailbox(self, mailbox, request_user=None): """Send a request to disable a mailbox to dimail API""" response = session.patch( f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}", json={"active": "no"}, - headers=self.get_headers(user_sub), + headers=self.get_headers(request_user), verify=True, timeout=self.API_TIMEOUT, ) @@ -375,12 +375,12 @@ class DimailAPIClient: "Mailbox %s successfully desactivated on domain %s by user %s", str(mailbox), str(mailbox.domain), - user_sub, + request_user, ) return response return self.raise_exception_for_unexpected_response(response) - def enable_mailbox(self, mailbox, user_sub=None): + def enable_mailbox(self, mailbox, request_user=None): """Send a request to enable a mailbox to dimail API""" response = session.patch( f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}", @@ -390,7 +390,7 @@ class DimailAPIClient: "surName": mailbox.last_name, "displayName": f"{mailbox.first_name} {mailbox.last_name}", }, - headers=self.get_headers(user_sub), + headers=self.get_headers(request_user), verify=True, timeout=self.API_TIMEOUT, ) @@ -399,7 +399,7 @@ class DimailAPIClient: "Mailbox %s successfully enabled on domain %s by user %s", str(mailbox), str(mailbox.domain), - user_sub, + request_user, ) return response return self.raise_exception_for_unexpected_response(response)