♻️(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:
@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

View File

@@ -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)

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.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

View File

@@ -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)