♻️(dimail) refacto setup_dimail_db to call dimail client

Management command "setup_dimail_db" called dimail directly, thus
creating duplicated code. It now calls "create_domain" and "create_allow"
methods from DimailAPIClient (create_user is left unchanged to create
special users such as dimail admin or people)
This commit is contained in:
Marie PUPO JEAMMET
2025-03-19 18:59:30 +01:00
committed by Marie
parent 28fdee868d
commit 8cbedeb76e
4 changed files with 43 additions and 55 deletions

View File

@@ -296,7 +296,7 @@ recreate-dimail-container:
dimail-setup-db: dimail-setup-db:
@echo "$(BOLD)Populating database of local dimail API container$(RESET)" @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 .PHONY: dimail-setup-db
# -- Mail generator # -- Mail generator

View File

@@ -9,6 +9,7 @@ from rest_framework import status
from mailbox_manager import enums from mailbox_manager import enums
from mailbox_manager.models import MailDomain, MailDomainAccess from mailbox_manager.models import MailDomain, MailDomainAccess
from mailbox_manager.utils.dimail import DimailAPIClient
User = get_user_model() User = get_user_model()
@@ -23,6 +24,8 @@ class Command(BaseCommand):
Management command populate local dimail database, to ease dev Management command populate local dimail database, to ease dev
""" """
client = DimailAPIClient()
help = "Populate local dimail database, for dev purposes." help = "Populate local dimail database, for dev purposes."
def add_arguments(self, parser): def add_arguments(self, parser):
@@ -84,7 +87,7 @@ class Command(BaseCommand):
else: else:
# create accesses for john doe # create accesses for john doe
self.create_user(name=people_base_user.sub) 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( MailDomainAccess.objects.get_or_create(
user=people_base_user, user=people_base_user,
domain=domain, 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( response = self.client.create_domain(name, request_user="setup_dimail_db.py")
url=f"{DIMAIL_URL}/domains/",
json={
"name": name,
"context_name": "context",
"features": ["webmail", "mailbox", "alias"],
},
auth=auth,
timeout=10,
)
if response.status_code == status.HTTP_201_CREATED: if response.status_code == status.HTTP_201_CREATED:
self.stdout.write( 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( response = self.client.create_allow(user, domain)
url=f"{DIMAIL_URL}/allows/",
json={
"domain": domain,
"user": user,
},
auth=auth,
timeout=10,
)
if response.status_code == status.HTTP_201_CREATED: if response.status_code == status.HTTP_201_CREATED:
self.stdout.write( self.stdout.write(
@@ -216,4 +202,4 @@ class Command(BaseCommand):
# create missing accesses # create missing accesses
for access in access_to_create: for access in access_to_create:
self.create_allows(access.user.sub, access.domain.name) self.create_allow(access.user.sub, access.domain.name)

View File

@@ -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.url == f"{DIMAIL_URL}/domains/"
assert responses.calls[2].request.body == ( assert responses.calls[2].request.body == (
b'{"name": "test.domain.com", "context_name": "context", ' b'{"name": "test.domain.com", "context_name": "test.domain.com", '
b'"features": ["webmail", "mailbox", "alias"]}' b'"features": ["webmail", "mailbox", "alias"], '
b'"delivery": "virtual"}'
) )
assert responses.calls[3].request.url == f"{DIMAIL_URL}/users/" 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.url == f"{DIMAIL_URL}/allows/"
assert ( assert (
responses.calls[4].request.body 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 # reset the responses counter
@@ -112,8 +113,9 @@ def test_commands_setup_dimail_db(settings):
assert ( assert (
f"{DIMAIL_URL}/domains/", f"{DIMAIL_URL}/domains/",
( (
b'{"name": "some.domain.com", "context_name": "context", ' b'{"name": "some.domain.com", "context_name": "some.domain.com", '
b'"features": ["webmail", "mailbox", "alias"]}' b'"features": ["webmail", "mailbox", "alias"], '
b'"delivery": "virtual"}'
), ),
) in dimail_calls ) in dimail_calls
@@ -124,5 +126,5 @@ def test_commands_setup_dimail_db(settings):
assert ( assert (
f"{DIMAIL_URL}/allows/", 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 ) in dimail_calls

View File

@@ -44,18 +44,18 @@ class DimailAPIClient:
API_CREDENTIALS = settings.MAIL_PROVISIONING_API_CREDENTIALS API_CREDENTIALS = settings.MAIL_PROVISIONING_API_CREDENTIALS
API_TIMEOUT = settings.MAIL_PROVISIONING_API_TIMEOUT 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, Build headers dictionary. Requires MAIL_PROVISIONING_API_CREDENTIALS setting,
to get a token from dimail /token/ endpoint. 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. thus allowing for more precise logs.
""" """
headers = {"Content-Type": "application/json"} headers = {"Content-Type": "application/json"}
params = None params = None
if user_sub: if request_user:
params = {"username": str(user_sub)} params = {"username": str(request_user)}
response = requests.get( response = requests.get(
f"{self.API_URL}/token/", f"{self.API_URL}/token/",
@@ -86,7 +86,7 @@ class DimailAPIClient:
payload = { payload = {
"name": domain_name, "name": domain_name,
"context_name": domain_name, # for now, we put each domain on its own context "context_name": domain_name, # for now, we put each domain on its own context
"features": ["webmail", "mailbox"], "features": ["webmail", "mailbox", "alias"],
"delivery": "virtual", "delivery": "virtual",
} }
try: try:
@@ -115,7 +115,7 @@ class DimailAPIClient:
return self.raise_exception_for_unexpected_response(response) 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.""" """Send a CREATE mailbox request to mail provisioning API."""
payload = { payload = {
@@ -126,7 +126,7 @@ class DimailAPIClient:
# displayName value has to be unique # displayName value has to be unique
"displayName": f"{mailbox.first_name} {mailbox.last_name}", "displayName": f"{mailbox.first_name} {mailbox.last_name}",
} }
headers = self.get_headers(user_sub) headers = self.get_headers(request_user)
try: try:
response = session.post( response = session.post(
@@ -148,7 +148,7 @@ class DimailAPIClient:
logger.info( logger.info(
"Mailbox successfully created on domain %s by user %s", "Mailbox successfully created on domain %s by user %s",
str(mailbox.domain), str(mailbox.domain),
user_sub, request_user,
) )
return response return response
@@ -163,10 +163,10 @@ class DimailAPIClient:
return self.raise_exception_for_unexpected_response(response) return self.raise_exception_for_unexpected_response(response)
def create_user(self, user_sub): def create_user(self, user_id):
"""Send a request to dimail, to create a new user there.""" """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: try:
response = session.post( response = session.post(
@@ -187,24 +187,24 @@ class DimailAPIClient:
if response.status_code == status.HTTP_201_CREATED: if response.status_code == status.HTTP_201_CREATED:
logger.info( logger.info(
'[DIMAIL] User "%s" successfully created on dimail', '[DIMAIL] User "%s" successfully created on dimail',
user_sub, user_id,
) )
return response return response
if response.status_code == status.HTTP_409_CONFLICT: if response.status_code == status.HTTP_409_CONFLICT:
logger.info( logger.info(
'[DIMAIL] Attempt to create user "%s" which already exists.', '[DIMAIL] Attempt to create user "%s" which already exists.',
user_sub, user_id,
) )
return response return response
return self.raise_exception_for_unexpected_response(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.""" """Send a request to dimail for a new 'allow' between user and the domain."""
payload = { payload = {
"user": user_sub, "user": user_id,
"domain": domain_name, "domain": domain_name,
} }
@@ -227,7 +227,7 @@ class DimailAPIClient:
if response.status_code == status.HTTP_201_CREATED: if response.status_code == status.HTTP_201_CREATED:
logger.info( logger.info(
'[DIMAIL] Permissions granted for user "%s" on domain %s.', '[DIMAIL] Permissions granted for user "%s" on domain %s.',
user_sub, user_id,
domain_name, domain_name,
) )
return response return response
@@ -235,7 +235,7 @@ class DimailAPIClient:
if response.status_code == status.HTTP_409_CONFLICT: if response.status_code == status.HTTP_409_CONFLICT:
logger.info( logger.info(
'[DIMAIL] Attempt to create already existing permission between "%s" and "%s".', '[DIMAIL] Attempt to create already existing permission between "%s" and "%s".',
user_sub, user_id,
domain_name, domain_name,
) )
return response return response
@@ -361,12 +361,12 @@ class DimailAPIClient:
) )
return imported_mailboxes 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""" """Send a request to disable a mailbox to dimail API"""
response = session.patch( response = session.patch(
f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}", f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}",
json={"active": "no"}, json={"active": "no"},
headers=self.get_headers(user_sub), headers=self.get_headers(request_user),
verify=True, verify=True,
timeout=self.API_TIMEOUT, timeout=self.API_TIMEOUT,
) )
@@ -375,12 +375,12 @@ class DimailAPIClient:
"Mailbox %s successfully desactivated on domain %s by user %s", "Mailbox %s successfully desactivated on domain %s by user %s",
str(mailbox), str(mailbox),
str(mailbox.domain), str(mailbox.domain),
user_sub, request_user,
) )
return response return response
return self.raise_exception_for_unexpected_response(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""" """Send a request to enable a mailbox to dimail API"""
response = session.patch( response = session.patch(
f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}", f"{self.API_URL}/domains/{mailbox.domain.name}/mailboxes/{mailbox.local_part}",
@@ -390,7 +390,7 @@ class DimailAPIClient:
"surName": mailbox.last_name, "surName": mailbox.last_name,
"displayName": f"{mailbox.first_name} {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, verify=True,
timeout=self.API_TIMEOUT, timeout=self.API_TIMEOUT,
) )
@@ -399,7 +399,7 @@ class DimailAPIClient:
"Mailbox %s successfully enabled on domain %s by user %s", "Mailbox %s successfully enabled on domain %s by user %s",
str(mailbox), str(mailbox),
str(mailbox.domain), str(mailbox.domain),
user_sub, request_user,
) )
return response return response
return self.raise_exception_for_unexpected_response(response) return self.raise_exception_for_unexpected_response(response)