From 33005248c9ddbf9c03eafc75139daaf3a550e6d1 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Mon, 28 Jul 2025 11:36:51 +0200 Subject: [PATCH] WIP: amavis quarantine frontend --- .dockerignore | 1 + .gitignore | 3 +- docker-compose.yml | 11 +++++ docker/Dockerfile.dev | 9 ++-- frontend/src/api/amavis.js | 7 +++ .../components/quarantine/QuarantineList.vue | 49 +++++++++++++++++++ frontend/src/router/index.js | 17 +++++++ .../src/views/quarantine/QuarantineView.vue | 11 +++++ modoboa/core/api/v2/viewsets.py | 10 ++++ .../management/commands/load_initial_data.py | 10 ++++ modoboa/urls_api_v2.py | 6 +++ test_project/test_project/settings.py | 15 ++++++ 12 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 frontend/src/api/amavis.js create mode 100644 frontend/src/components/quarantine/QuarantineList.vue create mode 100644 frontend/src/views/quarantine/QuarantineView.vue diff --git a/.dockerignore b/.dockerignore index ac3ce9c2f..da809c15f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,7 @@ build dist frontend/node_modules modoboa.egg-info +docker/mariadb .tox diff --git a/.gitignore b/.gitignore index 31a3fa9ed..750781646 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ node_modules /static/dist /frontend/webpack-stats.json /frontend/src/translations.json -/frontend/.__mf__temp/ +/frontend/.__mf__temp/ # TOX stuff test_project/modoboa.db @@ -43,3 +43,4 @@ test_project/media # Docker docker/collections docker/redis +docker/mariadb diff --git a/docker-compose.yml b/docker-compose.yml index dbb56a62d..bf0627510 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,17 @@ services: LDAP_ADMIN_PASSWORD: test profiles: [ldap] + mariadb: + image: mariadb:10 + restart: unless-stopped + environment: + MARIADB_ROOT_PASSWORD: Password1000 + MARIADB_DATABASE: amavis + + volumes: + - ./docker/mariadb:/var/lib/mysql + profiles: [mariadb] + rq: build: context: . diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 84410fbc9..71d868a2f 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -9,25 +9,26 @@ FROM base AS build RUN apk add --update openssl librrd python3-dev libffi-dev \ gcc g++ musl-dev libxml2-dev libxslt-dev \ - libressl-dev jpeg-dev rrdtool-dev file make \ + openssl-dev jpeg-dev rrdtool-dev file make \ gettext freetype-dev cairo-dev cargo git \ - openldap-dev \ + mariadb-dev openldap-dev \ && rm -rf /var/cache/apk/* RUN python3 -m venv $VIRTUAL_ENV WORKDIR /tmp COPY . /tmp RUN python -m pip install -U pip pip-tools ruff RUN pip-compile --output-file=requirements.txt pyproject.toml +RUN pip-compile --extra=mysql --output-file=mysql-requirements.txt pyproject.toml RUN pip-compile --extra=ldap --output-file=ldap-requirements.txt pyproject.toml RUN pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml RUN pip-compile --extra=test --output-file=test-requirements.txt pyproject.toml -RUN pip install -r requirements.txt -r ldap-requirements.txt -r test-requirements.txt -r dev-requirements.txt +RUN pip install -r requirements.txt -r mysql-requirements.txt -r ldap-requirements.txt -r test-requirements.txt -r dev-requirements.txt FROM base AS run COPY docker/doveadm /usr/local/bin RUN chmod +x /usr/local/bin/doveadm COPY --from=build $VIRTUAL_ENV $VIRTUAL_ENV -RUN apk add --no-cache --update openssl librrd libxslt libjpeg libressl git rrdtool libmagic sudo sqlite libldap \ +RUN apk add --no-cache --update openssl librrd libxslt libjpeg libressl git rrdtool libmagic sudo sqlite libldap mariadb-connector-c \ && rm -rf /var/cache/apk/* RUN mkdir /code WORKDIR /code diff --git a/frontend/src/api/amavis.js b/frontend/src/api/amavis.js new file mode 100644 index 000000000..7d6bb008b --- /dev/null +++ b/frontend/src/api/amavis.js @@ -0,0 +1,7 @@ +import repository from './repository' + +export default { + getQuarantineContent(params) { + return repository.get('/amavis/quarantine/', { params }) + }, +} diff --git a/frontend/src/components/quarantine/QuarantineList.vue b/frontend/src/components/quarantine/QuarantineList.vue new file mode 100644 index 000000000..84aa30bc5 --- /dev/null +++ b/frontend/src/components/quarantine/QuarantineList.vue @@ -0,0 +1,49 @@ + + + diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index 5a5ca046c..dbabfaa39 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -426,6 +426,23 @@ const routes = [ }, ], }, + { + path: 'quarantine', + component: () => import('@/layouts/user/UserLayout.vue'), + meta: { + requiresAuth: true, + }, + children: [ + { + path: '', + name: 'QuarantineView', + component: () => import('@/views/quarantine/QuarantineView.vue'), + meta: { + requiresAuth: true, + }, + }, + ], + }, ], }, { diff --git a/frontend/src/views/quarantine/QuarantineView.vue b/frontend/src/views/quarantine/QuarantineView.vue new file mode 100644 index 000000000..49e18c62e --- /dev/null +++ b/frontend/src/views/quarantine/QuarantineView.vue @@ -0,0 +1,11 @@ + + + diff --git a/modoboa/core/api/v2/viewsets.py b/modoboa/core/api/v2/viewsets.py index 643848234..3ec528978 100644 --- a/modoboa/core/api/v2/viewsets.py +++ b/modoboa/core/api/v2/viewsets.py @@ -177,6 +177,16 @@ class AccountViewSet(core_v1_viewsets.AccountViewSet): "url": "/admin", } ) + if "modoboa.amavis" in settings.MODOBOA_APPS: + apps.append( + { + "name": "amavis", + "label": _("Quarantine"), + "icon": "mdi-server-security", + "description": _("Amavis quarantine"), + "url": "/user/quarantine", + } + ) if hasattr(request.user, "mailbox"): if "modoboa.contacts" in settings.MODOBOA_APPS: apps += [ diff --git a/modoboa/core/management/commands/load_initial_data.py b/modoboa/core/management/commands/load_initial_data.py index 318bd9bbd..c15df8ea7 100644 --- a/modoboa/core/management/commands/load_initial_data.py +++ b/modoboa/core/management/commands/load_initial_data.py @@ -192,3 +192,13 @@ class Command(BaseCommand): }} """ ) + + +# ADD SIGNAL FOR THAT +# def load_initial_data(self): +# """Create records for existing domains and co.""" +# for dom in Domain.objects.all(): +# policy = create_user_and_policy("@{0}".format(dom.name)) +# for domalias in dom.domainalias_set.all(): +# domalias_pattern = "@{0}".format(domalias.name) +# create_user_and_use_policy(domalias_pattern, policy) diff --git a/modoboa/urls_api_v2.py b/modoboa/urls_api_v2.py index fd1e0b964..e6a77591e 100644 --- a/modoboa/urls_api_v2.py +++ b/modoboa/urls_api_v2.py @@ -1,5 +1,6 @@ """External API urls.""" +from django.conf import settings from django.urls import include, path from modoboa.core.extensions import exts_pool @@ -25,4 +26,9 @@ urlpatterns = [ path("webmail/", include("modoboa.webmail.urls")), ] +if "modoboa.amavis" in settings.MODOBOA_APPS: + urlpatterns += [ + path("amavis/", include("modoboa.amavis.urls")), + ] + urlpatterns += exts_pool.get_urls(category="api") diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py index 441d410ab..2fbb5e308 100644 --- a/test_project/test_project/settings.py +++ b/test_project/test_project/settings.py @@ -104,6 +104,7 @@ MODOBOA_APPS = ( "modoboa.contacts", "modoboa.calendars", "modoboa.webmail", + "modoboa.amavis", ) try: @@ -376,6 +377,7 @@ LOGGING = { SILENCED_SYSTEM_CHECKS = [ "security.W019", # modoboa uses iframes to display e-mails + "fields.W342", ] DISABLE_DASHBOARD_EXTERNAL_QUERIES = False @@ -387,3 +389,16 @@ LDAP_SERVER_PORT = os.environ.get("LDAP_SERVER_PORT", 3389) WEBMAIL_DEV_MODE = os.environ.get("WEBMAIL_DEV_MODE", "off") == "on" WEBMAIL_DEV_USERNAME = os.environ.get("WEBMAIL_DEV_USERNAME", "") WEBMAIL_DEV_PASSWORD = os.environ.get("WEBMAIL_DEV_PASSWORD", "") + +# Amavis + +DATABASES["amavis"] = { # NOQA + "ENGINE": "django.db.backends.mysql", + "HOST": "mariadb", + "NAME": "amavis", + "USER": "root", + "PASSWORD": "Password1000", +} + +DATABASE_ROUTERS = ["modoboa.amavis.dbrouter.AmavisRouter"] +AMAVIS_DEFAULT_DATABASE_ENCODING = "LATIN1"