✨(backend) domain accesses list API
Add an endpoint to list all accesses created for a domain Return all roles available to set for each access depending to the authenticated user.
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from mailbox_manager import models
|
||||
from core.api.serializers import UserSerializer
|
||||
|
||||
from mailbox_manager import enums, models
|
||||
|
||||
|
||||
class MailboxSerializer(serializers.ModelSerializer):
|
||||
@@ -50,7 +52,10 @@ class MailDomainSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class MailDomainAccessSerializer(serializers.ModelSerializer):
|
||||
"""Serialize mail domain accesses."""
|
||||
"""Serialize mail domain access."""
|
||||
|
||||
user = UserSerializer(read_only=True, fields=["id", "name", "email"])
|
||||
can_set_role_to = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = models.MailDomainAccess
|
||||
@@ -58,7 +63,44 @@ class MailDomainAccessSerializer(serializers.ModelSerializer):
|
||||
"id",
|
||||
"user",
|
||||
"role",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
"can_set_role_to",
|
||||
]
|
||||
read_only_fields = ["id", "user", "can_set_role_to"]
|
||||
|
||||
def get_can_set_role_to(self, access):
|
||||
"""Return roles available to set"""
|
||||
roles = list(enums.MailDomainRoleChoices)
|
||||
# get role of authenticated user
|
||||
authenticated_user_role = access.user_role
|
||||
if authenticated_user_role != enums.MailDomainRoleChoices.OWNER:
|
||||
roles.remove(enums.MailDomainRoleChoices.OWNER)
|
||||
# if the user authenticated is a viewer, they can't modify role
|
||||
# and only an owner can change role of an owner
|
||||
if authenticated_user_role == enums.MailDomainRoleChoices.VIEWER or (
|
||||
authenticated_user_role != enums.MailDomainRoleChoices.OWNER
|
||||
and access.role == enums.MailDomainRoleChoices.OWNER
|
||||
):
|
||||
return []
|
||||
# we only want to return other roles available to change,
|
||||
# so we remove the current role of current access.
|
||||
roles.remove(access.role)
|
||||
return sorted(roles)
|
||||
|
||||
|
||||
class MailDomainAccessReadOnlySerializer(MailDomainAccessSerializer):
|
||||
"""Serialize mail domain access for list and retrieve actions."""
|
||||
|
||||
class Meta:
|
||||
model = models.MailDomainAccess
|
||||
fields = [
|
||||
"id",
|
||||
"user",
|
||||
"role",
|
||||
"can_set_role_to",
|
||||
]
|
||||
read_only_fields = [
|
||||
"id",
|
||||
"user",
|
||||
"role",
|
||||
"can_set_role_to",
|
||||
]
|
||||
read_only_fields = ["id"]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""API endpoints"""
|
||||
|
||||
from django.db.models import Subquery
|
||||
|
||||
from rest_framework import filters, mixins, viewsets
|
||||
from rest_framework import permissions as drf_permissions
|
||||
|
||||
@@ -54,19 +56,67 @@ class MailDomainViewSet(
|
||||
|
||||
# pylint: disable=too-many-ancestors
|
||||
class MailDomainAccessViewSet(
|
||||
mixins.ListModelMixin,
|
||||
viewsets.GenericViewSet,
|
||||
mixins.ListModelMixin,
|
||||
mixins.RetrieveModelMixin,
|
||||
):
|
||||
"""
|
||||
MailDomainAccess viewset.
|
||||
API ViewSet for all interactions with mail domain accesses.
|
||||
|
||||
GET /api/v1.0/mail-domains/<domain_slug>/accesses/:<domain_access_id>
|
||||
Return list of all domain accesses related to the logged-in user and one
|
||||
domain access if an id is provided.
|
||||
"""
|
||||
|
||||
permission_classes = [drf_permissions.IsAuthenticated]
|
||||
serializer_class = serializers.MailDomainAccessSerializer
|
||||
filter_backends = [filters.OrderingFilter]
|
||||
ordering_fields = ["created_at", "user", "domain", "role"]
|
||||
ordering_fields = ["role", "user__email", "user__name"]
|
||||
ordering = ["-created_at"]
|
||||
queryset = models.MailDomainAccess.objects.all()
|
||||
queryset = (
|
||||
models.MailDomainAccess.objects.all()
|
||||
.select_related("user")
|
||||
.order_by("-created_at")
|
||||
)
|
||||
list_serializer_class = serializers.MailDomainAccessReadOnlySerializer
|
||||
detail_serializer_class = serializers.MailDomainAccessSerializer
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action in {"list", "retrieve"}:
|
||||
return self.list_serializer_class
|
||||
return self.detail_serializer_class
|
||||
|
||||
def get_serializer_context(self):
|
||||
"""Extra context provided to the serializer class."""
|
||||
context = super().get_serializer_context()
|
||||
context["domain_slug"] = self.kwargs["domain_slug"]
|
||||
return context
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return the queryset according to the action."""
|
||||
queryset = super().get_queryset()
|
||||
queryset = queryset.filter(domain__slug=self.kwargs["domain_slug"])
|
||||
|
||||
if self.action in {"list", "retrieve"}:
|
||||
# Determine which role the logged-in user has in the domain
|
||||
user_role_query = models.MailDomainAccess.objects.filter(
|
||||
user=self.request.user, domain__slug=self.kwargs["domain_slug"]
|
||||
).values("role")[:1]
|
||||
|
||||
queryset = (
|
||||
# The logged-in user should be part of a domain to see its accesses
|
||||
queryset.filter(
|
||||
domain__accesses__user=self.request.user,
|
||||
)
|
||||
# Abilities are computed based on logged-in user's role and
|
||||
# the user role on each domain access
|
||||
.annotate(
|
||||
user_role=Subquery(user_role_query),
|
||||
)
|
||||
.select_related("user")
|
||||
.distinct()
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
||||
class MailBoxViewSet(
|
||||
|
||||
Reference in New Issue
Block a user