This commit is contained in:
Antoine Nguyen
2025-06-08 15:12:49 +02:00
parent ddc471fa48
commit 00806cbff8
10 changed files with 49 additions and 113 deletions
-20
View File
@@ -6,7 +6,6 @@ import ipaddress
import logging
import random
import string
from functools import wraps
from itertools import chain
import dns.resolver
@@ -32,25 +31,6 @@ from . import signals
from .models import Alias, Domain, DomainAlias
def needs_mailbox():
"""Check if the current user owns at least one mailbox
Some applications (the webmail for example) need a mailbox to
work.
"""
def decorator(f):
@wraps(f)
def wrapped_f(request, *args, **kwargs):
if hasattr(request.user, "mailbox"):
return f(request, *args, **kwargs)
raise PermDeniedException(_("A mailbox is required"))
return wrapped_f
return decorator
def get_identities(user, searchquery=None, idtfilter=None, grpfilter=None):
"""Return all the identities owned by a user.
+1 -20
View File
@@ -2,8 +2,7 @@
from django.utils.translation import gettext as _
import django_otp
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
from django_otp.plugins.otp_static.models import StaticToken
from django_otp.plugins.otp_totp.models import TOTPDevice
from rest_framework import permissions, response, viewsets
@@ -33,24 +32,6 @@ class AccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet):
)
return response.Response()
@extend_schema(request=serializers.CheckTFASetupSerializer)
@action(methods=["post"], detail=False, url_path="tfa/setup/check")
def tfa_setup_check(self, request):
"""Check TFA setup."""
serializer = serializers.CheckTFASetupSerializer(
data=request.data, context={"user": request.user}
)
serializer.is_valid(raise_exception=True)
# create static device for recovery purposes
device = StaticDevice.objects.create(
user=request.user, name=f"{request.user} static device"
)
for _cpt in range(10):
token = StaticToken.random_token()
device.token_set.create(token=token)
django_otp.login(self.request, request.user.totpdevice_set.first())
return response.Response()
@action(methods=["post"], detail=False, url_path="tfa/disable")
def tfa_disable(self, request):
"""Disable TFA."""
+4 -31
View File
@@ -8,10 +8,10 @@ from .. import constants
class SMSBackend:
"""Base class of every SMS backend."""
serializer_settings = {}
settings = {}
structure = []
visibility_rules = {}
serializer_settings: dict = {}
settings: dict = {}
structure: list = []
visibility_rules: dict = {}
def __init__(self, params):
"""Default constructor."""
@@ -41,19 +41,6 @@ def get_backend_settings(name):
return backend_class.settings
def get_all_backend_settings():
"""Return settings of all backends."""
settings = {}
for backend in constants.SMS_BACKENDS:
name = backend[0]
if not name:
continue
b_settings = get_backend_settings(name)
if b_settings:
settings.update(b_settings)
return settings
def get_backend_serializer_settings(name):
"""Return serializer settings of given backend."""
backend_class = get_backend_class(name)
@@ -96,20 +83,6 @@ def get_all_backend_structures():
return structure
def get_all_backend_visibility_rules():
"""Return visibility rules of all backends."""
rules = {}
for backend in constants.SMS_BACKENDS:
name = backend[0]
if not name:
continue
backend_class = get_backend_class(name)
if not backend_class:
continue
rules.update(backend_class.visibility_rules)
return rules
def get_active_backend(parameters):
"""Return active SMS backend."""
name = parameters.get_value("sms_provider")
-26
View File
@@ -1,26 +0,0 @@
from django.conf import settings
from django.db import connection
from django.utils.translation import gettext as _
from modoboa.lib.exceptions import InternalError
def db_table_exists(table):
"""Check if table exists."""
return table in connection.introspection.table_names()
def db_type(cname="default"):
"""Return the type of the *default* database
Supported values : 'postgres', 'mysql', 'sqlite'
:param str cname: connection name
:return: a string or None
"""
if cname not in settings.DATABASES:
raise InternalError(_("Connection to database {} not configured".format(cname)))
for t in ["postgres", "mysql", "sqlite"]:
if settings.DATABASES[cname]["ENGINE"].find(t) != -1:
return t
return None
-13
View File
@@ -4,23 +4,10 @@ Form rendering tags.
from django import forms, template
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag
def render_form(form, tpl=None):
"""Render a form."""
if tpl is not None:
return render_to_string(tpl, {"form": form})
ret = ""
for field in form:
ret += f"{render_field(field)}\n"
return mark_safe(ret)
def configure_field_classes(field):
"""Add required CSS classes to field."""
if isinstance(field.field.widget, forms.CheckboxInput) or isinstance(
+7 -1
View File
@@ -189,6 +189,12 @@ class ParametersMixin:
class SimpleModoTestCase(ParametersMixin, TestCase):
"""Simple class to add parameters editing."""
@classmethod
def setUpTestData(cls): # noqa
"""Create a default user."""
super().setUpTestData()
management.call_command("load_initial_data", "--no-frontend")
class ModoTestCase(ParametersMixin, TestCase):
"""All test cases must inherit from this one."""
@@ -234,7 +240,7 @@ class ModoAPITestCase(ParametersMixin, APITestCase):
def setUpTestData(cls): # noqa
"""Create a default user."""
super().setUpTestData()
management.call_command("load_initial_data")
management.call_command("load_initial_data", "--no-frontend")
cls.sadmin = core_models.User.objects.get(username="admin")
cls.token = Token.objects.create(user=cls.sadmin)
+25
View File
@@ -5,6 +5,7 @@ from dateutil.relativedelta import relativedelta
from django.urls import reverse
from django.utils import timezone
from modoboa.core import models as core_models
from modoboa.admin import factories as admin_factories, models
from modoboa.lib.tests import ModoAPITestCase
from modoboa.maillog import factories
@@ -12,11 +13,21 @@ from modoboa.maillog import factories
class StatisticsViewSetTestCase(ModoAPITestCase):
@classmethod
def setUpTestData(cls): # NOQA:N802
"""Create test data."""
super().setUpTestData()
admin_factories.populate_database()
def test_list(self):
url = reverse("v2:statistics-list")
resp = self.client.get(url + "?gset=mailtraffic&period=day")
self.assertEqual(resp.status_code, 200)
self.set_global_parameter("greylist", True)
resp = self.client.get(url + "?gset=mailtraffic&period=day")
self.assertEqual(resp.status_code, 200)
resp = self.client.get(url + "?gset=mailtraffic&period=custom&start=2021-05-01")
self.assertEqual(resp.status_code, 400)
@@ -25,6 +36,20 @@ class StatisticsViewSetTestCase(ModoAPITestCase):
)
self.assertEqual(resp.status_code, 200)
def test_list_as_domain_admin(self):
account = core_models.User.objects.get(username="admin@test.com")
self.authenticate_user(account)
url = reverse("v2:statistics-list")
resp = self.client.get(
url + "?gset=mailtraffic&period=day&searchquery=test.com"
)
self.assertEqual(resp.status_code, 200)
resp = self.client.get(
url + "?gset=mailtraffic&period=day&searchquery=test2.com"
)
self.assertEqual(resp.status_code, 403)
class MaillogViewSetTestCase(ModoAPITestCase):
+2 -2
View File
@@ -10,7 +10,7 @@ from django.core.management import call_command
from django.test import override_settings
from modoboa.admin import factories as admin_factories
from modoboa.lib.tests import ModoTestCase
from modoboa.lib.tests import SimpleModoTestCase
class RunCommandsMixin:
@@ -47,7 +47,7 @@ class RunCommandsMixin:
@override_settings(RRDTOOL_TEST_MODE=True)
class ManagementCommandsTestCase(RunCommandsMixin, ModoTestCase):
class ManagementCommandsTestCase(RunCommandsMixin, SimpleModoTestCase):
"""Management command test cases."""
@classmethod
+10
View File
@@ -36,6 +36,16 @@ class PDFCredentialViewTestCase(ModoAPITestCase):
self.assertEqual(resp.status_code, expected_status)
return data
def test_link_present_in_account_actions(self):
"""Check if link is present after creation."""
self._create_account("leon@test.com")
url = reverse("v2:identities-list")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
for item in response.json():
if item["identity"] == "leon@test.com":
self.assertEqual(item["possible_actions"][0]["name"], "get_credentials")
def test_pdfcredentials_disabled(self):
self.set_global_parameter("enabled_pdfcredentials", False)
values = self._create_account("leon5@test.com")