Merge pull request #3147 from modoboa/fix/duplicate_alias

Prevent creation of same alias addresses using different case
This commit is contained in:
Antoine Nguyen
2023-12-22 09:17:50 +01:00
committed by GitHub
4 changed files with 28 additions and 10 deletions
+11 -5
View File
@@ -17,6 +17,7 @@ from modoboa.admin import models as admin_models
from modoboa.core import (
constants as core_constants, models as core_models, signals as core_signals
)
from modoboa.lib.exceptions import AliasExists
from modoboa.lib import (
email_utils, exceptions as lib_exceptions, fields as lib_fields,
permissions, validators, web_utils
@@ -467,9 +468,14 @@ class AliasSerializer(serializers.ModelSerializer):
def validate_address(self, value):
"""Check domain."""
local_part, self.domain = admin_models.validate_alias_address(
value, self.context["request"].user, instance=self.instance)
return value
try:
local_part, self.domain = admin_models.validate_alias_address(
value, self.context["request"].user, instance=self.instance)
except ValidationError as err:
raise serializers.ValidationError(err)
except AliasExists:
raise serializers.ValidationError(_("This alias already exists"))
return value.lower()
def create(self, validated_data):
"""Create appropriate objects."""
@@ -498,13 +504,13 @@ class SenderAddressSerializer(serializers.ModelSerializer):
def validate_address(self, value):
"""Check domain."""
local_part, domain = email_utils.split_mailbox(value)
local_part, domain = email_utils.split_mailbox(value.lower())
domain = admin_models.Domain.objects.filter(name=domain).first()
user = self.context["request"].user
if domain and not user.can_access(domain):
raise serializers.ValidationError(
_("You don't have access to this domain."))
return value
return value.lower()
def validate_mailbox(self, value):
"""Check permission."""
+11
View File
@@ -678,6 +678,17 @@ class AliasAPITestCase(ModoAPITestCase):
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 201)
def test_create_duplicate_alias(self):
url = reverse("v1:alias-list")
response = self.client.post(url, self.ALIAS_DATA, format="json")
self.assertEqual(response.status_code, 201)
# Try with same address but different case
data = copy.deepcopy(self.ALIAS_DATA)
data["address"] = "ALIAS_fromapi@test.com"
response = self.client.post(url, data, format="json")
self.assertEqual(response.status_code, 400)
def test_create_alias_as_domadmin(self):
"""As DomainAdmin, try to create a new alias."""
self.client.credentials(
+5 -4
View File
@@ -535,10 +535,11 @@ class AliasViewSetTestCase(ModoAPITestCase):
data = {"address": "alias@test.com"}
resp = self.client.post(url, data, format="json")
self.assertEqual(resp.status_code, 409)
al_id = models.Alias.objects.get(address="alias@test.com").pk
self.assertEqual(resp.json()["id"], al_id)
self.assertEqual(resp.status_code, 400)
self.assertEqual(
resp.json()["address"][0],
"This alias already exists"
)
data = {"address": "alias2@test.com"}
resp = self.client.post(url, data, format="json")
+1 -1
View File
@@ -28,7 +28,7 @@ def validate_alias_address(
address, creator, internal=False, instance=None, ignore_existing=False
):
"""Check if the given alias address can be created by creator."""
local_part, domain = split_mailbox(address)
local_part, domain = split_mailbox(address.lower())
domain = Domain.objects.filter(name=domain).first()
if domain is None:
raise ValidationError(_("Domain not found."))