✨(api) add CRUD for mailbox manager MailDomain models
Add create,list,retrieve and delete actions for MailDomain model.
This commit is contained in:
committed by
Marie
parent
ac81e86c88
commit
df24c24da1
@@ -3,7 +3,7 @@ Tests for Teams API endpoint in People's core app: retrieve
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
from core import factories
|
from core import factories
|
||||||
@@ -16,7 +16,7 @@ def test_api_teams_retrieve_anonymous():
|
|||||||
team = factories.TeamFactory()
|
team = factories.TeamFactory()
|
||||||
response = APIClient().get(f"/api/v1.0/teams/{team.id}/")
|
response = APIClient().get(f"/api/v1.0/teams/{team.id}/")
|
||||||
|
|
||||||
assert response.status_code == 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_teams_retrieve_authenticated_unrelated():
|
|||||||
response = client.get(
|
response = client.get(
|
||||||
f"/api/v1.0/teams/{team.id!s}/",
|
f"/api/v1.0/teams/{team.id!s}/",
|
||||||
)
|
)
|
||||||
assert response.status_code == HTTP_404_NOT_FOUND
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
assert response.json() == {"detail": "No Team matches the given query."}
|
assert response.json() == {"detail": "No Team matches the given query."}
|
||||||
|
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ def test_api_teams_retrieve_authenticated_related():
|
|||||||
f"/api/v1.0/teams/{team.id!s}/",
|
f"/api/v1.0/teams/{team.id!s}/",
|
||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == HTTP_200_OK
|
assert response.status_code == status.HTTP_200_OK
|
||||||
assert sorted(response.json().pop("accesses")) == sorted(
|
assert sorted(response.json().pop("accesses")) == sorted(
|
||||||
[
|
[
|
||||||
str(access1.id),
|
str(access1.id),
|
||||||
|
|||||||
12
src/backend/mailbox_manager/api/permissions.py
Normal file
12
src/backend/mailbox_manager/api/permissions.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
"""Permission handlers for the People mailbox manager app."""
|
||||||
|
|
||||||
|
from core.api import permissions as core_permissions
|
||||||
|
|
||||||
|
|
||||||
|
class AccessPermission(core_permissions.IsAuthenticated):
|
||||||
|
"""Permission class for access objects."""
|
||||||
|
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
"""Check permission for a given object."""
|
||||||
|
abilities = obj.get_abilities(request.user)
|
||||||
|
return abilities.get(request.method.lower(), False)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Client serializers for the People mailbox_manager app."""
|
"""Client serializers for People's mailbox manager app."""
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
@@ -18,4 +18,24 @@ class MailDomainSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.MailDomain
|
model = models.MailDomain
|
||||||
fields = ["id", "name"]
|
fields = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class MailDomainAccessSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serialize mail domain accesses."""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = models.MailDomainAccess
|
||||||
|
fields = [
|
||||||
|
"id",
|
||||||
|
"user",
|
||||||
|
"role",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
]
|
||||||
|
read_only_fields = ["id"]
|
||||||
|
|||||||
@@ -1,22 +1,75 @@
|
|||||||
"""API endpoints"""
|
"""API endpoints"""
|
||||||
|
|
||||||
from rest_framework import mixins, viewsets
|
from rest_framework import filters, mixins, viewsets
|
||||||
from rest_framework import permissions as drf_permissions
|
from rest_framework import permissions as drf_permissions
|
||||||
|
|
||||||
|
from core import models as core_models
|
||||||
|
|
||||||
from mailbox_manager import models
|
from mailbox_manager import models
|
||||||
|
from mailbox_manager.api import permissions, serializers
|
||||||
from . import serializers
|
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=too-many-ancestors
|
||||||
class MailDomainViewSet(
|
class MailDomainViewSet(
|
||||||
|
mixins.CreateModelMixin,
|
||||||
|
mixins.ListModelMixin,
|
||||||
|
mixins.RetrieveModelMixin,
|
||||||
|
mixins.DestroyModelMixin,
|
||||||
|
viewsets.GenericViewSet,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
MailDomain viewset.
|
||||||
|
|
||||||
|
GET /api/<version>/mail-domains/
|
||||||
|
Return a list of mail domains user has access to.
|
||||||
|
|
||||||
|
GET /api/<version>/mail-domains/<domain-id>/
|
||||||
|
Return details for a mail domain user has access to.
|
||||||
|
|
||||||
|
POST /api/<version>/mail-domains/ with expected data:
|
||||||
|
- name: str
|
||||||
|
Return newly created domain
|
||||||
|
|
||||||
|
DELETE /api/<version>/mail-domains/<domain-id>/
|
||||||
|
Delete targeted team access
|
||||||
|
"""
|
||||||
|
|
||||||
|
permission_classes = [permissions.AccessPermission]
|
||||||
|
serializer_class = serializers.MailDomainSerializer
|
||||||
|
filter_backends = [filters.OrderingFilter]
|
||||||
|
ordering_fields = ["created_at", "name"]
|
||||||
|
ordering = ["-created_at"]
|
||||||
|
queryset = models.MailDomain.objects.all()
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return self.queryset.filter(accesses__user=self.request.user)
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
"""Set the current user as owner of the newly created mail domain."""
|
||||||
|
|
||||||
|
domain = serializer.save()
|
||||||
|
models.MailDomainAccess.objects.create(
|
||||||
|
user=self.request.user,
|
||||||
|
domain=domain,
|
||||||
|
role=core_models.RoleChoices.OWNER,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=too-many-ancestors
|
||||||
|
class MailDomainAccessViewSet(
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
viewsets.GenericViewSet,
|
viewsets.GenericViewSet,
|
||||||
):
|
):
|
||||||
"""MailDomain ViewSet"""
|
"""
|
||||||
|
MailDomainAccess viewset.
|
||||||
|
"""
|
||||||
|
|
||||||
permission_classes = [drf_permissions.IsAuthenticated]
|
permission_classes = [drf_permissions.IsAuthenticated]
|
||||||
serializer_class = serializers.MailDomainSerializer
|
serializer_class = serializers.MailDomainAccessSerializer
|
||||||
queryset = models.MailDomain.objects.all()
|
filter_backends = [filters.OrderingFilter]
|
||||||
|
ordering_fields = ["created_at", "user", "domain", "role"]
|
||||||
|
ordering = ["-created_at"]
|
||||||
|
queryset = models.MailDomainAccess.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class MailBoxViewSet(
|
class MailBoxViewSet(
|
||||||
|
|||||||
@@ -18,9 +18,24 @@ class MailDomainFactory(factory.django.DjangoModelFactory):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.MailDomain
|
model = models.MailDomain
|
||||||
|
django_get_or_create = ("name",)
|
||||||
|
skip_postgeneration_save = True
|
||||||
|
|
||||||
name = factory.Faker("domain_name")
|
name = factory.Faker("domain_name")
|
||||||
|
|
||||||
|
@factory.post_generation
|
||||||
|
def users(self, create, extracted, **kwargs):
|
||||||
|
"""Add users to domain from a given list of users with or without roles."""
|
||||||
|
if not create or not extracted:
|
||||||
|
return
|
||||||
|
for user_entry in extracted:
|
||||||
|
if isinstance(user_entry, core_models.User):
|
||||||
|
MailDomainAccessFactory(domain=self, user=user_entry)
|
||||||
|
else:
|
||||||
|
MailDomainAccessFactory(
|
||||||
|
domain=self, user=user_entry[0], role=user_entry[1]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MailDomainAccessFactory(factory.django.DjangoModelFactory):
|
class MailDomainAccessFactory(factory.django.DjangoModelFactory):
|
||||||
"""A factory to create mail domain accesses."""
|
"""A factory to create mail domain accesses."""
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.0.3 on 2024-04-17 11:58
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mailbox_manager', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='maildomainaccess',
|
||||||
|
name='domain',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='accesses', to='mailbox_manager.maildomain'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -25,6 +25,29 @@ class MailDomain(BaseModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def get_abilities(self, user):
|
||||||
|
"""
|
||||||
|
Compute and return abilities for a given user on the domain.
|
||||||
|
"""
|
||||||
|
is_owner_or_admin = False
|
||||||
|
role = None
|
||||||
|
|
||||||
|
if user.is_authenticated:
|
||||||
|
try:
|
||||||
|
role = self.accesses.filter(user=user).values("role")[0]["role"]
|
||||||
|
except (MailDomainAccess.DoesNotExist, IndexError):
|
||||||
|
role = None
|
||||||
|
|
||||||
|
is_owner_or_admin = role in [RoleChoices.OWNER, RoleChoices.ADMIN]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"get": bool(role),
|
||||||
|
"patch": is_owner_or_admin,
|
||||||
|
"put": is_owner_or_admin,
|
||||||
|
"delete": role == RoleChoices.OWNER,
|
||||||
|
"manage_accesses": is_owner_or_admin,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MailDomainAccess(BaseModel):
|
class MailDomainAccess(BaseModel):
|
||||||
"""Allow to manage users' accesses to mail domains."""
|
"""Allow to manage users' accesses to mail domains."""
|
||||||
@@ -39,7 +62,7 @@ class MailDomainAccess(BaseModel):
|
|||||||
domain = models.ForeignKey(
|
domain = models.ForeignKey(
|
||||||
MailDomain,
|
MailDomain,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
related_name="mail_domain_accesses",
|
related_name="accesses",
|
||||||
null=False,
|
null=False,
|
||||||
blank=False,
|
blank=False,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
"""
|
||||||
|
Tests for MailDomains API endpoint in People's app mailbox_manager. Focus on "create" action.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core import factories as core_factories
|
||||||
|
|
||||||
|
from mailbox_manager import factories, models
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__create_anonymous():
|
||||||
|
"""Anonymous users should not be allowed to create mail domains."""
|
||||||
|
|
||||||
|
response = APIClient().post(
|
||||||
|
"/api/v1.0/mail-domains/",
|
||||||
|
{
|
||||||
|
"name": "mydomain.com",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
||||||
|
assert not models.MailDomain.objects.exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__create_name_unique():
|
||||||
|
"""
|
||||||
|
Creating domain should raise an error if already existing name.
|
||||||
|
"""
|
||||||
|
factories.MailDomainFactory(name="existing_domain.com")
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(identity.user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/mail-domains/",
|
||||||
|
{
|
||||||
|
"name": "existing_domain.com",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||||
|
assert response.json()["name"] == ["Mail domain with this name already exists."]
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__create_authenticated():
|
||||||
|
"""
|
||||||
|
Authenticated users should be able to create mail domains
|
||||||
|
and should automatically be added as owner of the newly created domain.
|
||||||
|
"""
|
||||||
|
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(identity.user)
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1.0/mail-domains/",
|
||||||
|
{
|
||||||
|
"name": "mydomain.com",
|
||||||
|
},
|
||||||
|
format="json",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_201_CREATED
|
||||||
|
domain = models.MailDomain.objects.get()
|
||||||
|
assert domain.name == "mydomain.com"
|
||||||
|
assert domain.accesses.filter(role="owner", user=user).exists()
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
"""
|
||||||
|
Tests for MailDomains API endpoint, in People's mailbox manager app. Focus on "delete" action.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core import factories as core_factories
|
||||||
|
|
||||||
|
from mailbox_manager import factories, models
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__delete_anonymous():
|
||||||
|
"""Anonymous users should not be allowed to destroy a team."""
|
||||||
|
domain = factories.MailDomainFactory()
|
||||||
|
|
||||||
|
response = APIClient().delete(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id!s}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
||||||
|
assert models.MailDomain.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__delete_authenticated_unrelated():
|
||||||
|
"""
|
||||||
|
Authenticated users should not be allowed to delete a domain to which they are not
|
||||||
|
related.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
domain = factories.MailDomainFactory()
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(identity.user)
|
||||||
|
response = client.delete(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id!s}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
|
assert response.json() == {"detail": "No MailDomain matches the given query."}
|
||||||
|
assert models.MailDomain.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__delete_authenticated_member():
|
||||||
|
"""
|
||||||
|
Authenticated users should not be allowed to delete a domain
|
||||||
|
to which they are only a member.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
domain = factories.MailDomainFactory(users=[(user, "member")])
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
response = client.delete(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||||
|
assert response.json() == {
|
||||||
|
"detail": "You do not have permission to perform this action."
|
||||||
|
}
|
||||||
|
assert models.MailDomain.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__delete_authenticated_administrator():
|
||||||
|
"""
|
||||||
|
Authenticated users should not be allowed to delete a domain
|
||||||
|
for which they are administrator.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
domain = factories.MailDomainFactory(users=[(user, "administrator")])
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
response = client.delete(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||||
|
assert response.json() == {
|
||||||
|
"detail": "You do not have permission to perform this action."
|
||||||
|
}
|
||||||
|
assert models.MailDomain.objects.count() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__delete_authenticated_owner():
|
||||||
|
"""
|
||||||
|
Authenticated users should be able to delete a domain
|
||||||
|
for which they are directly owner.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
domain = factories.MailDomainFactory(users=[(user, "owner")])
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
response = client.delete(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||||
|
assert models.MailDomain.objects.exists() is False
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
"""
|
||||||
|
Tests for MailDomains API endpoint in People's mailbox manager app. Focus on "list" action.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core import factories as core_factories
|
||||||
|
|
||||||
|
from mailbox_manager import factories
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__list_anonymous():
|
||||||
|
"""Anonymous users should not be allowed to list mail domains."""
|
||||||
|
|
||||||
|
factories.MailDomainFactory.create_batch(3)
|
||||||
|
|
||||||
|
response = APIClient().get("/api/v1.0/mail-domains/")
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
||||||
|
assert response.json() == {
|
||||||
|
"detail": "Authentication credentials were not provided."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__list_authenticated():
|
||||||
|
"""
|
||||||
|
Authenticated users should be able to list domains
|
||||||
|
to which they have access.
|
||||||
|
"""
|
||||||
|
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
expected_ids = {
|
||||||
|
str(access.domain.id)
|
||||||
|
for access in factories.MailDomainAccessFactory.create_batch(5, user=user)
|
||||||
|
}
|
||||||
|
factories.MailDomainFactory.create_batch(2) # Other teams
|
||||||
|
factories.MailDomainAccessFactory.create_batch(2) # Other teams and accesses
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
"/api/v1.0/mail-domains/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
results = response.json()["results"]
|
||||||
|
assert len(results) == 5
|
||||||
|
results_id = {result["id"] for result in results}
|
||||||
|
assert expected_ids == results_id
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
"""
|
||||||
|
Tests for MailDomains API endpoint in People's mailbox manager app. Focus on "retrieve" action.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APIClient
|
||||||
|
|
||||||
|
from core import factories as core_factories
|
||||||
|
|
||||||
|
from mailbox_manager import factories
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__retrieve_anonymous():
|
||||||
|
"""Anonymous users should not be allowed to retrieve a domain."""
|
||||||
|
|
||||||
|
domain = factories.MailDomainFactory()
|
||||||
|
response = APIClient().get(f"/api/v1.0/mail-domains/{domain.id}/")
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
||||||
|
assert response.json() == {
|
||||||
|
"detail": "Authentication credentials were not provided."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__retrieve_authenticated_unrelated():
|
||||||
|
"""
|
||||||
|
Authenticated users should not be allowed to retrieve a domain
|
||||||
|
to which they have access.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(identity.user)
|
||||||
|
|
||||||
|
domain = factories.MailDomainFactory()
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id!s}/",
|
||||||
|
)
|
||||||
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
||||||
|
assert response.json() == {"detail": "No MailDomain matches the given query."}
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_mail_domains__retrieve_authenticated_related():
|
||||||
|
"""
|
||||||
|
Authenticated users should be allowed to retrieve a domain
|
||||||
|
to which they have access.
|
||||||
|
"""
|
||||||
|
identity = core_factories.IdentityFactory()
|
||||||
|
user = identity.user
|
||||||
|
|
||||||
|
client = APIClient()
|
||||||
|
client.force_login(user)
|
||||||
|
|
||||||
|
domain = factories.MailDomainFactory()
|
||||||
|
factories.MailDomainAccessFactory(domain=domain, user=user)
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
f"/api/v1.0/mail-domains/{domain.id!s}/",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == status.HTTP_200_OK
|
||||||
|
assert response.json() == {
|
||||||
|
"id": str(domain.id),
|
||||||
|
"name": domain.name,
|
||||||
|
"created_at": domain.created_at.isoformat().replace("+00:00", "Z"),
|
||||||
|
"updated_at": domain.updated_at.isoformat().replace("+00:00", "Z"),
|
||||||
|
}
|
||||||
41
src/backend/mailbox_manager/urls.py
Normal file
41
src/backend/mailbox_manager/urls.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
"""API URL Configuration"""
|
||||||
|
|
||||||
|
from django.urls import include, path, re_path
|
||||||
|
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from mailbox_manager.api import viewsets
|
||||||
|
|
||||||
|
maildomain_router = DefaultRouter()
|
||||||
|
maildomain_router.register(
|
||||||
|
"mail-domains", viewsets.MailDomainViewSet, basename="mail-domains"
|
||||||
|
)
|
||||||
|
|
||||||
|
# - Routes nested under a mail domain
|
||||||
|
maildomain_related_router = DefaultRouter()
|
||||||
|
maildomain_related_router.register(
|
||||||
|
"accesses",
|
||||||
|
viewsets.MailDomainAccessViewSet,
|
||||||
|
basename="accesses",
|
||||||
|
)
|
||||||
|
maildomain_related_router.register(
|
||||||
|
"mailboxes",
|
||||||
|
viewsets.MailBoxViewSet,
|
||||||
|
basename="mailboxes",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path(
|
||||||
|
"",
|
||||||
|
include(
|
||||||
|
[
|
||||||
|
*maildomain_router.urls,
|
||||||
|
re_path(
|
||||||
|
r"^mail-domains/(?P<domain_id>[0-9a-z-]*)/",
|
||||||
|
include(maildomain_related_router.urls),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -8,16 +8,11 @@ from rest_framework.routers import DefaultRouter
|
|||||||
|
|
||||||
from core.api import viewsets
|
from core.api import viewsets
|
||||||
|
|
||||||
from mailbox_manager.api import viewsets as mail_viewsets
|
|
||||||
|
|
||||||
# - Main endpoints
|
# - Main endpoints
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register("contacts", viewsets.ContactViewSet, basename="contacts")
|
router.register("contacts", viewsets.ContactViewSet, basename="contacts")
|
||||||
router.register("teams", viewsets.TeamViewSet, basename="teams")
|
router.register("teams", viewsets.TeamViewSet, basename="teams")
|
||||||
router.register("users", viewsets.UserViewSet, basename="users")
|
router.register("users", viewsets.UserViewSet, basename="users")
|
||||||
router.register(
|
|
||||||
"mail-domains", mail_viewsets.MailDomainViewSet, basename="mail-domains"
|
|
||||||
)
|
|
||||||
|
|
||||||
# - Routes nested under a team
|
# - Routes nested under a team
|
||||||
team_related_router = DefaultRouter()
|
team_related_router = DefaultRouter()
|
||||||
@@ -33,14 +28,6 @@ team_related_router.register(
|
|||||||
basename="invitations",
|
basename="invitations",
|
||||||
)
|
)
|
||||||
|
|
||||||
# - Routes nested under a mail domain
|
|
||||||
maildomain_related_router = DefaultRouter()
|
|
||||||
maildomain_related_router.register(
|
|
||||||
"mailboxes",
|
|
||||||
mail_viewsets.MailBoxViewSet,
|
|
||||||
basename="mailboxes",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(
|
path(
|
||||||
@@ -53,11 +40,8 @@ urlpatterns = [
|
|||||||
r"^teams/(?P<team_id>[0-9a-z-]*)/",
|
r"^teams/(?P<team_id>[0-9a-z-]*)/",
|
||||||
include(team_related_router.urls),
|
include(team_related_router.urls),
|
||||||
),
|
),
|
||||||
re_path(
|
|
||||||
r"^mail-domains/(?P<domain_id>[0-9a-z-]*)/",
|
|
||||||
include(maildomain_related_router.urls),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
path(f"api/{settings.API_VERSION}/", include("mailbox_manager.urls")),
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user