Added unit tests about parameters API.

This commit is contained in:
Antoine Nguyen
2021-06-02 11:23:00 +02:00
parent 8aa155b6a6
commit 812608978f
6 changed files with 284 additions and 14 deletions
+22 -14
View File
@@ -39,7 +39,7 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
update_scheme = serializers.BooleanField(default=True)
default_password = serializers.CharField(default="password")
random_password_length = serializers.IntegerField(min_value=8, default=8)
update_password_url = serializers.URLField(required=False)
update_password_url = serializers.URLField(required=False, allow_blank=True)
password_recovery_msg = serializers.CharField(
required=False, allow_blank=True)
sms_password_recovery = serializers.BooleanField(default=False)
@@ -86,14 +86,16 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
default="", required=False, allow_blank=True)
# LDAP sync settings
ldap_sync_bind_dn = serializers.CharField(required=False)
ldap_sync_bind_password = serializers.CharField(required=False)
ldap_sync_bind_dn = serializers.CharField(required=False, allow_blank=True)
ldap_sync_bind_password = serializers.CharField(
required=False, allow_blank=True)
ldap_enable_sync = serializers.BooleanField(default=False)
ldap_sync_delete_remote_account = serializers.BooleanField(default=False)
ldap_sync_account_dn_template = serializers.CharField(
required=False, allow_blank=True)
ldap_enable_import = serializers.BooleanField(default=False)
ldap_import_search_base = serializers.CharField(required=False)
ldap_import_search_base = serializers.CharField(
required=False, allow_blank=True)
ldap_import_search_filter = serializers.CharField(
default="(cn=*)", required=False
)
@@ -124,7 +126,14 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
log_maximum_age = serializers.IntegerField(default=365)
items_per_page = serializers.IntegerField(default=30)
default_top_redirection = serializers.ChoiceField(
default="user", choices=[])
default="user", choices=[""])
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
sms_backend_fields = sms_backends.get_all_backend_serializer_settings()
for field, definition in sms_backend_fields.items():
self.fields[field] = definition["type"](
**definition["attrs"])
def validate_ldap_user_dn_template(self, value):
try:
@@ -175,15 +184,14 @@ class CoreGlobalParametersSerializer(serializers.Serializer):
else:
errors["sms_provider"] = _("This field is required")
if data["authentication_type"] != "ldap":
return data
if data["ldap_auth_method"] == "searchbind":
required_fields = ["ldap_search_base", "ldap_search_filter"]
else:
required_fields = ["ldap_user_dn_template"]
for f in required_fields:
if data.get(f, u"") == u"":
errors[f] = _("This field is required")
if data["authentication_type"] == "ldap":
if data["ldap_auth_method"] == "searchbind":
required_fields = ["ldap_search_base", "ldap_search_filter"]
else:
required_fields = ["ldap_user_dn_template"]
for f in required_fields:
if data.get(f, "") == "":
errors[f] = _("This field is required")
if len(errors):
raise serializers.ValidationError(errors)
return data
+108
View File
@@ -0,0 +1,108 @@
"""Core API related tests."""
import copy
from django.urls import reverse
from modoboa.lib.tests import ModoAPITestCase
CORE_SETTINGS = {
"authentication_type": "local",
"password_scheme": "sha512crypt",
"rounds_number": 70000,
"update_scheme": True,
"default_password": "Toto12345",
"random_password_length": 8,
"update_password_url": "",
"password_recovery_msg": "",
"sms_password_recovery": False,
"ldap_server_address": "localhost",
"ldap_server_port": 389,
"ldap_enable_secondary_server": False,
"ldap_secondary_server_address": "localhost",
"ldap_secondary_server_port": 389,
"ldap_secured": "none",
"ldap_is_active_directory": False,
"ldap_admin_groups": "",
"ldap_group_type": "posixgroup",
"ldap_groups_search_base": "",
"ldap_password_attribute": "userPassword",
"ldap_auth_method": "searchbind",
"ldap_bind_dn": "",
"ldap_bind_password": "",
"ldap_search_base": "",
"ldap_search_filter": "(mail=%(user)s)",
"ldap_user_dn_template": "",
"ldap_sync_bind_dn": "",
"ldap_sync_bind_password": "",
"ldap_enable_sync": False,
"ldap_sync_delete_remote_account": False,
"ldap_sync_account_dn_template": "",
"ldap_enable_import": False,
"ldap_import_search_base": "",
"ldap_import_search_filter": "(cn=*)",
"ldap_import_username_attr": "cn",
"ldap_dovecot_sync": False,
"ldap_dovecot_conf_file": "/etc/dovecot/dovecot-modoboa.conf",
"rss_feed_url": "",
"hide_features_widget": False,
"sender_address": "noreply@yourdomain.test",
"enable_api_communication": True,
"check_new_versions": True,
"send_new_versions_email": False,
"new_versions_email_rcpt": "postmaster@yourdomain.test",
"send_statistics": True,
"inactive_account_threshold": 30,
"top_notifications_check_interval": 30,
"log_maximum_age": 365,
"items_per_page": 30,
"default_top_redirection": ""
}
class ParametersAPITestCase(ModoAPITestCase):
def test_update(self):
url = reverse("v2:parameter-detail", args=["core"])
data = copy.copy(CORE_SETTINGS)
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
# Modify SMS related settings
data["sms_password_recovery"] = True
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 400)
self.assertIn("sms_provider", resp.json())
data["sms_provider"] = "test"
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 400)
data.update({
"sms_provider": "ovh",
"sms_ovh_application_key": "key",
"sms_ovh_application_secret": "secret",
"sms_ovh_consumer_key": "consumer"
})
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
# Modify some LDAP settings
data.update({
"authentication_type": "ldap",
"ldap_auth_method": "searchbind"
})
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 400)
self.assertIn("ldap_search_base", resp.json())
data.update({"ldap_auth_method": "directbind"})
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 400)
self.assertIn("ldap_user_dn_template", resp.json())
data.update({
"ldap_user_dn_template": "%(user)s",
"ldap_sync_account_dn_template": "%(user)s",
"ldap_search_filter": "mail=%(user)s"
})
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
+1
View File
@@ -784,6 +784,7 @@ GLOBAL_PARAMETERS_STRUCT = collections.OrderedDict([
"Choose a provider to send password recovery SMS"
)
}),
*sms_backends.get_all_backend_structures()
])
}),
("ldap", {
+44
View File
@@ -8,7 +8,9 @@ from .. import constants
class SMSBackend:
"""Base class of every SMS backend."""
serializer_settings = {}
settings = {}
structure = []
visibility_rules = {}
def __init__(self, params):
@@ -54,6 +56,48 @@ def get_all_backend_settings():
return settings
def get_backend_serializer_settings(name):
"""Return serializer settings of given backend."""
backend_class = get_backend_class(name)
if not backend_class:
return None
return backend_class.serializer_settings
def get_all_backend_serializer_settings():
"""Return serializer settings of all backends."""
settings = {}
for backend in constants.SMS_BACKENDS:
name = backend[0]
if not name:
continue
b_settings = get_backend_serializer_settings(name)
if b_settings:
settings.update(b_settings)
return settings
def get_backend_structure(name):
"""Return parameters structure of given backend."""
backend_class = get_backend_class(name)
if not backend_class:
return None
return backend_class.structure
def get_all_backend_structures():
"""Return parameters structure for all backends."""
structure = []
for backend in constants.SMS_BACKENDS:
name = backend[0]
if not name:
continue
b_structure = get_backend_structure(name)
if b_structure:
structure += b_structure
return structure
def get_all_backend_visibility_rules():
"""Return visibility rules of all backends."""
rules = {}
+59
View File
@@ -6,6 +6,8 @@ from django import forms
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from . import SMSBackend
@@ -54,6 +56,63 @@ class OVHBackend(SMSBackend):
}
}
serializer_settings = {
"sms_ovh_endpoint": {
"type": serializers.ChoiceField,
"attrs": {
"default": "ovh-eu",
"choices": (
("ovh-eu", _("OVH Europe")),
("ovh-us", _("OVH US")),
("ovh-ca", _("OVH North-America")),
("soyoustart-eu", _("So you Start Europe")),
("soyoustart-ca", _("So you Start North America")),
("kimsufi-eu", _("Kimsufi Europe")),
("kimsufi-ca", _("Kimsufi North America")),
)
}
},
"sms_ovh_application_key": {
"type": serializers.CharField,
"attrs": {
"required": False
}
},
"sms_ovh_application_secret": {
"type": serializers.CharField,
"attrs": {
"required": False
}
},
"sms_ovh_consumer_key": {
"type": serializers.CharField,
"attrs": {
"required": False
}
}
}
structure = [
("sms_ovh_endpoint", {
"label": _("API endpoint"),
"display": "sms_password_recovery=true&sms_provider=ovh",
}),
("sms_ovh_application_key", {
"label": _("Application key"),
"display": "sms_password_recovery=true&sms_provider=ovh"
}),
("sms_ovh_application_secret", {
"label": _("Appication secret"),
"display": "sms_password_recovery=true&sms_provider=ovh",
"password": True
}),
("sms_ovh_consumer_key", {
"label": _("Consumer key"),
"display": "sms_password_recovery=true&sms_provider=ovh",
"password": True
}),
]
visibility_rules = {
"sms_ovh_endpoint": "sms_provider=ovh",
"sms_ovh_application_key": "sms_provider=ovh",
+50
View File
@@ -0,0 +1,50 @@
"""Parameters API related tests."""
from django.urls import reverse
from modoboa.lib.tests import ModoAPITestCase
class ParametersAPITestCase(ModoAPITestCase):
def test_applications(self):
url = reverse("v2:parameter-applications")
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
# core, admin, limits
self.assertEqual(len(resp.json()), 3)
def test_get_structure(self):
url = reverse("v2:parameter-structure")
resp_full = self.client.get(url)
self.assertEqual(resp_full.status_code, 200)
resp_core = self.client.get(url + "?app=core")
self.assertEqual(resp_core.status_code, 200)
self.assertNotEqual(len(resp_full.json()), len(resp_core.json()))
def test_retrieve(self):
for app in ["core", "admin", "limits"]:
url = reverse("v2:parameter-detail", args=[app])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
def test_update(self):
data = {
"enable_admin_limits": True,
"deflt_user_domain_admins_limit": 0,
"deflt_user_domains_limit": 0,
"deflt_user_domain_aliases_limit": 0,
"deflt_user_mailboxes_limit": 0,
"deflt_user_mailbox_aliases_limit": 0,
"deflt_user_quota_limit": 0,
"enable_domain_limits": False,
"deflt_domain_domain_admins_limit": 0,
"deflt_domain_domain_aliases_limit": 0,
"deflt_domain_mailboxes_limit": 0,
"deflt_domain_mailbox_aliases_limit": 0
}
url = reverse("v2:parameter-detail", args=["limits"])
resp = self.client.put(url, json=data)
self.assertEqual(resp.status_code, 200)