diff --git a/modoboa/admin/lib.py b/modoboa/admin/lib.py index 9715c06c7..7d75b1725 100644 --- a/modoboa/admin/lib.py +++ b/modoboa/admin/lib.py @@ -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. diff --git a/modoboa/core/api/v1/viewsets.py b/modoboa/core/api/v1/viewsets.py index 2f4dad928..f757e9b9c 100644 --- a/modoboa/core/api/v1/viewsets.py +++ b/modoboa/core/api/v1/viewsets.py @@ -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.""" diff --git a/modoboa/core/sms_backends/__init__.py b/modoboa/core/sms_backends/__init__.py index 4f8ebb532..2fe795716 100644 --- a/modoboa/core/sms_backends/__init__.py +++ b/modoboa/core/sms_backends/__init__.py @@ -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") diff --git a/modoboa/lib/db_utils.py b/modoboa/lib/db_utils.py deleted file mode 100644 index c817394c8..000000000 --- a/modoboa/lib/db_utils.py +++ /dev/null @@ -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 diff --git a/modoboa/lib/templatetags/form_tags.py b/modoboa/lib/templatetags/form_tags.py index 50e6aaeb3..9c568cb41 100644 --- a/modoboa/lib/templatetags/form_tags.py +++ b/modoboa/lib/templatetags/form_tags.py @@ -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( diff --git a/modoboa/lib/tests/__init__.py b/modoboa/lib/tests/__init__.py index 757fc52ef..e1b5c3efb 100644 --- a/modoboa/lib/tests/__init__.py +++ b/modoboa/lib/tests/__init__.py @@ -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) diff --git a/modoboa/maillog/api/v2/tests.py b/modoboa/maillog/api/v2/tests.py index 50e020a24..80b7e696a 100644 --- a/modoboa/maillog/api/v2/tests.py +++ b/modoboa/maillog/api/v2/tests.py @@ -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): diff --git a/modoboa/maillog/tests/test_views.py b/modoboa/maillog/tests/test_views.py index be67411f3..bdae83b2d 100644 --- a/modoboa/maillog/tests/test_views.py +++ b/modoboa/maillog/tests/test_views.py @@ -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 diff --git a/modoboa/pdfcredentials/api/__init__.py b/modoboa/pdfcredentials/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/modoboa/pdfcredentials/api/v2/tests.py b/modoboa/pdfcredentials/api/v2/tests.py index 4b8d92766..37c3d312a 100644 --- a/modoboa/pdfcredentials/api/v2/tests.py +++ b/modoboa/pdfcredentials/api/v2/tests.py @@ -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")