Skip to content

Commit

Permalink
✨(plugin) add CommuneCreation plugin
Browse files Browse the repository at this point in the history
Add unit tests and refactor name normalization and zone naming.
  • Loading branch information
Laurent Bossavit authored and Laurent Bossavit committed Feb 10, 2025
1 parent 20f2db4 commit 0441ee1
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to

### Added

- ✨(plugin) add CommuneCreation plugin with domain provisioning #658
- ✨(frontend) display action required status on domain
- ✨(domains) store last health check details on MailDomain
- ✨(domains) add support email field on domain
Expand Down
29 changes: 22 additions & 7 deletions src/backend/plugins/organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import logging

from django.conf import settings
from django.utils.text import slugify
import re

import requests
from requests.adapters import HTTPAdapter, Retry
Expand Down Expand Up @@ -139,6 +141,8 @@ def get_organization_name_from_results(self, data, siret):

def dns_call(self, spec):
"""Call to add a DNS record"""
zone_name = self.zone_name(spec.inputs['name'])

records = [
{
"name": item["target"],
Expand All @@ -152,15 +156,23 @@ def dns_call(self, spec):
result.method = "PATCH"
result.base = "https://api.scaleway.com"
result.url = (
f"/domain/v2beta1/dns-zones/{spec.inputs['name']}.collectivite.fr/records"
f"/domain/v2beta1/dns-zones/{zone_name}/records"
)
result.params = {"changes": [{"add": {"records": records}}]}
result.headers = {"X-Auth-Token": settings.DNS_PROVISIONING_API_CREDENTIALS}
return result

def normalize_name(self, name: str) -> str:
name = re.sub("'","-", name)
return slugify(name)

def zone_name(self, name: str) -> str:
normalized = self.normalize_name(name)
return f"{normalized}.collectivite.fr"

def complete_commune_creation(self, name: str) -> ApiCall:
"""Specify the tasks to be completed after a commune is created."""
inputs = {"name": name.lower()}
inputs = {"name": self.normalize_name(name)}

create_zone = ApiCall()
create_zone.method = "POST"
Expand All @@ -175,15 +187,17 @@ def complete_commune_creation(self, name: str) -> ApiCall:
"X-Auth-Token": settings.DNS_PROVISIONING_API_CREDENTIALS
}

zone_name = self.zone_name(inputs['name'])

create_domain = ApiCall()
create_domain.method = "POST"
create_domain.base = settings.MAIL_PROVISIONING_API_URL
create_domain.url = "/domains"
create_domain.params = {
"name": f"{inputs['name']}.collectivite.fr",
"name": zone_name,
"delivery": "virtual",
"features": ["webmail", "mailbox"],
"context_name": f"{inputs['name']}.collectivite.fr",
"context_name": zone_name,
}
create_domain.headers = {
"Authorization": f"Basic {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
Expand All @@ -192,7 +206,7 @@ def complete_commune_creation(self, name: str) -> ApiCall:
spec_domain = ApiCall()
spec_domain.inputs = inputs
spec_domain.base = settings.MAIL_PROVISIONING_API_URL
spec_domain.url = f"/domains/{inputs['name']}.collectivite.fr/spec"
spec_domain.url = f"/domains/{zone_name}/spec"
spec_domain.headers = {
"Authorization": f"Basic {settings.MAIL_PROVISIONING_API_CREDENTIALS}"
}
Expand Down Expand Up @@ -234,7 +248,8 @@ def run_after_create(self, organization):
organization.save(update_fields=["name", "updated_at"])
logger.info("Organization %s name updated to %s", organization, name)

MailDomain.objects.get_or_create(name=f"{name.lower()}.collectivite.fr")
zone_name = self.zone_name(name)
MailDomain.objects.get_or_create(name=zone_name)

# Compute and execute the rest of the process
tasks = self.complete_commune_creation(name)
Expand All @@ -247,7 +262,7 @@ def run_after_grant_access(self, organization_access):
"""After granting an organization access, check for needed domain access grant."""
orga = organization_access.organization
user = organization_access.user
zone_name = orga.name.lower() + ".collectivite.fr"
zone_name = self.zone_name(orga.name)

try:
domain = MailDomain.objects.get(name=zone_name)
Expand Down
13 changes: 13 additions & 0 deletions src/backend/plugins/tests/organizations/test_commune_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,16 @@ def test_tasks_on_commune_creation_include_dns_records():
assert (
zone_call.headers["X-Auth-Token"] == settings.DNS_PROVISIONING_API_CREDENTIALS
)

def test_normalize_name():
plugin = CommuneCreation()
assert plugin.normalize_name("Asnières-sur-Saône") == "asnieres-sur-saone"
assert plugin.normalize_name("Bâgé-le-Châtel") == "bage-le-chatel"
assert plugin.normalize_name("Courçais") == "courcais"
assert plugin.normalize_name("Moÿ-de-l'Aisne") == "moy-de-l-aisne"
assert plugin.normalize_name("Salouël") == "salouel"
assert plugin.normalize_name("Bors (Canton de Tude-et-Lavalette)") == "bors-canton-de-tude-et-lavalette"

def test_zone_name():
plugin = CommuneCreation()
assert plugin.zone_name("Bâgé-le-Châtel") == "bage-le-chatel.collectivite.fr"

0 comments on commit 0441ee1

Please sign in to comment.