From 232ea97d87084233b991494ae04734ff695305ea Mon Sep 17 00:00:00 2001 From: Marie PUPO JEAMMET Date: Wed, 18 Sep 2024 11:11:52 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(dimail)=20populate=20dimail=20local?= =?UTF-8?q?=20database=20for=20dev=20use?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this commit adds a script and 'make' command to populate dimail database with basic objects: an admin account, a regie account, a domain and an owner for this domain. --- Makefile | 15 ++ .../mailbox_manager/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/setup_dimail_db.py | 148 ++++++++++++++++++ 4 files changed, 163 insertions(+) create mode 100644 src/backend/mailbox_manager/management/__init__.py create mode 100644 src/backend/mailbox_manager/management/commands/__init__.py create mode 100644 src/backend/mailbox_manager/management/commands/setup_dimail_db.py diff --git a/Makefile b/Makefile index 8feb603fc..8fa308fba 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,7 @@ bootstrap: \ back-i18n-compile \ mails-install \ mails-build \ + setup_dimail_db \ install-front-desk .PHONY: bootstrap @@ -109,6 +110,7 @@ run: ## start the wsgi (production) and development server @$(COMPOSE) up --force-recreate -d app-dev @$(COMPOSE) up --force-recreate -d celery-dev @$(COMPOSE) up --force-recreate -d keycloak + @$(COMPOSE) up -d dimail @echo "Wait for postgresql to be up..." @$(WAIT_KC_DB) @$(WAIT_DB) @@ -129,6 +131,12 @@ demo: ## flush db then create a demo for load testing purpose @$(MANAGE) create_demo .PHONY: demo +reset-dimail-container: + @$(COMPOSE) up --force-recreate -d dimail + @$(MAKE) setup-dimail-db +.PHONY: reset-dimail-container + + # Nota bene: Black should come after isort just in case they don't agree... lint: ## lint back-end python sources lint: \ @@ -272,6 +280,13 @@ i18n-generate-and-upload: \ crowdin-upload .PHONY: i18n-generate-and-upload +# -- INTEROPERABILTY +# -- Dimail configuration + +setup-dimail-db: + @echo "$(BOLD)Populating database of local dimail API container$(RESET)" + @$(MANAGE) setup_dimail_db +.PHONY: setup-dimail-db # -- Mail generator diff --git a/src/backend/mailbox_manager/management/__init__.py b/src/backend/mailbox_manager/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/mailbox_manager/management/commands/__init__.py b/src/backend/mailbox_manager/management/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/mailbox_manager/management/commands/setup_dimail_db.py b/src/backend/mailbox_manager/management/commands/setup_dimail_db.py new file mode 100644 index 000000000..d928b7ef8 --- /dev/null +++ b/src/backend/mailbox_manager/management/commands/setup_dimail_db.py @@ -0,0 +1,148 @@ +"""Management command creating a dimail-api container, for test purposes.""" + +from django.conf import settings +from django.contrib.auth import get_user_model +from django.core.management.base import BaseCommand, CommandError + +import requests +from rest_framework import status + +User = get_user_model() + + +DIMAIL_URL = "http://host.docker.internal:8001" +admin = {"username": "admin", "password": "admin"} +regie = {"username": "la_regie", "password": "password"} + + +class Command(BaseCommand): + """ + Management command populate local dimail database, to ease dev + """ + + help = "Populate local dimail database, for dev purposes." + + def handle(self, *args, **options): + """Handling of the management command.""" + if not settings.DEBUG: + raise CommandError( + ("This command is meant to run in local dev environment.") + ) + + # Create a first superuser for dimail-api container. User creation is usually + # protected behind admin rights but dimail allows to create a first user + # when database is empty + self.create_user( + auth=(None, None), + name=admin["username"], + password=admin["password"], + perms=[], + ) + + # Create Regie user, auth for all remaining requests + # and your own dev + self.create_user( + auth=(admin["username"], admin["password"]), + name=regie["username"], + password=regie["password"], + perms=["new_domain", "create_users", "manage_users"], + ) + + # we create a dimail user for keycloak+regie user John Doe + # This way, la RĂ©gie will be able to make request in the name of + # this user + people_base_user = User.objects.get(name="John Doe") + self.create_user(name=people_base_user.sub, password="whatever") # noqa S106 + + # we create a domain and add John Doe to it + domain_name = "test.domain.com" + self.create_domain(domain_name) + self.create_allows(people_base_user.sub, domain_name) + + self.stdout.write("DONE", ending="\n") + + def create_user( + self, + name, + password, + perms=None, + auth=(regie["username"], regie["password"]), + ): + """ + Send a request to create a new user. + """ + + response = requests.post( + url=f"{DIMAIL_URL}/users/", + json={ + "name": name, + "password": password, + "is_admin": name == admin["username"], + "perms": perms or [], + }, + auth=auth, + timeout=10, + ) + + if response.status_code == status.HTTP_201_CREATED: + self.stdout.write(self.style.SUCCESS(f"Creating user {name}......... OK")) + else: + self.stdout.write( + self.style.ERROR( + f"Creating user {name} ......... failed: {response.json()['detail']}" + ) + ) + + def create_domain(self, name, auth=(regie["username"], regie["password"])): + """ + Send a request to create a new domain. + """ + response = requests.post( + 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: + self.stdout.write( + self.style.SUCCESS(f"Creating domain '{name}' ........ OK") + ) + else: + self.stdout.write( + self.style.ERROR( + f"Creating domain '{name}' ........ failed: {response.json()['detail']}" + ) + ) + + def create_allows(self, user, domain, auth=(regie["username"], regie["password"])): + """ + Send a request to create a new allows between user and domain. + """ + response = requests.post( + url=f"{DIMAIL_URL}/allows/", + json={ + "domain": domain, + "user": user, + }, + auth=auth, + timeout=10, + ) + + if response.status_code == status.HTTP_201_CREATED: + self.stdout.write( + self.style.SUCCESS( + f"Creating permissions for {user} on {domain} ........ OK" + ) + ) + else: + self.stdout.write( + self.style.ERROR( + f"Creating permissions for {user} on {domain}\ + ........ failed: {response.json()['detail']}" + ) + )