mirror of
https://github.com/suitenumerique/docs.git
synced 2026-05-09 16:42:18 +02:00
Custom UserManaged returned profile_contact field when returning users. While this may be useful later, we'd currently rather have it return users.
154 lines
4.8 KiB
Python
154 lines
4.8 KiB
Python
"""Client serializers for the People core app."""
|
|
from rest_framework import exceptions, serializers
|
|
from timezone_field.rest_framework import TimeZoneSerializerField
|
|
|
|
from core import models
|
|
|
|
|
|
class ContactSerializer(serializers.ModelSerializer):
|
|
"""Serialize contacts."""
|
|
|
|
class Meta:
|
|
model = models.Contact
|
|
fields = [
|
|
"id",
|
|
"base",
|
|
"data",
|
|
"full_name",
|
|
"owner",
|
|
"short_name",
|
|
]
|
|
read_only_fields = ["id", "owner"]
|
|
|
|
def update(self, instance, validated_data):
|
|
"""Make "base" field readonly but only for update/patch."""
|
|
validated_data.pop("base", None)
|
|
return super().update(instance, validated_data)
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
"""Serialize users."""
|
|
|
|
timezone = TimeZoneSerializerField(use_pytz=False, required=True)
|
|
|
|
class Meta:
|
|
model = models.User
|
|
fields = [
|
|
"id",
|
|
"email",
|
|
"language",
|
|
"timezone",
|
|
"is_device",
|
|
"is_staff",
|
|
]
|
|
read_only_fields = ["id", "email", "is_device", "is_staff"]
|
|
|
|
|
|
class TeamAccessSerializer(serializers.ModelSerializer):
|
|
"""Serialize team accesses."""
|
|
|
|
abilities = serializers.SerializerMethodField(read_only=True)
|
|
|
|
class Meta:
|
|
model = models.TeamAccess
|
|
fields = ["id", "user", "role", "abilities"]
|
|
read_only_fields = ["id", "abilities"]
|
|
|
|
def update(self, instance, validated_data):
|
|
"""Make "user" field is readonly but only on update."""
|
|
validated_data.pop("user", None)
|
|
return super().update(instance, validated_data)
|
|
|
|
def get_abilities(self, access) -> dict:
|
|
"""Return abilities of the logged-in user on the instance."""
|
|
request = self.context.get("request")
|
|
if request:
|
|
return access.get_abilities(request.user)
|
|
return {}
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
Check access rights specific to writing (create/update)
|
|
"""
|
|
request = self.context.get("request")
|
|
user = getattr(request, "user", None)
|
|
role = attrs.get("role")
|
|
|
|
# Update
|
|
if self.instance:
|
|
can_set_role_to = self.instance.get_abilities(user)["set_role_to"]
|
|
|
|
if role and role not in can_set_role_to:
|
|
message = (
|
|
f"You are only allowed to set role to {', '.join(can_set_role_to)}"
|
|
if can_set_role_to
|
|
else "You are not allowed to set this role for this team."
|
|
)
|
|
raise exceptions.PermissionDenied(message)
|
|
|
|
# Create
|
|
else:
|
|
try:
|
|
team_id = self.context["team_id"]
|
|
except KeyError as exc:
|
|
raise exceptions.ValidationError(
|
|
"You must set a team ID in kwargs to create a new team access."
|
|
) from exc
|
|
|
|
if not models.TeamAccess.objects.filter(
|
|
team=team_id,
|
|
user=user,
|
|
role__in=[models.RoleChoices.OWNER, models.RoleChoices.ADMIN],
|
|
).exists():
|
|
raise exceptions.PermissionDenied(
|
|
"You are not allowed to manage accesses for this team."
|
|
)
|
|
|
|
if (
|
|
role == models.RoleChoices.OWNER
|
|
and not models.TeamAccess.objects.filter(
|
|
team=team_id,
|
|
user=user,
|
|
role=models.RoleChoices.OWNER,
|
|
).exists()
|
|
):
|
|
raise exceptions.PermissionDenied(
|
|
"Only owners of a team can assign other users as owners."
|
|
)
|
|
|
|
attrs["team_id"] = self.context["team_id"]
|
|
return attrs
|
|
|
|
|
|
class TeamSerializer(serializers.ModelSerializer):
|
|
"""Serialize teams."""
|
|
|
|
abilities = serializers.SerializerMethodField(read_only=True)
|
|
accesses = TeamAccessSerializer(many=True, read_only=True)
|
|
slug = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = models.Team
|
|
fields = ["id", "name", "accesses", "abilities", "slug"]
|
|
read_only_fields = ["id", "accesses", "abilities", "slug"]
|
|
|
|
def get_abilities(self, team) -> dict:
|
|
"""Return abilities of the logged-in user on the instance."""
|
|
request = self.context.get("request")
|
|
if request:
|
|
return team.get_abilities(request.user)
|
|
return {}
|
|
|
|
def get_slug(self, instance):
|
|
"""Return slug from the team's name."""
|
|
return instance.get_slug()
|
|
|
|
|
|
class InvitationSerializer(serializers.ModelSerializer):
|
|
"""Serialize invitations."""
|
|
|
|
class Meta:
|
|
model = models.Invitation
|
|
fields = ["email", "team", "role", "issuer"]
|
|
read_only_fields = ["team", "issuer"]
|