(mailbox_manager) modify API to get maildomain

Access to maildomain by slug name
This commit is contained in:
Sabrina Demagny
2024-06-03 16:59:55 +02:00
parent 23778fda0d
commit b4bafb6efb
12 changed files with 94 additions and 23 deletions

View File

@@ -18,6 +18,7 @@ class MailDomainSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.MailDomain model = models.MailDomain
lookup_field = "slug"
fields = [ fields = [
"id", "id",
"name", "name",

View File

@@ -23,14 +23,14 @@ class MailDomainViewSet(
GET /api/<version>/mail-domains/ GET /api/<version>/mail-domains/
Return a list of mail domains user has access to. Return a list of mail domains user has access to.
GET /api/<version>/mail-domains/<domain-id>/ GET /api/<version>/mail-domains/<domain-slug>/
Return details for a mail domain user has access to. Return details for a mail domain user has access to.
POST /api/<version>/mail-domains/ with expected data: POST /api/<version>/mail-domains/ with expected data:
- name: str - name: str
Return newly created domain Return newly created domain
DELETE /api/<version>/mail-domains/<domain-id>/ DELETE /api/<version>/mail-domains/<domain-slug>/
Delete targeted team access Delete targeted team access
""" """
@@ -39,6 +39,7 @@ class MailDomainViewSet(
filter_backends = [filters.OrderingFilter] filter_backends = [filters.OrderingFilter]
ordering_fields = ["created_at", "name"] ordering_fields = ["created_at", "name"]
ordering = ["-created_at"] ordering = ["-created_at"]
lookup_field = "slug"
queryset = models.MailDomain.objects.all() queryset = models.MailDomain.objects.all()
def get_queryset(self): def get_queryset(self):
@@ -85,16 +86,16 @@ class MailBoxViewSet(
def get_queryset(self): def get_queryset(self):
"""Custom queryset to get mailboxes related to a mail domain.""" """Custom queryset to get mailboxes related to a mail domain."""
domain_id = self.kwargs.get("domain_id", "") domain_slug = self.kwargs.get("domain_slug", "")
if domain_id: if domain_slug:
return self.queryset.filter(domain__id=domain_id) return self.queryset.filter(domain__slug=domain_slug)
return self.queryset return self.queryset
def perform_create(self, serializer): def perform_create(self, serializer):
"""Create new mailbox.""" """Create new mailbox."""
domain_id = self.kwargs.get("domain_id", "") domain_slug = self.kwargs.get("domain_slug", "")
if domain_id: if domain_slug:
serializer.validated_data["domain"] = models.MailDomain.objects.get( serializer.validated_data["domain"] = models.MailDomain.objects.get(
id=domain_id slug=domain_slug
) )
super().perform_create(serializer) super().perform_create(serializer)

View File

@@ -2,6 +2,8 @@
Mailbox manager application factories Mailbox manager application factories
""" """
from django.utils.text import slugify
import factory.fuzzy import factory.fuzzy
from faker import Faker from faker import Faker
@@ -22,6 +24,7 @@ class MailDomainFactory(factory.django.DjangoModelFactory):
skip_postgeneration_save = True skip_postgeneration_save = True
name = factory.Faker("domain_name") name = factory.Faker("domain_name")
slug = factory.LazyAttribute(lambda o: slugify(o.name))
@factory.post_generation @factory.post_generation
def users(self, create, extracted, **kwargs): def users(self, create, extracted, **kwargs):

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2024-06-03 14:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mailbox_manager', '0002_alter_maildomainaccess_domain'),
]
operations = [
migrations.AddField(
model_name='maildomain',
name='slug',
field=models.SlugField(blank=True, max_length=80),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.0.6 on 2024-06-03 14:14
from django.db import migrations, models
from django.utils.text import slugify
def populate_slug(apps, schema_editor):
MailDomain = apps.get_model('mailbox_manager', 'MailDomain')
for mail_domain in MailDomain.objects.filter(slug=''):
mail_domain.slug = slugify(mail_domain.name)
mail_domain.save()
class Migration(migrations.Migration):
dependencies = [
('mailbox_manager', '0003_maildomain_slug'),
]
operations = [
migrations.RunPython(populate_slug, reverse_code=migrations.RunPython.noop),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2024-06-03 14:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mailbox_manager', '0004_maildomain_fill_slug'),
]
operations = [
migrations.AlterField(
model_name='maildomain',
name='slug',
field=models.SlugField(max_length=80, unique=True),
),
]

View File

@@ -5,6 +5,7 @@ Declare and configure the models for the People additional application : mailbox
from django.conf import settings from django.conf import settings
from django.core import validators from django.core import validators
from django.db import models from django.db import models
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from core.models import BaseModel, RoleChoices from core.models import BaseModel, RoleChoices
@@ -16,6 +17,7 @@ class MailDomain(BaseModel):
name = models.CharField( name = models.CharField(
_("name"), max_length=150, null=False, blank=False, unique=True _("name"), max_length=150, null=False, blank=False, unique=True
) )
slug = models.SlugField(null=False, blank=False, unique=True, max_length=80)
class Meta: class Meta:
db_table = "people_mail_domain" db_table = "people_mail_domain"
@@ -25,6 +27,11 @@ class MailDomain(BaseModel):
def __str__(self): def __str__(self):
return self.name return self.name
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
return super().save(*args, **kwargs)
def get_abilities(self, user): def get_abilities(self, user):
""" """
Compute and return abilities for a given user on the domain. Compute and return abilities for a given user on the domain.

View File

@@ -18,7 +18,7 @@ def test_api_mail_domains__delete_anonymous():
domain = factories.MailDomainFactory() domain = factories.MailDomainFactory()
response = APIClient().delete( response = APIClient().delete(
f"/api/v1.0/mail-domains/{domain.id!s}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
@@ -36,7 +36,7 @@ def test_api_mail_domains__delete_authenticated_unrelated():
client = APIClient() client = APIClient()
client.force_login(identity.user) client.force_login(identity.user)
response = client.delete( response = client.delete(
f"/api/v1.0/mail-domains/{domain.id!s}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_404_NOT_FOUND assert response.status_code == status.HTTP_404_NOT_FOUND
@@ -56,7 +56,7 @@ def test_api_mail_domains__delete_authenticated_member():
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
response = client.delete( response = client.delete(
f"/api/v1.0/mail-domains/{domain.id}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_403_FORBIDDEN assert response.status_code == status.HTTP_403_FORBIDDEN
@@ -78,7 +78,7 @@ def test_api_mail_domains__delete_authenticated_administrator():
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
response = client.delete( response = client.delete(
f"/api/v1.0/mail-domains/{domain.id}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_403_FORBIDDEN assert response.status_code == status.HTTP_403_FORBIDDEN
@@ -100,7 +100,7 @@ def test_api_mail_domains__delete_authenticated_owner():
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
response = client.delete( response = client.delete(
f"/api/v1.0/mail-domains/{domain.id}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_204_NO_CONTENT assert response.status_code == status.HTTP_204_NO_CONTENT

View File

@@ -17,7 +17,7 @@ def test_api_mail_domains__retrieve_anonymous():
"""Anonymous users should not be allowed to retrieve a domain.""" """Anonymous users should not be allowed to retrieve a domain."""
domain = factories.MailDomainFactory() domain = factories.MailDomainFactory()
response = APIClient().get(f"/api/v1.0/mail-domains/{domain.id}/") response = APIClient().get(f"/api/v1.0/mail-domains/{domain.slug}/")
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.json() == { assert response.json() == {
@@ -38,7 +38,7 @@ def test_api_mail_domains__retrieve_authenticated_unrelated():
domain = factories.MailDomainFactory() domain = factories.MailDomainFactory()
response = client.get( response = client.get(
f"/api/v1.0/mail-domains/{domain.id!s}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_404_NOT_FOUND assert response.status_code == status.HTTP_404_NOT_FOUND
assert response.json() == {"detail": "No MailDomain matches the given query."} assert response.json() == {"detail": "No MailDomain matches the given query."}
@@ -59,7 +59,7 @@ def test_api_mail_domains__retrieve_authenticated_related():
factories.MailDomainAccessFactory(domain=domain, user=user) factories.MailDomainAccessFactory(domain=domain, user=user)
response = client.get( response = client.get(
f"/api/v1.0/mail-domains/{domain.id!s}/", f"/api/v1.0/mail-domains/{domain.slug}/",
) )
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK

View File

@@ -18,7 +18,7 @@ def test_api_mailboxes__create_anonymous_forbidden():
mail_domain = factories.MailDomainFactory() mail_domain = factories.MailDomainFactory()
response = APIClient().post( response = APIClient().post(
f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/", f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/",
{ {
"first_name": "jean", "first_name": "jean",
"last_name": "doe", "last_name": "doe",
@@ -44,7 +44,7 @@ def test_api_mailboxes__create_authenticated_missing_fields():
mail_domain = factories.MailDomainFactory() mail_domain = factories.MailDomainFactory()
response = client.post( response = client.post(
f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/", f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/",
{ {
"first_name": "jean", "first_name": "jean",
"last_name": "doe", "last_name": "doe",
@@ -58,7 +58,7 @@ def test_api_mailboxes__create_authenticated_missing_fields():
assert response.json() == {"local_part": ["This field is required."]} assert response.json() == {"local_part": ["This field is required."]}
response = client.post( response = client.post(
f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/", f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/",
{ {
"first_name": "jean", "first_name": "jean",
"last_name": "doe", "last_name": "doe",
@@ -82,7 +82,7 @@ def test_api_mailboxes__create_authenticated_successful():
mail_domain = factories.MailDomainFactory(name="saint-jean.collectivite.fr") mail_domain = factories.MailDomainFactory(name="saint-jean.collectivite.fr")
response = client.post( response = client.post(
f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/", f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/",
{ {
"first_name": "jean", "first_name": "jean",
"last_name": "doe", "last_name": "doe",

View File

@@ -18,7 +18,7 @@ def test_api_mailboxes__list_anonymous():
mail_domain = factories.MailDomainFactory() mail_domain = factories.MailDomainFactory()
factories.MailboxFactory.create_batch(2, domain=mail_domain) factories.MailboxFactory.create_batch(2, domain=mail_domain)
response = APIClient().get(f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/") response = APIClient().get(f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/")
assert response.status_code == status.HTTP_401_UNAUTHORIZED assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert response.json() == { assert response.json() == {
"detail": "Authentication credentials were not provided." "detail": "Authentication credentials were not provided."
@@ -37,7 +37,7 @@ def test_api_mailboxes__list_authenticated_no_query():
mailbox1 = factories.MailboxFactory(domain=mail_domain) mailbox1 = factories.MailboxFactory(domain=mail_domain)
mailbox2 = factories.MailboxFactory(domain=mail_domain) mailbox2 = factories.MailboxFactory(domain=mail_domain)
response = client.get(f"/api/v1.0/mail-domains/{mail_domain.id}/mailboxes/") response = client.get(f"/api/v1.0/mail-domains/{mail_domain.slug}/mailboxes/")
assert response.status_code == status.HTTP_200_OK assert response.status_code == status.HTTP_200_OK
assert response.json()["results"] == [ assert response.json()["results"] == [
{ {

View File

@@ -32,7 +32,7 @@ urlpatterns = [
[ [
*maildomain_router.urls, *maildomain_router.urls,
re_path( re_path(
r"^mail-domains/(?P<domain_id>[0-9a-z-]*)/", r"^mail-domains/(?P<domain_slug>[\w-]+)/",
include(maildomain_related_router.urls), include(maildomain_related_router.urls),
), ),
] ]