serializers.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. from rest_framework import serializers, status
  2. from rest_framework.exceptions import APIException, PermissionDenied
  3. from projects.serializers.serializers import OrganizationProjectSerializer
  4. from teams.models import Team
  5. from teams.serializers import TeamSerializer
  6. from users.models import User
  7. from users.serializers import UserSerializer
  8. from users.utils import is_user_registration_open
  9. from ..models import ROLES, OrganizationUser, OrganizationUserRole
  10. from .base_serializers import OrganizationReferenceSerializer
  11. class OrganizationSerializer(OrganizationReferenceSerializer):
  12. pass
  13. class OrganizationDetailSerializer(OrganizationSerializer):
  14. projects = OrganizationProjectSerializer(many=True)
  15. teams = TeamSerializer(many=True)
  16. openMembership = serializers.BooleanField(source="open_membership")
  17. scrubIPAddresses = serializers.BooleanField(source="scrub_ip_addresses")
  18. class Meta(OrganizationSerializer.Meta):
  19. fields = OrganizationSerializer.Meta.fields + (
  20. "projects",
  21. "openMembership",
  22. "scrubIPAddresses",
  23. "teams",
  24. )
  25. class HTTP409APIException(APIException):
  26. status_code = status.HTTP_409_CONFLICT
  27. class OrganizationUserSerializer(serializers.ModelSerializer):
  28. user = UserSerializer(required=False, read_only=True)
  29. role = serializers.CharField(source="get_role")
  30. roleName = serializers.CharField(source="get_role_display", read_only=True)
  31. dateCreated = serializers.DateTimeField(source="created", read_only=True)
  32. teams = serializers.SlugRelatedField(
  33. many=True, write_only=True, slug_field="slug", queryset=Team.objects.none()
  34. )
  35. isOwner = serializers.SerializerMethodField()
  36. class Meta:
  37. model = OrganizationUser
  38. fields = (
  39. "role",
  40. "id",
  41. "user",
  42. "roleName",
  43. "dateCreated",
  44. "email",
  45. "teams",
  46. "pending",
  47. "isOwner",
  48. )
  49. def __init__(self, *args, request_user=None, **kwargs):
  50. super().__init__(*args, **kwargs)
  51. if "request" in self.context:
  52. organization_slug = self.context["view"].kwargs.get("organization_slug")
  53. self.fields["teams"].child_relation.queryset = Team.objects.filter(
  54. organization__slug=organization_slug
  55. )
  56. def get_extra_kwargs(self):
  57. """email should be read only when updating"""
  58. extra_kwargs = super().get_extra_kwargs()
  59. if self.instance is not None:
  60. extra_kwargs["email"] = {"read_only": True}
  61. extra_kwargs["user"] = {"read_only": True}
  62. return extra_kwargs
  63. def get_isOwner(self, obj):
  64. if owner := obj.organization.owner:
  65. return owner.organization_user_id == obj.id
  66. return False
  67. def create(self, validated_data):
  68. role = OrganizationUserRole.from_string(validated_data.get("get_role"))
  69. email = validated_data.get("email")
  70. organization = validated_data.get("organization")
  71. teams = validated_data.get("teams")
  72. if (
  73. not is_user_registration_open()
  74. and not User.objects.filter(email=email).exists()
  75. ):
  76. raise PermissionDenied("Only existing users may be invited")
  77. if organization.organization_users.filter(email=email).exists():
  78. raise HTTP409APIException(f"The user {email} is already invited", "email")
  79. if organization.organization_users.filter(user__email=email).exists():
  80. raise HTTP409APIException(f"The user {email} is already a member", "email")
  81. org_user = super().create(
  82. {"role": role, "email": email, "organization": organization}
  83. )
  84. org_user.team_set.add(*teams)
  85. return org_user
  86. def update(self, instance, validated_data):
  87. get_role = validated_data.pop("get_role", None)
  88. if get_role:
  89. role = OrganizationUserRole.from_string(get_role)
  90. validated_data["role"] = role
  91. return super().update(instance, validated_data)
  92. def to_representation(self, obj):
  93. """Override email for representation to potentially show user's email"""
  94. self.fields["email"] = serializers.SerializerMethodField()
  95. return super().to_representation(obj)
  96. def get_email(self, obj):
  97. """Prefer user primary email over org user email (which is only for invites)"""
  98. if obj.user:
  99. return obj.user.email
  100. return obj.email
  101. class OrganizationUserDetailSerializer(OrganizationUserSerializer):
  102. teams = serializers.SlugRelatedField(
  103. source="team_set", slug_field="slug", read_only=True, many=True
  104. )
  105. roles = serializers.SerializerMethodField()
  106. class Meta(OrganizationUserSerializer.Meta):
  107. fields = OrganizationUserSerializer.Meta.fields + ("roles",)
  108. def get_roles(self, obj):
  109. return ROLES
  110. class OrganizationUserProjectsSerializer(OrganizationUserSerializer):
  111. projects = serializers.SerializerMethodField()
  112. class Meta(OrganizationUserSerializer.Meta):
  113. fields = OrganizationUserSerializer.Meta.fields + ("projects",)
  114. def get_projects(self, obj):
  115. return obj.organization.projects.filter(team__members=obj).values_list(
  116. "slug", flat=True
  117. )
  118. class ReinviteSerializer(serializers.Serializer):
  119. reinvite = serializers.IntegerField()
  120. def update(self, instance, validated_data):
  121. if validated_data.get("reinvite"):
  122. pass
  123. # Send email
  124. return instance
  125. class OrganizationUserOrganizationSerializer(OrganizationUserSerializer):
  126. """Organization User Serializer with Organization info"""
  127. organization = OrganizationSerializer()
  128. class Meta(OrganizationUserSerializer.Meta):
  129. fields = OrganizationUserSerializer.Meta.fields + ("organization",)
  130. class AcceptInviteSerializer(serializers.Serializer):
  131. accept_invite = serializers.BooleanField()
  132. org_user = OrganizationUserOrganizationSerializer(read_only=True)