Merge pull request #1332 from modoboa/feature/sender_address_api

New sender address API.
This commit is contained in:
Antoine Nguyen
2017-12-19 11:41:36 +01:00
committed by GitHub
6 changed files with 154 additions and 3 deletions
+17
View File
@@ -146,3 +146,20 @@ class AliasViewSet(viewsets.ModelViewSet):
if domain:
queryset = queryset.filter(domain__name=domain)
return queryset
class SenderAddressViewSet(viewsets.ModelViewSet):
"""View set for SenderAddress model."""
permission_classes = [IsAuthenticated, DjangoModelPermissions, ]
serializer_class = serializers.SenderAddressSerializer
def get_queryset(self):
"""Filter queryset based on current user."""
user = self.request.user
mb_ids = (
user.objectaccess_set.filter(
content_type=ContentType.objects.get_for_model(models.Mailbox))
.values_list("object_id", flat=True)
)
return models.SenderAddress.objects.filter(mailbox__pk__in=mb_ids)
+9
View File
@@ -63,6 +63,15 @@ class AliasFactory(PermissionFactory):
enabled = True
class SenderAddressFactory(factory.django.DjangoModelFactory):
"""Factory for SenderAddress model."""
mailbox = factory.SubFactory(MailboxFactory)
class Meta:
model = models.SenderAddress
def populate_database():
"""Create test data.
+29 -1
View File
@@ -105,7 +105,7 @@ class MailboxSerializer(serializers.ModelSerializer):
class Meta:
model = models.Mailbox
fields = ("full_address", "use_domain_quota", "quota", )
fields = ("pk", "full_address", "use_domain_quota", "quota", )
class AccountSerializer(serializers.ModelSerializer):
@@ -386,3 +386,31 @@ class AliasSerializer(serializers.ModelSerializer):
instance.save()
instance.set_recipients(recipients)
return instance
class SenderAddressSerializer(serializers.ModelSerializer):
"""Base Alias serializer."""
address = lib_fields.DRFEmailFieldUTF8AndEmptyUser()
class Meta:
model = admin_models.SenderAddress
fields = ("pk", "address", "mailbox")
def validate_address(self, value):
"""Check domain."""
local_part, domain = email_utils.split_mailbox(value)
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
def validate_mailbox(self, value):
"""Check permission."""
user = self.context["request"].user
if not user.can_access(value):
raise serializers.ValidationError(
_("You don't have access to this mailbox."))
return value
+89
View File
@@ -281,6 +281,7 @@ class AccountAPITestCase(ModoAPITestCase):
self.assertIsNot(user.mailbox, None)
domadmin = core_models.User.objects.get(username="admin@test.com")
self.assertTrue(domadmin.can_access(user))
self.assertIn("pk", account["mailbox"])
data = copy.deepcopy(self.ACCOUNT_DATA)
data["username"] = "fromapi_ééé@test.com"
@@ -660,3 +661,91 @@ class AliasAPITestCase(ModoAPITestCase):
address="user@test.com", alias__address="alias@test.com")
.exists()
)
class SenderAddressAPITestCase(ModoAPITestCase):
"""Check SenderAddress API."""
@classmethod
def setUpTestData(cls):
"""Create test data."""
super(SenderAddressAPITestCase, cls).setUpTestData()
cls.localconfig.parameters.set_value(
"enable_admin_limits", False, app="limits")
cls.localconfig.save()
factories.populate_database()
cls.sa1 = factories.SenderAddressFactory(
address="test@domain.ext",
mailbox__user__username="user@test.com",
mailbox__address="user",
mailbox__domain__name="test.com"
)
cls.da_token = Token.objects.create(
user=core_models.User.objects.get(username="admin@test.com"))
def test_list(self):
"""Retrieve a list of sender addresses."""
url = reverse("api:sender_address-list")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = response.json()
self.assertEqual(len(response), 1)
def test_create(self):
"""Create a new sender addresses."""
url = reverse("api:sender_address-list")
mbox = models.Mailbox.objects.get(
address="admin", domain__name="test.com")
data = {"address": "@extdomain.test", "mailbox": mbox.pk}
response = self.client.post(url, data)
self.assertEqual(response.status_code, 201)
self.client.credentials(
HTTP_AUTHORIZATION='Token ' + self.da_token.key)
data = {"address": "user@test2.com", "mailbox": mbox.pk}
response = self.client.post(url, data)
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.json()["address"][0],
"You don't have access to this domain.")
mbox = models.Mailbox.objects.get(
address="admin", domain__name="test2.com")
data = {"address": "toto@titi.com", "mailbox": mbox.pk}
response = self.client.post(url, data)
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.json()["mailbox"][0],
"You don't have access to this mailbox.")
def test_patch(self):
"""Patch an existing sender address."""
url = reverse("api:sender_address-detail", args=[self.sa1.pk])
mbox = models.Mailbox.objects.get(
address="user", domain__name="test.com")
data = {"address": "@extdomain.test"}
response = self.client.patch(url, data)
self.assertEqual(response.status_code, 200)
self.sa1.refresh_from_db()
self.assertEqual(self.sa1.mailbox, mbox)
self.assertEqual(self.sa1.address, data["address"])
def test_update(self):
"""Update an existing sender address."""
url = reverse("api:sender_address-detail", args=[self.sa1.pk])
mbox = models.Mailbox.objects.get(
address="user", domain__name="test.com")
data = {"address": "@extdomain.test", "mailbox": mbox.pk}
response = self.client.put(url, data)
self.assertEqual(response.status_code, 200)
self.sa1.refresh_from_db()
self.assertEqual(self.sa1.mailbox, mbox)
self.assertEqual(self.sa1.address, data["address"])
def test_delete(self):
"""Delete an existing sender address."""
url = reverse("api:sender_address-detail", args=[self.sa1.pk])
response = self.client.delete(url)
self.assertEqual(response.status_code, 204)
with self.assertRaises(models.SenderAddress.DoesNotExist):
self.sa1.refresh_from_db()
+2
View File
@@ -13,5 +13,7 @@ router.register(
r"domainaliases", api.DomainAliasViewSet, base_name="domain_alias")
router.register(r"accounts", api.AccountViewSet, base_name="account")
router.register(r"aliases", api.AliasViewSet, base_name="alias")
router.register(
r"senderaddresses", api.SenderAddressViewSet, base_name="sender_address")
urlpatterns = router.urls
+8 -2
View File
@@ -64,11 +64,14 @@ PERMISSIONS = {
["admin", "mailbox", "add_mailbox"],
["admin", "mailbox", "change_mailbox"],
["admin", "mailbox", "delete_mailbox"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "add_alias"],
["admin", "alias", "change_alias"],
["admin", "alias", "delete_alias"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "view_aliases"],
["admin", "senderaddress", "add_senderaddress"],
["admin", "senderaddress", "change_senderaddress"],
["admin", "senderaddress", "delete_senderaddress"],
],
"Resellers": [
["core", "user", "add_user"],
@@ -79,11 +82,14 @@ PERMISSIONS = {
["admin", "mailbox", "add_mailbox"],
["admin", "mailbox", "change_mailbox"],
["admin", "mailbox", "delete_mailbox"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "add_alias"],
["admin", "alias", "change_alias"],
["admin", "alias", "delete_alias"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "view_aliases"],
["admin", "senderaddress", "add_senderaddress"],
["admin", "senderaddress", "change_senderaddress"],
["admin", "senderaddress", "delete_senderaddress"],
["admin", "domain", "view_domains"],
["admin", "domain", "add_domain"],
["admin", "domain", "change_domain"],