89 lines
2.8 KiB
Python
89 lines
2.8 KiB
Python
|
|
"""A minimalist client to synchronize with mailbox provisioning API."""
|
||
|
|
|
||
|
|
from logging import getLogger
|
||
|
|
|
||
|
|
from django.conf import settings
|
||
|
|
from django.core import exceptions
|
||
|
|
|
||
|
|
import requests
|
||
|
|
from rest_framework import status
|
||
|
|
from urllib3.util import Retry
|
||
|
|
|
||
|
|
logger = getLogger(__name__)
|
||
|
|
|
||
|
|
adapter = requests.adapters.HTTPAdapter(
|
||
|
|
max_retries=Retry(
|
||
|
|
total=4,
|
||
|
|
backoff_factor=0.1,
|
||
|
|
status_forcelist=[500, 502],
|
||
|
|
allowed_methods=["PATCH"],
|
||
|
|
)
|
||
|
|
)
|
||
|
|
|
||
|
|
session = requests.Session()
|
||
|
|
session.mount("http://", adapter)
|
||
|
|
session.mount("https://", adapter)
|
||
|
|
|
||
|
|
|
||
|
|
class DimailAPIClient:
|
||
|
|
"""A dimail-API client."""
|
||
|
|
|
||
|
|
def get_headers(self, domain):
|
||
|
|
"""Build header dict from domain object."""
|
||
|
|
# self.secret is the encoded basic auth, to request a new token from dimail-api
|
||
|
|
headers = {"Content-Type": "application/json"}
|
||
|
|
|
||
|
|
response = requests.get(
|
||
|
|
f"{settings.MAIL_PROVISIONING_API_URL}/token/",
|
||
|
|
headers={"Authorization": f"Basic {domain.secret}"},
|
||
|
|
timeout=status.HTTP_200_OK,
|
||
|
|
)
|
||
|
|
|
||
|
|
if response.json() == "{'detail': 'Permission denied'}":
|
||
|
|
raise exceptions.PermissionDenied(
|
||
|
|
"This secret does not allow for a new token."
|
||
|
|
)
|
||
|
|
|
||
|
|
if "access_token" in response.json():
|
||
|
|
headers["Authorization"] = f"Bearer {response.json()['access_token']}"
|
||
|
|
|
||
|
|
return headers
|
||
|
|
|
||
|
|
def send_mailbox_request(self, mailbox):
|
||
|
|
"""Send a CREATE mailbox request to mail provisioning API."""
|
||
|
|
|
||
|
|
payload = {
|
||
|
|
"email": f"{mailbox.local_part}@{mailbox.domain}",
|
||
|
|
"givenName": mailbox.first_name,
|
||
|
|
"surName": mailbox.last_name,
|
||
|
|
"displayName": f"{mailbox.first_name} {mailbox.last_name}",
|
||
|
|
}
|
||
|
|
|
||
|
|
try:
|
||
|
|
response = session.post(
|
||
|
|
f"{settings.MAIL_PROVISIONING_API_URL}/domains/{mailbox.domain}/mailboxes/",
|
||
|
|
json=payload,
|
||
|
|
headers=self.get_headers(mailbox.domain),
|
||
|
|
verify=True,
|
||
|
|
timeout=10,
|
||
|
|
)
|
||
|
|
except requests.exceptions.ConnectionError as e:
|
||
|
|
logger.error(
|
||
|
|
"Connection error while trying to reach %s.",
|
||
|
|
settings.MAIL_PROVISIONING_API_URL,
|
||
|
|
exc_info=e,
|
||
|
|
)
|
||
|
|
|
||
|
|
if response.status_code == status.HTTP_201_CREATED:
|
||
|
|
extra = {"response": response.content.decode("utf-8")}
|
||
|
|
# This a temporary broken solution. Password will soon be sent
|
||
|
|
# from OX servers but their prod is not ready.
|
||
|
|
# In the meantime, we log mailbox info (including password !)
|
||
|
|
logger.info(
|
||
|
|
"Mailbox successfully created on domain %s",
|
||
|
|
mailbox.domain.name,
|
||
|
|
extra=extra,
|
||
|
|
)
|
||
|
|
|
||
|
|
return response
|